Security is important on the Web. Whether sharing financial, business, or personal information, people want to know with whom they are communicating (authentication), they want to ensure that what is sent is what is received (integrity), and they want to prevent others from intercepting what they are communicating (privacy). The Secure Sockets Layer protocol [13] provides one means for achieving these goals and is the subject of this article. We introduce SSL by reviewing cryptographic techniques and by discussing certificates. We then describe SSL and packages for implementing SSL. We conclude with examples of how to use SSLeay, the free implementation of SSL by Eric Young. We use the SSLeay toolkit to create a Certificate Authority, as well as server and client certificates.
1. Introduction
An introduction to SSL, this article is aimed at readers who are familiar with the Web, HTTP, and Web servers, but are not security experts. It is not intended to be a definitive guide to the SSL protocol, nor does it discuss specific servers, techniques for managing certificates in an organization, or the important legal issues of patents and import and export restrictions
. Rather, this article guides users in implementing SSL, and pulls together various concepts, definitions, and examples as a starting point for further exploration.
2. Cryptographic Techniques
Understanding SSL requires an understanding of cryptographic algorithms, message digest functions, and digital signatures. These techniques are the subject of entire books [
], and provide the basis for privacy, integrity, and authentication.
Cryptographic Algorithms
Suppose Alice wants to send a message to her bank to transfer some money. Alice would like the message to be private, since it will include information such as her account number and transfer amount. One solution is to use a cryptographic algorithm, a technique that would transform her message into an encrypted form, unreadable except by those it is intended for. Once in this form, the message may only be interpreted through the use of a secret key. Without the key the message is useless: good cryptographic algorithms make it so difficult for intruders to decode the original text that it isn't worth their effort.
There are two categories of cryptographic algorithms: conventional and public key.
Conventional cryptography, also known as symmetric cryptography, requires the sender and receiver to share a key: a secret piece of information that may be used to encrypt or decrypt a message. If this key is secret, then nobody other than the sender or receiver may read the message. If Alice and the bank know a secret key, then they may send each other private messages. The task of privately choosing a key before communicating, however, can be problematic.
Public key cryptography, also known as asymmetric cryptography, solves the key exchange problem by defining an algorithm which uses two keys, each of which may be used to encrypt a message. If one key is used to encrypt a message then the other must be used to decrypt it. This makes it possible to receive secure messages by simply publishing one key (the public key) and keeping the other secret (the private key). Anyone may encrypt a message using the public key, but only the owner of the private key will be able to read it. In this way, Alice may send private messages to the owner of a key-pair (the bank), by encrypting it using their public key. Only the bank will be able to decrypt it.
Message Digests
Although Alice may encrypt her message to make it private, there is still a concern that someone might modify her original message message or substitute it with a different one, in order to transfer the money to themselves, for instance. One way of guaranteeing the integrity of Alice's message is to create a concise summary of her message and send this to the bank as well. Upon receipt of the message, the bank creates its own summary and compares it with the one Alice sent. If they agree then the message was received intact.
A summary such as this is called a message digest, or one-way hash. Message digests are used to create short, fixed-length representations of longer, variable-length messages. Digest algorithms are designed to produce unique digests for different messages. Message digests are designed to make it too difficult to determine the message from the digest, and also impossible to find two different messages which create the same digest -- thus eliminating the possibility of substituting one message for another while maintaining the same digest.
Another challenge that Alice faces is finding a way to send the digest to the bank securely; when this is achieved, the integrity of the associated message is assured. One way to to this is to include the digest in a digital signature.
Digital Signatures
When Alice sends a message to the bank, the bank needs to ensure that the message is really from her, so an intruder does not request a transaction involving her account. A
digital signature
, created by Alice and included with the message, serves this purpose
Digital signatures are created by encrypting a digest of the message, and other information (such as a sequence number) with the sender's private key. Though anyone may decrypt the signature using the public key, only the signer knows the private key. This means that only they may have signed it. Including the digest in the signature means the signature is only good for that message; it also ensures the integrity of the message since no one can change the digest and still sign it. To guard against interception and reuse of the signature by an intruder at a later date, the signature contains a unique sequence number. This protects the bank from a fraudulent claim from Alice that she did not send the message -- only she could have signed it (non-repudiation).
3. Certificates
Although Alice could have sent a private message to the bank, signed it, and ensured the integrity of the message, she still needs to be sure that she is really communicating with the bank. This means that she needs to be sure that the public key she is using corresponds to the bank's private key. Similarly, the bank also needs to verify that the message signature really corresponds to Alice's signature. If each party has a certificate which validates the other's identity, confirms the public key, and is signed by a trusted agency, then they both will be assured that they are communicating with whom they think they are. Such a trusted agency is called a
Certificate Authority
, and certificates are used for authentication.
Certificate Contents
A certificate associates a public key with the real identity of an individual, server, or other entity, known as the subject. As shown in
Table 1
, information about the subject includes identifying information (the distinguished name), and the public key. It also includes the identification and signature of the Certificate Authority that issued the certificate, and the period of time during which the certificate is valid. It may have additional information (or extensions) as well as administrative information for the Certificate Authority's use, such as a serial number.
A distinguished name is used to provide an identity in a specific context -- for instance, an individual might have a personal certificate as well as one for their identity as an employee. Distinguished names are defined by the X.509 standard [2], which defines the fields, field names, and abbreviations used to refer to the fields (Table 2).
Organization or Company
Name is associated with this
organization
O=The Open Group
Organizational Unit
Name is associated with this
organization unit, such as a department
OU=Research Institute
City/Locality
Name is located in this City
L=Cambridge
State/Province
Name is located in this State/Province
SP=Massachusetts
Country
Name is located in this Country
(ISO code)
C=US
A Certificate Authority may define a policy specifying which distinguished field names are optional, and which are required. It may also place requirements upon the field contents, as may users of certificates. As an example, a Netscape browser requires that the Common Name for a certificate representing a server have a name which matches a regular expression for the domain name of that server, such as*.opengroup.org.
The binary format of a certificate is defined using the ASN.1 notation [ 1], [4]. This notation defines how to specify the contents, and encoding rules define how this information is translated into binary form.The binary encoding of the certificate is defined using Distinguished Encoding Rules (DER), which are based on the more general Basic Encoding Rules (BER). For those transmissions which cannot handle binary, the binary form may be translated into an ASCII form by using base64 encoding. This encoded version is called PEM encoded, when placed between the following lines:
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
Certificate Authorities
By first verifying the information in a certificate request
before granting the certificate, the Certificate Authority assures the identity of the private key owner of a key-pair. For instance, if Alice requests a personal certificate, the Certificate Authority must first make sure that Alice really is the person the certificate request claims.
Certificate Chains
A Certificate Authority may also issue a certificate for another Certificate Authority. When examining a certificate, Alice may need to examine the certificate of the issuer, for each parent Certificate Authority, until reaching one which she has confidence in. She may decide to trust only certificates with a limited chain of issuers, to reduce her risk of a "bad" certificate in the chain.
Creating a Root Level Certificate Authority
As noted earlier, each certificate requires an issuer to assert the validity of the identity of the certificate subject, up to the top-level Certificate Authority. This presents a problem: Since this is who vouches for the certificate of the top-level authority, which has no issuer? In this unique case, the certificate is "self-signed", so the issuer of the certificate is the same as the subject. As a result, one must exercise extra care in trusting a self-signed certificate. The wide publication of a public key by the root authority reduces the risk in trusting this key -- it would be obvious if someone else publicized a key claiming to be the authority. Browsers are preconfigured to trust well-known certificate authorities.
A number of companies, such as VeriSign [11] have established themselves as certificate authorities. These companies provide the following services:
Verifying certificate requests
Processing certificate requests
Issuing and managing certificates
It is also possible to create your own Certificate Authority. Although risky in the Internet environment, it may be useful within an Intranet where the organization can easily verify the identities of individuals and servers.
Certificate Management
Establishing a Certificate Authority is a responsibility which requires a solid administrative, technical, and management framework. Certificate Authorities not only issue certificates, they also manage them -- that is, they determine how long certificates are valid, they renew them, and they keep lists of certificates that have already been issued but are no longer valid (certificate revocation lists, or CRLs). Say Alice is entitled to a certificate as an employee of a company. Say too, that the certificate needs to be revoked when Alice leaves the company. Since certificates are objects that get passed around, it is impossible to tell from the certificate alone that it has been revoked. When examining certificates for validity, therefore, it is necessary to contact the issuing Certificate Authority to check CRLs -- this is not usually an automated part of the process.
NOTE
If you use a Certificate Authority that is not configured into browsers by default, it is necessary to load the Certificate Authority certificate into the browser, enabling the browser to validate server certificates signed by that Certificate Authority. Doing so may be dangerous, since once loaded, the browser will accept all certificates signed by that Certificate Authority.
4. SSL
The Secure Sockets Layer protocol (SSL) is a protocol layer which may be placed between a reliable connection-oriented network layer protocol (e.g. TCP/IP) and the application protocol layer (e.g. HTTP). SSL provides for secure communication between client and server by allowing mutual authentication, the use of digital signatures for integrity, and encryption for privacy.
The protocol is designed to support a range of choices for specific algorithms used for cryptography, digests, and signatures. This allows algorithm selection for specific servers to be made based on legal, export or other concerns, and also enables the protocol to take advantage of new algorithms. Choices are negotiated between client and server at the start of establishing a protocol session.
There are a number of versions of the SSL protocol, as shown in Table 3.
published by Netscape [12]
Original protocol
Netscape 3.0, Internet Explorer 3.0
SSL 3.0
Expired Internet Draft [13]
Revisions to prevent specific security attacks, add ciphers, and support certificate chains
Netscape 3.0, Internet Explorer 3.0
As noted in Table 3, one of the benefits in SSL 3.0 is that it adds support of certificate chain loading. This feature allows a server to pass a server certificate along with issuer certificates to the browser. Chain loading also permits the browser to validate the server certificate, even if Certificate Authority certificates are not installed for the intermediate issuers, since they are included in the certificate chain. SSL 3.0 is the basis for the Transaction Layer Security [TLS] protocol standard, currently in development by the Internet Engineering Task Force (IETF).
Session Establishment
The SSL session is established by following a
handshake sequence
between client and server, as shown in
Figure 1
. This sequence may vary, depending on whether the server is configured to provide a server certificate or request a client certificate. Though cases exist, where additional handshake steps are required for management of cipher information, this article summarizes one common scenario: see the SSL specification for the full range of possibilities.
Note
Once an SSL session has been established it may be reused, thus avoiding the performance penalty of repeating the many steps needed to start a session.
The elements of the handshake sequence, as used by the client and server, are listed below:
Negotiate the Cipher Suite to be used during data transfer
Establish and share a session key between client and server
Optionally authenticate the server to the client
Optionally authenticate the client to the server
The first step, Cipher Suite Negotiation, allows the client and server to choose a Cipher Suite supportable by both of them. The SSL3.0 protocol specification defines 31 Cipher Suites. A Cipher Suite is defined by the following components:
Key Exchange Method
Cipher for Data Transfer
Message Digest for creating the Message Authentication Code (MAC)
These three elements are described in the sections that follow.
Key Exchange Method
The
key exchange method
defines how the shared secret symmetric cryptography key used for application data transfer will be agreed upon by client and server. SSL 2.0 uses RSA key exchange, while SSL 3.0 supports a choice of key exchange algorithms including the RSA key exchange when certificates are used, and Diffie-Hellman key exchange for exchanging keys without certificates and without prior communication between client and server [
One variable in the choice of key exchange methods is digital signatures -- whether or not to use them, and if so, what kind of signatures to use. Signing with a private key provides assurance against a man-in-the-middle-attack during the information exchange used in generating the shared key [8, p516].
Cipher for Data Transfer
SSL uses the conventional cryptography algorithm (symmetric cryptography) described earlier for encrypting messages in a session. There are nine choices, including the choice to perform no encryption:
No encryption
Stream Ciphers
RC4 with 40-bit keys
RC4 with 128-bit keys
CBC Block Ciphers
RC2 with 40 bit key
DES40, DES, 3DES_EDE.
Idea
Fortezza
"CBC" refers to Cipher Block Chaining, which means that a portion of the previously encrypted cipher text is used in the encryption of the current block. "DES" refers to the Data Encryption Standard [
8, ch12
], which has a number of variants (including DES40 and 3DES_EDE). "Idea" is one of the best and cryptographically strongest available algorithms, and "RC2" is a proprietary algorithm from RSA [
8, ch13
Digest Function
The choice of digest function determines how a digest is created from a record unit. SSL supports the following:
No digest (Null choice)
MD5, a 128-bit hash
Secure Hash Algorithm (SHA), a 160-bit hash designed for use with the Digital Signature Standard (DSS) [5].
The message digest is used to create a Message Authentication Code (MAC) which is encrypted with the message to provide integrity and to prevent against replay attacks.
Handshake Sequence Protocol
The handshake sequence uses three protocols:
The "SSL Handshake Protocol" for performing the client and server SSL session establishment.
The "SSL Change Cipher Spec protocol" for actually establishing agreement on the Cipher Suite for the session.
The "SSL Alert Protocol" for conveying SSL error messages between client and server.
These protocols, as well as application protocol data, are encapsulated in the "SSL Record Protocol", as shown in
Figure 2
. An encapsulated protocol is transferred as data by the lower layer protocol, which does not examine the data. The encapsulated protocol has no knowledge of the underlying protocol.
The encapsulation of SSL control protocols by the record protocol means that if an active session is renegotiated the control protocols will be transmitted securely. If there were no session before, then the NULL cipher suite is used, which means there is no encryption and messages have no integrity digests until the session has been established.
Data Transfer
The SSL Record Protocol, shown in
Figure 3
, is used to transfer application and SSL Control data between the client and server, possibly fragmenting this data into smaller units, or combining multiple higher level protocol data messages into single units. It may compress, attach digest signatures, and encrypt these units before transmitting them using the underlying reliable transport protocol.
Securing Web HTTP Communication
One common use of SSL is to secure Web HTTP communication between a browser client and a Web server. This case does not preclude the use of non-secured HTTP. The secure version uses URLs that begin with
https
rather than
http
, and a different server port (by default
). The browser will maintain client certificate private keys when they are generated, and display an indicator if a secure connection is being used.
Implementing SSL
Although one might write an SSL implementation from scratch following the specification, it is much easier to use one of the existing SSL toolkit libraries. In addition, because of patents, it is usually necessary to license some of the cryptography libraries, at least in the United States. SSL toolkits include encryption, message digest, and certificate management routines. Each also requires the use of a licensed public key package in the United States, from Security Dynamics (Originally available from the Public Key Partners [RFC1170] and then from RSA, which was acquired by Security Dynamics [
] .)
There are two prominent RSA public key packages available:
RSARef The RSA Reference implementation, an unsupported source code toolkit from RSA, may be used for freeware and noncommercial applications. Consensus Development Corp used to market a license for commercial use but will no longer do so [17].
BSAFE3.0 Commercial implementation of RSARef[16].
These two public key implementations include a complete toolkit of public key algorithms (including RSA encryption and Diffie-Hellman key exchange), symmetric encryption algorithms, and digest functions. They may be used with SSL Toolkits, the most prominent of which include the following:
SSLRef Sample SSL 3.0 implementation from Netscape Communications Corporation [19].
SSLPlus Commercial source code toolkit available from Consensus Development Corp, an enhancement of SSLRef3.0. It requires BSAFE3.0 (from RSA) for use [20].
SSLava SSL3.0 compliant toolkit written in Java from Phaos Technology [18].
SSLeay SSLeay-0.8.1 [21] is a free noncommercial implementation of SSL 2.0 and 3.0. It includes a public key implementation which may be used outside the United States. In the United States, RSARef or BSAFE3.0 must be used due to patent requirements. SSLeay offers an inexpensive way to get started with SSL, and is the subject of the next section.
6. SSLeay Examples
This section offers examples for creating a Certificate Authority, as well as requesting, signing, and using certificates with SSLeay. The
Appendix
offers brief instructions for
installing SSLeay
, establishing the SSLeay
certificate environment
, information on the
SSLeay configuration file
, and sample HTML pages and CGI scripts.
SSLeay 0.6.6 supports SSL 2.0, and SSLeay-0.8.1 supports both SSL 2.0 and 3.0. SSL 2.0 is widely implemented and interoperation is easier than with SSL 3.0; we use SSLeay with SSL 2.0 in the examples that follow.
a. Creating a Self-Signed CA Certificate
The first step in creating a Certificate Authority (apart from designing the management, administrative and legal framework) is to create a
self-signed certificate
for the Certificate Authority. This is done in SSLeay by running the
command (
see Example 5
in the Appendix). This command produces a certificate file (
CAcert.pem
) and key file (
CAkey.pem
). The CA certificate and key files must remain in
$SSLDIR/private
, which is where SSLeay will look for them by default (as specified in the
ssleay.cnf
CA
default
section), both when acting as a certificate authority, and also when used by the server to implement SSL and validate client certificates signed by the CA.
Install the self-signed certificate in a browser so the browser will recognize server certificates signed by the Certificate Authority. Installing a CA certificate in a browser is somewhat dangerous, unless you trust that certificate and the security of the Certificate Authority. Once installed, the browser accepts any certificate signed by that authority.
To install the CA certificate, load it using HTTP Content-Type application/x-x509-ca-cert. To do this in a manner which does not depend on the server, use the cgi-script (Example 6 in the Appendix), or save the certificate in a file with a cacert suffix and define this suffix in the server configuration file to correspond to the application/x-x509-ca-cert MIME type. For the Apache server, for example, add the line AddType application/x-x509-ca-cert cacert to srm.conf. The certificate and key files must also remain available to SSLeay for the server to be able to use the public key, and the certificate authority to use the private key.
b. Creating a Server Certificate
A
server certificate
authenticates the server to the client. To make a server certificate, create a certificate request, sign it with the self-signed CA certificate, and then install the certificate as follows:
Use the "req" command to create a new certificate request with SSLeay (See Example 8 in the Appendix). This command creates files containing a certificate request and the private key.
Sign the request using the "ca" command (see Example 11 in the Appendix). This will produce a file containing the certificate.
Copy the certificate and key files to the server certificate directories.
cp newcert.pem $certdir/sitecert.pem
cp newkey.pem $certdir/sitekey.pem
CD $certdir
ln -s sitecert.pem `$SSLDIR/bin/x509 -noout -hash < sitecert.pem`.0
Update the server configuration file to specify that this is the server certificate to use.
In order to easily find certificates, SSLeay uses hashes of the certificate subject names. Thus, when looking for the certificate of the issuer of a certificate, it looks for a file named with the hash value of the issuer name. The avoids opening files and examining certificates to find a match. The SSLeay
x509
command may be used to manipulate certificates; one option is to create a hash of the subject name.
Once these steps have been completed, an SSL connection may be established if the server does not require client certificates.
b. Creating a Client Certificate
A
client certificate
is used to authenticate a client to a server. Creating and installing a client certificate is more difficult than creating a server certificate because the client must generate a key-pair, keep the private key to itself, and send the public key to the certificate authority to be incorporated into a certificate request. Once a signed certificate has been created using the Certificate Authority, this client certificate must be installed in the client so that the client may present it when needed.
Different clients such as Netscape Navigator 3.01 Gold and Microsoft Internet Explorer 3.02 support different mechanisms for creating client certificates. In this section, we demonstrate a technique for creating and installing a client certificate for each, using SSLeay certificate routines to sign certificate requests (Back up the Windows NT registry before creating client certificates with Internet Explorer).
The procedure for creating a client certificate involves HTML forms; these forms include client specific features such as special tags or JavaScript programs, and Perl CGI scripts that call SSLeay certificate handling applications. The procedures do not rely on special server features, other than the ability to run Perl CGI scripts. The examples completely automate the process, causing a client certificate to be installed once the request form is submitted. (In a production environment the Certificate Authority would need to perform validation instead of automatically issuing the certificate.)
The general steps for creating a client certificate are as follows:
User requests HTML page that displays form on client
User enters identification information
Submission of the form causes the following sequence to occur:
Browser generates a key pair (public and private key)
Private key is stored in browser
Public key is sent with identification information to the server
Server CGI script creates certificate and loads it into the client
The HTML form includes fields (containing defaults) for the different distinguished name attributes which are to be used in the client certificate, information allowing the browser to generate a key-pair, and a hidden field used to return this information to the CGI script. This hidden information is browser dependent.
In Netscape Navigator, the form contains an additional FORM tag, the <KEYGEN> tag. This tag creates a key pair, and causes the public key to be returned as a form value when the form is submitted (see Example 12 in the Appendix for source of a sample form). The <KEYGEN> tag causes the browser to display a choice of security grades, depending on the version of Navigator. All of the form information is used by the CGI script to create a certificate request, and this request is used to create a client certificate (See Figure 4).
The Microsoft Internet Explorer HTML form in Figure 5 is more complicated, because Internet Explorer requires a JavaScript (or Visual Basic) program in the page to use an ActiveX control to generate a key pair and create a certificate request. The JavaScript program is downloaded with the HTML page, and called when you press the Submit form button. The program calls the GenReqForm method of thecertenr3 ActiveX control, passing it the distinguished name values from the form. The certificate request produced by the control is then loaded into a hidden field of the form, and returned with the form values to the server CGI script (see Example 15 in the Appendix for a sample HTML page).
Both Netscape Navigator and Microsoft Internet Explorer present a sequence of dialogs as part of the key-pair creation. If this sequence is successfully completed then the form will cause the server CGI script to be called with the data from the form. Examples 13 and 15 in the Appendix present two CGI scripts, one for each browser, since the processing is different.
The CGI script for Netscape Navigator (Example 14 in the Appendix) creates a file containing the distinguished name values returned by the form, and a special SPKAC value for the "Signed Public Key And Challenge" generated by Navigator The "ca" command is called with this file as an argument to generate a client certificate. If successful this is returned by the CGI script as an application/x-x509-user-certHTTP Content-Type. Navigator recognizes this type, and prompts the user for the remainder of the steps required to install the user certificate in the browser. (See Example 13 for the sample CGI script for Netscape Navigator).
The CGI script for processing the Internet Explorer request (Example 16 in the Appendix) is more complicated. It takes the certificate request returned by the form and reformats it to conform to lines of length 72, and then uses the SSLeay ca command to create a signed user certificate based on this request. It then takes the client certificate and combines it with the SSLeay certificate revocation list (CRL) to create a PKCS#7 certificate using the SSLeay crl2pkcs7 utility. The CGI Perl script then dynamically creates an HTML page which includes a JavaScript program to call the AcceptCredentials method of thecertenr3 ActiveX control to install the PKCS#7 certificate. This page is designed to take advantage of the JavaScript onLoad method to automatically call the JavaScript program when the page is loaded, so that the certificate is immediately installed without user interaction. (In a production system such automatic installation may not be desired.)
NOTE
Although I was able to establish an SSL connection using client certificates with Netscape Navigator, and establish an SSL connection with a VeriSign client certificate and the
VeriSign client certificate test page
, I was unable to establish an SSL client-certificate connection using my client certificate with Microsoft Internet Explorer. The reason for this discrepancy will require more research or additional information from Microsoft.
Once the HTML forms and CGI scripts have been written, and the ActiveX control installed, the process of creating client certificates using SSLeay is simple for users.
Configuring a Server and Establishing an SSL connection
The server must have a server certificate installed, and the server's CA certificate must have been installed in the browser. The server will only request a client certificate from the browser if it is required in the server configuration file. Apache uses the following directive in httpd.conf :
# Set SSLVerifyClient to:
# 0 if no certificate is required
# 1 if the client may present a valid certificate
# 2 if the client must present a valid certificate
# 3 if the client may present a valid certificate but it is not required to
# have a valid CA
SSLVerifyClient 0
An SSL connection is established by requesting a URL from the browser of the form "https://example.opengroup.org/", where the domain refers to the server which supports SSL.
Conclusion
SSL uses encryption, message digests, digital signatures and certificates to implement a protocol layer for providing privacy, integrity and authentication to application protocols such as HTTP. This is valuable in the Web since it will allow a much greater degree of secure communication than is available without SSL. A number of toolkits exist for implementing SSL, including SSLeay. These toolkits also provide the facilities for creating ones own Intranet Certificate Authority and managing certificates. Many issues exist with respect to certificates, including those of certificate revocation and expiration, as well as management issues. Undoubtedly the remaining issues involved in the management of certificates and Web security will be addressed, but an implementation of SSL using SSLeay permits much more confidence in Web communications.
Appendix
This appendix offers a number of examples for certificate management using SSLeay. The CGI scripts assume you are using Apache (tested with 1.2b7). If you have trouble it might be due to a
CGI.pm
version issue. The scripts in these examples also assume that the server installation directory includes the following subdirectories:
htdocs (standard document root)
cgi-bin (standard CGI directory)
certs (new directory for certificate processing)
When the scripts operate they create files containing certificate requests, and certificates.
SSLeay Installation
We have experimented using SSLeay and RSARef on UNIX with the Secure Domain Gateway, a special SSL web server that interfaces with the Distributed Computing Environment (DCE). We have also experimented using Apache-SSL (
apache_1.2b10+ssl_1.6.tar
). The following examples assume that you are building SSLeay under UNIX (e.g. HP-UX) but it is possible to build SSLeay on other platforms such as Windows NT.
The SSLeay-0.8.1 distribution is obtained as a tar file (SSLeay-0.8.1.tar). Extracting from the
file will create a new directory,
SSLeay-0.8.1
in which SSLeay is built.
The following examples assume you are working in the SSLeay-0.8.1 directory. Change to this directory and build SSLeay following the directions in the INSTALL file. The examples assume that the results of building SSLeay are installed in $SSLDIR (e.g. /opt/dev/ssl).
SSLeay uses a configuration file (ssleay.cnf) which supports named sections, so one configuration file may be used for several purposes. We have modified this file, and show some of these modifications in the examples that follow. Subsequent descriptions in this document show various relevant sections of the log file.
Note that the addition of SSL to the server requires rebuilding the server to include the SSL toolkit and public key sources, and modifying the server configuration to support SSL.
The SSLeay Certificate Environment
Before using SSLeay, create an environment for managing certificates, update the SSLeay configuration file, and update the server configuration file. Establish the SSLeay certificate management environment using the sequence in Example 1.
mkdir ${SSLDIR}/newcerts
mkdir ${SSLDIR}/private
echo "01" > ${SSLDIR}/serial
touch ${SSLDIR}/index.txt
The SSLeay Configuration File
The SSLeay configuration file (
ssleay.cnf
) has multiple sections. These configuration sections must be updated before the certificate authority may be used, especially the
specification in the certificate authority configuration shown in Example 2. The
specification value should be the same as $SSLDIR (e.g.
/opt/dev/ssl
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################
[ CA_default ]
dir = /opt/dev/ssl # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir/newcerts # default place for new certs.
certificate = $dir/private/CAcert.pem # The CA certificate
serial = $dir/serial # The current serial number
crl = $dir/clr/crl.pem # The current CRL
private_key = $dir/private/CAkey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = x509v3_extensions # The extentions to add to the cert
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = md5 # which md to use.
preserve = no # keep passed DN ordering
# A few difference way of specifying how similar the request should look
# For type CA, the listed attributes must be the same, and the optional
# and supplied fields are just that :-)
policy = policy_match
The "req" section of the configuration file is used when creating certificate requests, and supplies defaults and length limits for the various distinguished name fields. In our examples it has the configuration as shown in Example 3.
default_bits = 512
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = US
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = MA
localityName = Locality Name (eg, city)
localityName_default = Cambridge
organizationName = Organization Name (eg, company)
organizationName_default = The Open Group
organizationalUnitName = Organizational Unit Name (eg, section)
organizationalUnitName_default = Research Institute
commonName = Common Name (eg, YOUR name)
commonName_default = example.osf.org
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 40
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
The policy section of the configuration file is used to define different certificate request signing policies. The examples here include the most lenient policy (policy_anything) and a stricter policy (policy_match) which restricts the values of certificate fields. The purpose of a policy is to guide processing of a certificate request.
In Example 4, match means that the value of the field in the request must match the value in the CA certificate, or the request will not be signed. optional means the the field need not be present, whilesupplied means that it must be present in the certificate request.
stateOrProvinceName = match
organizationName = match
organizationalUnitName = match
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
The SSLeay
command creates a self-signed certificate when the
-x509
switch is used. The certificate is placed in the file
CAcert.pem
, and the private key in
CAkey.pem
. This command prompts for the password (e.g. caKEY) for the private key, and is used as shown in Example 5.
$SSLDIR/bin/ssleay req -new -x509 -keyout ${SSLDIR}/private/CAkey.pem \
-out ${SSLDIR}/private/CAcert.pem -config /opt/www/lib/ssleay.cnf
Using configuration from /opt/www/lib/ssleay.cnf
Generating a 512 bit private key
writing new private key to '../private/CAkey.pem'
Enter PEM pass phrase:
Verifying password - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorperated
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) [US]:
State or Province Name (full name) [MA]:
Locality Name (eg, city) [Cambridge]:
Organization Name (eg, company) [The Open Group]:
Organizational Unit Name (eg, section) [Research Institute]:
Common Name (eg, YOUR name) [example.osf.org]:Example CA
Email Address []:f.hirsch@opengroup.org
The SSLeay configuration file specifies the location of the CA certificate and key files using the following directives in the ca section:
The Apache-SSL server httpd.conf file specifies the CA certificate and key files as follows:
# Set the CA certificate verification path (must be PEM encoded).
SSLCACertificatePath /opt/dev/ssl/private
# Set the CA certificate verification file (must be PEM encoded).
SSLCACertificateFile /opt/dev/ssl/private/CAcert.pem
Loading a CA certificate into a browser using a CGI script
Load the CA certificate into the browser by accessing an HTML form like that in Example 6. This form calls a CGI script to load the certificate using the
application/x-x509-ca-cert
MIME type as the Content-Type.
<HTML><HEAD><TITLE>Load CA Certificate</TITLE></HEAD><BODY>
<H1>Load Certificate Authority Certificate</H1>
<FORM ACTION="http://example.osf.org/cgi-bin/loadCAcert.pl" METHOD=post>
<TABLE>
<TR>
<TD>Netscape Browser (PEM Format):</TD>
<TD><INPUT TYPE="RADIO" NAME="FORMAT" VALUE="PEM" CHECKED></TD></TR>
<TR><TD>Microsoft Browser (DER Format):</TD>
<TD><INPUT TYPE="RADIO" NAME="FORMAT" VALUE="DER"></TD></TR>
</TABLE>
<INPUT TYPE="SUBMIT" VALUE="Load Certificate">
</FORM>
</BODY></HTML>
Example 7 shows the loadCAcert.pl script.
my $cert_dir = "/opt/www/lib/certs";
my $cert_file = "CAcert.pem";
my $query = new CGI;
my $kind = $query->param('FORMAT');
if($kind eq 'DER') { $cert_file = "CAcert.der"; }
my $cert_path = "$cert_dir/$cert_file";
open(CERT, "<$cert_path");
my $data = join '',;
close(CERT);
print "Content-Type: application/x-x509-ca-cert\n";
print "Content-Length: ", length($data), "\n\n$data";
Install the Certificate Authority certificate in the server certificate database as well as the browser, so that the server is able to locate the public key and validate certificate signatures signed by the certificate authority.
Server Certificates
Creating a Certificate Request
The SSLeay
command is used to create a PKCS#10 (Public-Key Cryptography Standards [
]) certificate request. It also generates a key pair when
-new
is specified, and may indicate the length of time the certificate is valid with the
-days
switch. SSLeay prompts for a new password for this certificate (call it siteKEY). A certificate request may be created as shown in Example 8.
cd $SSLDIR/bin
./ssleay req -new -keyout newkey.pem -out newreq.pem -days 360\
-config /opt/www/lib/ssleay.cnf
Using configuration from /opt/www/lib/ssleay.cnf
Generating a 512 bit private key
writing new private key to 'newkey.pem'
Enter PEM pass phrase:
Verifying password - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorperated
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) [US]:
State or Province Name (full name) [MA]:
Locality Name (eg, city) [Cambridge]:
Organization Name (eg, company) [The Open Group]:
Organizational Unit Name (eg, section) [Research Institute]:
Common Name (eg, YOUR name) [example.osf.org]:
Email Address []:f.hirsch@opengroup.org
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
Example 9 shows the results in a certificate request being created in newreq.pem (in this paper certificates and keys are truncated).
-----BEGIN CERTIFICATE REQUEST-----
MIIBXTCCAQcCAQAwgaMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJNQTESMBAGA1UE
Aty7AlcmN9XNwxUk1w0H3hk=
-----END CERTIFICATE REQUEST-----
Example 10 shows a private key for the certificate being created in newkey.pem.
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,21F13B37A796482C
XIY0c7gnv0BpVKkOqXIiqpyONx8xqW67wghzDlKyoOZt9NDcl9wF9jnddODwv9ZU
QxS2zwfKG1u+YqS1c2v5ecBgqW78DQLvxMkpYU8+xge7vDeoYKE14w==
-----END RSA PRIVATE KEY-----
Signing a Certificate Request
A server certificate is created by signing the certificate request using the SSLeay
command. The
-policy
switch specifies the section of the SSLeay configuration file that defines which distinguished name fields are required, and the order of the fields. As an example, our test configuration file specifies the
policy_anything
section which makes all the listed distinguished name fields optional.
When this command is executed, it prompts for the certificate authority password, as shown in Example 11.
Example 11: Signing a Certificate Request to Create Server Certificate
cat newreq.pem newkey.pem > new.pem
./ssleay ca -policy policy_anything -out newcert.pem \
-config /opt/www/lib/ssleay.cnf -infiles new.pem
Using configuration from /opt/www/lib/ssleay.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:'MA'
localityName :PRINTABLE:'Cambridge'
organizationName :PRINTABLE:'The Open Group'
organizationalUnitName:PRINTABLE:'Research Institute'
commonName :PRINTABLE:'example.osf.org'
emailAddress :IA5STRING:'f.hirsch@opengroup.org'
Certificate is to be certified until May 12 15:39:33 1998 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
Data Base Updated
The server certificate is created in the file newcert.pem as shown in Example 12 (line-breaks added for issuer and subject).
issuer :/C=US/SP=MA/L=Cambridge/O=The Open Group/OU=Research Institute/
CN=Example CA/Email=f.hirsch@opengroup.org
subject:/C=US/SP=MA/L=Cambridge/O=The Open Group/OU=Research Institute/
CN=example.osf.org/Email=f.hirsch@opengroup.org
serial :01
Certificate:
Data:
Version: 0 (0x0)
Serial Number: 1 (0x1)
Signature Algorithm: md5withRSAEncryption
Issuer: C=US, SP=MA, L=Cambridge, O=The Open Group,
OU=Research Institute,
CN=Example CA/Email=f.hirsch@opengroup.org
Validity
Not Before: May 12 15:39:33 1997 GMT
Not After : May 12 15:39:33 1998 GMT
Subject: C=US, SP=MA, L=Cambridge, O=The Open Group,
OU=Research Institute,
CN=example.osf.org/Email=f.hirsch@opengroup.org
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Modulus:
00:a1:41:0b:0c:15:53:a5:a5:c4:37:a8:48:f5:79:
39:9f:18:2d:f4:bf:43:34:36:21:23:03:48:a5:65:
cb:e2:f8:97:af:9c:7d:df:1e:9b:54:e2:ad:21:e3:
41:3e:54:9a:ce:dc:66:4d:61:59:fb:83:11:36:BF:
9c:3b:47:20:fb
Exponent: 65537 (0x10001)
Signature Algorithm: md5withRSAEncryption
63:77:e7:f8:aa:0b:90:5e:13:9e:4b:57:f1:0f:22:f9:4c:e3:
7a:AA:ff:a7:8a:2e:3c:1c:a2:92:07:bc:9f:22:3f:2f:13:3f:
60:62:57:a7:74:12:35:28:82:b1:00:2a:36:54:de:67:CD:a2:
9e:24:3e:98:be:14:4e:35:b7:7f
-----BEGIN CERTIFICATE-----
MIICLTCCAdcCAQEwDQYJKoZIhvcNAQEEBQAwgZ4xCzAJBgNVBAYTAlVTMQswCQYD
Ij8vEz9gYlendBI1KIKxACo2VN5nzaKeJD6YvhRONbd/
-----END CERTIFICATE-----
The Apache-SSL httpd.conf file must be modified to specify the server certificate and key files as follows:
# Point SSLCertificateFile at a PEM encoded certificate.
SSLCertificateFile /opt/www/lib/certs/sitecert.pem
# If the key is not combined with the certificate, use this directive to
# point at the key file. If this starts with a '/' it specifies an absolute
# path, otherwise it is relative to the default certificate area. That is,
# it means "/private/".
SSLCertificateKeyFile /opt/www/lib/certs/sitekey.pem
Client Certificates
Form to create Netscape Client Certificate Request
Netscape returns a "Signed Public Key And Challenge" (SPKAC) public key when the <KEYGEN> form element is encountered. The form in Example 13 returns this in the SPKAC hidden field. The CGI script then accesses this field and passes the SPKAC value to SSLeay using the
-spkac
switch to the
command. (See
ns-ca.doc
in the
directory in the SSLeay distribution).
<HTML><HEAD><TITLE>Create Client Certificate</TITLE></HEAD><BODY>
<CENTER><H1>Create Client Certificate</H1></CENTER>
<FORM NAME="GenerateForm" ACTION="http://example.osf.org/cgi-bin/ns_key.pl">
<TABLE>
<TR><TD>Common Name:</TD><TD>
<INPUT TYPE="TEXT" NAME="commonName" VALUE="Client Certificate" SIZE=64>
</TD></TR>
<TR><TD>email:</TD><TD>
<INPUT TYPE="TEXT" NAME="emailAddress" VALUE="f.hirsch@opengroup.org" SIZE=40>
</TD></TR>
<TR><TD>Organization:</TD><TD>
<INPUT TYPE="TEXT" NAME="organizationName" VALUE="The Open Group">
</TD></TR>
<TR><TD>Organizational Unit:</TD><TD>
<INPUT TYPE="TEXT" NAME="organizationalUnitName" VALUE="Research Institute">
</TD></TR>
<TR><TD>Locality (City):</TD><TD>
<INPUT TYPE="TEXT" NAME="localityName" VALUE="Cambridge">
</TD></TR>
<TR><TD>State:</TD><TD>
<INPUT TYPE="TEXT" NAME="stateOrProvinceName" VALUE="MA">
</TD></TR>
<TR><TD>Country:</TD><TD>
<INPUT TYPE="TEXT" NAME="countryName" VALUE="US" SIZE="2">
</TD></TR>
</TABLE>
<!--
' keygen is Netscape specific and will be ignored in
' internet explorer
-->
<KEYGEN NAME="SPKAC" CHALLENGE="challengePassword">
<INPUT TYPE="SUBMIT" NAME="SUBMIT">
</FORM>
<P><HR></BODY></HTML>
Perl Script to Process Netscape Client Certificate Request
Example 14 shows a Perl script used to create a client certificate for Netscape Navigator, as discussed in the section "Creating a Client Certificate".
Example 14: Sample Perl Script to Process Netscape Client Certificate Request
use CGI;
use File::CounterFile; # module to maintain certificate request counter
my $doc_dir = $ENV{'DOCUMENT_ROOT'}; # apache specific location for storage
unless($doc_dir) {
print "<HTML><HEAD><TITLE>Failure</TITLE></HEAD>";
print "<BODY>DOCUMENT_ROOT not defined</BODY></HTML>";
exit(0);
my $base_dir = $doc_dir;
$base_dir =~ s/\/htdocs//;
my $SSLDIR = '/opt/dev/ssl'; # define where SSLeay files are located
my $CA = "$SSLDIR/bin/ca";
my $CONFIG = "/opt/www/lib/ssleay.cnf";
my $CAPASS = "caKEY";
my $query = new CGI; # get a handle on the form data
my $key = $query->param('SPKAC'); # this will fail if not Netscape browser
unless($key) { fail("No Key provided $key. Netscape required"); }
my $counter = new File::CounterFile("$base_dir/.counter", 1);
unless($counter) { fail("Could not create counter: $!"); }
my $count = $counter->inc();
my $certs_dir = "$base_dir/certs";
my $req_file = "$certs_dir/cert$count.req"; # certificate request filename
my $result_file = "$certs_dir/cert$count.result"; # certificate filename
# Explicitly list form fields we must have for certificate creation to work.
my @req_names = ('commonName', 'emailAddress', 'organizationName',
'organizationalUnitName', 'localityName', 'stateOrProvinceName',
'countryName', 'SPKAC');
# build the request file
open(REQ, ">$req_file") or fail("Could not create request $req_file: $!");
my $name;
foreach $name (@req_names) {
my $value = $query->param("$name");
$value =~ tr/\n//d;
print REQ "$name = $value\n";
close(REQ);
# make sure we actually created a request file
unless(-f $req_file) { fail("request missing: $req_file"); }
unless(-e $CA) { fail("command missing"); } # ensure that ca command will run
# command for processing certificate request, without password
my $cmd = "$CA -config $CONFIG -spkac $req_file -out $result_file -days 360";
my $rc = system("$cmd -key $CAPASS 2>errs");
if($rc != 0) { fail("$cmd<P>rc = $rc", "errs"); }
open(CERT, "<$result_file") or fail("Could not open $result_file<P>$!");
# send the client certificate to the browser
print "Content-Type: application/x-x509-user-cert\n";
my $result = join '', <CERT>;
close CERT;
my $len = length($result);
print "Content-Length: $Len\n\n";
print $result;
exit(0);
sub fail {
my($msg, $errs) = @_;
print $query->header;
print $query->start_html(-title => "Certificate Request Failure");
print "<H2>Certificate request failed</H2>$MSG<P>";
if($errs) {
if(open(ERR, "<errs")) {
while(<ERR>) {
print "$_<BR>";
close ERR;
print $query->dump();
print $query->end_html();
exit(0);
The CGI script for Netscape Navigator creates a file containing the distinguished name values returned by the form, and a special SPKAC value for the "Signed Public Key And Challenge (SPKAC)" generated by Navigator. This file contains the information which would be in a certificate request, and is used to generate the certificate.
The SSLeay ca command is called with this file as an argument to generate a client certificate, as follows (Also see ns-ca.doc from the SSLeay documentation) :
$SSLDIR/bin/ca -spkac $req_file -out $result_file -days 360 -key $CAPASS \
-config /opt/www/lib/ssleay.cnf 2>errs
This example shows the command after some of the Perl processing to create the command has been performed. The $req_file variable contains the name of a unique file in the certs directory used to contain the certificate request information obtained from the CGI form data. The $result_file variable contains the name of a unique file in the certs directory used to contain the certificate. The $CAPASS Perl variable contains the CA key.
If the ca command is successful, then the certificate is returned by the CGI script as an application/x-x509-user-cert HTTP Content-Type. Navigator recognizes this type, and prompts the user for the remainder of the steps required to install the user certificate in the browser.
Form to create Microsoft Client Certificate Request
Example 15 shows the HTML form used to generate a certificate request from Microsoft Internet Explorer, as discussed in the section "Creating a client certificate".
Example 15: Sample HTML Form with JavaScript and ActiveX to Request Microsoft Internet Explorer Client Certificate
<HTML><HEAD><TITLE>Client Certificate Request</TITLE></HEAD><BODY>
<!-- Use the Microsoft ActiveX control to generate the certificate -->
<OBJECT CLASSID="clsid:33BEC9E0-F78F-11cf-B782-00C04FD7BF43"
CODEBASE=certenr3.dll
ID=certHelper>
</OBJECT>
<!-- JavaScript or Visual Basic will work. -->
<SCRIPT LANGUAGE="JavaScript">
<!---
// this is from JavaScript: The Definitive Guide, since
// Microsoft implementation of Math.random() is broken
function random() {
random.seed = (random.seed*random.a + random.c) % random.m;
return random.seed/random.m;
random.m = 714025; random.a = 4096; random.c = 150889;
random.seed = (new Date()).getTime()%random.m;
function GenReq ()
var sessionId = "a_unique_session_id";
var reqHardware = 0;
var szName = "";
var szPurpose = "ClientAuth";
var doAcceptanceUINow = 0;
var doAcceptanceUILater = 0;
var doOnline = 1;
var keySpec = 1;
szName = "";
if (document.GenReqForm.commonName.value == "")
alert("No Common Name");
return false;
else
szName = "CN=" + document.GenReqForm.commonName.value;
if (document.GenReqForm.countryName.value == "")
alert("No Country");
return false;
else
szName = szName + "; C=" + document.GenReqForm.countryName.value;
if (document.GenReqForm.stateOrProvinceName.value == "")
alert("No State or Province");
return false;
else
szName = szName + "; S=" + document.GenReqForm.stateOrProvinceName.value;
if (document.GenReqForm.localityName.value == "")
alert("No City");
return false;
else
szName = szName + "; L=" + document.GenReqForm.localityName.value;
if (document.GenReqForm.organizationName.value == "")
alert("No Organization");
return false;
else
szName = szName + "; O=" + document.GenReqForm.organizationName.value;
if (document.GenReqForm.organizationalUnitName.value == "")
alert("No Organizational Unit");
return false;
else
szName = szName + "; OU=" + document.GenReqForm.organizationalUnitName.value;
/* make session id unique */
sessionId = "xx" + Math.round(random() * 1000);
sz10 = certHelper.GenerateKeyPair(sessionId, reqHardware, szName,
0, szPurpose, doAcceptanceUINow,
doOnline, keySpec, "", "", 1);
* The condition sz10 being empty occurs on any condition in which the
* credential was not successfully generated. In particular, it occurs
* when the operation was cancelled by the user, as well as additional
* errors. A cancel is distinguished from other unsuccessful
* generations by an empty sz10 and an error value of zero.
if (sz10 != "")
document.GenReqForm.reqEntry.value = sz10;
document.GenReqForm.sessionId.value = sessionId;
} else {
alert("Key Pair Generation failed");
return false;
</SCRIPT>
<CENTER><H3>Generate key pair and client certificate request</H3></CENTER>
<FORM METHOD=POST ACTION="http://example.osf.org/cgi-bin/ms_key.pl"
NAME="GenReqForm" onSubmit="GenReq()">
<TABLE>
<TR><TD>Common Name:</TD><TD>
<INPUT TYPE=TEXT NAME="commonName" VALUE="Client Certificate" SIZE=64>
</TD></TR><TR><TD>Country:</TD><TD>
<INPUT TYPE=TEXT NAME="countryName" VALUE="US" SIZE=2>
</TD></TR><TR><TD>State or Province:</TD><TD>
<INPUT TYPE=TEXT NAME="stateOrProvinceName" VALUE="MA">
</TD></TR><TR><TD>City:</TD><TD>
<INPUT TYPE=TEXT NAME="localityName" VALUE="Cambridge">
</TD></TR><TR><TD>Organization:</TD><TD>
<INPUT TYPE=TEXT NAME="organizationName" VALUE="The Open Group">
</TD></TR><TR><TD>Organizational Unit:</TD><TD>
<INPUT TYPE=TEXT NAME="organizationalUnitName" VALUE="Research Institute">
</TD></TR></TABLE>
<INPUT TYPE=HIDDEN NAME="sessionId">
<INPUT TYPE=HIDDEN NAME="reqEntry">
<INPUT TYPE="SUBMIT" name="SUBMIT">
</FORM>
</BODY></HTML>
Perl Script to Process Microsoft Client Certificate Request
Example 16 shows a Perl script used to create a client certificate for Microsoft Internet Explorer, as discussed in the section "Creating a client certificate". This script uses JavaScript and an ActiveX control to install the certificate into Internet Explorer.
Example 16: Sample Perl Script to Process Internet Explorer Client Certificate Request
use CGI;
use File::CounterFile; # module to maintain certificate request counter
my $SSLDIR = '/opt/dev/ssl';
my $CA = "$SSLDIR/bin/ca";
my $CRL2PKCS7 = "$SSLDIR/bin/crl2pkcs7";
my $CONFIG = "/opt/www/lib/ssleay.cnf";
my $CRL = "$SSLDIR/crl/crl.pem";
my $CAPASS = "caKEY";
my $doc_dir = $ENV{'DOCUMENT_ROOT'}; # apache specific location for storage
unless($doc_dir) {
print "<HTML><HEAD><TITLE>Failure</TITLE></HEAD><BODY>DOCUMENT_ROOT not defined</BODY></HTML>";
exit(0);
my $base_dir = $doc_dir;
$base_dir =~ s/\/htdocs//;
my $query = new CGI;
my $req = $query->param('reqEntry');
unless($req) { fail("No Certificate Request Provided"); }
my $counter = new File::CounterFile("$base_dir/Counter", 1);
unless($counter) { fail("Count not create counter: $!"); }
my $count = $counter->inc();
my $certs_dir = "$base_dir/certs";
my $req_file = "$certs_dir/cert$count.req";
my $result_file = "$certs_dir/cert$count.result";
my $key_file = "$certs_dir/$count.key";
my $debug_file = "$certs_dir/$count.debug";
my $pkcs7_file = "$certs_dir/cert$count.pkcs";
#process request
$req =~ tr/\r//d;
$req =~ tr/\n//d;
# save the certificate request to a file, as received
open(REQ, ">$req_file") or fail("Could no save certificate request to file");
print REQ "-----BEGIN CERTIFICATE REQUEST-----\n";
my $result = 1;
while($result) {
$result = substr($req, 0, 72);
if($result) {
print REQ "$result\n";
$req = substr($req, 72);
print REQ "-----END CERTIFICATE REQUEST-----\n";
close(REQ);
unless(-e $CA) { fail("$CA command missing"); }
my $cmd = "$CA -config $CONFIG -in $req_file -out $result_file -days 360 -policy policy_match";
my $rc = system("$cmd -key $CAPASS 2>errs <<END\ny\NY\nEND");
my $session = $query->param('sessionId');
my $cn = $query->param('commonName');
if($rc != 0) { fail("Certification Request Failed</h2>$cmd<P>rc = $rc<P>\
sessionID = $session<BR>req = $req<BR>", "errs"); }
my $cmd = "$CRL2PKCS7 -certfile $result_file -in $CRL -out $pkcs7_file";
my $rc = system("$cmd 2>errs");
open(CERT, "<$pkcs7_file") or fail("Could not open $pkcs7_file<P>$!");
my $certificate = "";
my $started = 0;
while(<CERT>) {
if(/BEGIN PKCS7/) {
$started = 1;
next;
if(/END PKCS7/) {
last;
if($started) {
chomp;
$certificate .= "$_";
close(CERT);
open(MSG, ">MSG") or fail("Could not generate message");
print MSG <<_END_TEXT_;
<HTML><HEAD><TITLE>Finish Client Certificate Installation</TITLE>
<!-- Use the Microsoft ActiveX control to install the certificate -->
<OBJECT CLASSID="clsid:33BEC9E0-F78F-11cf-B782-00C04FD7BF43"
CODE=certenr3.dll
ID=certHelper>
</OBJECT>
<SCRIPT LANGUAGE="JavaScript">
<!--
function InstallCert (subject, sessionId, cert)
if( sessionId == "") {
alert("No Session id");
return;
if(cert == "") {
alert("No Certificate");
return;
var doAcceptanceUILater = 0;
result = certHelper.AcceptCredentials(sessionId, cert, 0,
doAcceptanceUILater);
if(result == "") {
var MSG = "Attempt to install " + subject + " client certificate failed";
alert(MSG);
return false;
} else {
var MSG = subject + " client certificate installed";
alert(MSG);
-->
</SCRIPT>
</HEAD>
<BODY onLoad="InstallCert('$cn', '$session', '$certificate');">
Installing client certificate for $cn<BR>
session: $session<BR>
</BODY>
</HTML>
_END_TEXT_
close(MSG);
open(RD, "<MSG") or fail("Could not open MSG file");
my $MSG = join '', <RD>;
close(RD);
my $Len = length($MSG);
print "Content-Type: text/html\n";
print "Content-Length: $Len\n\n";
print $MSG;
exit(0);
sub fail {
my($MSG, $errs) = @_;
print $query->header;
print $query->start_html(-title => "Certificate Request Failure");
print "<H2>Certificate request failed</H2>$MSG<P>";
if($errs) {
if(open(ERR, "<errs")) {
while(<ERR>) {
print "$_<BR>";
close ERR;
print $query->dump();
print $query->end_html();
exit(0);
It is more complicated than the Netscape Navigator CGI script because it must create an HTML page containing JavaScript which calls an ActiveX control in order to install the client certificate. The CGI script does the following:
Validates and reformats the certificate request passed in the hidden field.
Calls the SSLeay ca command to create a certificate from the request
Combines the certificate with a certificate revocation list to create a PKCS#7 certificate
Dynamically generates an HTML form containing the certificate
Sends the HTML form to browser to install the certificate
The script takes the certificate request generated by Internet Explorer from a hidden form field, and reformats it so that each line in the request is 72 characters long. It then passes this certificate request to the SSLeay ca command to generate a certificate, as follows:
$SSLDIR/bin/ca -in $req_file -out $result_file -days 360 -policy policy_match \
-config /opt/www/lib/ssleay.cnf -key $CAPASS 2>errs
This example shows the command after some of the Perl processing to create the command has been performed. The
$req_file
variable contains the name of a unique file in the certs directory used to contain the reformatted certificate request (the file is useful for debugging). The
$result_file
variable contains the name of a unique file in the certs directory used to contain the certificate. The
$CAPASS
Perl variable contains the CA key.
Once the certificate has been successfully generated, the SSLeay crl2pkcs7 utility is used to combine the certificate with the SSLeay certificate revocation list (CRL) to create a PKCS#7 certificate. This is done using the crl2pkcs7 command as follows:
$SSLDIR/bin/crl2pkcs7 -certfile $result_file -in $CRL -out $pkcs7_file 2>errs
This example shows the command after some of the Perl processing to create the command has been performed. The
$result_file
variable contains the name of a unique file in the certs directory used to contain the certificate. The
$pkcs7_file
Perl variable contains the name of a unique file in the certs directory used to contain the result PKCS#7 certificate. The
$CRL
Perl variable contains
$SSLDIR/crl/crl.pem
, the file containing the Certificate Authority certificate revocation list.
A certificate revocation list may be created using SSLeay as follows:
$SSLDIR/bin/ca -gencrl -config /opt/www/lib/ssleay.cnf -out $SSLDIR/crl/crl.pem
Once the PKCS#7 certificate has been successfully generated, an HTML page is dynamically generated. This page contains JavaScript code which calls an ActiveX control to install the certificate in the browser. The page in this example is designed to automatically load the certificate once the page has loaded into the browser, by using the JavaScript onLoad command. In a production system such automatic installation may not be desired.
Acknowledgements
Many thanks to Eric Young for creating SSLeay, Tim Hudson for his SSLeay work, and Jeff Barber for modifying it to work with Netscape client certificates.
Thanks to Rick Cormier, Ed Frankenberry, Scott Meeks, Tom Titchner, David Weisman and Mary Ellen Zurko for reviewing this article and providing many useful suggestions and insights. Thanks to Doug McEachern for reviewing the Perl code.
Footnotes
[*] Our investigations make use of the fact that patent issues may be avoided in non-commercial experimentation, and export issues may be avoided by using weaker cryptography. The SSL 3.0 specification provides some information on U.S. export regulations. We do not address patent or export regulations here, other than to say you should be aware of them, observe them, and consult an attorney. There are a number of surveys of the issues available [6]. In addition, a brief explanation of export control law can be found in Simson Garfinkle's article, "Cryptography and the Web", in theSummer 1997 World Wide Web Journal.
[**] For more information on digital signatures see the "DSig 1.0 Signature Labels" specification in the "W3C Reports" section of the Summer 1997 World Wide Web Journal.
References
CCITT. Recommendation X.208: Specification of Abstract Syntax Notation One (ASN.1). 1988.
CCITT. Recommendation X.509: The Directory - Authentication Framework. 1988.
Kaliski ,Burton S.,Jr., "An Overview of the PKCS Standards", An RSA Laboratories Technical Note, revised November 1, 1993. http://www.rsa.com/rsalabs/pubs/PKCS/
Kaliski, Burton S., Jr., "A Layman's Guide to a Subset of ASN.1, BER, and DER", An RSA Laboratories Technical Note, revised November 1, 1993. http://www.rsa.com/rsalabs/pubs/PKCS/
Kaufman, Charlie, Perlman, Radia , Speciner, Mike , Network Security: PRIVATE Communication in a PUBLIC world, Prentice Hall, 1995.
Koops, Bert-Jaap, "Crypto Law Survey", version 8.2, May 1997. http://cwis.kub.nl/~frw/people/koops/lawsurvy.htm
Phaos, SSL Resource Center, http://www.phaos.com/sslresource.html
Schneier,Bruce , Applied Cryptography, 2nd Edition, Wiley, 1996. See http://www.counterpane.com/ for various materials by Bruce Schneier.
Microsoft Certificate Specifications, "Installing Certificates and Root Keys in Microsoft Internet Explorer 3.0 and IIS", http://www.microsoft.com/intdev/security/csa/enroll.htm
Netscape Certificate Specifications, http://www.netscape.com/eng/security/certs.html
VeriSign Digital Id FAQ, http://digitalid.verisign.com/id_faqs.htm
SSL2.0, http://www.netscape.com/newsref/std/SSL_old.html
SSL3.0 Internet Draft, http://www.consensus.com/ietf-tls/tls-ssl-version3-00.txt
TLS Working Group (IETF), http://www.consensus.com/ietf-tls/
TLS2.0, http://www.consensus.com/ietf-tls/tls-protocol-02.txt
BSAFE3.0, http://www.rsa.com/rsa/prodspec/bsafe/bsafe_3_0_f.htm
RSARef, http://www.consensus.com/RSAREF/rsaref_toc.html
SSLava, http://www.phaos.com/solutions.html
SSLRef, http://www.netscape.com/newsref/std/sslref.html
SSLPlus, http://www.consensus.com/SSLPlus/
SSLeay FAQ, http://www.psy.uq.oz.au/~ftp/Crypto/
Additional Resources
Taher Elgamal, Jeff Treuhaft, Frank Chen, "Securing Communications on the Intranet and Over the Internet", Netscape Communications Corporation, July 1996. http://www.go-digital.net/whitepapers/securecomm.html
Flanegan, D., JavaScript - The Definitive Guide, 2nd Edition, O'Reilly & Associates, 1997.
Laurie, Ben, and Laurie, Peter, Apache - The Definitive Guide, O'Reilly & Associates, 1997.
RSARef-FAQ, http://www.consensus.com/RSAREF/rsaref_faq.html
Stein, Lincoln D., How to Set Up and Maintain a Web Site, 2nd Edition, Addison-Wesley, 1997.
SSL_Talk_FAQ, http://www.consensus.com/security/ssl-talk-faq.html
SSLeay-0.8.1 ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/ (SSLeay-0.8.1.tar.gz)
Wall, L, Christiansen,T, Schwartz, R, Programming Perl, 2nd Edition, O'Reilly & Associates, 1996.
World Wide Web Journal, "Advancing HTML", Winter 1997, Vol. 2, No. 1.
About the Author
Frederick J. Hirsch
The Open Group Research Institute
11 Cambridge Center, Room 418
Cambridge, MA 02142
f.hirsch@opengroup.org
Frederick J. Hirsch is a Principal Research Engineer at The Open Group Research Institute.
His interests include human-computer interaction, artificial intelligence and marketing. He is currently working on software to add functionality and ease of use to the Web by extending browsers, filtering HTTP streams, and implementing server plugins.
Before joining the Open Group Research Institute he wrote software for security trading at the MacGregor group and for network analysis at Bolt, Beranek and Newman (BBN). Prior to that, he worked on the Datakit local network at AT&T Bell Laboratories. He has an MBA from Boston University, a Master's in Computer Engineering from Stanford University, and a Bachelor of Science in Computer Science and Electrical Engineering from MIT.