4.5. Setting Up a Certificate Authority
If you want to become a CA, everything you need is included in the OpenSSL toolkit. This step is only feasible in a few high-end cases in which security is critical and you need to be in full control of the process. T he utilities provided with OpenSSL will perform the required cryptographic computations and automatically track issued certificates using a simple, file-based database. To be honest, the process can be cryptic (no pun intended) and frustrating at times, but that is because experts tend to make applications for use by other experts. Besides, polishing applications is not nearly as challenging as inventing something new. Efforts are under way to provide more user-friendly and complete solutions. Two popular projects are:
After choosing a machine to run the CA operations on, remove the existing OpenSSL installation. Unlike what I suggested for web servers, for CA operation it is better to download the latest version of the OpenSSL toolkit from the main distribution site. The installation process is simple. You do not want the toolkit to integrate into the operating system (you may need to move it around later), so specify a new location for it. The following will configure, compile, and install the toolkit to /opt/openssl:
$ ./configure --prefix=/opt/openssl $ make $ make test # make install
Included with the OpenSSL distribution is a convenience tool CA.pl (called CA.sh or CA in some distributions), which simplifies CA operations. The CA.pl tool was designed to perform a set of common operations with little variation as an alternative to knowing the OpenSSL commands by heart. This is particularly evident with the usage of default filenames, designed to be able to transition seamlessly from one step (e.g., generate a CSR) to another (e.g., sign the CSR).
The file CA.pl was not designed to use the full path to the openssl binary. Consequently, if two OpenSSL installations are on the machine, it will probably call the one installed by the system. This needs to be changed unless you have removed the previous installation as I suggested before. The five lines are near the top of the CA.pl file:
$REQ="openssl req $SSLEAY_CONFIG"; $CA="openssl ca $SSLEAY_CONFIG"; $VERIFY="openssl verify"; $X509="openssl x509"; $PKCS12="openssl pkcs12";
The five lines need to be changed to the following:
$OPENSSL="/opt/openssl/bin/openssl"; $REQ="$OPENSSL req $SSLEAY_CONFIG"; $CA="$OPENSSL ca $SSLEAY_CONFIG"; $VERIFY="$OPENSSL verify"; $X509="$OPENSSL x509"; $PKCS12="$OPENSSL pkcs12";
You are ready to create a CA:
# cd /opt/openssl # ./ssl/misc/CA.pl -newca
In the first stage of CA.pl execution to create a CA, you will be asked to provide the CA certificate name (this refers to any existing CA certificates you might have, so leave it blank by pressing return) and a passphrase (choose a long password). In the second stage, you will be required to enter the same fields as you did for a standard web server certificate (e.g., country, state, city). After the script ends, the following files and directories appear in /opt/openssl/demoCA:
4.5.1. Preparing the CA Certificate for Distribution
The format in which certificates are normally stored (text-based PEM) is not suitable for distribution to clients. The CA certificate you created needs to be converted into binary DER format, which is the default format browsers expect:
# cd /opt/openssl/demoCA # openssl x509 -inform PEM -outform DER -in cacert.pem -out demoCA.der
Now, you can distribute the file demoCA.der to your users. Importing a DER-encoded certificate (into a program, usually a browser) is easy: users can download it from a web page somewhere or double-click the file if it is on the filesystem (in which case the certificate is likely to be imported into Internet Explorer). For web server distribution, Apache must be configured to serve DER-encoded files using the application/x-x509-ca-cert MIME type. The default mod_ssl configuration already does this for the extension .crt. You can rename the DER file to have this extension or associate the MIME type with the .der extension by adding the following line to the httpd.conf configuration file:
AddType application/x-x509-ca-cert .der
Test the configuration by trying to import the certificate into your own browser. If the import process begins, the server is configured properly. If a standard download window appears, you need to investigate what has gone wrong. Perhaps you have forgotten to restart the web server after configuring the DER MIME type?
4.5.2. Issuing Server Certificates
To use SSL, each web server must be supplied with a server certificate. Before issuing a first certificate, you may need to adjust the default policy, specified in the openssl.cnf file. The policy controls which of the fields in the CA certificate must match fields in the issued certificates. The default policy requires the fields countryName, stateOrProvinceName, and organizationName to match:
[ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional
Option values have the following meanings:
To create a certificate, assuming you were given a CSR by some other web server administrator in your organization, rename the CSR file to newreq.pem and execute the following command to sign it:
# CA.pl -signreq
That is all there is to it. You will be asked to type in the CA passphrase, and you will be given an opportunity to verify the details are in order. When you type in your passphrase, only asterisks will be shown, helping to keep your passphrase private.
# CA.pl -signreq Using configuration from /opt/openssl/ssl/openssl.cnf Enter pass phrase for ./demoCA/private/cakey.pem:****** Check that the request matches the signature Signature ok Certificate Details: Serial Number: 1 (0x1) Validity Not Before: Jul 23 17:25:01 2004 GMT Not After : Jul 23 17:25:01 2005 GMT Subject: countryName = GB localityName = London organizationName = Apache Security commonName = www.apachesecurity.net emailAddress = email@example.com X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 63:65:EB:29:0E:58:69:5B:A1:5D:CB:2D:EC:52:DE:8C:53: 87:0F:B5 X509v3 Authority Key Identifier: keyid:F8:2D:16:DB:72:84:49:B5:D5:E5:51:FE:D8:18:54: E5:54:09:FC:E8 DirName:/C=GB/L=London/O=Apache Security/CN=Apache Security CA/emailAddressfirstname.lastname@example.org serial:00 Certificate is to be certified until Jul 23 17:25:01 2005 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
You can also create a private key and a CSR on the spot (which you may do if you are the only person in charge of certificates). When the private key needs a passphrase, use the -newreq switch:
# CA.pl -newreq
When a private key without a passphrase is needed, use the -newreq-nodes switch:
# CA.pl -newreq-nodes
4.5.3. Issuing Client Certificates
To create a passphrase-protected client certificate, execute the following two commands in sequence:
# CA.pl -newreq # CA.pl -signreq
Most client applications (typically browsers) require the certificate to be supplied in PKCS12 format. The following line will take the certificate from the file newcert.pem and create a file newcert.p12. You will be asked to enter an export password to protect the file. Whoever attempts to import the certificate will be required to know this password.
# CA.pl -pkcs12
4.5.4. Revoking Certificates
Certificate revocation is a simple operation. To perform it you need the certificate you intend to revoke. OpenSSL keeps copies of all issued certificates in the newcerts/ folder, with filenames that match certificate serial numbers. To locate a certificate, open the index.txt file and search for the email address of the user or the web address of the server. Each line in the file, represented by the following two lines, corresponds to one issued certificate:
V 050723172501Z 01 unknown /C=GB/L=London/O=Apache Security/CN=www.apachesecurity.net/emailAddressemail@example.com
The third token on the line is the serial number. After locating the correct serial number, revoke the certificate with that serial number:
# cd /opt/openssl # openssl ca -revoke ./demoCA/newcerts/01.pem
In step two of certificate revocation, generate a Certificate Revocation List (CRL). The CRL is a signed collection of all revoked certificates. All CAs are required to publish revocation lists on a regular basis.
# openssl ca -gencrl -out demoCA.crl
In step three, you need to distribute the CRL to all your web servers. A good idea is to place it on a web server somewhere. Have a cron job on every other web server that compares the CRL on the web server that always contains the most up-to-date CRL with the local version. If they are different, it should update the locally stored copy and restart Apache to make changes active.
4.5.5. Using Client Certificates
After all our hard work, using client certificates consists of adding a few lines to the httpd.conf file on each web server to be used for SSL communication:
# CA certificate path SSLCACertificateFile /usr/local/apache2/conf/ssl/demoCA.crt # Certificate revocation list path SSLCARevocationFile /usr/local/apache2/conf/ssl/demoCA.crl # Clients are required to have valid certificates # in order to access the web site SSLVerifyClient require # Client certificates are accepted as valid only # if signed directly by the CA given above SSLVerifyDepth 1
It is important to have only one CA known to the Apache installation so only client certificates signed by this CA are accepted as valid. For example, if Apache is configured to trust all certificate authorities in the certificate bundle distributed with OpenSSL, then client certificates signed by any of the well-known authorities would be deemed acceptable. An attacker might go and acquire a free personal certificate from Thawte (for example) and use that certificate to access the protected web site.
The value of the SSLVerifyDepth directive should be set to 1, which instructs Apache to accept only client certificates that are signed directly by the CA we trust, the demoCA. This setting limits the certificate chain to two certificates, preventing nonroot certificate owners from creating valid client certificates.