Time to start using Subject Alternative Names

I have been experimenting with my personal/test CA recently, since I wanted to try out the extension for Subject Alternative Names and make a Unified Communications Certificate to enable me to use name-based virtual hosts using SSL on a single IP address, something that was well-known to be impossible before.

Due to the particular circumstances that made me look into this, I was going to get this working under Microsoft’s IIS 7.5. I already knew that I couldn’t generate the CSR under IIS since it doesn’t really support the SAN extension. For the real certificate that I would ultimately use, I placed an order with GeoTrust and their online ordering system elegantly rewrote the data from my request, adding among other things the Subject Alternative Names.

However, I wanted to test this immediately rather than waiting for them to verify my shoe size and whatever, so I decided to create a UCC using my own test CA. The procedure turned out to be relatively simple. Just add a few lines to the [ v3_req ] section in openssl.cnf:

subjectAltName   = @alt_names 
 
[alt_names]
DNS.1 = name1.domain.com
DNS.2 = name2.domain.com
DNS.3 = name3.domain.com
DNS.4 = name4.domain.com

Now create a certificate request using a suitable CN and sign it, and it should work!

The easiest way to install this into IIS is to first use openssl’s pkcs12 command to export both the private key and the certificate into a pkcs12 file:

openssl pkcs12 –exportin newcert.pem –inkey newkey.pem –out mycert.p12

Copy the file over to the server and importing it there. You need to import it into the local computer’s certificate store, however. Use the Certificates snap-in to mmc or import it directory using the IIS Management Console.

I should probably point out that private keys aren't really meant to be handled like this. They should be created on the system that will be using the key/certificate, and not moved around. This was only done for test purposes, and because IIS can't create the right kind of CSR.

Now you can go to one of your servers, edit the “bindings” and select this certificate for SSL. However, you will probably find the “Host name” box greyed out, which is something IIS routinely does for SSL bindings.

The fix is simple: Start mmc, add the Certificates snap-in for the local computer, find your certificate under “Personal”, double click on it, go to Details and click “Edit…”. Now you get to add a “friendly name” to the certificate, and there’s the key. Set the name to “*.domain.com” (for the above example) and go back to the IIS Management Console. Vollalla! Now you can edit the Host name.

After this fix, you can change the SSL binding for all those web servers to use the same certificate and IP address, and also to use name-based virtual host selection!

The first issue I ran into was that the CN was actually ignored by the client when subjectAltName was present. Thus, the first domain name, which I had set to the CN, didn’t work when I installed it to the server. This is in fact according standard: RFC 2818 section 3.1 says so:

If a subjectAltName extension of type dNSName is present, that MUST be used as the identity. Otherwise, the (most specific) Common Name field in the Subject field of the certificate MUST be used. Although the use of the Common Name is existing practice, it is deprecated and Certification Authorities are encouraged to use the dNSName instead.

After issuing a new certificate with all hostnames as subjectAltNames, it worked.

Since I wanted to test this properly, I tried it out with various browsers, and once again ran into an unexpected problem: Safari for Windows, alone, complained that the server couldn’t be verified.

Strangely enough, the certificate details showed the certificate as OK, and the root CA certificate was also OK, so I was stumped for a bit. Then I found the explanation in a discussion online: Safari does a CRL check on the certificate, and if that fails for some reason, it gives this warning. The “details” windows for the certificate actually shows this as an error if you look closely.

Of course, I never bothered to set up any kind of CRL support in my little test CA, and so I set out to do so, verify that this was indeed the problem, and get rid of this warning, I set out to do so.

First, to create an empty CRL for my CA:

openssl ca -gencrl -out crl.pem

My first attempt to publish this placeholder CRL was of course the most ambitious one. I found this guide to setting up an OCSP responder, which I followed, more or less. Then I added a reference to this responder to my openssl.cnf and made a new certificate:

authorityInfoAccess = OCSP;URI:http://ocsp.liss.pp.se/

This didn’t help. Safari still displayed the warning. So I looked up the simple, pre-OCSP way of serving CRLs, and set up a new web server for this purpose. Then I added yet another line to my openssl.cnf and made yet a new certificate:

crlDistributionPoints=URI:http://ca.liss.pp.se/liss.crl

This time it worked perfectly. Safari opened the page without complaining, and also showed that it had done a CRL check.

Easy-peasy. Took only half a day, all in all. And I’m still waiting for the GeoTrust cert.

Update

The GeoTrust certificate arrived, and I had another little problem, although easily solved. When trying to complete the certificate request in the IIS Management Console, I received the message

Cannot find the certificate request associated with this certificate file. A certificate request must be completed on the computer where it was created.

After a while I found this page, which said (Note, at point 7) to check if the certificate hadn't been installed after all, and it turned out it had.

Another piece of trivia was that, although I had ordered a certificate with one of the host names as CN and the rest as SAN records, they did in fact include the CN host name among the SAN records as well. This is apparently common practice.