Securing Communications with SSL/TLS: Streamlined CA Procedures (cert.command & sign.command)

by Chris Pepper

In Securing Communications with SSL/TLS: A High-Level Overview, I discussed command-line procedures for working with SSL/TLS certificates. In Securing Communications with SSL/TLS: Using CA.pl, I discussed command-line procedures for actually using SSL/TLS certificates. In this article, I look at some streamlined CA tools.

I have developed a couple simple tools, cert.command and sign.command. They can be launched like normal Mac programs (by double-clicking) or used from a command line. cert.command walks through the process of creating a CSR and signing it, to create a brand-new signed certificate; sign.command takes an existing certificate and signs it, as a commercial CA would. The behavior of each tool is the same whether launched in a shell window (without arguments) or double-clicked: the script prompts for necessary information and produces a .crt file, signed by the root certificate specified in openssl.cnf. cert.command also prompts for the organizational information used to build a CSR, while sign.command doesn't, since the information is already inside the CSR.

For greater efficiency, both scripts may be run from a command line with an argument: either being the filename of the certificate to create (as in "cert.command www.reppep.com.20071108"), or the CSR file to sign (as in "sign.command www.reppep.com.20071108.csr").

1. Create a new Certificate Authority -- This is rare enough that I didn't bother providing an alternative to CA.pl. See Securing Communications with SSL/TLS: Using CA.pl for details.

2. Create a new certificate signing request -- Every certificate starts with a CSR, so if you want a CSR -- perhaps to send to a commercial CA -- you could use cert.command and disregard certificate.crt (signed by your own CA) and instead submit certificate.csr to another CA to be signed. cert.command also creates certificate.key, containing the private key which the CSR and eventual certificate are based on. See #5 below for more on cert.command.

3. Create a self-signed certificate -- With a private CA, there's little reason to use a self-signed certificate, so don't.

4. Request that a CA sign a CSR and return a signed certificate -- This is entirely in the CA's hands.

5. Sign a CSR with your own root certificate -- This is the core CA activity, and can be done with either cert.command (to create a new CSR and sign it in one operation) or sign.command (to sign an existing CSR). Both scripts can be run from the command line without any arguments or double-clicked; in this case they prompt for all the pertinent information (including the CA key passphrase) and produce a signed certificate.

cert.command also prompts for the "Common Name", which is normally the web site's fully qualified domain name, and (if not specified on the command line) a name to use for the key, CSR, and certificate file (each uses a different suffix). sign.command prompts for the filename of the CSR to sign, unless it is provided as an argument. I suggest using the fully qualified domain name of the host and the date as the certificate name, as in "cert.command www.reppep.com.20071108" or "sign.command www.reppep.com.20071108.csr". This makes it easier to keep track of expirations and renewals.

www:/Volumes/ca.reppep.com julia$ /usr/local/bin/cert.command www.reppep.com.20071108
Generating RSA private key, 512 bit long modulus
..............++++++++++++
.....++++++++++++
e is 65537 (0x10001)
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) [US]:
State or Province Name (full name) [New York]:
Locality Name (eg, city) [Brooklyn]:
Organization Name (eg, company) [reppep]:
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:www.reppep.com
Email Address [webmaster@reppep.com]:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Using configuration from /System/Library/OpenSSL/openssl.cnf
Enter pass phrase for /Volumes/ca.reppep.com/private/ca.reppep.com.key:
Check that the request matches the signature
Signature ok
Certificate Details:
    Serial Number: 1 (0x1)
    Validity
        Not Before: Jun 24 21:42:29 2007 GMT
        Not After : Jun 23 21:42:29 2008 GMT
    Subject:
        countryName               = US
        stateOrProvinceName       = New York
        organizationName          = reppep
        commonName                = www.reppep.com
        emailAddress              = webmaster@reppep.com
    X509v3 extensions:
        X509v3 Basic Constraints: 
        CA:FALSE
        Netscape Comment: 
        OpenSSL Generated Certificate
        X509v3 Subject Key Identifier: 
        1D:14:92:0B:BF:20:78:5D:A6:B6:F6:21:64:4B:CA:F3:4C:11:81:65
        X509v3 Authority Key Identifier: 
        keyid:0A:F5:FA:E0:72:AF:35:D1:2F:4B:3F:AA:35:07:DF:51:43:DE:86:65
        DirName:/C=US/ST=New York/L=Brooklyn/O=reppep/CN=ca.reppep.com/emailAddress=webmaster@reppep.com
        serial:DF:ED:F0:28:A6:EC:B4:9A

Certificate is to be certified until Jun 23 21:42:29 2008 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
Your files are:
-rw-r--r--   1 julia  admin  6714 Jun 24 17:42 www.reppep.com.20071108.crt
-rw-r--r--   1 julia  admin   505 Jun 24 17:42 www.reppep.com.20071108.csr
-rw-------   1 julia  admin   497 Jun 24 17:42 www.reppep.com.20071108.key

For comparison, here's sign.command signing www.reppep.com.20071108.csr, created above:

www:/Volumes/ca.reppep.com julia$ /usr/local/bin/sign.command mail.reppep.com.20070624.csr 
Using configuration from /System/Library/OpenSSL/openssl.cnf
Enter pass phrase for /Volumes/ca.reppep.com/private/ca.reppep.com.key:
DEBUG[load_index]: unique_subject = "no"
Check that the request matches the signature
Signature ok
Certificate Details:
    Serial Number: 2 (0x2)
    Validity
        Not Before: Jun 24 21:45:49 2007 GMT
        Not After : Jun 23 21:45:49 2008 GMT
    Subject:
        countryName               = US
        stateOrProvinceName       = New York
        organizationName          = reppep
        commonName                = mail.reppep.com
        emailAddress              = webmaster@reppep.com
    X509v3 extensions:
        X509v3 Basic Constraints: 
        CA:FALSE
        Netscape Comment: 
        OpenSSL Generated Certificate
        X509v3 Subject Key Identifier: 
        1F:05:49:6D:2B:2D:DD:BA:B0:E2:35:F0:78:FA:88:63:55:4C:7E:37
        X509v3 Authority Key Identifier: 
        keyid:0A:F5:FA:E0:72:AF:35:D1:2F:4B:3F:AA:35:07:DF:51:43:DE:86:65
        DirName:/C=US/ST=New York/L=Brooklyn/O=reppep/CN=ca.reppep.com/emailAddress=webmaster@reppep.com
        serial:DF:ED:F0:28:A6:EC:B4:9A

Certificate is to be certified until Jun 23 21:45:49 2008 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
Your signed certificate is:
-rw-r--r--   1 julia  admin  7086 Jun 24 17:45 ./mail.reppep.com.20070624.crt

6. Install a certificate in a server -- Both cert.command and sign.command append the root certificate to the signed certificate, which makes configuring server software slightly simpler -- they avoid a third file (the CA certificate) which otherwise must be used with the server certificate.

7. Trust a certificate -- Both cert.command and sign.command append the root certificate to the signed certificate, to make it easier to trust the root certificate.

8. Verify a certificate file -- I have nothing further to suggest beyond the pointers in Securing Communications with SSL/TLS: Using CA.pl.

9. Test an SSL/TLS connection -- I have nothing further to suggest beyond the pointers in Securing Communications with SSL/TLS: Using CA.pl.


up