wissel.net

Usability - Productivity - Business - The web - Singapore & Twins

A certificate wants a SAN


Following my recent blog about creating you own CA you will find out, like I did, that the certs are quite wanting.

The Subject Alternate Name (SAN)

Even after importing the ca-chain.cert.pem into your keyring / keystore Chrome will barf at the certificate, complaining about a missing SAN.

The idea of a SAN is to allow additional name variations to be recognised for one given certificate, reducing the effort for multi-purpose servers. E.g.: myawesomesite.com, www.myawesomesite.com, myawesomesite.io, www.myawesomesite.com, crazydata.com

I tried really hard, but at the time of writing, it seems the only way to create SAN for your certs is to provide a configuration file. I didn't find a command line option (short of various attempts on redirection and pipeing).

The hack I came up with:

Edit the intermediate\openssl.cnf and add to the [ server_cert ] section one line: subjectAltName = @alt_names. The @ sign tells OpenSSL to look for a section with that name and expand its content as the parameter.

Using the following shell script generates a certificate that works for:

  • www.domain (e.g. www.awesome.io)
  • domain (e.g. awesome.io)
  • domain.local (e.g. awesome.io.local)

The last one is helpful when you want to try SSL on localhost and amend your hosts file to contain awesome.io.local

#!/bin/bash
# Create new server certificates with the KEEP intermediate CA
if [ -z "$1" ]
  then
    echo "Usage: ./makecert.sh domain_name (without www) e.g. ./makecert.sh funsite.com"
    exit 1
fi
export SSL_DOMAIN_NAME=$1
export CONFNAME=intermediate/$1.cnf
cat intermediate/openssl.cnf > $CONFNAME
echo [alt_names] >> $CONFNAME
echo DNS.0 = $SSL_DOMAIN_NAME >> $CONFNAME
echo DNS.1 = www.$SSL_DOMAIN_NAME  >> $CONFNAME
echo DNS.2 = $SSL_DOMAIN_NAME.local  >> $CONFNAME
openssl ecparam -genkey -name prime256v1 -outform PEM -out intermediate/private/$SSL_DOMAIN_NAME.key.pem
chmod 400 intermediate/private/$SSL_DOMAIN_NAME.key.pem
openssl req  -config $CONFNAME  -key intermediate/private/$SSL_DOMAIN_NAME.key.pem -new -sha256 -out intermediate/csr/$SSL_DOMAIN_NAME.csr.pem
openssl ca -config $CONFNAME -extensions server_cert -days 375 -notext -md sha256 -in intermediate/csr/$SSL_DOMAIN_NAME.csr.pem -out intermediate/certs/$SSL_DOMAIN_NAME.cert.pem
chmod 444 intermediate/certs/$SSL_DOMAIN_NAME.cert.pem
openssl pkcs12 -export -in intermediate/certs/$SSL_DOMAIN_NAME.cert.pem -inkey intermediate/private/$SSL_DOMAIN_NAME.key.pem -out intermediate/private/$SSL_DOMAIN_NAME.pfx -certfile intermediate/certs/ca-chain.cert.pem
rm $CONFNAME

This will settle the Subject Alternate Name challenge. There are a more challenges to be had. Depending on what application you use, you need to import your intermediate keychain ca-chain.cert.pem in multiple places in different formats (Remember, I urged you not to do that in production!).

On Mac and Linux you have a keychain, but NodeJS and Java don't recognize them. Edge (and its older sibling) have their own key store, as has Firefox. Python, depending on version and library, has its own ideas about keys too. So manual management is a PITA.

As usual YMMV


Posted by on 26 October 2019 | Comments (0) | categories: HTTP(S) Networking OpenSource WebDevelopment

Comments

  1. No comments yet, be the first to comment