[HCoop-Discuss] SSL without warnings (ie X.509 v3)

Anders Petersson demitar at worldforge.org
Thu Sep 14 08:24:31 EDT 2006


(This became rather long and probably belongs on the wiki, I'll just 
toss it out here first though and we'll see what becomes of it.)

I've investigated the murky depths of (Open)SSL and discovered how we 
can use a single SSL certificate for all hcoop hosted domains. (I 
stumbled upon this while experimenting with shared certificiates, which 
basically are globbing patterns for hostnames.)

X.509 is the standard for certificate metadata. In version 1 you set the 
CN (Common Name) to the (virtual) host which the client tries to connect 
to and if  they do not match the client warns the user.

X.509 version 3 allows a number of extensions, among those the most 
interesting one is subjectAltName, it allows you to specify a list of 
names (not only hostnames) the certificate is valid for.

subjectAltName is detailed in http://rfc.sunsite.dk/rfc/rfc2459.html and 
http://www.openssl.org/docs/apps/x509v3_config.html#Subject_Alternative_Name_

The subjectAltName is of the form:

subjectAltName=DNS:hcoop.net,DNS:members.hcoop.net,DNS:soddensquirrel.net

and so on. They also allow the same basic globbing as CN names does.

For self-signed certificates the subjectAltName line should be in the 
[v3_ca] section of the config and for sign requests in the [v3_req] 
section. Also the x509_extensions and req_extensions fields need to 
contain v3_ca and v3_req respectively.

Most likely we'll want the v1 field CN (only accepting a single name) to 
be set to members.hcoop.net meaning if a client doesn't support v3 
(quite unlikely today) we'll still be no worse off than we already are.

This way we could generate a single certificate for all the domains 
hosted, we could even have domtool generate it for all the specified ssl 
hosts automagically. You want a complete copy of openssl.cnf (here it's 
located in /etc/ssl) to be modified since openssl doesn't accept more 
than one -config option (the latter overwrite the complete previous).

However, the fun does not end here.

If we generate new self-signed certificates the users will have to 
accept a new certificate every time we add a new ssl host.

The solution is to generate a certificate authority and sign the newly 
generated certificates using that. That way the users only have to 
install that single certificate authority, or even better, we get ours 
signed from an upsteam source, such as http://www.cacert.org/

To set up our own Certificate Authority we need to take the following steps:

 1. Create a directory, say hcoop.netCA/

 2. In that directory create the directories hcoop.netCA/newcerts/ and 
hcoop.netCA/private/

 3. Create a serial file: echo "01" > hcoop.netCA/serial

 4. Create an index: touch hcoop.netCA/index.txt

 5. Finally generate our CA key:

     * Self signed: openssl req -x509 -newkey rsa:1024 -keyout 
hcoop.netCA/private/cakey.pem -out hcoop.netCA/cacert.pem -days 9999 
-nodes -config openssl.cnf

     * Or to be signed: openssl req -new -key 
hcoop.netCA/private/cakey.pem -out req.pem -config openssl.cnf

Now since we want the v3 fields to get into our signed certificate we'll 
have to enable copy_extensions = copy in the CA section [CA_default] 
most likely.

Also we probably want the CA policy to allow different organizations in 
the signed certificates, which means we want to change organizationName 
in [policy_match] from match to supplied.

Finally we're ready to start signing our own keys:

 1. Generate a whole new key and certificate request (it's possible to 
generate them separately and reuse the key in the future - only generate 
a new certificate request - see the x509 manpage): openssl req -new -key 
key.pem -out req.pem -config openssl.cnf

 2. Then we sign it using our CA: openssl ca -in req.pem -out 
newcert.pem -config openssl.cnf

 3. And finally we make them something the server likes: cat key.pem 
newcert.pem > server.pem

Finally, I've attached the config I've experimented with and the diff 
against the system default.

There are ways to make openssl not prompt for specifics basically you 
chenge the [req_distinguished_name] section to something like:

[ req_distinguished_name ]
C = GB
ST = Test State or Province
L = Test Locality
O = Organization Name
OU = Organizational Unit Name
CN = Common Name
emailAddress = test at email.address

and

[ req_attributes ]
challengePassword =

This is all detailed in http://www.openssl.org/docs/apps/req.html

There is one issue which I'm not quite certain of though, which is how 
our CA sitting in the middle is exposed to the client. Perhaps it's 
determined by an apache directive?

Oh, and I should probably turn this into a wiki page instead. :)

Be sure to let me know what is confusing in here.





More information about the HCoop-Discuss mailing list