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:
#!/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 # Generate CA private key openssl genrsa -out ca.key 2048 # Create Certificate Signing Request openssl req -config OPENSSL.CONF -new -key ca.key -out ca.csr -subj "/O=Your Company Here/CN=Your Root CN Here" # Self-sign the key. (Roots are self-signed.) openssl x509 -req -days 365000 -in ca.csr -out ca.crt -signkey ca.key # Generate DH parameters. openssl dhparam -out dh.pem 2048 # Generate first CRL. openssl ca -config OPENSSL.CONF -gencrl -out ca.crl chmod 755 . chmod 644 dh.pem ca.crt ca.crl
And create a script (+x) called "GENERATE" as follows:
#!/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
# Create new key.
openssl genrsa -out "${cert}.key" 2048
# Create Certificate Signing Request.
openssl req -config OPENSSL.CONF -new -key "${cert}.key" -out "${cert}.csr" -subj "/O=Your Company Here/CN=${cert}"
# Sign key.
openssl ca -config OPENSSL.CONF -in "${cert}.csr" -cert ca.crt -keyfile ca.key -out "${cert}.crt"
# Show info about the key.
#openssl x509 -noout -text -in "${cert}.crt"
chmod 644 "${cert}.crt"
And create a script (+x) called "REVOKE" as follows:
#!/bin/sh -e
umask 077
cert=$1
if [ -z "$cert" ]; then
echo "Specifiy filename of certificate (.crt) to revoke."
exit 1
fi
# Revoke in local storage.
openssl ca -config OPENSSL.CONF -revoke "${cert}"
# Generate new CRL for distribution.
openssl ca -config OPENSSL.CONF -gencrl -out ca.crl
# Show info about reovked certificates.
#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
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