certifix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit c70eefbf567914fe5529d82e21d6d3a331dde3b5
parent 7fb8e1142ca6bcb9bf6be532396dac7f701965bb
Author: Daniel Barlow <dan@telent.net>
Date:   Wed,  2 Oct 2024 18:04:42 +0100

polish the README and remove my local config from it

Diffstat:
MREADME.md | 76+++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Ropenssl.cnf -> openssl.cnf.example | 0
2 files changed, 55 insertions(+), 21 deletions(-)

diff --git a/README.md b/README.md @@ -26,53 +26,87 @@ has not been audited. Try it at your own risk._ It's written in [Fennel](https://www.fennel-lang.org). To build it either use Nix or read [package.nix](package.nix) and figure out how to replicate the steps manually. Note that it requires a patch to the -luaossl module +luaossl module. +### CA key and cert + +Create the CA key and the certificate used for signing. You will be +asked a bunch of questions that will be incorporated into the +certificate: when prompted for "Common Name", say "Certificate +Authority" or something like that + +``` +openssl genrsa -out ca.key 4096 +openssl req -addext basicConstraints=critical,CA:TRUE,pathlen:1 --x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt +``` + +### Server key and cert + +The certifix service is exposed over HTTPS, so it needs its own +certificate signed by the CA. Use your hostname when prompted for +Common Name + +``` +openssl req -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 +``` + +### Build and start the server + +The server needs to be told of all of the preceding files, _plus_ a +file containing the expected value of the pre-shared key that you want +it to check client certificate requests against. ``` -# pick a PSK echo 'loves labours lost' > psk chmod 0700 psk +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 +``` -# create CA key and cert used for signing -openssl genrsa -out ca.key 4096 -CN=CA openssl req -config openssl.cnf -addext basicConstraints=critical,CA:TRUE,pathlen:1 --x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.crt +### Try it and see if it works -# 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 +To set the `challengePassword` attribute in a CSR using OpenSSL, you +need to create a configuration file. Copy `openssl.cnf.example` to +`openssl.cnf` and edit it for your setup. + +* the values in `req_distinguished_name` should match your organisation +* the `challengePassword` attribute must match whatever you told the + service to expect (`psk` file in the preceding step) -# 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 +``` +# make CSR +CN=mydevice 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 +# send it to certifix, should get a certificate in response curl --cacert ca.crt -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 +* the CA key is readable by and present in the memory of the process +that reads and parses network requests. Bearing in mind the the whole +point is to automate signing we can only do so much about this, but at +least we could move the actual signing to a separate process which is +only invoked once an acceptable request has been received. -* there is no "intermediate" key: requests are signed by the root key +* there is no intermediate key - the requests are signed directly by the root CA * I haven't checked that the protocols or the ciphers are restricted -to modern and sensible defaults + 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 - - +* probably has wrong basicConstraints in CA cert +* likewise other TLS best practices ## Background - * [RFC 5967 - spec for a CSR](https://datatracker.ietf.org/doc/html/rfc5967) +* [A gentle introduction to ASN1. and DER](https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/) diff --git a/openssl.cnf b/openssl.cnf.example