If you tell enough stories, perhaps the moral will show up.

2007-04-28

Barefoot PKI 2: X.509 PKI

This post is part of a series introduced here.

Certificate PKI. For Simpletons.

In the previous post we saw how successful use of public key encryption (PKE) replaces one difficulty with another. We don't have to worry about sharing secret keys, but we do have to get trustworthy copies correspondents public keys. The solution to the problem — a trustworthy means of distributing keys — is called a Public Key Infrastructure. The X.509 PKI uses the certificates mentioned in the previous post: X.509 is the standard that defines the format and the meaning.

The certificate is the instrument that allows trust. Looking more formally:

  1. A certificate is a structured text document which asserts — certifies — that a particular name will use a particular public key for a particular purpose over a particular period.

If you trust the assertion in the certificate , and trust the entity named to manage their private keys securely, you can make the public key magic work for you — encrypt, decrypt or check a signature and all the rest. Unfortunately, by itself, the plain certificate is worthless: anyone could draft such a document. I might generate a key pair; write myself a certificate that said that the public key belonged to Citibank; and start signing banker's drafts! So we need another stage:

  1. Certificates are trusted if they are signed by a trusted certification authority (CA). Trust is a belief that the CA a) will follow a defined policy to ensure that it only signs "true" certificates, and b) keep its private key a secret so that no-one else can sign certificates that will validate with the CAs own public key.

Signed here means signed in the PKE sense. The signed document is a) the plain text document, and b) an encrypted hash of the document. If you know the CA's public key, you can decrypt the signature: if it comes out the same as the hash of the plain text, then the encryption must have been done using the CA's private key. If you trust the CA to keep their private key secret you can be sure that the document text offered to you is the same as that signed by the CA. If you trust the CA to only sign true certificates, you can be sure you have the public key you want to use.

(Diversion no. 1: You can see that this works off-line. A lot of the weirdness and toughness in X.509 PKI comes from the requirement for off-line working. It's a child of the eighties and it shows.)

(Diversion no. 2: Discussions of PKI tend to ignore the really important points like the diligence and process at the CA, and the ability of parties to look after their private keys. Consider that the most common use by far of certificates is to certify the identity of a public web server, and consider that that server probably has to be able to start-up, unattended, on an inaccessible hosting site and you can see that privacy of the private key is a bit of an issue.)

So: how do you know the CA's public key? You have to get it some way you can accept. CA keys arrive as so-called self-signed certificates: you can't check them, you just have to take care to get a true one. Browsers come with a long list of CA certificates pre-installed, Windows has a certificate store interface and tools to add CA and other certificates to it.

(Diversion no. 3: Check out the list of CA's your browser has decided that you need to trust. Then research Go Daddy's signing policy. That's a lot of why I think PKI doesn't work — you can't actually trust them to the level you want. Remember, you have no legal agreement with any of these CAs: You won't be able to sue e.g. Belgacom (who?) if you get robbed by a merchant abusing one of their certificates.)

It's a good deal more complicated than this. Certificates have limited validity and limited capability. Very often, intermediate CAs — CAs whose public key is signed by another, "higher" CA — do the actual signing, and you have to trust them too.

X.509 Certificates for Simpletons

So we can use certificates to build a PKI. Obviously these certificates need to be in a standard format and the universal format is X.509, an ITU standard which attempts to define a PKI. X.509 is old — pre-Internet — and as with so many international standards, it's oriented to a world which never happened. For our purposes, X.509 defines data formats for key parts of the certification process, most importantly the certificate itself. But we have other standards as well, notably Public Key Certificate Standards (PKCS) from RSA, which define the format of .Pnn files like the .p12 file which is crucial to Windows.

What is a certificate on the disk? It's a data-structure, unambiguously encoding all the values in such a robust way that the same encryption processes will yield the same result. The requirement for repeatable, checkable, bit-for-bit identicality, despite byte-endian reversals, network transmission, packing and unpacking, and fixed line lengths means that plain text won't do.

X.509 defines the structures using ASN.1. ASN.1 is a data-structure definition language with primitives like octet, integer, sequence etc. It doesn't define formats, but it does define content and order. For example, a simple certificate (not X.509) might be defined as a sequence consisting of a serial number which is an integer, a common name which is a character string, a public key which is .... That ties the content down very precisely, but it doesn't for example say whether the serial number is going to be a 128-bit GUID or a 32-bit long int. So X.509 defines the ASN.1 code for a number of data structures in the certificate process, including the certificate itself.

So those are the formats. Actually representing the content of a data structure is a job for an encoding method. There are many defined encodings for ASN.1, but X.509 uses just one, the DER which creates a binary octet stream. So an actual certificate, or a request, or whatever is a DER string in a file. In Windows, this carries the .CER extension. (Watch out: there is a CER encoding method, and CER is a superset of DER; nonetheless, .CER files contain .DER sequences.)

The DER format with the .CER extension is usual in Windows, but Unix goes one stage further. An early and now obselete use for X.509-style certificates was called Privacy Enhanced Mail (PEM), and it had to pass certificates over the old seven-bit, fixed-line-length mailers common at the time. The solution was the old favourite (really old — it goes back to uucp) base64 encoding, which encodes octet data in a set of 64 7-bit characters, with fixed line length. PEM is gone now, but .PEM files are still widely used — they're the OpenSSH default, because text is always convenient, and you can mix text and data without confusion. A .PEM file is a base64 representation of a DER octet sequence.

So that's the format, and it's pretty obvious that the public key, the name and the CA signature are going to be included in the certificate details. But there's more: the applicability period and the usage types.

The period just means something like : "I will use this key throughout 2006". NB that the validity of the certificate is not affected by the expiry of the applicability period. The key and the certificate may still be required long after its expiry, or the expiry of the key used to sign it: it may be needed to check a signature made in that year, or decrypt a message sent then. The validity refers to intended use rather than actual integrity of the certificate.

And finally, the usage types limit what the certificate can be used for. It may be an encryption key. It may be a signing key. It may authenticate the name of the entity for SSL challenge-response. These purposes are divided up by X.509 into capabilities, V3 capabilities and extended capabilities, with a detailed, extensible underlying structure (called OIDs ). However for all practical purposes they can be regarded as a set of check marks saying what the key can do. One capability to watch out for is "CA": the capability to sign certificates which will inherit the trust of the root certificate.

Other X.509 and PKI Data

The certificate is just one item. To ensure that certificates do what we want, other files and formats are defined by the basic workflow around certificate issue. The basic sequence of operations is linear:

  • It starts with generation of a key pair. This is a standard cryptographic function — nothing to do with X.509 or the the CA — the user should do it locally to reduce the risk of exposing the private key. Not all applications can generate a key pair and so it's a standard CA function to do so, with the private key being returned (password encrypted) alongside the certificate in a PKCS12 (.P12) file.
  • The application has to give something to the CA to sign. That is the job of the certificate request. PKI users which can generate a key can also generate a certificate request, otherwise the CA has to do it. The request is defined in X.509 — a DER-encoded ASN.1 data structure which contains all the user-specific content for the certificate, including the name, requested validity period, the "capabilities" requested and the public key to be used. It's a bit like an unsigned certificate. It's not confidential because it doesn't contain the private key, but CRs can be passworded to stop casual snooping. OpenSSL can generate CRs from a public key, by default in PEM format. Some public CAs, outside our current scope insist on DER requests.
  • When a CA sees a request, it has to decide whether to sign it. Some tests are simple: few CAs will routinely sign a request that requests CA capability. Others are more complex: is the name requested legitimate? and does the period exceed our policy? Where theses choices are mechanical they are encoded into the setup of the CA software: The OpenSSL CA functions get this policy from the openssl.conf file.
  • Signing produces a certificate. For some apps, that's sufficient. Others may just need the format translated (from PEM to DER, say). But apps that didn't generate their own private key will need the key pair back too, and, for Windows apps, this is the job of the .P12 file. The .P12 file is a DER stream, not defined by X.509 which contains a certificate and the corresponding (encrypted) private key. This file will install into the Windows certificate store with a double click.

Simple And that is really all there is to it. I've left out the the Certificate Revocation mechanism. All I'm going to say about that is that if you have a system which depends on X.509 certificate revocation to communicate withdrawal or ceasing of access, you have already failed.

No comments: