Using OpenSSL as a Certificate Authority

by Mark Wilkinson

$Id: ssl-openssl-ca.html,v 1.3 2003/08/15 14:20:00 mhw Exp $

Background

These instructions were prepared using OpenSSL version 0.9.6b running on Red Hat Linux 7.2. Pathnames may vary for other installations, or if you build the package from source code.

The openssl program contains a large collection of tools for performing operations related to the SSL protocol. Unfortunately, user-friendlyness wasn't high on the list of requirements when it was being written. OpenSSL comes with a Perl wrapper script called CA.pl though, and this simplifies certificate management operations somewhat.

Setting Things Up

To get things going you need to find the CA.pl script and use it to create a directory hierarchy and the certification authority key pair1. For convenience we'll copy the CA.pl script into the directory hierarchy; on a Red Hat Linux system it is installed in /usr/share/ssl/misc/CA.pl. Points where I had to enter information are highlighted.

[mhw@kremvax ssl]$ cp /usr/share/ssl/misc/CA.pl ca
[mhw@kremvax ssl]$ ./ca -newca
CA certificate filename (or enter to create)
press Enter
Making CA certificate ...
Using configuration from /usr/share/ssl/openssl.cnf
Generating a 1024 bit RSA private key
.........++++++
...............................++++++
writing new private key to './demoCA/private/cakey.pem'
Enter PEM pass phrase: enter a pass phrase
Verifying password - Enter PEM pass phrase: enter a pass phrase
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:GB
State or Province Name (full name) [Some-State]:West Yorkshire
Locality Name (eg, city) []:Leeds
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Diagonal Solutions
Organizational Unit Name (eg, section) []:Diagonal Solutions Certification Authority
Common Name (eg, your name or your server's hostname) []:Diagonal Solutions Signing Key
Email Address []:certification@diagonal-solutions.co.uk
[mhw@kremvax ssl]$ 

This should create a new directory hierarchy called demoCA within which are a few other files and directories. Amongst them are:

demoCA/private/cakey.pem
The private key for the certification authority.
demoCA/cacert.pem
The signed certification authority certificate.
These files are in a format known as PEM: ASN1 DER data that has been optionally encrypted (using a DES3 cypher by default) and MIME base64 encoded with headers and footers added. You can look at them in an editor, but you won't learn much from doing so. Instead, you can use openssl to decode the files. The certificate file looks like this:
-----BEGIN CERTIFICATE-----
MIIEljCCA/+gAwIBAgIBADANBgkqhkiG9w0BAQQFADCB6DELMAkGA1UEBhMCR0Ix
[omitted]
Ze2xQolf13goaXTn7AkdjJgh5Z7YrJusIvI=
-----END CERTIFICATE-----
Use openssl to print the information in a certificate:
[mhw@kremvax ssl]$ openssl x509 -text -noout -in demoCA/cacert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 0 (0x0)
        Signature Algorithm: md5WithRSAEncryption
        Issuer: C=GB, ST=West Yorkshire, L=Leeds, O=Diagonal Solutions, OU=Diagonal Solutions Certification Authority, CN=Diagonal Solutions Signing Key/Email=certification@diagonal-solutions.co.uk
        Validity
            Not Before: Mar  6 16:25:27 2002 GMT
            Not After : Mar  6 16:25:27 2003 GMT
[omitted]
[mhw@kremvax ssl]$ 
The private key file looks like this:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,788C9567EB21832A

mzRR07HI7T5gM9iw1EfX1KofvdSYfnc/3cxDJqkfJj+dZkETR/1w/2xUexeydg3M
[omitted]
JpAlFay8kjDVwXtH2/EJpNneUuyKcEmHIQ5xNCXVTuhABTNJRK6jiA==
-----END RSA PRIVATE KEY-----
from which you can glean that the file is DES3 encrypted. There's not much to be learned from printing the private key out, but here's the command to use if you're interested:
[mhw@kremvax ssl]$ openssl rsa -text -noout -in demoCA/private/cakey.pem
You'll need to enter the PEM pass phrase to decrypt the private key file.

Making a Certificate for your Server

Once you've got the certification authority set up you can create keys for your servers and sign them to make certificates. There are basically three steps in this process:

  1. Generate a public and private key pair, and a certificate request. The certificate request is the server's public key combined with some information about you, your organization and the server. The server software that you're using might come with a tool to do this, or you can use openssl to do the work.
  2. Sign the certificate request using the certification authority key.
  3. Deploy the signed certificate (and possibly the keys) to the server.
I like to keep all the files for a given server in a sub-directory named after the server. I'll use ${D} to represent this directory in the following. You should start by creating the directory for your server:
[mhw@kremvax ssl]$ D=bugs2
[mhw@kremvax ssl]$ mkdir ${D}
[mhw@kremvax ssl]$ 

Generate a Key Pair and a Certificate

The main trick here is to work out what each of the files you're dealing with represent. This is not as easy as it sounds because different pieces of software use different naming conventions. Here's a quick reference:

  private key certificate request certificate notes
OpenSSL CA script   newreq.pem newcert.pem  
Red Hat 7.2 Apache2 server.key   server.crt  
AOLserver 2.3 newkey.pem newreq.pem newcert.pem server generates key and request: read my instructions

You might also find that some pieces of software like to generate their own private keys and certificate requests. The instructions that follow assume that you're generating a certificate for an Apache web server using mod_ssl.

You will also need to decide whether you want to encrypt your private key. Encrypting the private key is a good idea in theory: it prevents people stealing your key and then impersonating you using it. However, it also requires you to be present when your server restarts: the server software will need to decrypt the key using the pass phrase in order to use it.

To generate an encrypted private key, do this:

[mhw@kremvax ssl]$ openssl genrsa -des3 -out ${D}/server.key 1024
Generating RSA private key, 1024 bit long modulus
...........................................++++++
......++++++
e is 65537 (0x10001)
Enter PEM pass phrase: enter a pass phrase
Verifying password - Enter PEM pass phrase: re-enter pass phrase
[mhw@kremvax ssl]$ 
If you want an unencrypted key, drop the -des3 option:
[mhw@kremvax ssl]$ openssl genrsa -out ${D}/server.key 1024
Generating RSA private key, 1024 bit long modulus
..............................++++++
.....................................................++++++
e is 65537 (0x10001)
[mhw@kremvax ssl]$ 

Next, create the certificate request. The information you enter here is similar to that which you entered for the certification authority certificate earlier. The main feature of note is that the Common Name field should be set to the fully qualified domain name of your machine as your clients see it. If your private key is encrypted you'll be asked for the pass phrase as the first step of the process, but that's not shown in this transcript:

[mhw@kremvax ssl]$ openssl req -new -key ${D}/server.key -out newreq.pem
Using configuration from /usr/share/ssl/openssl.cnf
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:GB
State or Province Name (full name) [Some-State]:West Yorkshire
Locality Name (eg, city) []:Leeds
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Diagonal Solutions
Organizational Unit Name (eg, section) []:press Enter
Common Name (eg, your name or your server's hostname) []:bugs2.kremvax.net
Email Address []:infrastructure@diagonal-solutions.co.uk

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:press Enter
An optional company name []:press Enter
[mhw@kremvax ssl]$ 

You will now have a private key for your server in the file ${D}/server.key and a certificate request ready for signing in newreq.pem.

Sign the Certificate Request

Just to recap, at this point you should have setup a certification authority directory hierarchy and have a certificate request in a file called newreq.pem sitting in that directory.

This step is now relatively simple:

[mhw@kremvax ssl]$ ./ca -sign
Using configuration from /usr/share/ssl/openssl.cnf
Enter PEM pass phrase: enter the certification authority pass phrase
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName           :PRINTABLE:'GB'
stateOrProvinceName   :PRINTABLE:'West Yorkshire'
localityName          :PRINTABLE:'Leeds'
organizationName      :PRINTABLE:'Diagonal Solutions'
commonName            :PRINTABLE:'bugs.diagonal-solutions.co.uk'
emailAddress          :IA5STRING:'infrastructure@diagonal-solutions.co.uk'
Certificate is to be certified until Mar  6 16:38:16 2003 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Signed certificate is in newcert.pem
[mhw@kremvax ssl]$ cp newcert.pem ${D}/server.crt
[mhw@kremvax ssl]$ 
Note that we copy the new certificate into the server's directory for safe keeping.

Deploy the Certificate

Finally you need to configure your server to use the certificate you've just created. For the Red Hat 7.2 Apache installation I'm working with you would copy server.key to /etc/httpd/conf/ssl.key/server.key and server.crt to /etc/httpd/conf/ssl.crt/server.crt.

Distribute your Certification Authority Certificate

You should now have a web server which clients can communicate with using secure SSL connections. It will have one annoying feature though: at the beginning of every browser session the user's web browser will warn them that the certificate is not valid because it's not signed by a certification authority that the browser knows about. To cure this problem you need to provide a copy of your certification authority certificate in a form that the web browser can import into it's list of trusted certification authorities.

Typically the certification authority certificate is distributed from a web server as a DER encoded file with the MIME type application/x-x509-ca-cert. The Red Hat 7.2 /etc/httpd/conf/httpd.conf file contains the following directive

AddType application/x-x509-ca-cert .crt
which will allow you to serve such files if you give them a .crt extension. To generate a suitable DER encoded file you would use the following command:
[mhw@kremvax ssl]$ openssl x509 -in demoCA/cacert.pem -outform DER -out ca-rsa.crt
[mhw@kremvax ssl]$ 
You can then copy the generated ca-rsa.crt file onto your web server for client browsers to download and install.

Notes

  1. The CA.pl script creates certificates that are valid for 365 days. If you expect your certificates to be in use for longer than that you should edit the script to alter the lifespan of the certificates it creates. Edit your copy of CA.pl and find a line that reads

    $DAYS="-days 365";
    
    You can use any value for the -days parameter that you want.
  2. That is, the default /etc/http/conf/httpd.conf from the apache-1.3.22-2 at least. Check your httpd.conf for lines similar to the following:

    SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt
    SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key