Welcome the company of trees

Certification Authority

2012-12-07

Abstract

Providing a secure channel to your server is essential. Many services uses the TLS protocol and you need a Certificate to use it. This article discusses different options and shows you how to set up your own CA and using it to generate certificates.


Introduction

To secure the communication of many services the TLS protocol is used. To enable it for our applications we need a certificate. We can get these certificates from a company that sell them, or get a free one from StartSSL, or get a free one from CA Cert, or make your own Certification Authority (CA). One can also just self-sign a certificate but that is not recommended, the CA certification has a purpose.

There are several advantages and drawbacks with each selection. Using a commercial vendor costs money. Symantec, the market leader takes $599/year at the time of this writing for a "Secure Site SSL Certificates", their simplest certificate. This certificate is just valid for one URL. You have to have a better reason to give out so much cash then to just safely read your email over IMAPS. The advantage is that your certificate is well known and accepted by all browsers.

A cheaper alternative is StartSSL that is accepted by most browsers and has a different pricing structure. A simple combination (example.com/www.example.com) is free, but has the requirement that you validate your domain once a month. The certificate is only valid one year and you will have then to update it again. They have a "StartSSL™ Verified" product that costs $59.90 per year. You have to provide personal information for this product, like copy of your passport etc. You are allowed unlimited two year certificates for a year (eg 350 days). StartSSL is located in Israel.

CA Cert is a Certificate Authority that provides free certificates. One big drawback is that the CA is not included in many browsers, due to the need for an expensive Webtrust audit. This means that if a user comes to your site they will be greeted with a big red warning in the browser that your site is not trusted. They can then add the root certificate to their browser, and then your site will be trusted. This step is not very easy for a non-technical user.

A self signed CA have the same problem with inclusion in web browsers as CA Cert but to that your users need to trust you personally, or at least your CA. There are situations where the control of a self signed CA is useful, for example in a Company where you then can provide your users the CA in a central manner. Still adding the CA to all different devices can be difficult.

Building a Certification Authority

First we must make a structure on our encrypted partition to hold all our future keys and certificates. We also need to set up the appropriate serial and crlnumbers. Easy steps with the following commands.

cd /mnt/crypt/ca/

,

mkdir example.org-CA

,

cd
      example.org-CA

and

mkdir certs crl newcerts
      private req key-certs keys user-p12

, Create some basic files,

touch index.txt

,

echo '01' >
      serial

and

echo '01' > crlnumber

.

Now we are ready to start creating things for our CA, but first we need a configuration file. We will use the standard debian file, but we'll store it to the CA directory so that we can add any special commands to it. The openssl configuration file can sometimes be overridden by the command line but in other cases it is harder. Therefor it is better to have a file for you CA where your settings are stored. First copy the debian default file to the CA directory.

cp /etc/ssl/openssl.cnf
      .

. We change the dir to point to the current directory. dir = .. Lets also set countryName_default, stateOrProvinceName_default, 0.organizationName_default, organizationalUnitName_default and emailAddress_default so that we don't have to enter a full string every time. For emailAddress_default we can put for example cert@example.org to create a contact point for certificate questions.

Now, we can start to create the CA. Lets start to generate the main key. This key will control the CA and we must make sure that we do not loose it, and pick a difficult long pass phrase. We can let pwsafe generate a password for us. One can get pretty much impossible long and complex password from the pwsafe.

openssl genrsa -aes256 -out private/cakey.pem
      4096

generates the key. To create the CA certificate we now do

openssl req -config openssl.cnf -new -x509
      -extensions v3_ca -days 1095 -sha1 -key private/cakey.pem -out
      cacert.pem

. From the soup of options we have picked to create a key with AES256, and for the certificate we have selected the SHA1 hash algorithm. The CA is valid for 3 years, and that is a good start. Extension v3_ca points to a section in your configuration file, where some basic CA settings are set. For the common name we set simply example.org ca

Creating server certificates

Now we when we have a CA we can create our first certificates. For what services do we need a certificate ? To begin with we create certificates for a webserver running several virtual hosts. (exemple.org, exemple.com and exemple.net). Then we also create a certificate for our mailserver and our ldap server, named mail.example.org and ldap.example.org.

To create a certificate for multiple hosts we need to add some information to the openssl.cnf. At the end of the file we create a new section for a request called req_www.example.org.

[ req_www.example.org ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

subjectAltName = @example_names
      

to that section we add another for our CA certification :

[ ca_www.example.org ]
basicConstraints=CA:FALSE
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

subjectAltName = @example_names
      

Both these sections points to a third section we have to create. That section lists all names we want the server to be valid for :

[example_names]
DNS.1   = example.org
DNS.2   = www.example.org
DNS.3   = example.net
DNS.4   = www.example.net
DNS.5   = example.com
DNS.6   = www.example.com
      

Now we can start creating keys and requests that we later can sign with our CA to certificates.

First we generate the key

openssl genrsa -aes256 -out
      keys/key-www.example.org.pem 2048

and now we just pick an password with pwsafe and store it at the same time. Since the password will be used to start the SSL server, it will be used every time so keep the pwsafe handy, and have a backup. Then we create a request so our CA can sign a certificate.

openssl req -config openssl.cnf -new -nodes -reqexts
      req_www.example.org -out req/req-www.example.org.pem -key
      keys/key-www.example.org.pem

Here the section we created in the configuration file is use with the command line switch -reqexts. The common name should be example.org matching the DNS.1 entry.

The mail server and the ldap server are simpler since the certificate are only for one common name. Do the same procedure with these and give the common names mail.example.org and ldap.example.org.

openssl genrsa -aes256 -out
      keys/key-mail.example.org.pem 2048

and

openssl req -config openssl.cnf -new -nodes -out
      req/req-mail.example.org.pem -key
      keys/key-mail.example.org.pem

. The same for the LDAP server

openssl genrsa -aes256 -out
      keys/key-ldap.example.org.pem 2048

openssl
      req -config openssl.cnf -new -nodes -out
      req/req-ldap.example.org.pem -key
      keys/key-ldap.example.org.pem

.

Now we have a bunch of requests that we would like to sign, to create properly signed certificates. The www.example.org certificate needs the extension flag to add the additional names.

openssl ca -config openssl.cnf -extensions
      ca_www.example.org -out certs/cert-www.example.org.pem -infiles
      req/req-www.example.org.pem

creates the signed certificate. We have to enter the CA pass phrase and decide if we want to sign the request. Lets sign the www.example.org request. We sign the mail.example.org and ldap.example.org certificate as well.

openssl ca -config openssl.cnf
      -out certs/cert-mail.example.org.pem -infiles
      req/req-mail.example.org.pem

and

openssl ca
      -config openssl.cnf -out certs/cert-ldap.example.org.pem
      -infiles req/req-ldap.example.org.pem

.

The certificate can also be made slimmer by stripping it of the human readable text. Lets do that and create a copy with a stripped version.

openssl x509 -in
      certs/cert-www.example.org.pem -out
      certs/cert-www.example.org-s.pem

. The command is simple and can be used for all the generated certificates.

openssl x509 -in certs/cert-mail.example.org.pem -out
      certs/cert-mail.example.org-s.pem

openssl
      x509 -in certs/cert-ldap.example.org.pem -out
      certs/cert-ldap.example.org-s.pem

Sometimes a separate key and cert file are needed and sometimes a combined file. That depends on the application. To combine the two files just

cat keys/key-www.example.org.pem
      certs/cert-www.example.org-s.pem >
      key-certs/key-cert-www.example.org.pem

The last step we do is to create a revocation list. This lists what certificates are valid and what have been invalidated.

openssl ca -config openssl.cnf -gencrl -crldays 31 -out
      crl/ca-crl.pem

Revoking your certificates and replacing them

This section I had to write faster then I intended. The DSA-1571 made me look into this very quickly. I had some problem finding how self-signed certificate authorities are handled but this thread on openssl-user gave me some hints. I wish this information would have been published on the Key Rollover page, since it is not so common to change CA.

So, lets get those broken certificates out of the wild. We start by creating new CA that we can trust. First move the key and certificate out of the way.

mv cakey.pem
      cakey.pem-dsa-1571

and

mv cacert.pem
      cacert.pem-dsa-1571

. Then move the password inside the pwsafe so that we still have access to the password, but can create a new for the new certificate.

pwsafe -e
      tree.se.cert.ca

. Changing the name name: [ca] ca-dsa-1571. If your CA expired or was compromised because of some other reason you can put old or whatever instead of dsa-1571.

Now we generate a new key and set a new password.

openssl genrsa -aes256 -out private/cakey.pem
      4096

and

pwsafe -a

with the input

name: ca
group [<none>]: tree.se.cert
username: current
password [return for random]:
Generate random password? [y]
      

Then we generate the CA.

openssl req -config
      openssl.cnf -new -x509 -extensions v3_ca -days 1095 -sha1 -key
      private/cakey.pem -out cacert.pem

Now we need to retire the broken certificates. But first lets move the certificate out of the way, so that we do not accidentally delete them.

mv key-example.org.pem
      key-example.org.pem-dsa-1571

. We move all the certs out of the way as well. We also need to rearrange the pwsafe, so we know which keys belong to which certificates.

So lets start revoking.

openssl ca -config openssl.cnf
      -revoke certs/cert-ldap.example.org.pem-dsa-1571 -keyfile
      private/cakey.pem-dsa-1571 -cert cacert.pem-dsa-1571

and it will tell you Revoking Certificate 03. Data Base Updated. Then do the same with all certificates.

Now we start create new certificates like we did earlier, in the section above. Once that is done we need to publish them and create CRL file to be able to tell the world about the withdrawn certificates. To generate the CRL do

openssl ca
      -config openssl.cnf -gencrl -crldays 31 -out
      crl/ca-crl.pem

.

Renew server certificates

Once the certificates expires one can easily renew them with a script like in #!/bin/bash date=`date +%d-%b-%Y` _renew () { echo " ----=== $1 ===----" openssl genrsa -aes256 -out $date/keys/key-$1.pem 2048 if [[ $1 == www* ]] then openssl req -config openssl.cnf -new -nodes -reqexts req_$1 -out $date/req/req-$1.pem -key $date/keys/key-$1.pem openssl ca -config openssl.cnf -extensions ca_$1 -out $date/certs/cert-$1.pem -infiles $date/req/req-$1.pem else openssl req -config openssl.cnf -new -nodes -out $date/req/req-$1.pem -key $date/keys/key-$1.pem openssl ca -config openssl.cnf -out $date/certs/cert-$1.pem -infiles $date/req/req-$1.pem fi openssl x509 -in $date/certs/cert-$1.pem -out $date/certs/cert-$1-s.pem cat $date/keys/key-$1.pem $date/certs/cert-$1-s.pem > $date/key-certs/key-cert-$1.pem } mkdir -p $date/keys $date/req $date/certs $date/key-certs _renew www.example.com _renew special.example.com Please note that www.example.com is a special case, and needs an appropriate section in the openssl.cnf file, as discussed above. One still have to approve the suggested defaults, and write the Common Name (CN) at the prompt. All passwords for the keys and the CA has also to be provided. Still it is faster than writing all the commands by hand.