> On Jan 24, 2018, at 9:21 AM, Danny Horne <da...@trisect.uk> wrote: > >> You can get away with a lot less complexity than the usual OpenSSL CA. >> See, for example: >> >> >> https://raw.githubusercontent.com/openssl/openssl/master/test/certs/mkcert.sh >> >> which creates certificates via "openssl x509 -req" without all the overhead >> of >> a stateful CA. What you'd do differently is password-protect the CA key, and >> perhaps issue certificates with a somewhat shorter lifetime than the 100 >> years >> in that script. >> > I'll stick with what I have for now. Read up about creating a private > CA and it went over my head, I also couldn't figure out what input that > script needed from me
It contains sample code that creates keys, root CAs, intermediate CAs, CA-issued leaf certificates, and self-signed certificates. It was used to create the certificates for the OpenSSL test-suite, and is not as-is intended to be used for other purposes, though enough knobs are likely there to make that possible. Usage examples can be found in: https://raw.githubusercontent.com/openssl/openssl/master/test/certs/setup.sh if anyone wants to take a closer look. That said, it sounds like the path forward is for Postfix to add support for 2-level (private CA and server cert, not just self-signed) certificate chains to the "postfix tls" command. That'll have to wait for 3.4, as 3.3 is almost done at this point, too late to be adding new features, and in any case my cycles are presently too limited. -- Viktor. P.S. A quick overview of mkcert.sh internals (uses some bash-specific features): The key() function generates RSA, DSA, ECDSA, DH or ED25519 keys (if the output file is not already present): key() { local key=$1; shift local alg=rsa if [ -n "$OPENSSL_KEYALG" ]; then alg=$OPENSSL_KEYALG fi local bits=2048 if [ -n "$OPENSSL_KEYBITS" ]; then bits=$OPENSSL_KEYBITS fi if [ ! -f "${key}.pem" ]; then args=(-algorithm "$alg") case $alg in rsa) args=("${args[@]}" -pkeyopt rsa_keygen_bits:$bits );; ec) args=("${args[@]}" -pkeyopt "ec_paramgen_curve:$bits") args=("${args[@]}" -pkeyopt ec_param_enc:named_curve);; dsa) args=(-paramfile "$bits");; ed25519) ;; *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;; esac stderr_onerror \ openssl genpkey "${args[@]}" -out "${key}.pem" fi } the req() function generates a certificate signing request (CSR) after generating a key (if not already present) and list of DN components of the form "name = value": req() { local key=$1; shift key "$key" local errs stderr_onerror \ openssl req -new -"${OPENSSL_SIGALG}" -key "${key}.pem" \ -config <(printf "string_mask=%s\n[req]\n%s\n%s\n[dn]\n" \ "$REQMASK" "prompt = no" "distinguished_name = dn" for dn in "$@"; do echo "$dn"; done) } The cert() function reads a CSR from standard input and creates a signed certificate: cert() { local cert=$1; shift local exts=$1; shift stderr_onerror \ openssl x509 -req -"${OPENSSL_SIGALG}" -out "${cert}.pem" \ -extfile <(printf "%s\n" "$exts") "$@" } The various gen* functions, put these together to create various certificates. Specifically genroot(), genca() and genee() create root CAs, intermediate CAs and End-Entity certificates. This "CA" is stateless, no record is kept of issued certificates, so OCSP and CRLs are not possible.