PKI for Implementors

So, you'd like to start using X.509 certificates in your application. And you'd like to "do it right". Well, this guide is intended to help you do that.

We're writing this guide because we've found that PKI tutorials tend to fall into one of two categories. Either they focus on a how a given library or application implements some PKI features, or they explain PKI from a high-level concepts view. Some familiarity with these high-level concepts will be assumed from here on in, so if you aren't sure what a Registration Authority, a Certification Authority, or non-repudiation is, or if you aren't sure of the basics of digital signature, then you may want to take a minute to read the guides that we've written on these topics. For basic information, our Fingerpuppet PKI Tutorials will give you a good start. We've also written a more in-depth PKI guide as well.

All right, now that everyone has all the basic concepts, let's get into what an implementor needs to know. Broadly, they can be summed up as follows:

What are the consequences of mis-identifying either the client or the server?
This is the best place to start, since the answer to this question determines how much of the rest of this tutorial you need to read. Notice that we're talking about identifying things. That is the single use for which PKI is best suited. A lot of people think you need certificates for encrypting things, but that's actually a misunderstanding. The major focus of assigning an X.509 certificate to an individual is in binding that individual to the private key corresponding to the public key in the certificate. It is this binding that the Certificate Authority is attesting to by issuing the certificate.

If you don't really care about the identities of the parties in a communication, and all you want to do is encrypt things, then you can save yourself a lot of effort and implement a simple shared secret scheme. Unfortunately, if you are stuck using SSL (or TLS as it is now called), then at least the server side of your service needs a certificate, but it can be a self-signed certificate that provides no identity assurance, as long as both ends of the communication turn off any certificate validity checking. If you are working with web clients (i.e.: web browsers such as Internet Explorer and Mozilla Firefox), then save yourself a lot of problems, and just buy your server certificate from a commercial Certificate Authority.

If you DO care about the identities of the two parties that are communicating, then you are using the right technology. PKI is very well suited to helping two parties confirm their identities. You do still need to ask yourself what is the real danger of accepting an identity that you shouldn't, since that will directly influence the complexity of what you need to do to make sure that all identities are confirmed correctly.

How are the identities you need expressed in the certificate
In a certificate, the identity of a key holder is found in a couple of places. The first is in the "Subject" field. This field is an X.500 Distinguished Name (DN), usually ending in a Common Name (CN). It is up to the entity that issues the certificate to decide how a given identity will be expressed in this field, and, moreover, how uniqueness of names will be guaranteed. Let's take a look at a couple of examples:

Certificate #1:
Subject: C=CA, O=Carillon Information Security Inc., OU=Technical Services, CN=Alice Smith (Identity)

Certificate #2:
Subject: C=DE, O=Very Large Company, OU=Business Unit Name, serialNumber=123456789, CN=Alice Smith

Certificate #3:
Subject: C=DE, O=Very Large Company, OU=Business Unit Name, serialNumber=456789012, CN=Alice Smith

Certificate #4:
Subject: DC=com, DC=example, O=Example Widget Company, CN=Alice Smith

In Certificate #1, we see that Alice Smith works in the Technical Services division of Carillon. Now, at Carillon, we issue certificates with additional information in the CN, to make choosing which certificate (Identity, Signature, or Encryption) a user wants to use for a given task easier. We have to do it this way, since there is no good way to tell the difference between an Identity Certificate and a Signature Certificate, and there are many limits on what a program such as Internet Explorer will display to the user when a server asks for it to present a client certificate. As a general rule, a Certificate Authority will explain in its Certificate Policy how it names users. If this Certificate Policy is in RFC 3647 format, this will be found in sections 3.1.2, 3.1.4, and 3.1.5.

In Certificates #2 and #3, you can see that once again, we're looking at Certificates for a Subscriber named Alice Smith. However, we also have to look at the serialNumber field to know WHICH Alice Smith we are identifying. This is because the Certificate Authority that issues these certificates guarnatees name uniqueness by including the employee number in the serialNumber field. Realistically, one would not have to look at the commonName field at all, and just match the value of the serialNumber field with whatever is being used behind the scenes to validate identity.

Certificate #4 is included to show an alternate encoding of a Disinguished Name, using Domain Component (DC) names. This is the format that is native to Microsoft Active Directory, so applications that need to accept Certificates issued by a Microsoft Certificate Authority will need to be able to understand this form of Distinguished Name as well.

Now, there is another place in the certificate where identity information may be found. That's the 'subjectAltName', or Subject Alternative Name, extension. This is an X.509 extension that contains one or more values of the form type:value (Note to ASN.1 purists: This is a conceptual shortcut - those curious about the actual encoding of the bits can look at RFC 5280). Some common types are:

  • email (or rfc822email);
  • DNS;
  • UPN (or userPrincipalName also sometimes seen as principalName); and
  • IP Address (either IPv4 or IPv6).
These are used to convey extra information associated with the entity or person who is the Subject of the certificate. Many applications find this information much more interesting, as this information is often in a format that is sensible for the application. For instance, a subjectAltName of type email is used by the S/MIME protocol to make sure that the certificate being used matches the email address of either the sender or recipient of the message. So you, as an implementor, may want to make sure that you can understand the values in this extension to help you identify the holder of the certificate being presented.

How do you decide which certificates to trust?
Ultimately, if you are using PKI, you have decided that there are one or more entities that you would like to trust to verify identities and issue certificates that your application will use. One thing to keep in mind is that not all Certificate Authorities are created equal, and not all user identity-proofing processes (whereby the Registration Authority makes sure that a given person really is associated with a given key) are the same. These differences in registration process will be discussed more in the section on Certificate Policies, but when thinking of this problem, what you should be most concerned with is how your application will manage these "trust anchors" (certificates associated with a given Certificate Authority), how you will add new anchors over time, and how you will remove old ones that either you wish no longer to trust, or which now have a technical problem with their cryptographic algorithms (such as being signed with a now broken hash algorithm). Keep in mind that this is often the most fragile point in the entire chain. If someone is able to add a rogue trust anchor, then that may leave your application open to accepting certificates from entities that you do not trust. If you have the option, you should simply rely on the mechanisms that your underlying operating system provides for trust anchor management, because most of the have figured out a good way to do this. That's not to say that using the default "Trusted Root Store" (or equivalent) is necessarily what you want. You should definitely, in the installation instructions for your application, have a section that details which certificates should be in that store, and instructs whomever is installing your application to remove all other trust anchors.

It gets more complicated when your application must work in a bridge environment, such as that formed by the US Federal Bridge PKI, CertiPath, the Government of Canada PKI Federal Bridge, or SAFE. In these environments, what is best practice is to use a single trust anchor belonging to one of the bridge members, and then use the Path Discovery and Validation algorithm in chapter 6 of RFC 5280 to resolve the trust of any given client certificate that is presented.

Is the certificate presented allowed to be used for this purpose?
Just about every certificate that an application will be presented with will have, somewhere within its structure, an indication of what the Certificate Authority permits it to be used for. This information is found in the 'keyUsage' and 'extendedKeyUsage' X.509 extensions. The keyUsage extension contains one or more of the following values:

  • digitalSignature
  • nonRepudiation (recent editions of X.509 have renamed this bit to contentCommitment)
  • keyEncipherment
  • dataEncipherment
  • keyAgreement
  • keyCertSign
  • cRLSign
  • encipherOnly
  • decipherOnly

The meanings of these values are listed in RFC 5280, but a simplifying assumption can be made. In most regimes (and it is certainly best practice as promoted by NIST and ETSI), you should not have a certificate used for more than one purpose. Therefore, you need to check with your Certificate Authority, and see how they distinguish between their Identity, Signature, and Encryption certificates (for instance, CertiPath, in Section 10 of their Policy describes different profiles for each certificate use. Once you know this, you should make sure that the certificate presented is being used in the manner that the Certificate Authority wishes. If they do not make a distinction, then you should still check this field, especially in light of the restrictions outlined in RFC 5280.

Once you have made the basic distinction, you should then check the extendedKeyUsage extension, if present, and see if there are any further restrictions put on the use of this certificate. According to RFC 5280, populating a value in extendedKeyUsage means that that certificate may only be used for that purpose. So, a certificate with only "Client Authentication" could not be used for Secure Email, and a certificate with only "Microsoft SmartCard Login" could not be used for web site client authentication. Consequently, your application should very carefully examine this field, and make sure that it is only accepting certificates that the Certificate Authority deems appropriate.

One last thing to mention here is something called "extension criticality". Under the technical specification for X.509 Certificates, many extensions can be marked as "critical". If an extension is so marked, then an application absolutely must follow the indications and limitations of the contents of that extension. If you application does not know how to process a given critical extension, then it must reject the certificate containing that critical extension as invalid.

How are you making sure that all of the certificates are valid?
This is probably the single most overlooked step, and one of the most misunderstood. Among the best reasons for using PKI X.509 certificates is the fact that you can easily revoke them, in a single central location, and theoretically, that certificate will be rejected by everyone from that point forward. This "revoke once, never allow access anywhere" idea is one of the key differentiators and value propositions of PKI, but most applications still get it wrong. When a certificate is presented, among the first things that an application should do is to check the "Not Valid Before" and "Not Valid After" fields, and compare them to the current date and time. If the current date and time falls between these two values, then the very next thing that an application should do is check the signatures. Does this certificate have a valid signature chain back to a trust anchor? Once this is done, and the trust chain built, the application then needs to find out if any of the certificates in the trust chain have been revoked.

Revocation checking is done by validating that the serial number of the certificate being validated does not appear on the Certificate Revocation List (CRL) issued by the same entity as is listed in the "Issuer" field of the Certificate. (This is a bit of a simplification, since the Issuer can delegate CRL functionality to another entity.) If this is the case for the Certificate Authority that you've decided to trust, please see RFC 5280, section 4.2.1.13, and the discussion on "crlIssuer". The URL to find this CRL information is usually included in the X.509 extension 'crlDistributionPoints', and usually indicates that an application can use the HTTP protocol or the LDAP protocol to download it. In the case where more than one URL is listed, it is good practice to try each in turn, and stop after one is successful. If a certificate does not contain a CRL distribution point, then an application only has one option, and that is to have a configuration option that specifies the CRL location for that Certificate Authority, and use that when necessary.

Another way of checking revocation that is gaining popularity is the use of the Online Certificate Status Protocol (OCSP). Use of this protocol is often faster, since, unless carefully managed and properly cached, CRL fetching can rapidly cause network and performance problems, due to their size (there are anecdotal accounts of CRLs of several MB begin generated by certain long running PKI implementations). Again, most certificates have a pointer to an OCSP server that has information about them, in the OCSP value of the 'authorityInformationAccess' extension.

It is worth stressing that not only the client certificate, but every certificate in your trust chain needs to be validated by checking either CRL or OCSP, with one exception, and that is your trust anchor. Trust Anchors are never listed in a CRL, and they are not revoked in the normal manner. The only way to mark a trust anchor as untrusted is to remove it from the list of trust anchors. This is why, as listed in the section on trust anchors, it is critical to have a good process for trust anchor management.

How are you making sure that all of the certificates are issued according to a policy that you agree with?
Not all Certificate Authorities are equal in the rigour that they apply to the process of issuing certificates. Moreover, even within a given CA infrastructure, there can be a variance in the processes used to bind a given certificate to a given individual. The processes whereby a certificate is bound to an individual are often called "assurance levels" (as in "How assured am I that this certificate belongs to that individual"), and are referred to by names such as "rudimentary", "basic", "medium" and "high". More important than the names, however, are the processes behind those names. A Certificate Authority will list, in its Certificate Policy document, a list of the various assurance levels that it issues from a particular CA, and will detail in that Certificate Policy document the steps it uses to verify the identity of a person before it issues a certificate to that person. There are two ways that an application can automatically tell which assurance level and policy a given certificate was issued under. Either (like Verisign does) the CA will list as a field in the Issuer Distinguished Name which policy and assurance level it is operating under, or, as promoted by the Four Bridges Forum and the CA Browser Forum, the CA will include a value for that assurance level in the certificatePolicies X.509 extension.

If an application wants to make sure that it is only accepting identities that it can be sure of, then checking this field is very important. Without it, there is no other way for an application to tell if someone is presenting a certificate issued under a "rudimentary" assurance level (with no identity checking) or if someone is presenting a certificate issued under a "medium" assurance level (which, in some policies, requires a face-to-face meeting, and presentation of a passport or national ID to prove identity).

What about all of the encryption stuff?
In the first section, we said that using certificates to encrypt things was the wrong usage. One does not need to use certificates to encrypt things. The most efficient encryption algorithms today are not based around the same kind of cryptography as is used for certificates. Certificates use public/private key (asymmetric) cryptography, whereas most encryption systems use symmetric cryptography with a single shared secret key. The key differences are outlined in our PKI Tutorial, so we will not cover them here again, but a discussion of how certificates are used in encryption schemes such as S/MIME and the encryption portion of SSL/TLS are in order.

Certificates are used in order to establish the symmetric key that both sides will use to actually encrypt the data. As has already been hinted, encrypting data with RSA is very, very slow, whereas encrypting data with a symmetric algorithm such as AES is very fast. So, the designers of the various common cryptographic protocols restricted the use of asymmetric protocols to simply setting up and agreeing on the symmetric keys that will be used for the real encryption of the data. This use of certificates for key propagation is an optimisation, since in the environment which most of the protocols were designed (the military), applications cared very much about not only keeping people from seeing the data (encrypting it), but also ensuring exactly who was party to the conversation (authentication). And thus, protocols that do both are more efficient than two that do only half the job each. The use of a CA also allowed parties who may have never met to establish authentication with each other, and, once authenticated, establish secure communications with each other.

This all sounds complicated. Is there any way to make this simpler?
At Carillon, we have built a number of tools to simplify integrating PKI into applications. Moreover, we have extensive experience in building PKI aware applications, and in assisting organisations like yours to adopt PKI, through both our technical services group and our training department.

We also publish extensive guides to setting up your own CA that would be usable to help you test your application. If you don't wish to set up your own, Carillon can provide test certificates that are cross-certified with the CertiPath bridge at test level.

Why not contact us, and find out how we can help you get a head start on integrating PKI in your application?

Did this guide answer your PKI Implementation questions?
We hope this guide was useful. If you had a question that was not answered, please do not hesitate to contact us and we will do our best to answer.