In Chapter 1, we described a scenario known as a man-in-the-middle attack, in which an attacker could intercept and even manipulate communications secured with public key cryptography. The attack is possible because public key cryptography provides no means of establishing trust when used on its own. Public Key Infrastructure (PKI) provides the means to establish trust by binding public keys and identities, thus giving reasonable assurance that we’re communicating securely with who we think we are.
Using public key cryptography, we can be sure that only the encrypted data can be decrypted with the corresponding private key. If we combine this with the use of a message digest algorithm to compute a signature, we can be sure that the encrypted data has not been tampered with. What’s missing is some means of ensuring that the party we’re communicating with is actually who they say they are. In other words, trust has not been established. This is where PKI fits in.
In the real world, we often have no way of knowing firsthand who a public key belongs to, and that’s a big problem. Unfortunately, there is no sure-fire way to know that we’re communicating with who we think we are. The best we can do is extend our trust to a third party to certify that a public key belongs to the party that is claiming ownership of it.
Our intention in this chapter is to give you a basis for understanding how PKI fits into the big picture. PKI is important to using public key cryptography effectively, and is essential to understanding and using the SSL protocol. A comprehensive discussion of PKI is beyond the scope of this book. For much more in-depth discussion, we recommend the book Planning for PKI: Best Practices Guide for Deploying Public Key Infrastructure by Russ Housley and Tim Polk ( John Wiley & Sons).
In this chapter, we’ll look at how PKI functions. We start by examining the various components that comprise such an infrastructure. Then we demonstrate how to become a part of a public infrastructure so that others wishing to communicate securely with us can do so. Finally, we look at how to use the OpenSSL command-line tool to set up our own private infrastructure.
At the heart of PKI is something called a certificate . In simple terms, a certificate binds a public key with a distinguished name . A distinguished name is simply the name of the person or entity that owns the public key to which it’s bound. Perhaps a certificate can be best compared to a passport, which binds a picture with a name, thus solidifying a person’s identity. A passport is issued by a trusted third party (the government) and contains information about the person to whom it has been issued (the subject) as well as information about the government that issued it (the issuer). Similarly, a certificate is also issued by a trusted third party, contains information about the subject, and contains information about the third party that issued it.
Not unlike a passport, which contains a watermark used to verify its authenticity, a certificate also contains safeguards intended to allow the authenticity of the certificate to be verified, and aid in the detection of forgery or tampering. Also similar to a passport, a certificate is valid only for a defined period. Once it has expired, a new certificate must be issued, and the old one should no longer be trusted.
A certificate is signed with the issuer’s private key, and it contains almost all of the information necessary to verify its validity. It contains information about the subject, the issuer, and the period for which it is valid. The key component that is missing is the issuer’s certificate. The issuer’s certificate is the key component for verifying the validity of a certificate because it contains the issuer’s public key, which is necessary for verifying the signature on the subject’s certificate.
By signing a certificate with the issuer’s private key, anyone that has the issuer’s public key can verify its authenticity. The signature serves as a safeguard to prevent tampering. By signing the subject’s certificate, the issuer asserts that it has verified the authenticity of the public key that the certificate contains and states that it may be trusted. As long as the issuer is trusted, the certificates that it issues can also be trusted.
It’s important to note that the issuer’s certificate or public key may be contained in an issued certificate. It’s more important to note that this information cannot be trusted to authenticate the certificate. If it was trusted, the element of trust established from a third party is effectively eliminated. Anyone could create another key pair to use in signing a certificate and place that public key in the certificate.
Certificates are also created with a serial number embedded in them. The serial number is unique only to the issuer of the certificate. No two certificates issued by the same issuer should ever be assigned the same serial number. The certificate’s serial number is often used to identify a certificate quickly.
A Certification Authority (CA) is an organization or company that issues certificates. By its very nature, a CA has a huge responsibility to ensure that the certificates it issues are legitimate. That is, the CA must ensure beyond all reasonable doubt that every certificate it issues contains a public key that was issued by the party that claims to have issued it. It must be able to produce acceptable proof for any certificate that it issues on demand. Otherwise, how can the CA itself be trusted?
There are two basic types of CAs. A private CA has the responsibility of issuing certificates only for members of its own organization, and is likewise trusted only by members of its own organization. A public CA, such as VeriSign or Thawte, has the responsibility of issuing certificates for any member of the public, and must be trusted by the public. The burden of proof varies depending on the type of CA that has issued a certificate and the type of certificate that is issued.
A CA must be trusted, and so for that trust to be extended, its certificate containing its public key must be widely distributed. For public CAs, their certificates are generally published so that anyone can obtain them. More commonly, the software that makes use of them, such as a web browser, is shipped containing them. Most often, the software allows certificates from other CAs to be added to its list of trusted certificates, thus facilitating the use of private CAs with off-the-shelf software.
A private CA is often ideal for use in a corporate setting. For example, a company could set up its own CA for email, using S/MIME as the standard for encrypting and authenticating email messages. The company’s CA would issue certificates to each employee, and each employee would configure their S/MIME-capable email clients to recognize the company’s CA as being trusted.
For a private CA, verifying the identity of a subject is often a reasonably simple and straightforward matter. When used in a corporate environment, for example, employees are known, and their identities can be easily identified using information obtained from the company’s human resources department. In such a scenario, the human resources department is said to be acting as a Registration Authority (RA).
A public CA commonly issues certificates for public web sites requiring encryption and/or authentication, often for e-commerce in which customer information must be transmitted securely to place an order. For such operations, it’s essential that the customers transmit their information to the site that is supposed to be receiving it without worrying about someone else obtaining the information.
For a public CA, verifying the identity of a subject[1] is considerably more difficult than it is for a private CA. The information required from the subject to prove its identity to the CA varies depending on whether the subject is an individual or a business. For an individual, the proof required could be as simple as a photocopy of a government-issued ID, such a driver’s license or passport. For a business or other organization, similar government documentation proving your right to use the name will also likely be required.
It’s important to note that most public CAs provide their services to make money, and not to simply benefit the public. They still have a responsibility to verify a subject’s identity, but not actually guarantee anything—the liability is too great to provide an absolute guarantee. Certainly, it is in the CA’s best interests to verify a subject’s identity to the best of its ability, however. If a CA gains the reputation of issuing certificates to anyone who asks (and pays them enough money), they’re not going to remain in business for very long because nobody will trust them.
A certificate that is issued by a CA can be used to issue and sign another certificate, if the issued certificate is created with the appropriate permissions to do so. In this way, certificates can be chained. At the root of the chain is the root CA’s certificate. Because it is at the root of the chain and there is no other authority to sign its certificate, the root CA signs its own certificate. Such a certificate is known as a self-signed certificate .
There is no way to digitally verify the authenticity of a self-signed certificate because the issuer and the subject are the same, which is why it has become a common practice to provide them with the software that uses them. When they’re included with an application, they are generally obtained by the software author through some physical means. For example, Thawte provides its root certificates on its web site, free and clear, but strongly advises anyone making use of them to confirm the certificate fingerprints with Thawte via telephone before using or distributing them.
To verify the authenticity and validity of a given certificate, each certificate in the chain must also be verified, from the certificate in question’s issuer all the way up to the root certificate. If any certificate in the chain is invalid, each certificate below it in the chain must also be considered invalid. Invalid certificates typically have either expired or been revoked (perhaps due to certificate theft). A certificate is also considered invalid if it has been tampered with and the signatures on the certificate don’t match with the ones that should have been used to sign it.
The decision whether to employ a certificate hierarchy more complex than a single root CA depends on many factors. These factors and their trade-offs are well beyond the scope of this book. Entire books have been devoted to PKI, and we strongly recommend that you consult one or more of them to assist you in making an informed decision. Again, we strongly recommend Planning for PKI by Russ Housley and Tim Polk.
The most widely accepted format for certificates is the X.509 format, first introduced in 1988. There are three versions of the format, known as X.509v1, X.509v2, and X.509v3. The most recent revision of the standard was introduced in 1996, and most, if not all, modern software now supports it. A large number of changes were made between X.509v1 and X.509v3, but perhaps one of the most significant features introduced in the X.509v3 standard is its support of extensions.
Version 3 extensions allow a certificate to contain additional fields
beyond those defined by previous versions of the X.509 standard. The
additional fields may be standard in X.509v3, such as the
basicConstraints or keyUsage
fields, or they may be completely nonstandard, perhaps recognized
only by a single application. Each extension has a name for its
field, a designation indicating whether the extension is
critical
, and a value to be associated with
the extension field. When an extension is designated as critical,
software that does not recognize the extension must reject the certificate
as being invalid. If the extension is noncritical, it may be ignored.
The X.509v3 standard defines 14 extensions in an effort to consolidate the most common extensions implemented by third parties. One example is the permissible uses for a certificate—for instance, whether a certificate is allowed to sign another certificate, or is usable in an SSL Server. If each application were to create its own disparate extensions, the information in those extensions would be either unusable by other applications or significantly complicate the process of validating a certificate because it would need to recognize a virtually unlimited number of different extensions that all essentially mean the same thing.
Of the 14 standard extensions defined by X.509v3, only 4 are well-supported and in widespread use. Only one of them must be designated critical according to the standard, while the other three may or may not be. Since the majority of the standard extensions are not well supported, we won’t discuss them here. Later in this chapter, when we setup our own CA, we’ll be making use of some of the better-supported extensions, as appropriate.
The
basicConstraints
extension is a sequence that may contain two
possible components: cA
and
pathLenConstraint. Without getting into the
technical details of an X.509 certificate, a sequence can best be
thought of as a container, which contains other components; it has no
value of its own. The cA component is a boolean
indicating whether the certificate may be used as a
CA’s certificate. If the cA
component is absent, OpenSSL will check the
keyUsage
extension to determine whether to allow the certificate to be used as
a CA certificate. If the keyUsage extension is
present and the keyCertSign bit is not set, the
certificate may not be used as a CA certificate. The optional
pathLenConstraint
component is an integer that specifies the maximum number of
certificates in the chain that may be used below this certificate. If
the value is less than the number of certificates in the chain that
have already been validated, this certificate must be rejected.
The keyUsage
extension is a bit string that
defines how a certificate can be used, and may or may not be
designated critical. If the extension is present in the certificate,
it should be marked critical. If it is designated critical, the
information that it contains will always be used to determine valid
usage. If the extension is absent or designated noncritical, the
certificate should be treated as though all bits are set. Rather than
individually explain what each bit means, it’s more
useful to show which bits should be set for each of the common uses
for a certificate, which we do in Table 3-1.
|
Purpose of certificate |
Bit settings to use |
|
Certification Authority Certificate |
|
|
Certificate Signing |
|
|
Object Signing |
|
|
S/MIME Encryption |
|
|
S/MIME Signing |
|
|
SSL Client |
|
|
SSL Server |
|
The extKeyUsage
extension is a sequence of object
identifiers that further defines which uses of the certificate are
permissible, and may or may not be designated critical. As with the
keyUsage extension, if this extension is present,
it should be designated critical. If it is designated critical, the
certificate must be used for one of the purposes defined by the
extension. If it is designated noncritical, the information is
advisory only and may be ignored. There are eight possible purposes
defined for use with this extension, as summarized in Table 3-2.
|
Purpose of certificate |
Object identifier (OID) |
|
Server Authentication |
1.3.6.1.5.5.7.3.1 |
|
Client Authentication |
1.3.6.1.5.5.7.3.2 |
|
Code Signing |
1.3.6.1.5.5.7.3.3 |
|
|
1.3.6.1.5.5.7.3.4 |
|
IPSec End System |
1.3.6.1.5.5.7.3.5 |
|
IPSec Tunnel |
1.3.6.1.5.5.7.3.6 |
|
IPSec User |
1.3.6.1.5.5.7.3.7 |
|
Timestamping |
1.3.6.1.5.5.7.3.8 |
It’s worth noting that neither the
keyUsage nor the extKeyUsage
extension is well-defined, and as such, their usage is subject to
wide interpretation. In particular, how to treat the critical flag on
either extension is not well-defined, but it would seem that in many
existing software products, the extensions are largely ignored. In
addition, various profiles (guidelines that dictate what certificates
should contain) specify their usage differently. For instance, PKIX
(the IETF Public Key Infrastructure working group) has obsoleted the
three IPSec-related OIDs that may be present in an
extKeyUsage sequence. Additionally, they are not
implemented consistently across vendors. As a result of these
problems, these two extensions are mostly useless. If you do use
them, be sure that you are using them in a consistent manner with any
existing software with which you’ll be
interoperating.
The
cRLDistributionPoints
extension is a sequence that is used
to communicate how the CA that issued the certificate makes its CRLs
available. The standard indicates that this extension should be
designated noncritical; however, it does advise CAs to include the
information. Providing the location of the CRL that would contain
this certificate’s serial number if it is revoked
inside the certificate itself is perhaps the best possible way for
software validating a certificate to obtain the information.
Once a certificate has been issued, it is generally put into production, where it will be distributed to many clients. If an attacker compromises the associated private key, he now has the ability to use the certificate even though it doesn’t belong to him. Assuming the proper owner is aware of the compromise, a new certificate with a new key pair should be obtained and put into use. In this situation there are two certificates for the same entity—both are technically valid, but one should not be trusted. The compromised certificate will eventually expire, but in the meantime, how will the world at large know not to trust it?
The answer lies in something called a certificate revocation list (CRL). A CRL contains a list of all of the revoked certificates a CA has issued that have yet to expire. When a certificate is revoked, the CA declares that the certificate should no longer be trusted.
Bandwidth is a significant concern when distributing CRLs, since clients need to have reasonably current revocation information in order to properly validate a certificate. In an ideal world, the client would get up-to-date revocation information as soon as the CA gets the information. Unfortunately, many CAs distribute CRLs only as a huge list. Downloading a huge list before validating each certificate could easily add unacceptable latency and place an undue load on the server when there are a lot of clients. As a result, CAs tend to update their CRLs regularly, but not immediately after they learn about key compromises. Included in the revocation list is the date and time that the next update will be published, so once an application has downloaded the list, it doesn’t need to do so again until the one it has expires. Clients are encouraged to cache the information (which can be infeasible if the client has limited storage space).
This scheme leaves a window of vulnerability in which the CA knows about a revoked certificate, yet the client does not find out about it immediately. If a CA publishes the list too frequently, it will require massive amounts of bandwidth in order to sustain the frequent demand for the list. On the other hand, if a CA publishes the list too infrequently, certificates that need to be revoked will still be considered valid until the next list is published. Each CA needs to strike a balance with the community that it’s serving to determine how frequently to publish its list.
One solution to this problem is for the CA to break up its CRLs into segments. To do this, the CA specifies ranges of certificate serial numbers that each CRL contains. For example, the CA could create a different CRL for each 1,000 serial numbers. Therefore, the first CRL would be for serial numbers 1 through 1,000; the second would be for serial numbers 1,001 through 2,000, and so on. This solution does require forethought and planning on the part of the CA, but it reduces the size of the CRLs that the CA issues. Another option is to use " delta CRLs,” where a CA periodically publishes incremental changes to its CRL list. Delta CRLs still require the client to cache CRL information or download everything anew each time a certificate needs to be validated.
Another problem with CRLs is that while there is a standard means to publish them formally, specified in RFC 2459, that mechanism is optional, and many of the more common public CAs, such as VeriSign, do not distribute their CRLs this way. There are also other standard methods for distributing CRLs, but the overall problem is that there isn’t just one, and so many software applications do not actually make use of CRLs. Of the various methods of distribution, LDAP is most commonly used as a repository for CRLs. Additionally, multiple applications on the same machine, or even on the local network, could be interested in the same data and require that it be queried from the CA multiple times within a short period.
The problems with the distribution of CRLs currently make them difficult to manage, and what’s worse, few applications even make the attempt. This essentially makes CRLs useless and leaves no way for a CA to revoke a certificate effectively once it’s been issued. Ideally, CAs need to standardize a method for CRL distribution, and both CAs and applications need to start making use of it.
Another potentially serious problem that has not been addressed is what happens when a root CA’s certificate needs to be revoked. A CRL is not suited to handle this, and neither are applications. The reason for this is that CRLs are issued by a parent (a CA) for its children, but a root CA has no parent. It is possible for a CA to revoke its own certificate as long as it still has its private key. For the purposes of signing a CRL containing its own certificate, the CA’s compromised key can still be trusted. Unfortunately, given the poor state of CRL handling in existing software in general, it’s not likely that this situation is handled very well, if at all.
A classic example demonstrating that CRLs are poorly supported is what happened in early 2001 when VeriSign issued two class 3 code-signing certificates to Microsoft Corporation. The problem was that Microsoft never requested these certificates—someone claiming to represent Microsoft did. VeriSign handled the situation in the appropriate manner and published the serial numbers of the certificates in a new CRL. What really demonstrated the flaws with CRLs was how Microsoft handled the situation. It quickly became clear that Microsoft’s software, while distributing VeriSign’s root certificates and using their services, did not check VeriSign’s CRLs. Microsoft issued a patch to deal with the problem of the revoked certificates, but the patch did nothing to fix the problem of their software not utilizing the CRLs at all. Had Microsoft’s software made proper use (or, arguably, any use at all) of CRLs, no patch would have been necessary, and the problem would have ended with VeriSign’s publication of its CRL (minus the inherent window of vulnerability).
It could be argued that if a major software company like Microsoft can’t handle CRLs properly, how can smaller software companies and individual software developers be expected to handle them properly? While the argument may very well be faulty in a number of respects, it is still a question worth asking, and in truth, the answer, at least for right now, is not one that we would all like to hear. PKI is still relatively immature, and much work needs to be done to remedy not only the issues that we’ve discussed here, but others that we leave as an exercise for the reader to explore as well. While CRLs may not be the ultimate answer to revoking a certificate, for the time being, they are the most widely implemented means by which to do so. It’s worth taking the time to ensure that your software is capable of dealing with the technology and provides for a reasonably safe and pleasant experience for your users.
To complicate matters more, the standard CRL specification has changed over time, and both the old format (Version 1) and the new format (Version 2) are actively used. OpenSSL supports both Version 1 and Version 2 CRLs, but there is much software still in common use that does not yet support Version 2, and certainly old legacy applications that are no longer being developed or supported never will, even though they continue to be used. The major addition that Version 2 offers is extensions. The standard defines four extensions that are used primarily to indicate when a certificate was revoked, why a certificate was revoked, and how to handle a certificate that has been revoked.
The fourth standard extension is used in indirect CRLs. An indirect CRL is one that is not necessarily issued by a CA, but instead by a third party. Such a CRL can contain certificates from multiple CAs. The extension, then, is used to indicate which CA issued the certificate that has been revoked. Currently, indirect CRLs are not very common, because CRLs in Version 2 format are not widely supported.
The Online Certificate Status Protocol (OCSP), formally specified in RFC 2560, is a relatively new addition to PKI. Its primary aim is to address some of the distribution problems that have traditionally plagued CRLs.
Using OCSP, an application makes a connection to an OCSP responder and requests the status of a certificate by passing the certificate’s serial number. The responder replies “good,” “revoked,” or “unknown.” A “good” response indicates that the certificate is valid, so far as the responder knows. This does not necessarily mean that the certificate was ever issued, just that is hasn’t been revoked. A “revoked” response indicates that the certificate has been issued and that it has indeed been revoked. An “unknown” response indicates that the responder doesn’t know anything about the certificate. A typical reason for this response could be that the certificate was issued by a CA that is unknown to the responder.
An OCSP responder is typically operated by a CA or by a trusted third party that is authorized by the CAs for which it provides information. The client must trust the OCSP responder in a manner similar to a root CA. More importantly, there is only one way to revoke an OCSP’s trusted status, and it’s not pretty. If an OCSP responder is compromised, every client that makes use of that responder must be reconfigured manually either not to trust it or to use a new certificate that can be trusted.
A client’s request includes information about the issuer of the certificate it is requesting status information for, so it is possible for a single OCSP responder to provide certificate revocation information for more than a single CA. Unfortunately, one of the problems of OCSP responders when run by a third party is that the information they’re serving can become stale. At the very least, a delay often occurs between the time when a CA revokes a certificate and when the responder receives the information from the CA, particularly if the responder is relying on CRLs published by its serviceable CAs to supply its information.
Currently, OCSP is not nearly as widely recognized or implemented as CRLs are, so unless you know that all your users will have an OCSP server available, it is generally best to use the technology to supplement CRLs rather than replace them completely.
Three of the more significant problems that OCSP introduces are the potential for denial of service, replay, and man-in-the-middle attacks. Most servers are vulnerable to denial of service attacks to some extent, but the nature of the service, the amount of information transferred, and the way requests are handled help determine just how vulnerable a given server is to such an attack. The details of denial of service attacks are beyond the scope of this book; however, OCSP responders are typically more susceptible to them than other common services such as HTTP.
The OCSP Version 1 specification allows responders to pre-produce signed responses in an effort to reduce the load on the responder required by signing definitive responses. Allowing for pre-produced signed responses opens the door for replay attacks. Man-in-the-middle attacks are possible because error responses are not signed, although this type of attack could more accurately be considered a denial of service attack. Perhaps what’s most disturbing about the aforementioned vulnerabilities is the fact that each one is noted in the RFC, yet nothing was done when formalizing the standard to prevent them.
There are only a handful of public OCSP responders available at the time of this writing, as listed by www.OpenValidation.org . The small number of responders is a clear indication that OCSP is not widely deployed. While OCSP is an attempt at resolving the problems of CRLs, we feel that the additional problems it creates, at least in its current state, outweigh the problems that it solves. Certainly, it cannot be reasonably considered as a replacement for CRLs. In its defense, there was an IETF draft submitted in March of 2001 for Version 2 of the protocol, which addresses some of the issues, but this has not yet completed the standards process.
Before obtaining a certificate, you first need to determine what purpose the certificate will serve. There are many different types of certificates offered by a variety of CAs, both public and private. For the purposes of this discussion, we will investigate what is necessary to obtain three different types of certificates from a public CA. While it is certainly not the only public CA, we’ve chosen VeriSign as the CA that we’ll obtain a certificate from because it is perhaps the most established public CA and offers the widest variety of certificates for a variety of uses.
As we mentioned, there are many different types of certificates, each used for different purposes. VeriSign’s offerings range from personal certificates for use with S/MIME to enterprise solutions that are more sophisticated. We’ll find out how to get a personal certificate for S/MIME, a code-signing certificate for signing your software so that users can verify that it came from you, and a certificate for securing your web site for applications such as e-commerce.
S/MIME email relies on personal certificates (as opposed to certificates granted to an organization), which VeriSign calls a Class 1 Digital ID . It is the easiest kind of certificate to obtain, and is available for a modest price, but it is limited to email security only. You can get a Class 1 Digital ID that works with Netscape Messenger, or you can get one intended to work with Microsoft Outlook express. If you use a different application to read and write your email, you should consult with that application’s vendor to find out whether it interoperates with either of these certificate types.
The first step in obtaining a personal certificate is to visit VeriSign’s web site at http://www.verisign.com/ and follow the links from the main page to “Secure E-Mail”, which is listed under “Home & Home Office” products, to the Digital ID enrollment form. We won’t outline all of the links here, not only because they’re subject to change, but because there’s a wealth of information on the site that is well worth reading, including information on how to make use of the certificate once it has been issued. Once you have filled out and submitted the enrollment form, VeriSign will send an automated email to the address you provided with instructions on how to “pick up” the certificate.
The first set of questions on the enrollment form is self-explanatory. The first and last name that you enter will be how your Digital ID is listed in VeriSign’s directory service. The email address that you enter should be the one that you will be using with the Digital ID. It becomes the certificate’s distinguished name. It is also listed alongside your first and last name in the directory. VeriSign will also use the address to verify its validity by sending an automated email to that address with instructions on how to retrieve the certificate that has been issued.
Next, VeriSign will request a challenge phrase, which will be used to protect the certificate. The phrase will be available to you and VeriSign. You should not share it with anyone else! VeriSign will use the phrase to verify that you are the owner of the certificate when you request that it be revoked, renewed, or replaced. Be sure to choose a phrase that you’ll be able to remember, but one that will not be easily guessed by someone that knows you well.
VeriSign chooses a default key length for the certificate and issues it to you based upon the information from your browser. You shouldn’t need to change the key length that is selected for you unless you’re using something other than Netscape or Microsoft products to access your email, in which case the documentation for your email software or the vendor of the software should have advised you on the proper setting to choose.
If you’re using Microsoft Internet Explorer, your certificate will be unprotected by default. That is, once you install it in your email software, you will not be required to enter any password or passphrase to gain access to it. If you opt to keep your certificate unprotected in this manner, you must make every assurance that the private key for your certificate is not compromised. It is generally not a good idea to leave your certificate unprotected, so VeriSign offers two methods of protecting it. One step up from the default of low security is medium security, which requires your approval each time the private key is accessed. With medium security, you still are not required to enter a password or passphrase to unlock the private key. High security requires you to enter a password or passphrase to unlock the key each time it is accessed.
Remember that anybody gaining access to your private key will be able to use your certificate to masquerade as you. When an email is signed with your private key, people are going to trust it, and this can have disastrous effects if your key is compromised. Anyone with access to your private key will also be able to decrypt email that has been encrypted with your public key. Sure, your certificate can be revoked, but as we discussed earlier, revoking a certificate doesn’t have any effect if its revocation status is not being checked. With this in mind, particularly for mobile users, we strongly recommend that you choose high security.
Finally, you must read and accept VeriSign’s subscriber agreement and privacy policy. If you’re using Microsoft Internet Explorer and you checked the checkbox for securing your certificate, a dialog will be presented to you to select the security level that you wish to apply to the certificate. Within an hour or so, you will receive an email from VeriSign at the address that you entered into the enrollment form containing instructions on how to “pick up” your certificate from VeriSign. Included in the email are a URL and a PIN, both of which will be required to get the certificate from VeriSign. You should use the same machine and browser to retrieve the certificate as you did to request it.
That’s all there is to it! Once you’ve retrieved your certificate from VeriSign, follow the directions presented on VeriSign’s site to use the certificate in either Netscape or Microsoft Internet Explorer. Again, if you’re using other software to access your email, follow the vender’s directions to enable the certificate. Now you’re ready to start sending and receiving secure email!
VeriSign offers code-signing certificates for use by software developers and software vendors. The purpose of such a certificate is to sign code that users download off the Internet. By signing your code, users can be assured that the code has not been tampered with or corrupted since it was digitally signed with your certificate. In the online world where people are not only becoming increasingly aware of security issues, but also worry about viruses and worms, signing your code provides a certain assurance to your users that they are getting the software that they’re expecting to get.
Obtaining a code-signing certificate is not nearly as quick and easy as obtaining a personal certificate. They are also considerably more expensive, but then again, they’re not really intended for everyday individual users. At the time that this text was written, VeriSign offered six different types of code-signing certificates for various types of programs. You must be sure to get the proper certificate for the code that you wish to sign because the different types of certificates may not work properly with other types of code. For example, Microsoft Authenticode certificates only work for Microsoft’s Internet Explorer browser. For Netscape browsers, you need to get a Netscape Object Signing certificate. The available types of code-signing certificates are listed as part of the process of obtaining a code-signing certificate. Choosing a type is the first step in obtaining a code-signing certificate.
The type of code-signing certificate determines the specific requirements for making the request to VeriSign to obtain it. For a Microsoft Authenticode Digital ID, for example, much of the work is automated through Microsoft’s Internet Explorer, while a Sun Java Signing Digital ID requires you to generate a certificate request using Sun’s Java tools to be submitted along with the request. For each type of certificate, VeriSign supplies full instructions on what code-signing-certificate-dependent information is needed and how to go about obtaining and supplying it to VeriSign.
While each type of code-signing certificate has its own specific requirements for making the request, there are common requirements that must be met as well. Most of the requirements are self-explanatory, such as contact and payment information. Each certificate must also have information about who owns the certificate. Such information includes the name of the company or organization and the location from which it does business. For example, a company doing business from the United States would be required to supply the city and state in which it is located.
There is, of course, also the very important need for the CA, VeriSign in this case, to verify that they’d be issuing the certificate to someone who should legitimately have it. The quickest and easiest way for VeriSign to verify this information is with a Dun & Bradstreet D-U-N-S number. Supplying this information is optional, but the alternatives require more time and effort both on your part and VeriSign’s. If you do not have or do not want to use a D-U-N-S number, you can optionally mail or fax copies of your business license, articles of incorporation, or partnership papers along with your request for a code-signing certificate.
Once your request, including any appropriate documentation, has been submitted, VeriSign takes it under review. If everything is in order, a code-signing certificate is issued and instructions on how to retrieve the certificate so that you may distribute and use it are provided. Unlike a personal certificate, the request for a code-signing certificate is reviewed and verified by an actual living human being, and so is not made immediately available. Depending on VeriSign’s workload, it may take several days for the certificate to be issued, although VeriSign expedites requests for an additional fee.
The process of obtaining a certificate for use in securing a web site, which VeriSign calls a secure server certificate, is similar to the process for obtaining a certificate for a code-signing certificate. Much of the same information is required, although there are some differences worth noting. Obviously, one of the primary differences is in the types of certificates offered. While code-signing certificates differ based on the type of code that will be signed (Netscape plug-ins versus Java applets, for example), secure server certificates are one of either 40-bit or 128-bit SSL certificates. That is, web site certificates explicitly restrict the size of the symmetric keys that should be used with the certificate. We recommend you stick with 128-bit certificates, since 40-bit symmetric keys are widely regarded as unacceptably weak.
No matter which server software you plan to use, you must follow its instructions on how to generate a Certificate Signing Request (CSR). Due to the wide variety of servers available today, it is not practical for us to provide instructions on how to do this here. VeriSign has instructions for many of the more popular servers available on its web site. The CSR you generate will also generate a key pair. While you must submit the CSR to VeriSign to have the certificate issued, you should keep the private key to yourself. It should not be sent to VeriSign or to anybody else.
As with code-signing certificates, you must also provide acceptable proof to VeriSign that you have a right to the certificate you are requesting. The options for providing this proof are the same—provide either a D-U-N-S number or a copy of one of the aforementioned acceptable documents. Additionally, a secure server certificate is bound to a domain name. VeriSign will issue certificates only to the registered owner of a domain. This means that if the domain is owned by a corporate entity, you must be an employee of that company.
Once your request, including any appropriate documentation, has been submitted, VeriSign takes it under review. If everything is in order, a secure server certificate is issued and the certificate is emailed to the technical contact that was provided when the request was submitted. As with code-signing certificates, an actual living human being reviews the information, so it may take several days for the certificate to be issued, depending on VeriSign’s workload. Expedited processing is also available for an additional fee.
Setting up a CA can seem like a daunting task, but it doesn’t have to be. There are a number of free and commercial CA packages available. The OpenSSL command-line tool even provides all of the functionality required to set up a minimal CA that can be used in a small organization. The OpenSSL command-line tool’s CA functionality was originally intended as an example only, but two of the more popular freely available CA packages, OpenCA and pyCA, use it as their foundation. As of this writing, these tools are still fairly immature, and offer very little that the OpenSSL command-line tool doesn’t have (LDAP storage is the notable exception).
In this section, we’ll go through the necessary steps to set up a CA using OpenSSL’s command-line tools. We’ll show you how to create a self-signed root certificate for use by your CA, how to build a configuration file that OpenSSL can use for your CA, and how to issue certificates and CRLs with your CA. Since OpenSSL’s command-line CA functionality was intended primarily as an example of how to use OpenSSL to build a CA, we don’t recommend that you attempt to use it in a large production environment. Instead, it should be used primarily as a tool to learn how PKI works and as a starting point for building a real CA with tools designed specifically for use in a production environment.
The first step in setting up a CA with the OpenSSL command-line tool is creating an environment for it to run in. Several files and directories must be created. The easiest way to set everything up is from the command line, using your favorite text editor to create the necessary files. For our example CA, we’ll be using the bash shell on a Unix system. Whether the system is Linux or FreeBSD or some other variety of Unix doesn’t matter; the instructions will be the same. There will be some variation for Windows-based systems.
First, we must choose a location for all of our CA’s files to reside. For our example, we use /opt/exampleca as the root directory for our CA, but you may choose any location you like on your system. All of our CA’s files, including issued certificates and CRLs, will be contained within this directory. Keeping the files together makes it easier to find any of the files used by our CA and to set up multiple CAs.
Within the CA’s root directory, we need to create two subdirectories. We’ll name them certs and private . The subdirectory certs will be used to keep copies of all of the certificates that we issue with our CA. The subdirectory private will be used to keep a copy of the CA certificate’s private key. For the most part, the majority of the files that the CA uses are visible to anyone on the system. In fact, many of the files are supposed to be distributed to the public, or at least to anyone who makes any use of the certificates issued by our CA. The one notable exception is the CA certificate’s private key. The private key should never be disclosed to anyone not authorized to issue a certificate or CRL from our CA.
A good CA needs to protect its private key as best it can. 2,048 bits are the bare minimum length for a CA key. The private key should be stored in hardware, or at least on a machine that is never put on a network (CSRs would arrive via the sneaker net).
Besides key generation, we will create three files that our CA infrastructure will need. The first file is used to keep track of the last serial number that was used to issue a certificate. It’s important that no two certificates ever be issued with the same serial number from the same CA. We’ll call this file serial and initialize it to contain the number 1. OpenSSL is somewhat quirky about how it handles this file. It expects the value to be in hex, and it must contain at least two digits, so we must pad the value by prepending a zero to it. The second file is a database of sorts that keeps track of the certificates that have been issued by the CA. Since no certificates have been issued at this point and OpenSSL requires that the file exist, we’ll simply create an empty file. We’ll call this file index.txt (see Example 3-1).
One more file still needs to be created, but it is significantly more complex than the first two files that we’ve already created. It is a configuration file that will be used by the OpenSSL command-line tool to obtain information about how to issue certificates. We could conceivably skip creating this file and use the OpenSSL defaults, which are actually quite sane, but by using a configuration file, we save ourselves some work in issuing commands to OpenSSL. We briefly discussed configuration files and their use with the command-line tool in the Chapter 2. Now it’s time to actually create a configuration file of our own and put it to use.
The OpenSSL command for the CA functions is aptly named
ca
, and so the first section that
we’re interested in is named ca.
For our purposes, this section is quite simple, containing only a
single key:
default_ca
. The value is the name of a section
containing the configuration for the default CA. OpenSSL allows for
multiple CA configurations in the same configuration file. If the
name of a configuration to use is not specified, OpenSSL uses the
name paired with the default_ca key. The default
can be overridden on the command line with the
name option.
Example 3-2 shows the configuration file for our CA.
We’ve already explained what the files and
directories we’ve created are for, so the first set
of keys in the example should be clear; we’re simply
telling OpenSSL where we’ve decided to place the
files and directories that it needs to use. The three keys,
default_crl_days
,
default_days
, and
default_md
, correspond to the command-line
crldays, days, and
md options, and may be overridden by using them.
The default_crl_days key specifies the number of
days between CRLs. You may wish to use
default_crl_hours
instead if you plan to publish CRLs more
than once a day. This setting computes the
nextUpdate field of the CRL when it is generated.
The default_days key specifies the number of days
an issued certificate will be valid. The
default_md specifies the message digest algorithm
that will be used to sign issued certificates and CRLs. Possible
legal values for this key include md5,
sha1, and mdc2.
The policy key specifies the name of a section
that will be used for the default policy. It may be overridden on the
command line with the policy option. A policy
definition is a set of keys with the same name as the fields in a
certificate’s distinguished name.
For each key or field, there are three
legal values: match, supplied,
or optional. A value of match
means that the field by that name in a certificate request must match
the same field in the CA’s certificate. A value of
supplied means that the certificate request must
contain the field. A value of optional means that
the field is not required in the certificate request.
By default, when a certificate is issued, OpenSSL orders the DN
(distinguished name) fields in the same order as they appear in the
policy definition being used. Any fields that are present in the
certificate request but not present in the policy definition are
omitted from the issued certificate. This behavior can be changed by
using the preserveDN
option or by setting the
preserve key to yes in the CA
definition section. When this option is set, all of the fields in the
certificate request are included in the issued certificate, and they
remain in the same order as they were in the certificate request.
Ordinarily, you should not need to enable this option unless
you’re dealing with older versions of Microsoft
Internet Explorer, which require the fields in the issued certificate
to match the certificate request. If you’re dealing
with very old versions of Microsoft Internet Explorer, you may also
need to enable the “MSIE hack”
either by using the
msie_hack
option or by setting the
msie_hack key to yes in the CA
definition section.
The
x509_extensions
key specifies the name of a section that
will contain the extensions to be added to each certificate issued by
our CA. If this key is absent, OpenSSL creates an X.509v1
certificate, but if it is present, even if it is empty, an X.509v3
certificate is created. The only extension that
we’ve included in our example is the
basicConstraints
extension, and we’ve set its cA
component to false so that the certificates issued by our CA, in
turn, may not be used as CA certificates. The certificate chain stops
with certificates that we issue. Example 3-2 shows
the configuration file.
[ ca ] default_ca = exampleca [ exampleca ] dir = /opt/exampleca certificate = $dir/cacert.pem database = $dir/index.txt new_certs_dir = $dir/certs private_key = $dir/private/cakey.pem serial = $dir/serial default_crl_days = 7 default_days = 365 default_md = md5 policy = exampleca_policy x509_extensions = certificate_extensions [ exampleca_policy ] commonName = supplied stateOrProvinceName = supplied countryName = supplied emailAddress = supplied organizationName = supplied organizationalUnitName = optional [ certificate_extensions ] basicConstraints = CA:false
Now that we’ve
created a configuration file, we need to tell OpenSSL where to find
it. By default, OpenSSL uses a system-wide configuration file. Its
location is determined by your particular installation, but common
locations are /usr/local/ssl/lib/openssl.cnf or
/usr/share/ssl/openssl.cnf. Since
we’ve created our own configuration file solely for
the use of our CA, we do not want to use the system-wide
configuration file. There are two ways to tell OpenSSL where to find
our configuration file: using the environment variable
OPENSSL_CONF, or specifying the filename with the
config option on the command line. Since we will
issue a sizable number of commands that should make use of our
configuration file, the easiest way for us to tell OpenSSL about it
is through the environment (see Example 3-3).
Before we can begin issuing certificates with our CA, it needs a certificate of its own with which to sign the certificates that it issues. This certificate will also be used to sign any CRLs that are published. Any certificate that has the authority to sign certificates and CRLs will do. By this definition, a certificate from another CA or a self-signed root certificate will work. For our purposes, we should create our own self-signed root certificate to do the job.
The first thing that we need to do is add some more information to
our configuration file. Example 3-4 shows the newly
added information. Note that we’ll be using the
command-line tool’s
req
command, so we’ll
start by adding a new section by the same name. Since we will use
only this configuration file for our CA, and since we will use only
the command-line tool’s req
command this one time, we’ll put all of the
necessary information that OpenSSL allows in the configuration file
rather than typing it out on the command line. It’s
a little more work to do it this way, but it is the only way to
specify X.509v3 extensions, and it also allows us
to keep a record of how the self-signed root certificate was created.
[ req ] default_bits = 2048 default_keyfile = /opt/exampleca/private/cakey.pem default_md = md5 prompt = no distinguished_name = root_ca_distinguished_name x509_extensions = root_ca_extensions [ root_ca_distinguished_name ] commonName = Example CA stateOrProvinceName = Virginia countryName = US emailAddress = ca@exampleca.org organizationName = Root Certification Authority [ root_ca_extensions ] basicConstraints = CA:true
The default_bits
key in the req section
tells OpenSSL to generate a private key for the certificate with a
length of 2,048 bits. If we don’t specify this, the
default is to use 512 bits. A key length of 2,048 bits provides
significantly more protection than 512, and for a self-signed root
certificate, it’s best to use all of the protection
afforded to us. With the vast computing power that is affordable
today, the speed penalty for using a 2,048-bit key over a 512-bit key
is well worth the trade-off in protection, since the security of this
one key directly impacts the security of all keys issued by our CA.
The
default_keyfile
key in the req section
tells OpenSSL where to write the newly generated private key. Note
that we’re specifying the same directory for output
as we specified earlier in the ca section as the
location of the private key for the certificate. We
can’t use the $dir
“macro” here because the
dir key is private to the ca
section, so we need to type out the full path again.
The default_md
key in the req section
tells OpenSSL which message digest algorithm to use to sign the key.
Since we specified MD5 as the algorithm to use when signing new
certificates and CRLs, we’ll use the same algorithm
here for consistency. The SHA1 algorithm is actually a stronger
algorithm and would be preferable, but for the sake of this example,
we’ve chosen MD5 because it is more widely used and
all but guaranteed to be supported by any software that could
possibly be using our certificates. If you will be using only
software that you know supports SHA1 with your certificates, we
recommend that you use SHA1 instead of MD5.
The prompt
and distinguished_name
keys determine how OpenSSL gets the information it needs to fill in
the certificate’s distinguished name. By setting
prompt to no,
we’re telling OpenSSL that it should get the
information from the section named by the
distinguished_name key. The default is to prompt
for the information, so we must explicitly turn prompting off here.
The keys in the distinguished_name section that
we’ve defined by the name of
root_ca_distinguished_name are the names of the
fields making up the distinguished name, and the values are the
values that we want placed in the certificate for each field.
We’ve included only the distinguished name fields
that we previously configured as required and omitted the one
optional field.
Finally, the
x509_extensions
key specifies the name of a section that
contains the extensions that we want included in the certificate. The
keys in the section we’ve named
root_ca_extensions are the names of the extension
fields that we want filled in, and the values are the values we want
them filled in with. We discussed the
basicConstraints key earlier in this chapter.
We’ve set the cA component of the
extension to true, indicating that this
certificate is permitted to act as a CA to sign both certificates and
CRLs.
Now that we have the configuration set up for generating our
self-signed root certificate, it’s time to actually
create the certificate and generate a new key pair to go along with
it. The options required on the command line are minimal because
we’ve specified most of the options that we want in
the configuration file. From the root directory of the CA,
/opt/exampleca, or whatever
you’ve used on your system, execute the following
command. Make sure that you’ve set the
OPENSSL_CONF environment variable first so that OpenSSL can find
your configuration file!
# openssl req -x509 -newkey rsa -out cacert.pem -outform PEM
When you run the command, OpenSSL prompts you twice to enter a passphrase to encrypt your private key. Remember that this private key is a very important key, so choose your passphrase accordingly. If this key is compromised, the integrity of your CA is compromised, which essentially means that any certificates issued, whether they were issued before the key was compromised or after, can no longer be trusted. The key will be encrypted with 3DES, using a key derived from your passphrase. Example 3-5 shows the results of the command we just generated followed by a textual dump of the resulting certificate. Although your certificate will be different because your public and private key will be different from ours, your output should look similar.
# openssl req -x509 -newkey rsa -out cacert.pem -outform PEM
Using configuration from /opt/exampleca/openssl.cnf
Generating a 1024 bit RSA private key
..................................................++++++
.........++++++
writing new private key to '/opt/exampleca/private/cakey.pem'
Enter PEM pass phrase:
Verifying password - Enter PEM pass phrase:
-----
# openssl x509 -in cacert.pem -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 0 (0x0)
Signature Algorithm: md5WithRSAEncryption
Issuer: CN=Example CA, ST=Virginia, C=US/Email=ca@exampleca.org,
O=Root
Certificate Authority
Validity
Not Before: Jan 13 10:24:19 2002 GMT
Not After : Jan 13 10:24:19 2003 GMT
Subject: CN=Example CA, ST=Virginia, C=US/Email=ca@exampleca.org,
O=Root
Certificate Authority
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:cb:4f:55:6c:a4:2c:8a:f4:21:44:ec:fc:ca:9f:
ca:c7:43:2f:14:7d:07:1a:05:e7:3f:08:6c:ee:88:
30:ef:5b:24:6c:90:59:a2:81:af:99:bc:f6:94:96:
ab:48:53:98:b3:13:b2:42:aa:01:31:7d:59:0d:9a:
99:dc:95:b8:c2:0a:fc:b5:d0:d1:7a:5c:db:87:a3:
e0:db:8a:3f:c3:10:40:b5:d5:e9:5f:58:8d:fd:f1:
06:65:e2:73:7a:17:7f:98:ac:6f:b5:be:56:e1:5f:
16:2b:43:02:60:d8:80:b7:7e:0e:d4:48:3e:6a:c9:
2d:a6:02:3d:b0:e1:ac:fc:3d
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:TRUE
Signature Algorithm: md5WithRSAEncryption
2e:54:2c:cf:d8:1a:d0:bc:bb:9d:eb:3e:2f:fa:8b:7b:21:ef:
4f:30:0e:93:6c:85:26:8d:c2:62:69:49:7b:55:26:09:6a:ea:
00:bc:a0:03:ab:5b:45:8a:71:eb:39:46:6c:50:29:4b:00:ff:
19:a1:e8:a2:4a:75:07:79:50:f0:38:6d:d2:20:09:63:48:75:
67:6b:59:41:74:ae:63:69:13:4e:27:6b:5d:7e:55:6a:7b:3c:
86:c8:b2:c5:15:01:e3:68:08:ec:3c:8a:00:68:43:ce:43:f0:
76:e2:e2:97:ad:88:08:bf:87:ec:ba:d1:db:fa:c4:91:fb:b6:
33:95You’ll notice in Example 3-5’s output that when OpenSSL
displays a DN in a shortened form, it uses a
nonstandard representation that can be somewhat confusing. In this
example, we see C=US/Email=ca@exampleca.org as an
example of this representation. What’s confusing
here is the slash separating the two fields. The reason for this is
that the Email and O fields are
nonstandard in a DN. OpenSSL lists the standard fields first and the
nonstandard fields second, separating them with a slash.
Everything is now set up for our CA, and it’s time to take it out for a test drive by issuing a certificate. To do that, we need a certificate request. It’s also a good idea to know how to create a certificate request that your CA will be able to use. Unless you plan to create both the certificate requests and certificates for anybody you’ll be issuing a certificate to, you’ll probably need to be able to tell someone how to give you a certificate request that you can use. Either way, you’ll still need to know how to do it yourself.
To create a certificate request, start with a clean shell without the
OPENSSL_CONF environment variable set so that the
default configuration file is used. We don’t want to
use our custom configuration file to do this, as that configuration
file is intended for use only by the CA, and generating a certificate
request is not at all a function of a CA.
The command to generate a certificate request is similar to the
command we used to create our self-signed root certificate. We use
the command-line tool’s
req
command, but we’ll
need to specify some extra parameters. The operation will be much
more interactive, prompting for information to fill in the
certificate request’s distinguished name. Example 3-6 shows the output from generating a certificate
request.
# openssl req -newkey rsa:1024 -keyout testkey.pem -keyform PEM -out testreq.pem -outform PEM Using configuration from /usr/share/ssl/openssl.cnf Generating a 1024 bit RSA private key .........++++++ .........++++++ writing new private key to 'testkey.pem' Enter PEM pass phrase: Verifying password - 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. ----- Country Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:Virginia Locality Name (eg, city) []:Manassas Organization Name (eg, company) [Internet Widgits Pty Ltd]:Test Request Organizational Unit Name (eg, section) []: Common Name (eg, your name or your server's hostname) []:www.exampleca.org Email Address []:ca@exampleca.org Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:cloud noon sundry presto madrid baker An optional company name []:Examples-R-Us, Inc.
The result of this command is the creation of two files: testreq.pem and testkey.pem. The former, testreq.pem, contains the certificate request as shown in Example 3-7, and testkey.pem contains the private key that matches the public key embedded in the certificate request. As part of the process to generate a certificate request, a new key pair was also generated. The first passphrase that is prompted for is the passphrase used to encrypt the private key. The challenge phrase is stored in the certificate request, and is otherwise ignored by OpenSSL. Some CAs may make use of it, however.
# openssl req -in testreq.pem -text -noout
Using configuration from /usr/share/ssl/openssl.cnf
Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=US, ST=Virginia, L=Manassas, O=Test Request,
CN=www.exampleca.org/Email=ca@exampleca.org
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:d8:a5:1b:c6:b6:e4:75:bf:f3:e3:ce:29:1d:ab:
e2:5b:0d:bb:2e:94:de:52:a1:20:51:b1:77:d9:42:
a3:6c:26:1f:c3:3e:58:8f:91:b1:b3:ed:bd:7c:62:
1c:71:05:3b:47:ff:1a:de:98:f3:b4:a6:91:fd:91:
26:db:41:76:85:b5:10:3f:c2:10:04:26:4f:bc:03:
39:ff:b9:42:d0:d3:2a:89:db:91:8e:75:6d:f5:71:
ec:96:e8:d6:03:29:8e:fe:20:3f:5d:d8:cb:14:5e:
e5:64:fc:be:fa:d1:27:42:b6:72:eb:b4:16:16:71:
77:d3:0e:8c:cc:87:16:fc:41
Exponent: 65537 (0x10001)
Attributes:
unstructuredName :drowssap egnellahc
challengePassword :drowssap egnellahc
Signature Algorithm: md5WithRSAEncryption
25:aa:ca:78:64:fa:29:46:cf:dc:df:d9:95:dd:48:24:bf:4f:
7b:7e:f4:09:76:96:c4:c5:b1:10:9b:64:95:19:30:8d:cd:d0:
da:ac:b2:21:5e:34:e6:be:7b:41:52:2c:b3:e7:d4:dc:99:e5:
a0:c2:46:12:9f:ef:99:0e:03:89:c1:f9:db:0d:0d:21:1b:e2:
da:4e:23:ef:c1:aa:1b:24:b5:ce:53:a1:05:08:6e:4a:85:78:
6e:71:ef:bc:36:48:5c:3e:ee:b1:bb:28:f4:31:df:23:a9:89:
96:35:1b:b4:01:f9:63:4d:46:b4:ed:5d:be:1d:28:50:1c:86:
43:5eWith a certificate request now in hand, we can use our CA to issue a
certificate. For the sake of convenience in this example, the
certificate request that we’ll be using,
testreq.pem, which we just created, should be in
the CA’s root directory. Make sure that the
OPENSSL_CONF
variable is
set to the CA’s configuration file, and issue the
command to generate a certificate, as shown in Example 3-8.
# openssl ca -in testreq.pem
Using configuration from /opt/exampleca/openssl.cnf
Enter PEM pass phrase:
Check that the request matches the signature
Signature ok
The Subjects Distinguished Name is as follows
countryName :PRINTABLE:'US'
stateOrProvinceName :PRINTABLE:'Virginia'
localityName :PRINTABLE:'Manassas'
organizationName :PRINTABLE:'Test Request'
commonName :PRINTABLE:'www.exampleca.org'
emailAddress :IA5STRING:'ca@exampleca.org'
Certificate is to be certified until Jan 14 04:31:25 2003 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 1 (0x1)
Signature Algorithm: md5WithRSAEncryption
Issuer: CN=Example CA, ST=Virginia, C=US/Email=ca@exampleca.org,
O=Root
Certificate Authority
Validity
Not Before: Jan 14 04:58:29 2002 GMT
Not After : Jan 14 04:58:29 2003 GMT
Subject: CN=www.exampleca.org, ST=Virginia,
C=US/Email=ca@exampleca.org, O=Test Request
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:d8:a5:1b:c6:b6:e4:75:bf:f3:e3:ce:29:1d:ab:
e2:5b:0d:bb:2e:94:de:52:a1:20:51:b1:77:d9:42:
a3:6c:26:1f:c3:3e:58:8f:91:b1:b3:ed:bd:7c:62:
1c:71:05:3b:47:ff:1a:de:98:f3:b4:a6:91:fd:91:
26:db:41:76:85:b5:10:3f:c2:10:04:26:4f:bc:03:
39:ff:b9:42:d0:d3:2a:89:db:91:8e:75:6d:f5:71:
ec:96:e8:d6:03:29:8e:fe:20:3f:5d:d8:cb:14:5e:
e5:64:fc:be:fa:d1:27:42:b6:72:eb:b4:16:16:71:
77:d3:0e:8c:cc:87:16:fc:41
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Signature Algorithm: md5WithRSAEncryption
13:33:75:8e:a4:05:9b:76:de:0b:d0:98:b8:86:2a:95:5a:13:
0b:14:c7:48:83:f3:95:0e:3e:bf:76:04:f7:ab:ae:cc:cd:76:
ae:32:77:ea:8c:96:60:28:52:4e:89:c5:ed:85:68:47:68:95:
74:53:9f:dc:64:95:62:1a:b0:21:09:76:75:14:25:d4:fd:17:
de:f9:87:7f:d5:dc:e4:41:1e:ad:f6:7b:2d:bf:a6:8a:cd:65:
60:3b:71:74:bc:4d:0d:94:5a:22:c4:35:de:b0:19:46:f3:c1:
bb:c5:e0:d4:f7:a2:92:65:ec:40:4c:cc:d4:b7:a3:84:bd:a9:
b0:86
-----BEGIN CERTIFICATE-----
MIICcjCCAdugAwIBAgIBATANBgkqhkiG9w0BAQQFADB7MRMwEQYDVQQDEwpFeGFt
cGxlIENBMREwDwYDVQQIEwhWaXJnaW5pYTELMAkGA1UEBhMCVVMxHzAdBgkqhkiG
9w0BCQEWEGNhQGV4YW1wbGVjYS5vcmcxIzAhBgNVBAoTGlJvb3QgQ2VydGlmaWNh
dGUgQXV0aG9yaXR5MB4XDTAyMDExNDA0NTgyOVoXDTAzMDExNDA0NTgyOVowdDEa
MBgGA1UEAxMRd3d3LmV4YW1wbGVjYS5vcmcxETAPBgNVBAgTCFZpcmdpbmlhMQsw
CQYDVQQGEwJVUzEfMB0GCSqGSIb3DQEJARYQY2FAZXhhbXBsZWNhLm9yZzEVMBMG
A1UEChMMVGVzdCBSZXF1ZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDY
pRvGtuR1v/Pjzikdq+JbDbsulN5SoSBRsXfZQqNsJh/DPliPkbGz7b18YhxxBTtH
/xremPO0ppH9kSbbQXaFtRA/whAEJk+8Azn/uULQ0yqJ25GOdW31ceyW6NYDKY7+
ID9d2MsUXuVk/L760SdCtnLrtBYWcXfTDozMhxb8QQIDAQABow0wCzAJBgNVHRME
AjAAMA0GCSqGSIb3DQEBBAUAA4GBABMzdY6kBZt23gvQmLiGKpVaEwsUx0iD85UO
Pr92BPerrszNdq4yd+qMlmAoUk6Jxe2FaEdolXRTn9xklWIasCEJdnUUJdT9F975
h3/V3ORBHq32ey2/porNZWA7cXS8TQ2UWiLENd6wGUbzwbvF4NT3opJl7EBMzNS3
o4S9qbCG
-----END CERTIFICATE-----
Data Base UpdatedThe first thing that happens is OpenSSL asks for a passphrase. The passphrase that it is looking for is not the passphrase for the certificate request, but the passphrase for the CA’s private key. The private key will be used to sign the new certificate. After displaying the subject’s distinguished name, OpenSSL prompts you for confirmation to sign the certificate. Since certificate requests are likely to come from people needing certificates from you, you should check to be sure that the information they’ve provided in their certificate requests is correct before issuing the certificate. The next and final prompt is to confirm whether the certificates should be committed to the CA’s database. Finally, the new certificate will be written to stdout, and the command is finished.
The confirmation prompts that are issued can be suppressed and
automatically answered in the affirmative by adding the
batch option. This is useful if
you’re building a wrapper around the OpenSSL
command-line tool, or if you’ve already manually
verified the information in the request and you
don’t want to be prompted. It’s
also possible to issue multiple certificates for multiple certificate
requests all with one command. For example, suppose you have three
certificate requests that need to have certificates issued. The
infiles option can be used instead of the
in option; the list of files to be processed
follows immediately after it. If you use the
infiles option, be aware that it must be the last
option specified; everything after it is treated as an input
filename.
The resulting certificate is also written to the directory that we
specified in our configuration file with the
new_certs_dir key. It’s written
out in PEM format and given a filename composed of the
certificate’s serial number and an extension of
.pem. The output of the certificate to stdout
when it is created can be suppressed by using the
notext option. Using the out
option, the name of a file to write the certificate to can be
specified. We recommend that you also use the
notext option if you use the
out option. The result will be a file containing a
certificate that is identical to the one written to the
new_certs_dir directory,
/opt/exampleca/certs in our example. If you use
the out option, it’ll save you
having to search through all of the certificates that
you’ve issued and pick the highest numbered among
them to pass on to their owners.
After the command has completed and the certificate has been issued, you should see a new file in the subdirectory certs that we created. This file is the certificate that was issued. You should also be able to see that information was added to the file index.txt, OpenSSL’s CA database. Finally, you should be able to see that the serial number in the file serial was incremented. When you look at the text dump of the certificate that was created, you’ll notice that it was assigned a serial number of “1”, the number that we used to seed the serial number file.
The first certificate that we issued with our CA was simply a test certificate to make sure that the CA is working properly. We can see that the certificate was issued properly, but it’s a certificate that we don’t actually want anybody to be able to use, so we will need to revoke the certificate. This provides us with an excellent opportunity to find out how certificate revocation works using OpenSSL’s CA command.
Revoking a certificate is a simple process. All you need is a copy of
the certificate to be revoked. Even if you don’t
keep a copy of all of the certificates that you’ve
issued, the CA infrastructure we created does. We can obtain a copy
of the certificate that way, but it’s much easier to
keep a copy of your own and name the file something meaningful since
the CA simply names the file containing the certificates it issues
with each certificate’s serial number. Using the
command in the example from the last section to create the test
certificate, we didn’t keep a copy for ourselves,
but we issued only a single certificate, so it’s
quite easy to get a copy of the certificate file.
We’ll make a copy of that certificate file in the
CA’s root directory and call it
testcert.pem. Then we’ll use
that file as the certificate required by the
revoke option to the ca command
(see Example 3-9).
# cp certs/01.pem testcert.pem # openssl ca -revoke testcert.pem Using configuration from /opt/exampleca/openssl.cnf Enter PEM pass phrase: Revoking Certificate 01. Data Base Updated
Once again, the command-line tool prompts us for a passphrase. The passphrase it is looking for is the passphrase that protects the CA’s private key. Although the key is not actually used for any signing as part of the certificate revocation process, it is required to validate the certificate as the CA’s own and as a security measure to ensure that only someone authorized to use the CA can revoke a certificate that it has issued.
No change is made to the certificate at all. In fact, the only noticeable change is to the CA’s database to indicate that the certificate has been revoked. Remember that once a certificate has been issued, it cannot be modified. It’s presumably out in the wild and there’s no way to ensure that every copy of the certificate in existence can be updated. This is where CRLs become relevant. We’ve revoked the first certificate that we issued with our CA, but the only entity that is aware of the revocation is the CA itself. By itself, this doesn’t do anybody any good. Anybody that might be using the certificate also needs to know that the certificate has been revoked, so we need to issue a CRL.
When we issue our first CRL, we set the initial policy for how frequently we’ll be issuing CRLs. In our configuration, we’ve indicated that we’ll issue them once a week. When a CRL is made available, it contains a field that indicates the next time a new one will be published. In other words, each CRL is given an expiration date, and a new one must be obtained once the current one expires. Whether there are any new certificate revocations, a new CRL should be generated when the old one expires.
While CRLs should be published on a regularly scheduled periodic basis, it is also possible to generate and publish CRLs when a new one is needed. In fact, it’s good practice to do so. Consider that not all software may cache the CRLs that it retrieves, particularly if they’re retrieved automatically. It’s also possible that the current CRL was most likely not retrieved by everyone that may be using certificates issued by your CA. Therefore, it’s best to make the information as current as possible rather than waiting until the current CRL expires, especially if the period between issuance is large.
Issuing a CRL before a new one is due means there are possibly two or more CRLs from your CA in distribution, but that’s fine. CRLs usually have only data added to them, and any time data is removed, it’s because the revoked certificate has expired, and thus its revocation status is irrelevant. Some CAs may opt to keep even expired certificates in their CRLs. While this may not be a bad idea for a short period of time after a certificate expires, it’s generally not a good idea to keep the information indefinitely; otherwise, the CRL could grow to be quite large and make distribution of it more costly in terms of both time and bandwidth.
Without any further ado, let’s issue our first CRL.
This is done by issuing a simple ca command using
the gencrl option, along with an
out option to specify the name of the file to
write the resultant CRL to (see Example 3-10).
OpenSSL prompts us for the passphrase protecting the
CA’s private key, which it will use to sign the CRL
that it generates.
The command completes without writing anything to stdout indicating
success, but if there is a problem, an appropriate error message will
be written. We can see that the command completed successfully by
noting that the file we specified with the -out
option has been written. With that file, we can use the command-line
tool’s crl command to investigate
the details of the CRL that we just generated.
# openssl ca -gencrl -out exampleca.crl
Using configuration from /opt/exampleca/openssl.cnf
Enter PEM pass phrase:
# openssl crl -in exampleca.crl -text -noout
Certificate Revocation List (CRL):
Version 1 (0x0)
Signature Algorithm: md5WithRSAEncryption
Issuer: /CN=Example CA/ST=Virginia/C=US/Email=ca@exampleca.org/O=Root
Certificate Authority
Last Update: Jan 14 05:42:08 2002 GMT
Next Update: Jan 21 05:42:08 2002 GMT
Revoked Certificates:
Serial Number: 01
Revocation Date: Jan 14 05:16:43 2002 GMT
Signature Algorithm: md5WithRSAEncryption
32:73:3b:e5:b4:f6:2d:57:58:15:e8:87:05:23:27:c3:5d:e5:
10:a0:5d:1d:09:68:27:b8:8c:70:5c:5d:4a:0d:07:ff:63:09:
2d:df:61:13:7b:ea:5a:49:74:3b:0a:e9:2b:2d:92:3e:4d:c6:
f4:4f:18:fa:c9:9e:f7:bb:92:b5:ed:46:14:a1:c2:25:5d:3f:
9d:5a:b4:c9:63:5f:06:fc:04:22:0b:80:aa:fd:77:a5:16:9d:
36:47:f7:e9:5b:95:16:ff:bb:e6:db:98:3c:2a:aa:bd:4f:91:
eb:20:86:44:09:7f:ef:62:69:ef:db:1e:79:7e:24:70:72:34:
cf:1e
# openssl crl -in exampleca.crl -noout -CAfile cacert.pem
verify OKWhen we get a text dump of the CRL, we can see the algorithm that was
used to sign it, the CA that issued it, when it was issued, when the
next list will be issued, and a list of all of the certificates that
it contains. We can also use the crl command to
verify the signature on the CRL. Doing so requires us to have a copy
of the certificate that was used to sign it.
We can see in Example 3-10 that the version of the
CRL that was generated was Version 1. By default, this is what
OpenSSL will produce unless the crl_extensions key
is specified in the configuration file in the ca
section. We strongly recommend that you produce only Version 1 CRLs,
unless you can be sure all of the software you’re
using with your certificates supports Version 2. If
it’s important that the software that supports
Version 2 CRLs get them, you can produce both Version 1 and Version 2
lists.
Note that you are essentially on your own when it comes to publishing CRLs. One reasonable solution is to make CRLs available to all via secure HTTP.