How to add SubjectAltNames to end-entity certificate in private PKI

certificatesopensslssl

We have an internal/private PKI that issues certificates so only the employees of the company can access some subdomains (for example admin.example.com).

Here is the script we used to generate the certificates:

names="john maria foo bar"

for name in $names; do
        echo "$name"
        openssl genrsa -aes256 -out $name.key 2048

        # Creating the certificate signing request
        openssl req -new -key $name.key -out $name.csr

        # Signing the certificate
        openssl ca -in $name.csr -out $name.crt

        # Exporting both the key and the certificate in a p12 file
        openssl pkcs12 -export -clcerts -in $name.crt -inkey $name.key -out $name.p12
        # And now a bit of cleaning
        rm $name.csr
done

The script generates a .key , .crt and .p12 files for each employee, the employee can then add his p12 file to his browser (along with the company's CA Root certificate) to access the subdomain.

But recently, it wasn't working anymore with chrome, apparently there has been an update and we need to have SANs (Subject Alt Names) in the personals certificates used by the employees.

Following FAQ/subjectAltName (SAN), I modified the OpenSSL configuration file:

[req]
req_extensions = v3_req

[ v3_req ]

# Extensions to add to a certificate request

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = admin.example.com
DNS.2 = admindashboard.example.com

but the resulting certificate didn't contain the SANs.

I removed the last part of the script which destroyed the .csr file, relaunched the script and tested a csr file with the command

openssl req -text -noout -in john.csr | grep DNS

At this point it seems to work since I got

DNS:admin.example.com, DNS:admindashboard.example.com

as a result.

But when I test the crt file with

openssl x509 -text -noout -in john.crt | grep DNS

I get nothing.

Am I missing something ?

Best Answer

OpenSSL will only copy the extension from the request to the certificate if it is configured to do so.

The option is called copy_extensions within the [ca] section of your config file.

If it is missing, or set to none then no extensions will be copied from your request to your certificate.

If set to copy it will copy any additional extensions from the request that are not in the certificate.

If set to copyall it will copy all extensions, overwriting any that are in the certificate.

man ca will tell you about it. It also comes with a warning. If you causally sign any request with the openssl ca command, when this option is set; you could end up issuing certificate with extensions such as CA:True. Check your requests first.

Related Question