Certified, with multiple identities

I’ve just had to generate a new self-signed X.509 certificate for an internal website at work, and I thought I’d generate a certificate with multiple names, so we can refer to it as “www.foo.org”, and “foo.org”, and “machine.foo.org”, and all of the other variants that people are likely to generate.

It wasn’t easy to find the exact incanctations needed, but for the record, here they are:

The hardest bit is understanding the structure of the configuration file, and what bits do what. The documentation (i.e. man pages) isn’t all that clear about the structure of it all. Let’s assume that the machine is called “colin.example.com”, and also serves www.colin.example.com. There are three sections needed in the config file. I’ll go through each one in turn.

[req]
default_bits = 1024
default_md = rsa
x509_extensions = v3_ext
distinguished_name = colin_dname

The first section, above, is the “base” for the request. I think that the section name must be [req], and that this matches the openssl req command used later on. The distinguished_name parameter refers to a section in the file (which can have any name), which contains the DN for the certificate. I’m not convinced that the x509_extensions actually does anything here.

[colin_dname]
countryName             = Country
stateOrProvinceName     = County
localityName            = Town
organizationName        = Organization Name
organizationalUnitName  = Organization Unit Name
commonName_max          = 64
emailAddress            = Email
emailAddress_max        = 40
commonName                      = Common Name

countryName_default             = GB
stateOrProvinceName_default     = Farkingshire
localityName_default            = Magnum Parva
organizationName_default        = Example, Ltd.
organizationalUnitName_default  = Department of Infernal Investigations
emailAddress_default            = john@example.com
commonName_default              = colin.example.com

The second section is the one referred to by the distinguished_name parameter in the first section. The first chunk of this section is the prompts for the various DN sections when the certificate is generated. The second chunk (with the _default suffixes) gives the default answers for those prompts.

[v3_ext]
subjectAltName = DNS:www.colin.example.com, DNS:colin.example.com

The last section, as with the second section, can have any name you like. It’s referred to by the x509_extensions parameter in the first section, but, as I said, I’m not sure if that has any effect. You can supply a comma-separated list of alternative names as values to the subjectAltName parameter here. There are a whole range of other options that can be supplied here, too. See man x509v3_config for the options and syntaxes.

Using the configuration

Create the private key data:

$ openssl genrsa -out certificate.key

Create a certificate request based on the data in the config file. The -config option refers to the config file we created above. The -extensions option points at the section of the file containing the extension parameters.

$ openssl req -new -key certificate.key -out certificate.csr -config config -extensions v3_ext

Sign the certificate request:

$ openssl x509 -req -days 365 -in certificate.csr -signkey certificate.key -out certificate.crt -extensions v3_ext -extfile config

Inspect the certificate:

$ openssl x509 -in certificate.crt -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            aa:bb:cc:dd:ee:ff:00:11
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=GB, ST=Farkingshire, L=Magnum Parva, O=Example Ltd., OU=Department of Infernal Investigations/emailAddress=john@example.com, CN=colin.example.com
        Validity
            Not Before: Oct 23 12:16:12 2008 GMT
            Not After : Oct 23 12:16:12 2009 GMT
        Subject: C=GB, ST=Farkingshire, L=Magnum Parva, O=Example Ltd., OU=Department of Infernal Investigations/emailAddress=john@example.com, CN=colin.example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (512 bit)
                Modulus (512 bit):
                    00:ff:66:ee:aa:fd:e7:8b:4c:8f:a5:88:a7:ea:40:
                    5d:1b:75:26:0e:47:58:41:14:c2:ee:05:4d:ee:c3:
                    78:95:cb:12:df:77:10:2b:71:1d:dd:47:7e:25:6c:
                    e6:e5:dc:ae:77:cd:7c:cf:04:aa:d5:02:93:6c:ee:
                    6e:31:3b:c6:df
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Alternative Name: 
                DNS:www.colin.example.com, DNS:colin.example.com
    Signature Algorithm: sha1WithRSAEncryption
        58:44:22:1f:0e:55:89:ea:ff:95:c0:77:7f:93:00:e6:53:bd:
        e2:55:de:89:49:44:d8:1e:39:55:9a:08:42:77:8b:06:dd:ab:
        62:ad:ff:19:b9:d3:aa:6f:c9:6b:e4:33:d1:9b:82:43:44:80:
        62:88:6b:3c:8e:8f:aa:67:a3:a4
-----BEGIN CERTIFICATE-----
…

The important bits to see here are that the version number is 3, and that there is an X509v3 Subject Alternative Name section. If you’ve got those, then your self-signed certificate is ready to go.