new package certifix-client uses certifix to sign ssl client cert

this is initially for TLS-enabled logging but would be useful for
anything on a liminix box that wants to talk to a network service in a
"zero trust" setup
This commit is contained in:
Daniel Barlow 2024-10-03 22:50:21 +01:00
parent 7ca822c826
commit 197e2eb5b1
4 changed files with 126 additions and 0 deletions

View File

@ -0,0 +1,80 @@
(local { : view } (require :fennel))
(local { : assoc : split } (require :anoia))
(local ctx (require :openssl.ssl.context))
(local csr (require :openssl.x509.csr))
(local pkey (require :openssl.pkey))
(local xn (require :openssl.x509.name))
(local http (require :fetch))
(macro ncall [f]
`(case ,f
ok# ok#
(nil err#) (error err#)))
(fn x509-name [subj]
(let [n (xn.new)]
(each [_ c (ipairs (split "," subj))]
(let [(k v) (string.match c "(.-)=(.+)")]
(n:add k v)))
n))
(fn parse-args [args]
(case args
["--secret" secret & rest]
(assoc (parse-args rest)
:secret (with-open [f (ncall (io.open secret :r))] (f:read "l")))
["--subject" subject & rest]
(assoc (parse-args rest) :subject subject)
["--key-out" pathname & rest]
(assoc (parse-args rest) :key-out pathname)
["--certificate-out" pathname & rest]
(assoc (parse-args rest) :certificate-out pathname)
[server] { : server }
_ {}))
(local options (parse-args arg))
(fn private-key []
(pkey.new { :type :rsa :bits 1024 }))
(fn signing-request [pk]
(doto (csr.new)
(: :setVersion 3)
(: :setSubject (x509-name options.subject))
(: :setPublicKey pk)
(: :addAttribute :challengePassword [options.secret])
(: :sign pk)))
(fn http-post [url body]
(match
(http.request "POST" url
"" 0
"application/x-pem-file"
body)
s s
(nil code msg) (error (.. "Error " code " POST " url ": " msg))))
(fn run []
(let [pk (private-key)
csr (signing-request pk)
;; key-out (or options.key-out-handle io.stdout)
;; cert-out (or options.cert-out-handle io.stdout)
cert (http-post options.server (csr:toPEM))]
(with-open [f (ncall (io.open options.key-out :w))]
(f:write (pk:toPEM :private)))
(with-open [f (ncall (io.open options.certificate-out :w))]
(f:write cert))
(print "done")))
{ : run }

View File

@ -0,0 +1,36 @@
{
fetchurl,
writeFennel,
fennel,
fennelrepl,
runCommand,
lua,
anoia,
lualinux,
fetch-freebsd,
openssl,
luaossl',
stdenv
}:
let name = "certifix-client";
in stdenv.mkDerivation {
inherit name;
src = ./.;
buildInputs = [fetch-freebsd openssl lua];
buildPhase = "";
installPhase = ''
mkdir -p $out/bin
cp -p ${writeFennel name {
packages = [
fetch-freebsd
fennel
anoia
lualinux
luaossl'
] ;
mainFunction = "run";
} ./${name}.fnl } $out/bin/${name}
'';
}

View File

@ -0,0 +1,9 @@
(local { : view } (require :fennel))
(local ctx (require openssl.ssl.ctx))
(fn run []
(print "hey"))
{ : run }

View File

@ -60,6 +60,7 @@ in {
# please keep the rest of this list alphabetised :-)
anoia = callPackage ./anoia { };
certifix-client = callPackage ./certifix-client { };
devout = callPackage ./devout { };
fetch-freebsd = callPackage ./fetch-freebsd { };
fennel = callPackage ./fennel { };