Setting up client-side certificate authentication

This is written and tested on apache2. Requires openSSL, tested on OpenSSL version 1.0.1f 6 Jan 2014. First, setup openssl for use in being a certificate authority. For that you have to edit openssl.conf ( on debian based systems should be located at /etc/ssl/ ) There are a lot of options there but some basics for example. Your policy_match will probably look different in production, also the default days (of key validity) should probably be not 10 years for production.

default_ca = CA_development

[ CA_development ]
dir = /etc/ssl/private
database = $dir/index.txt
serial = $dir/serial
private_key = $dir/ca.key.pem
certificate = $dir/ca.crt
default_days = 3650
default_md = md5
new_certs_dir = $dir
policy = policy_match

[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = match
commonName = supplied
emailAddress = optional

Following commands should be run in /etc/ssl/ unless you choose another location for your keys. Now you need cert authority key which can be generated by openssl genrsa -out private/ca.key Now generate a new certificate request with openssl req -new -key private/ca.key -out private/ca.csr And sign it openssl x509 -req -days 3650 -in private/ca.csr -signkey private/ca.key -out private/ca.crt Setup the first serial number for our keys, should be a 4 digit hex string echo FAD0 > private/serial Create key database touch private/index.txt And finally, create a cert revocation list for removing user certs openssl ca -gencrl -out /etc/ssl/private/ca.crl -crldays 7

Now, we need a certificate for our webserver. Don't bother putting a password on it since you need it to start apache. If there's a good workaround for this, please let us know. Let's generate the apache key, openssl genrsa -out private/apache.key Create a certificate request for it openssl req -new -key apache.key -out apache.csr and sign it openssl ca -in private/apache.csr -cert private/ca.crt -keyfile private/ca.key -out private/apache.crt

Now we are ready to setup apache to use our keys for authentication. A sample apache2 conf

SSLEngine on
SSlOptions +StrictRequire
SSLCertificateFile /etc/ssl/private/apache.crt
SSLCertificateKeyFile /etc/ssl/private/apache.key
SSLCACertificateFile /etc/ssl/private/ca.crt
SSLVerifyClient require

replace the repeating lines from previous apache conf with lines from this one

There could be some more mojo needed to check if Certificates are expired and etc but I haven't really tested it out yet.

Now let's create an example user certificate. Start off with the key openssl genrsa -des3 -out $base/users/$1/$1.key 1024 . Now a certificate signing request for that key openssl req -new -key $base/users/$1/$1.key -out $base/users/$1/$1.csr and finally let's sign it openssl ca -in $base/users/$1/$1.csr -cert $base/ca.crt -keyfile $base/ca.key -out $base/users/$1/$1.crt and we should be done.

In real life (!development), user should generate their own key and cert request.