How to create multidomain certificates using config files

openssl can make life easy be creating its keys, CSRs and certificates on the basis of config files. Creating these config files, however, is not easy! This page is the result of my quest to to generate a certificate signing requests for multidomain certificates.

This is a working configuration which is explained below:

# OpenSSL configuration to generate a new key with signing requst for a x509v3 
# multidomain certificate
#
# openssl req -config bla.cnf -new | tee csr.pem
# or
# openssl req -config bla.cnf -new -out csr.pem
[ req ]
default_bits       = 4096
default_md         = sha512
default_keyfile    = key.pem
prompt             = no
encrypt_key        = no

# base request
distinguished_name = req_distinguished_name

# extensions
req_extensions     = v3_req

# distinguished_name
[ req_distinguished_name ]
countryName            = "DE"                     # C=
stateOrProvinceName    = "Hessen"                 # ST=
localityName           = "Keller"                 # L=
postalCode             = "424242"                 # L/postalcode=
streetAddress          = "Crater 1621"            # L/street=
organizationName       = "apfelboymschule"        # O=
organizationalUnitName = "IT Department"          # OU=
commonName             = "example.com"            # CN=
emailAddress           = "webmaster@example.com"  # CN/emailAddress=

# req_extensions
[ v3_req ]
# The subject alternative name extension allows various literal values to be 
# included in the configuration file
# http://www.openssl.org/docs/apps/x509v3_config.html
subjectAltName  = DNS:www.example.com,DNS:www2.example.com # multidomain certificate

# vim:ft=config
The quotes are not strictly neccessary, but without them strange things happen if the value contains e.g. an apostrophe.

req / [ req ]

openssl req creates and processes certificate requests. It reads the [ req ] section of the config file.

Some of the available options:

Section distinguished_name

In the default mode with prompting, the user is asked for the values. Default values can be defined by duplicating the option and appending _default to the name. This is what is in the examples all over the web, and it's annoying if all you want is to define a certain CSR for later use. If prompt is set to yes, the value will be taken directly from the option which defined the prompt in interactive mode. The _default-options are no longer valid. This is documented in openssl-req. (But where are the valid options in this section documented?)

The order of the definitions is relevant. If for example postalCode is directly under CN, the result will be CN=…/postalCode=…. If postalCode is under countryName the result will bm C=…/postalCode=…. The order in the example is modelled after a certificate bought from a real CA.

Section req_extensions

This option defines a section for X.509 v3 extension. Valid options documented in man openssl-x509v3_config. Note that half of the man page only affects CA actions.

Requests for multidomain certificates are done by requesting a Subject Alternative Name x509v3 extensions with the DNS literal.

Result

This is what that CSR looks like
mori@apfelboymchen:/tmp $ openssl req -config bla.cnf -new | openssl req -text -noout
Generating a 512 bit RSA private key
.++++++++++++
............++++++++++++
writing new private key to 'key.pem'
-----
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=DE, ST=Hessen, L=Keller/postalCode=424242/street=Crater 1621, O=apfelboymschule, OU=IT Department, CN=example.com/emailAddress=webmaster@example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (512 bit)
                Modulus:
                    00:9b:9a:de:a2:29:5c:d2:50:80:af:6e:d4:43:f9:
                    63:58:ec:b5:b0:9f:8b:40:89:88:ce:14:ff:47:ec:
                    a4:18:81:33:fa:47:8f:c8:58:92:00:b4:89:27:0c:
                    71:d3:0f:e5:83:5c:e3:ad:41:d5:30:38:5d:a5:3d:
                    58:a4:27:ac:17
                Exponent: 65537 (0x10001)
        Attributes:
        Requested Extensions:
            X509v3 Subject Alternative Name: 
                DNS:www.example.com, DNS:www2.example.com
    Signature Algorithm: sha1WithRSAEncryption
        08:94:37:9c:ac:03:07:aa:ca:ae:69:ed:38:db:57:0f:da:92:
        78:06:45:bd:24:9d:05:d7:76:92:49:b6:f3:9b:5c:c1:77:c5:
        e0:c4:a7:6b:63:82:01:44:48:f2:63:73:fb:2b:e9:14:45:56:
        a1:d4:e3:54:8a:2f:fb:53:06:34

Multiple CNs

I once bought a certificate where I defined the multidomains in a browser textfield instead of the CSR. The certificate that came back not only had the X.509 extension, but also multiple CNs. The following distinguished_name-snippet reproduces this. I don't know if this is neccessary or even a good idea though. The certificate also had the domain from the CN duplicated in the extension, which doesn't look right either and makes me suspicious of the whole thing.
[ req_distinguished_name ]
countryName            = "DE"                             # C=
stateOrProvinceName    = "Hessen"                         # ST=
localityName           = "Keller"                         # L=
postalCode             = "424242"                         # L/postalCode=
streetAddress          = "Crater 1621"                    # L/street=
organizationName       = "apfelboymschule"                # O=
organizationalUnitName = "IT Department                   # OU=
0.commonName           = "example.com"                    # CN=
emailAddress           = "netzwerk@example.com"           # CN/emailAddress=
1.commonName           = "www.example.com"                # CN=
2.commonName           = "www2.example.com"               # CN=
3.commonName           = "www3.example.com"               # CN=

Multidomain certificates as a CA

So now I have a CSR with multidomain request. What I couldn't get to work yet was to automatically use this information as the signing CA.

See also

A man page giving a generic overview of the configuration seems to have been axed. It's not on my system or on www.openssl.org, but still on the web: man openssl.cnf.

Licensed under the Creative Commons Attribution-Share Alike 3.0 License.