commit 197e2eb5b1576bd10f2ab02f8b809c8163e814df
parent 7ca822c8265ba86ade57ad01d71dd55bf4f3476b
Author: Daniel Barlow <dan@telent.net>
Date: Thu, 3 Oct 2024 22:50:21 +0100
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
Diffstat:
4 files changed, 126 insertions(+), 0 deletions(-)
diff --git a/pkgs/certifix-client/certifix-client.fnl b/pkgs/certifix-client/certifix-client.fnl
@@ -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 }
diff --git a/pkgs/certifix-client/default.nix b/pkgs/certifix-client/default.nix
@@ -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}
+ '';
+}
diff --git a/pkgs/certifix-client/main.fnl b/pkgs/certifix-client/main.fnl
@@ -0,0 +1,9 @@
+(local { : view } (require :fennel))
+(local ctx (require openssl.ssl.ctx))
+
+(fn run []
+ (print "hey"))
+
+
+
+{ : run }
diff --git a/pkgs/default.nix b/pkgs/default.nix
@@ -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 { };