OpenSSL Quick

With thanks to user786653 on StackOverflow[1], I came up with a streamlined arrangement to manage an OpenSSL certificate authority, such as for OpenVPN or Bacula. I like this approach because it's simple, I can see and understand everything it does, and therefore it's easy to customize, repeat, and fix.

After doing the setup below, just run "./INIT" to generate a new root (self-signed) CA key. Then for each certificate, run "./GENERATE who.your-company.com" to generate and sign the keys. To revoke a certificate, run "./REVOKE who.your-company.com.crt" (note inclusion of ".crt"), and be sure the new ca.crl is respected by all relevant ingress points.

Create a directory; I like /usr/local/etc/ssl. In it, create a few files. Replace "Your Company Here" with your own name.

Create a script (+x) called "INIT" as follows:
 * 1) !/bin/sh -e

umask 077

if [ -s DB/serial.txt ] || [ -s ca.key ]; then echo "Already initialized. Remove DB and ca.key to override." exit 1 fi

mkdir -p DB # Signed certificates storage touch DB/index.txt # Index of signed certificates echo 01 > DB/serial.txt # Next (sequential) serial number echo 01 > DB/crlserial.txt # Next crl serial number

openssl genrsa -out ca.key 2048
 * 1) Generate CA private key

openssl req -config OPENSSL.CONF -new -key ca.key -out ca.csr -subj "/O=Your Company Here/CN=Your Root CN Here"
 * 1) Create Certificate Signing Request

openssl x509 -req -days 365000 -in ca.csr -out ca.crt -signkey ca.key
 * 1) Self-sign the key. (Roots are self-signed.)

openssl dhparam -out dh.pem 2048
 * 1) Generate DH parameters.

openssl ca -config OPENSSL.CONF -gencrl -out ca.crl
 * 1) Generate first CRL.

chmod 755. chmod 644 dh.pem ca.crt ca.crl

And create a script (+x) called "GENERATE" as follows:
 * 1) !/bin/sh -e

umask 077

cert=$1 if [ -z "$cert" ]; then echo "Specifiy CN of new certificate. (Usually hostname or email address to identify.)" exit 1 fi

if [ -s "${cert}.key" ]; then echo "Key already exists. Remove first if you want to replace it." exit 1 fi

openssl genrsa -out "${cert}.key" 2048
 * 1) Create new key.

openssl req -config OPENSSL.CONF -new -key "${cert}.key" -out "${cert}.csr" -subj "/O=Your Company Here/CN=${cert}"
 * 1) Create Certificate Signing Request.

openssl ca -config OPENSSL.CONF -in "${cert}.csr" -cert ca.crt -keyfile ca.key -out "${cert}.crt"
 * 1) Sign key.


 * 1) Show info about the key.
 * 2) openssl x509 -noout -text -in "${cert}.crt"

chmod 644 "${cert}.crt"

And create a script (+x) called "REVOKE" as follows:
 * 1) !/bin/sh -e

umask 077

cert=$1 if [ -z "$cert" ]; then echo "Specifiy filename of certificate (.crt) to revoke." exit 1 fi

openssl ca -config OPENSSL.CONF -revoke "${cert}"
 * 1) Revoke in local storage.

openssl ca -config OPENSSL.CONF -gencrl -out ca.crl
 * 1) Generate new CRL for distribution.


 * 1) Show info about reovked certificates.
 * 2) openssl crl -in ca.crl -text

chmod 644 ca.crl

And create a file called OPENSSL.CONF as follows: [ ca ] default_ca = ca_default

[ ca_default ] dir =. certs = $dir/DB new_certs_dir = $dir/DB database = $dir/DB/index.txt serial = $dir/DB/serial.txt RANDFILE = $dir/DB/rand certificate = $dir/ca.crt private_key = $dir/ca.key crl_dir = $dir crlnumber = $dir/DB/crlserial.txt crl = $dir/ca.crl default_days = 365000 default_crl_days = 30 default_md = md5 preserve = no policy = generic_policy

[ generic_policy ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional

[ req ] default_bits = 2048 distinguished_name = req_distinguished_name

[ req_distinguished_name ] 0.organizationName = Organization Name (eg, company) 0.organizationName_default = Your Company Here commonName = Common Name (e.g. hostname or email address) commonName_max = 64

[1] http://stackoverflow.com/questions/7768593/openssl-as-a-ca-without-touching-the-certs-crl-index-etc-environment

Creating .pfx format
Windows likes to deal with SSL certificates in .pfx format. To create these:

openssl pkcs12 -inkey my.key -in my.crt -export -out my.pfx