
Building a Security Infrastructure
by Rich Salz
December 09, 2003
In my previous column I offered a rationale for XKMS as an important
web service, and I looked at reducing the problem of implementing such a
service to a reasonable size. This time we'll build the infrastructure
necessary to develop and deploy an XKMS registration server that can issue
certificates and which is intended for use within an enterprise.
Our server will need an SSL certificate and private key. Since it will
be signing certificates for others, it will also need a CA certificate and
private key; that is, a certificate that says it is allowed to create
certificates. We could follow the standard process and just buy our SSL
certificate from the reigning
monopoly, or we could create a quick "snake-oil" certificate for
demonstration purposes. It turns out that it only takes a modest effort
to do something real, however; doing that will be the focus this
month.
Public Key Infrastructure and Hierarchy
In this exercise we're going to build an enterprise-quality public
key infrastructure. We'll then use one of the certificates to create
a server that uses SSL. Our hierarchy will look like this:
ROOT CA
|
+-- Level 1 CA
|
+-- SSL Certificate(s)
|
+-- XKMS Server CA
The root will sign the Level 1 CA and then be taken offline. Anyone
who wants to validate any identity within our organization only needs to
have our root certificate. If the enterprise merges or joins a commercial
PKI (such as Identrus), then we
only need to get the root certificate signed by our new "super root".
We'll only create one Level 1 (L1) CA, although for a large
organization we might want to create one for each division or geographic
boundary. The L1 CA's are used to issue certificates to our application
servers and to the SSL certificates which they use. If the applications
are being used outside the enterprise, then we might want to have a
commercial SSL CA sign those SSL certs.
Each of the three CA's follow the same directory structure:
NAME-ca
+-- .rand
+-- serial
+-- index.txt
+-- certreq.pem
+-- cert.pem
+-- key.pem
+-- certs
+-- 01.pem, 02.pem, ...
+-- crl.pem
+-- crls
+-- old CRL's ...
The .rand, serial, and index.txt
files are used by OpenSSL to maintain state when generating keys and issue
certificates; each cert will be copied to the certs
directory, with a filename generated from the serial number. The actual
cert is in cert.pem, and the private key is in
key.pem; we'll discuss the risks of that later. In order to
make it easy to get our CA's recertified, we'll keep a copy of the
original request in certreq.pem.
For naming, we'll use the Country, organizationName, organizationUnit,
and commonName components (or, rather, "C", "O", "OU", and "CN"). If
there's an emailAddress, we'll move it to the subjectAltName
extension, and not put it in our DN. We'll require that everything have
the same C and O components. We'll also require that the certificates our
XKMS Server generates must have an emailAddress.
The OpenSSL configuration file for this hierarchy can be found in xkms.conf. A script to create the directory
tree can be found in setup-pki-part0. The
script can be run with a single argument, --restart, to
remove an old configuration. It will also ask for the country and
organization names, and it will build a certificate request template used
by the other scripts. After running setup-pki-part0, you can
edit the req.conf file it generates.
If you want to build the service in a directory other than
/opt/xkms, you'll have to edit both files. Both that
directory and the /opt/xkms/openssl directory must exist
(with appropriate permissions) before doing anything else. Copy both
files to the /opt/xkms/openssl directory.
Creating the PKI
The next step is to create the root CA keypair and use the key to
create a self-signed certificate. Following that, we'll create a Level 1
CA and have the root sign the L1 certificate. This is done with the setup-pki-part1 script.
Most items are protected by one safeguard. For example, a private key
is protected by a password. From the security viewpoint, if we can
double that, we have accomplished a great deal. I encourage you to
actually try the steps described below, to get a feel for good security
practice.
To create the first two CA's, you'll need at least three volunteers and
the administrator of the Level 1 CA. Two volunteers will be used to
prevent the root private key from being compromised, and the third watches
the behavior of the first two. We'll protect the root key with a
password; one volunteer will get the password, and the other will get the
key. (In my organization, the password was kept in a sealed envelope with
other confidential Personnel files, and the key was written to a CD which
was sent to our lawyer. We then scrubbed the disk.)
In addition to protecting the company, this type of two-part safeguard
also protects you. No matter what happens, it's impossible for you to
falsely issue certificates. You don't have the key, you don't have the
password, and the third volunteer watched to make sure that the other two
put their items into safe escrow.
Running the ``part 1'' script, you see output like the following:
**
** GENERATING ROOT KEYPAIR
**
Generating a 2048 bit RSA private key
......................................................+++
.....+++
writing new private key to '/opt/xkms/openssl/root-ca/key.pem'
Enter PEM pass phrase:
Have the first volunteer type a password, they will then have to verify
it. They need to write it down on a piece of paper, fold it, and hold
onto it. Next you should enter the fields for the root CA name:
Country Code [US]:
Organization Name [XKMS Service]:
Organizational Unit (eg, department) []:
Common Name (i.e., name of person or server) []:
Email Address []:
Now the root will sign its own certificate. Have the first volunteer
enter the password again.
Now we generate the Level 1 CA. Whoever is in charge of that
should enter the password. You should then enter the name:
Country Code [US]:
Organization Name [XKMS Service]:
Organizational Unit (eg, department) []:
Common Name (i.e., name of person or server) []:Level 1 CA
Email Address []:level1@example.com
Now the first volunteer will have to enter the root password, look at
the certificate, and decide to sign and commit it. At this point, we no
longer need the root. Give the key,
/opt/xkms/openssl/root-ca/key.pem, to the second volunteer.
Have the third volunteer walk the first one to the storage place, and
watch them seal the envelope and put the password away. The third
volunteer then repeats the process with the second volunteer and the
private key.
More from Rich Salz
SOA Made Real
SOA Made Simple
The xml:id Conundrum
Freeze the Core
WSDL 2: Just Say No
You can see why this is called a key signing ceremony. In
order to sign a new certificate, it's necessary for each volunteer to
bring their piece to the signing machine, watch the operation, and take
their parts away. This shows one of the paradoxes about PKI: the more
valuable the certificates, the harder it is to sign things. The paradox
is that if the CA has to issue a revocation list (CRL), it's a lot of work
and long time can pass. XKMS (among other mechanisms) address this.
We'll skip the details of running setup-pki-part2. This ceremony is much less
inolved: it requires only those running the Level 1 CA and the XKMS
Server to be present. Just remember that the common name should be the
name of the server host for the SSL and XKMS certificates.
server.py implements a small Python
server that listens on local port 9999 using the SSL certificate we just
created. Use a browser to connect to a URL like
https://localhost:9999/foo. You can then walk-through the
security and certificate settings, seeing references to the PKI you just
created.
Next month we'll begin implementing the web service.