OpenSSL Quick

From Devpit
Jump to: navigation, search

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" to generate and sign the keys. To revoke a certificate, run "./REVOKE" (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

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

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

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

# 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

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

# 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