Go to file
Daniel Barlow 0844177d51 more text, inclding actual reasons you shouldn't use it 2024-09-29 10:20:10 +01:00
Makefile initial commit 2024-09-25 10:20:14 +01:00
README.md more text, inclding actual reasons you shouldn't use it 2024-09-29 10:20:10 +01:00
default.nix initial commit 2024-09-25 10:20:14 +01:00
main.fnl handle CSRs with no attributes 2024-09-29 10:19:07 +01:00
openssl.cnf improve README 2024-09-25 12:07:30 +01:00
package.nix implement policy-based signing 2024-09-25 21:14:13 +01:00
shell.nix add openssl in shell environment 2024-09-25 21:17:42 +01:00

README.md

Certifix

Not an Asterix character.

A small HTTPS API modelled on the description of the Puppet CA "Policy-based autosigning" functionality, that accepts X509 CSRs and automatically signs them without human interaction if they have a custom challengePassword attribute containing a pre-agreed value.

What's it for? I have a bunch of small devices on my LAN that may or may not be able to retain persistent state across reboots. I would like them to be able to talk securely to services on the network using standard TLS with client authentication, and (because "[zero trust] (https://en.wikipedia.org/wiki/Zero_trust_security_model)") without having to rely on network firewall rules to prevent the rest of the world also being able to talk to the service.

To try it out

This is alpha-quality code which was written by someone with only the most passing familiarity with TLS or cryptography in general, and has not been audited. Try it at your own risk.

It's written in Fennel. To build it either use Nix or read package.nix and figure out how to replicate the steps manually. Note that it requires a patch to the luaossl module

# pick a PSK
echo 'loves labours lost' > psk
chmod 0700 psk

# create CA key and cert used for signing
openssl genrsa -out ca.key 4096
CN=CA openssl req -config openssl.cnf -x509 -new -nodes -key ca.key -sha256 -days 3650  -out ca.crt

# create key for the server and sign it with the CA
CN=localhost openssl req -config openssl.cnf -newkey rsa:2048 -nodes -keyout server.key --out server.csr
openssl x509 -req -in server.csr -days 365 -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt

# create example client CSR for testing (check openssl.cnf against "psk" file)
CN=rotuer openssl req -config openssl.cnf -newkey rsa:2048 -nodes -keyout client.key -out client.csr

# build and start the server
nix-build && result/bin/certifix  --challenge-password psk  --ca-certificate ca.crt --ca-private-key --server-certificate server.crt --server-private-key server.key localhost:19613
# send it
curl -v -H 'content-type: application/x-pem-file' --data-binary @client.csr  https://localhost:19613/sign

Reasons this is not secure

  • the CA key is present in the memory of the process that reads and parses network requests

  • there is no "intermediate" key: requests are signed by the root key

  • I haven't checked that the protocols or the ciphers are restricted to modern and sensible defaults

  • doesn't set 4.2.1.6. Subject Alternative Name

  • doesn't set Key Usage extension (https://www.rfc-editor.org/rfc/rfc5280#section-4.2.1.3)

  • likewise other TLS best practices

Background