Certificate Authorities (CAs) Demystified
Kjell Wooding | 2003-01-11
There seems to be a great deal of unnecessary mystery about SSL, IPsec, and public-key certificates in general. This mystery often leads people to self-sign their entire public key infrastructure (or simply use pre-shared keys), without realizing what they are doing, or why they are doing it. This document aims to clear up that mystery.
This document talks about OpenSSL, as it is one of the most popular toolsets for generating and managing keys, and (as usual) assumes everyone is running OpenBSD.
Contents
- Terminology and Concepts
- File Locations
- Generating an RSA key pair
- Self-signed certificates
- Certificate Signing Requests
- Certificate Authority Creation
- Certificate Authority Signatures
- Exporting Certificates to Other Systems
- IPsec Policy and Keynote
- Extended Key Usage (EKU) fields
- More Information
Terminology and Concepts
In order to talk about Certificate Authorities (CAs), and Public-Key Infrastructures (PKIs), we will require some terminology:
- Public Key
- The public component of an RSA key pair. This may be extracted from an RSA private key, such as those generated using the openssl genrsa command. These keys are usually stored in PEM format.
- Private Key
- The private component of an RSA key pair. These are generated using the openssl genrsa command, and contain all the information required to generate an associated public key. These keys are usually stored in PEM format.
- PEM format
-
The most common file format for RSA key files. Ths format consists of a base64-encoded ASN.1 DER-encoded format offset by
-----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----
lines.
- x509 Certificate
- Essentially, a signed public key.
- Certificate Authority (CA)
- A trusted entity responsible for signing public keys (and hence, creating certificates).
- Public Key Infrastructure (PKI)
- A hierarchy of certificate authorities. This can range in complexity from a single, central certificate authority, to the highly decentralized PGP web-of-trust model.
- Distinguished Name (DN)
- A formal notation describing the holder of a particular x509 certificate.
File Locations
For this document, we assume keys are stored in their default locations on an OpenBSD machine; i.e.
- /etc/ssl
- SSL public keys
- /etc/ssl/private
- SSL private keys
In practice, the public key directory should be world readable, and the private key directory should be readable only by root.
Generating an RSA key pair
The following generates an RSA private key. This key also includes sufficient information to generate the public key, if desired.
# openssl genrsa -out /etc/ssl/private/host.key 1024
To generate an encrypted key (protected by a passphrase):
# openssl genrsa -3des -out /etc/ssl/private/host.key 1024
Once generated, this key may be manipulated using the openssl rsa command. There are several possible reasons to manipulate this key:
- To convert between file formats (PEM, DER, NET)
- To add, remove, or modify key encryption (and the associated password)
For example, to remove a passphrase from a host key:
# openssl rsa -in host.key -out host-nopw.pem
To convert a PEM-format key to a DER-format one:
# openssl rsa -in host.key -outform DER -out host.der
RSA Private key file formats
There are currently 3 formats in use:
- PEM (default)
- Ths format consists of a base64-encoded DER format with additional header and footer lines.
- DER
- An ASN.1 DER-encoded format compatible with the PKCS#1 RSAPrivateKey or SubjectPublicKeyInfo format.
- NET
- This is a format compatible with older Netscape and IIS servers. As it uses unsalted ARC4 for its encryption, it is not particularly secure and should be avoided if possible.
Self-signed certificates
A self-signed certificate is a public key that has been signed by its own private key. Why bother, you ask? Public key infrastructures expect that someone is certifying the authenticity of a public key. If there is no-one else available, a certificate must be self-signed.
Self-signing is useful for generating test certificates for a variety of applications. Production certificates, however, should always be signed using some form of certificate authority - either a commercial entity (such as thawte), or your own personal (or corporate) CA.
Self-signing is accomplished by using the -signkey option of openssl x509. This process takes as input:
- csr - The certificate request
- key - The signing (RSA) key. Normally, this is the CA's private key. Since this is a self-signed certificate, it is the server's own private key.
And produces as output:
- crt - A signed X.509 public-key certificate
Example:
# openssl x509 -req -days 365 -in /etc/ssl/private/host.csr \
-signkey /etc/ssl/private/host.key -out /etc/ssl/host.crt
Certificate Signing Requests (CSRs)
Once the RSA key pair has been generated, a signing request must be created. This request is then submitted to the CA for signing. These requests are created and processed in PKCS#10 format.
# openssl req -new -key /etc/ssl/private/host.key \
-out /etc/ssl/private/host.csr
In fact, the RSA key generation and CSR generation can be combined using the -newkey option of openssl req:
# openssl req -newkey rsa:1024 -keyout /etc/ssl/private/host.key \
-out /etc/ssl/private/host.csr
Certificate Authority Creation
If we are not using a third-party, CA we must create our own CA infrastructure. This essentially consists of generating a self-signed key pair to serve as the CA's signing key. Because compromise of the CA means compromise of the entire public-key infrastructure, it is important to ensure the CA key both of sufficient bit length, and is protected by a passphrase.
# openssl req -newkey rsa:2048 -keyout /etc/ssl/private/ca.key \
-out /etc/ssl/private/ca.csr
# openssl x509 -req -days 365 -in /etc/ssl/private/ca.csr \
-signkey /etc/ssl/private/ca.key -out /etc/ssl/ca.crt
# ln -s /etc/ssl/ca.crt /etc/isakmpd/ca/ca.crt
Certificate Authority Signatures
At this point, the CA will be used to sign all relevant host (public) keys. This is done using the openssl x509 command.
# openssl x509 -req -days 365 -CAcreateserial \
-CA /etc/ssl/ca.crt -CAkey /etc/ssl/private/ca.key \
-in /etc/ssl/private/host.csr -out /etc/ssl/host.crt
# chmod 600 /etc/ssl/private/*
Once the keys are signed (and if they are to be used with isakmpd), they must have a subjectAltName extension field added to them for each of the identities that will be bound to the certificate. This is typically done with the certpatch(8) tool, though it may also be done with a clever application of environment variables in the openssl.cnf file (see the Extended Key Usage example, below).
The following example adds a fully qualified domain name identity to an existing certificate. Other identification types are listed below:
# certpatch -k /etc/ssl/private/ca.key -t FQDN -i "your_FQDN" \
/etc/ssl/host.crt /etc/ssl/host.crt
# ln -s /etc/ssl/private/host.key /etc/isakmpd/private/host.key
# ln -s /etc/ssl/host.crt /etc/isakmpd/certs/host.crt
Note that trusted public keys (namely, those signed at this CA by the process above) can be used directly by isakmpd if placed in the following locations (based on the certificate identification type):
- IPv4 - /etc/isakmpd/pubkeys/ipv4/A.B.C.D
- IPv6 - /etc/isakmpd/pubkeys/ipv6/abcd:abcd::ab:bc
- FQDN - /etc/isakmpd/pubkeys/fqdn/foo.bar.org
- UFQDN - /etc/isakmpd/pubkeys/ufqdn/user@foo.bar.org
Certificate Identification Types
There are three main identification types for certificates, as defined in RFC 2407.
- IP
- This may be either an IPv4 dotted-quad address, or an IPv6 address.
- FQDN
- A Fully Qualified Domain Name. Note that use of this certificate identification type can make the infrastructure vulnerable to DNS-based attacks (if the attacker gains posession of the FQDN-identified keypair
- User FQDN (UFQDN)
- This format represents a fully-qualified username string. This identification type is useful when a user may not be originating from a fixed IP address. e.g. luser@example.com, or luser@laptop04.example.com.
Note that, for the purposes of isakmpd (under OpenBSD, at least), both FQDN and UFQDN are handled as strings. No verification (name resolution) of the data is performed.
Exporting Certificates for Other Systems
For some tasks, it is useful to be able to export certificates to another machine. Typically, certificates are exported in PKCS#12 format. The following command will perform the export:
# openssl pkcs12 -export -in /etc/ssl/host.crt -out host.p12 \
-certfile /etc/ssl/ca.crt -inkey /etc/ssl/private/host.key
IPSec Policy and Keynote
IPsec policy (under OpenBSD, anyway) used to be enforced by the Keynote trust management system. This is essentially a language used for describing whether a given IPsec connection attempt is legitimate or not. Typically, this policy is located in /etc/isakmpd/isakmpd.policy. (Later versions of OpenBSD eliminated this requirement.)
One common policy states the following:
- Only certificates issued from our CA are recognized.
- Connections must use ESP
- a non-null encryption algorithm is required
To configure this type of policy, it is essential that the correct distuguished name be extracted from the CA certificate. This may be accomplished by the following:
# openssl x509 -in /etc/ssl/ca.crt -noout -subject | \
sed -e 's@^subject= @@g'
Once this DN has been extracted, the isakmpd.policy file may be constructed:
Keynote-version: 2
Authorizer: "POLICY"
Licensees: "DN:/C=CA/ST=Alberta/L=Calgary/O=My company/CN=ca@mycompany.com"
Conditions: app_domain == "IPsec policy" &&
esp_present == "yes" &&
esp_enc_alg != "null" -> "true";
Other references include:
- Marcus Muller's ipsec tools.
- Juan Vera's handy tutorial (local copy) for setting up a VPN and CA infrastructure between Win2k and OpenBSD
- Nate Carlson's Linux/Windows Openswan tutorial
- NDSS 2001 paper
- RFC 2704 - Keynote
- RFC 2792 - Keynote RSA and DSA public key formats.
Extended Key Usage (EKU) fields
EKU fields are used in X.509 certificates to indicate what applications a particular certificate may be used for. They are represented as OIDs, dotted-decimal strings of 28-bit integers. An OID is a totally general, but uniquely allocated hierarchial identifier used in a variety of standards. A master repository of OIDs is available at http://oid.elibel.tm.fr/.
For many crypto applications, EKU fields are not used at all. Occasionally, such as when interoperating between different vendors' products (e.g. Microsoft, using RADIUS authentication), it may be necessary to add one or more extension to a particular certificate. Some common EKU OIDs are:
- 1.3.6.1.5.5.7.3.1 (serverAuth)
- SSL/TLS Web Server Certificate
- 1.3.6.1.5.5.7.3.2 (clientAuth)
- SSL/TLS Web Client Certificate
- 1.3.6.1.5.5.7.3.3 (codeSigning)
- Code Signing
- 1.3.6.1.5.5.7.3.4 (emailProtection)
- Email Protection
- 1.3.6.1.5.5.7.3.8 (timeStamping)
- Time Stamping
- 1.3.6.1.4.1.311.2.1.21 (msCodeInd)
- Microsoft Individual Code Signing
- 1.3.6.1.4.1.311.2.1.22 (msCodeCom)
- Microsoft Commercial Code Signing
- 1.3.6.1.4.1.311.10.3.1 (msCTLSign)
- Microsoft Trust List Signing
- 1.3.6.1.4.1.311.10.3.3 (msSGC)
- Microsoft Server Gated Crypto (strong crypto export approved)
- 1.3.6.1.4.1.311.10.3.4 (msEFS)
- Microsoft Encrypted File System
- 2.16.840.1.113730.4.1 (nsSGC)
- Netscape Server Gated Crypto (strong crypto export approved)
EKUs are added when a key is signed. To add extensions, they must first be saved to a configuration file; i.e.
[ ext_client ] # OID:1.3.6.1.5.5.7.3.2 = clientAuth to OpenSSL extendedKeyUsage=clientAuth subjectAltName=critical,email:$ENV::CN
If the above is saved to a file called /etc/ssl/ext.cnf, the following invocation will sign a certificate, adding both the SSL Client Certificate EKU and the subjectAltName extension used by isakmpd.
# CN=user@example.com openssl x509 -req -days 365 \
-in /etc/isakmpd/private/user@example.com.csr \
-CA /etc/ssl/ca.crt \
-CAkey /etc/ssl/private/ca.key -CAcreateserial \
-extfile /etc/ssl/ext.cnf \
-extensions ext_client \
-out /etc/isakmpd/certs/user@example.com.crt
The most recent list of common extensions can likely be extracted from the OpenSSL source code. OIDs associated with Microsoft Cryptography are available from Microsoft, or via a local snapshot.
Useful Tools
- My openssl.cnf, making use of environment variables and extensions.
- ca.conf - Configuration file containing file locations
- ca-setup - shell script to set up a CA infrastructure on an OpenBSD machine
- ca-usercert - shell script to create user certificates
- ca-hostcert - shell script to create host certificates