Creating a Certificate Authority (CA)

Configuring an OpenSSL Certificate Authority (CA)

Before we can sign certificate requests and produce valid certificates of our own for use internally in our organisation we need to configure the OpenSSL application to operate as a Certificate Authority. Before we can configure the OpenSSL application we need to create a directory structure to hold the files related to the Certificate Authority (CA) we shall be creating.

In the example below we create a suitable directory structure and the initial empty files which will be required by the OpenSSL application. As you can see we have decided to keep our CA related files in /etc/certauth, although any secure location which is regularly backed-up could be used instead. Under this directory we have created a directory called hacking so that we can keep multiple Certificate Authorities files logically grouped together.

lisa mkdir -p /etc/certauth/hacking
lisa cd /etc/certauth/hacking
lisa hacking mkdir certificates database keys private requests revoked
lisa hacking echo '01' > database/serial
lisa hacking echo '01' > revoked/crlnumber
lisa hacking touch database/index.txt

Now that we have a suitable directory layout, complete with blank files to be used by the database of this CA, we can begin to configure the OpenSSL application. The first step in this process is to move the existing package-supplied default configuration so that we can create a new configuration from scratch without losing the valuable reference material provided in the original file.

lisa mv /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.example

A detailed description of the format of the configuration file can be found in the ssl-config manual, which can be accessed as shown in the example below, so we shall not reproduce that information here. Thankfully it is fairly simple and its basic structure should be obvious from the examples which follow.

lisa man 5 ssl-config

Whilst we shall endeavour to explain all the configuration options we introduce in this section we shall not cover some of them in great detail and unused options will not be mentioned. More information on the available configuration settings and suitable values for those settings can be found in the ssl-ca manual, which can be accessed as shown below.

lisa man 1 ssl-ca

With the original configuration safely out of the way we can begin to create a new configuration file in its place. The first entry we shall create sets the default Certificate Authority to use if none is specified on the command line when executing the openssl application. As you can see we have set the default CA to the arbitrary name ca_hacking which we shall use to identify the CA configuration we shall create in later steps.

/etc/ssl/openssl.cnf
[ ca ]
default_ca = ca_hacking

The next block of entries we shall create configures the paths which will be used to store the certificates and database files used by this CA. As you can see once a variable has been declared it can be used in other configuration entries to save typing and reduce the chance of errors.

/etc/ssl/openssl.cnf
[ ca_hacking ]
dir = /etc/certauth/hacking
certs = $dir/certificates
new_certs_dir = $certs
certificate = $certs/cacert.pem
database = $dir/database/index.txt
serial = $dir/database/serial
crl_dir = $dir/revoked
crlnumber = $crl_dir/crlnumber
private_key = $dir/private/cakey.pem

Next we shall add a block of configuration entries to set the defaults which will be used by this Certificate Authority. As you can see we have specified a default Message Digest algorithm, in this case SHA-1, as well as a default lifetime for both the certificates we shall issue and the Certificate Revocation List.

/etc/ssl/openssl.cnf
default_md       = sha1
default_days = 365
default_crl_days = 30

The next four options control how the certificate request is displayed during the signing process and whether the order of the request Distinguished Name attributes should be maintained. We have specified the default display method for both the Distinguished Name and the Certificate and set the preserve attribute to no so that the DN order of the generated certificate will be the same as in the relevant policy section. We have also set the email_in_dn attribute to no so that any email address is placed in an extension, instead of the Distinguished Name, as recommended in the RFC.

/etc/ssl/openssl.cnf
name_opt         = ca_default
cert_opt = ca_default
preserve = no
email_in_dn = no

The final four entries which are required in the CA configuration block specify the "policy" of this CA, the Certificate Revocation List Extensions that we shall be using and the X.509 certificate extensions which will be present in any certificates we issue from this CA. As you can see all of these entries are simply arbitrary strings which refer to sections which we shall be creating next. The final line specifies that we want to copy any Certificate Extensions from the Certificate Signing Request

/etc/ssl/openssl.cnf
policy           = policy_match
crl_extensions = crl_ext
x509_extensions = usr_cert
copy_extensions = copy

As you can see from the example below the policy section consists of a list of certificate Distinguished Name fields followed by one of either supplied, optional or match. In the example below we specify that the organizationName in the Certificate Signing Request (CSR) must match that of the certificate used by this Certificate Authority to sign certificates, that the countryName, stateOrProvinceName and commonName fields will be used as supplied in the CSR and that the organizationalUnitName and emailAddress fields are optional.

/etc/ssl/openssl.cnf
[ policy_match ]
countryName = supplied
stateOrProvinceName = supplied
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

Next we specify the Certificate Revocation List (CRL) extensions that we shall be using. The example entry below ensures that the id of the key used to sign the certificate as well as the id of the issuer is included in any CRL entry.

/etc/ssl/openssl.cnf
[ crl_ext ]
authorityKeyIdentifier = keyid:always,issuer:always

The next section specifies the X.509 certificate extensions which will be present in any certificates we issue from this CA. The most important line is the basicConstraints entry which specifies that any certificates issued by this CA cannot be used themselves to issue more certificates by operating as a CA using this certificate as its root certificate. The next two entries specify that we use a hash as a key identifier in accordance with RFC3280 and that we should copy the subject key identifier from the parent certificate or, if that fails, that we should include the issuer and serial number from the issuer certificate in the generated certificate. These entries will be used to find the certificate in any Certificate Revocation Lists (CRL) we publish. The final entry configures a single CRL distribution point.

/etc/ssl/openssl.cnf
[ usr_cert ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid, issuer
crlDistributionPoints = URI:http://www.hacking.co.uk/ca/crl.pem
Caution:
The CRL distribution address should not be on an SSL/TLS secured web server which uses a certificate issued by the same Certificate Authority. If the certificate of the server distributing the CRL was revoked then no future CRLs could be obtained until the certificate was replaced. Also, as the CRL is signed, https adds nothing in terms of security.
 

More information on the X.509 v3 certificate extensions configuration options can be found in the openssl manual using the command below.

lisa man 5 ssl-x509v3_config

Configuring default Certificate Signing Request (CSR) attrributes

Although we have completed the configuration of the Certificate Authority options we still have some more work to do on the configuration before we can generate our own self-signed root certificate. When requesting a certificate, self-signed or otherwise, the openssl application will use the configuration options specified in the following sections.

The first block of configuration options can be logically split into three groups. The first three lines specify the defaults for the Message Digest (MD) algorithm, the default key length and the default key file. The next two lines specify that we shall be using the UTF-8 character encoding scheme. The final three lines specify additional sections which will be used to provide configuration options, as well as default values for those options if desired, for the Distinguished Name (DN) portion of the certificate, the request attributes and the X.509 extensions to be used when requesting a certificate.

/etc/ssl/openssl.cnf
[ req ]
default_md = sha1
default_bits = 4096
default_keyfile = privkey.pem
utf8 = yes
string_mask = utf8only
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca_req

The next block of configuration options we shall examine simply sets the default values and constraints to be used when requesting a certificate. As these options are fairly self-explanatory no further explanation will be given here save that the country code is one of the two character ISO 3166 country codes which is not always the same as the TLD of that country, hence GB not UK in the example below.

/etc/ssl/openssl.cnf
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = GB
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State, Province or County (full name)
stateOrProvinceName_default = Cambridgeshire
localityName = Locality Name (eg, city)
localityName_default = Cambridge
organizationName = Organisation Name (eg, company)
organizationName_default = Hacking Networked Solutions
organizationalUnitName = Organisational Unit Name (eg, section)
commonName = Common Name (eg, YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64

The third block of options specifies the default certificate request attributes. As you can see from the example below we have only specified a challenge password along with its minimum and maximum length.

/etc/ssl/openssl.cnf
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 6
challengePassword_max = 20

The final configuration block specifies the X.509 extensions to be used when requesting an X.509 certificate. As the first certificate we shall be creating is a Certificate Authority (CA) certificate we shall specify the options required to create such a certificate.

/etc/ssl/openssl.cnf
[ v3_ca_req ]
basicConstraints = critical, CA:TRUE, pathlen:0
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer:always
crlDistributionPoints = URI:http://www.hacking.co.uk/ca/hacking.crl
keyUsage = keyCertSign, cRLSign
nsCertType = sslCA, emailCA, objCA

More information on the X.509 v3 certificate request configuration options can be found in the openssl manual using the command below.

lisa man 1 ssl-req

Creating the root Certificate Authority (CA) certificate

Now that we have completed the configuration of the Certificate Authority and the Certificate Signing Request settings we can generate a self-signed certificate to be used by this CA. The example command below will create such a certificate with a lifetime of approximately ten years using the options we specified when configuring the CSR section. As you can see the openssl application will prompt for a password as well as the fields required by the CSR and will offer the defaults we specified in the configuration file.

lisa cd /etc/certauth/hacking
lisa hacking openssl req -new -x509 -days 3650 -out certificates/cacert.pem -keyout private/cakey.pem
Generating a 4906 bit RSA private key 
...........................................................++ 
.............................++ 
writing new private key to 'private/cakey.pem' 
Enter PEM pass phrase: 
Verifying - Enter PEM pass phrase: 
----- 
You are about to be asked to enter information that will be incorporated 
into your certificate request. 
What you are about to enter is what is called a Distinguished Name or a DN. 
There are quite a few fields but you can leave some blank 
For some fields there will be a default value, 
If you enter '.', the field will be left blank. 
----- 
Organisation Name (eg, company) [Hacking Networked Solutions]: 
Country Name (2 letter code) [GB]: 
State, Province or County (full name) [Cambridgeshire]: 
Locality Name (eg, city) [Cambridge]: 
Organisational Unit Name (eg, section) []:Certificate Authority 
Common Name (eg, YOUR name) []:Hacking Networked Solutions Root CA 
Email Address []:spamcatcher@hacking.co.uk 

Assuming that the command completes without error a private-key file, encrypted with the PEM pass phrase and a self-signed certificate suitable for use by the CA will have been created and placed in the correct locations.