In the previous episode, Alice and Bob used sound cryptographic tools like strong symmetric encryption and they encrypted the ephemeral symmetric key with an RSA public key to provide secrecy of their private data exchange. Furthermore, they used digital signatures to reliably detect tampering. Still, despite all their efforts to come up with a rock solid scheme, Mallory was able to easily impersonate Alice and Bob with a simple man-in-the-middle attack.

In this post, a Public Key Infrastructure (PKI) comes to the rescue and will shield Alice and Bob from Mallory’s malicious actions. You’ll learn about webs and chains of trust, X.509 certificates and those mysterious Certification Authorities (CA).

Assessing the problem

Intriguingly, there was nothing wrong with the quality or strength of the crypto algorithms that Alice and Bob used: those are currently state of the art and very robust against all known practical cryptanalysis techniques. They may have some hidden weaknesses (i.e. probably a non-linear key space), but for all practical day-to-day uses, they are among the best algorithms the general public can use, and still be safe, when used properly.

So why did Alice and Bob’s crypto protocol so easily break down? If you remember, the essential weakness was that Bob had to trust the public key it allegedly got from Alice as really belonging to Alice… and vice-versa. This trust was in no way justified, as Mallory was able to sneak in and replace the public keys on their way to the other side with her own.

If Alice and Bob had an independent way to verify that a public key really belonged to whom it claims to belong, Mallory would have no chance to sneak in, and would be left out in the cold. This post shows how trust in public keys can be established.

Introducing Trent

In our hypothetical scenario, Trent is a crypto-activist who not only believes in the sacro sankt right of people to secrecy, but who is also very vocal about it. He even published a famous book about cryptography in many countries, and included (a base-64 representation of) his public key in it as an appendix. Of course, his public key is also widely spread across key servers, web sites (his own and gazillions of third-party sites, blogs etc.), and his friends and fans have even cooked up YouTube videos showing his public key in all kinds of creative ways.

Trent’s business and income depend heavily on the trust people are willing to put in him. As he proved to be 100% honest and totally immune to corruption, his reputation grew tremendously over the years, and today, Trent is widely recognized as an authority whom you can even trust with your life. Oh, by the way, Trent often goes to conferences and conventions to talk about encryption, the right of privacy and secrecy… and of course to promote his own book and business.

It was during one of those conventions that Bob had the privilege to meet Trent personally and to chat him up. Trent explained to Bob what his business was all about, and offered Bob an autograph, because Bob was such a sympathetic guy. However, Trent’s autograph (signature) was very special. Instead of some scribbled text on a postcard (everyone and his dog can do that), Trent offered to sign Bob’s public key instead. Now that’s elitist, isn’t it? This is what they did:

  1. Bob had to create a private/public key pair right there at the convention (he carried a laptop, so it was pretty easy). He saved this key pair as an encrypted file bobprivkey.pem on his laptop’s hard drive.
  2. Bob extracted his public key from bobprivkey.pem and saved it as bobpubkey.pem onto a fresh new USB stick.
  3. Bob gave that USB stick with bobpubkey.pem to Trent, and showed him his own passport as proof of identity.
  4. Trent checked Bob’s passport thoroughly, and made sure it was both genuine and belonged to Bob.
  5. Trent wrote a file with the following text in it: “I, Trent, hereby certify until 08/01/2010 that the following public key really belongs to Bob: (bobpubkey.pem attached). Signed, Trent.”.
  6. Trent signed this file with his own private key, and wrote a copy of that signed file to Bob’s USB stick. He than gave Bob his USB stick and his password back.
  7. Bob saved this file from the USB-Stick as bobcert_from_trent.pem on his laptop.

Bob thanked Trent a lot and went home… wondering what to do with that strange file. He soon forgot about it.

Alice gets and verifies Bob’s certificate

Remember? When Alice wanted to send Bob the ephemeral password of ciphertext.asc, she needed Bob’s public key. This time, Bob suddenly remembered that this strange certificate he got from Trent a couple of months ago actually contained his own public key. “Why won’t I send this certificate to Alice, instead of my raw public key?“, did he asked himself. “After all, I’d like to make a good impression on Alice, by showing her that I met the famous Trent personally, and that he even signed my public key. She’ll be mighty impressed!“, and so he emailed bobcert_from_trent.pem to Alice.

Sure enough, Alice was impressed. She didn’t expect Bob to have friends in such famous circles. Of course, she too knew about Trent, and just like Bob, she owned a dead tree version of Trent’s seminal work on cryptography. Therefore, she had an easy way to get Trent’s public key, and to verify that his public key was genuine. With Trent’s (widely available) public key, Alice verified Trent’s digital signature in bobcert_from_trent.pem and sure eough, the signature verified OK. So she was now 100% certain, that Bob wasn’t kidding her about him knowing Trent: she knew it first hand, because she could verify that the very real Trent, digitally signed something he claimed to be Bob’s public key. The certificate read:

I, Trent, hereby certify until 08/01/2010 that the following public key really belongs to Bob: (bobpubkey.pem attached). Signed, Trent.”

Alice had no reason not to trust Trent’s certificate, and since this certificate didn’t expire yet (it was not yet 08/01/2010 when Alice checked this cert), she decided for herself that the included public key bobpubkey.pem in that bobcert_from_trent.pem really belongs to Bob, because Trent said so. Now, feeling a lot more confident, she extracted bobpubkey.pem from Trent’s certificate, and used that to encrypt the ephemeral password “cryptme” of ciphertext.asc, and she sent this encrypted password to Bob. Bob was then able to decrypt that ephemeral password with his own private key, and use “cryptme” to decrypt ciphertext.asc to alicesong.mp3.

What about Eve?

Well, Eve saw bobcert_from_trent.pem pass her by, and was able to read Bob’s public key bobpubkey.pem. But this public key was useless to her, because she needed Bob’s private key to decrypt the RSA-encrypted emphemeral password “cryptme” that Alice sent to Bob a few minutes later. Without that private key, Eve was left wondering what Alice wanted to say to Bob, and without the ephemeral key for the symmetric encryption algorithm, she wasn’t able to decrypt ciphertext.asc. Bob was safe, and couldn’t be convicted of criminal copyright infringement and being disposed off by his government in the most painful way possible.

And what about Mallory?

Just like Eve, Mallory saw bobcert_from_trent.pem pass her by, as Bob sent it to Alice. Now, Mallory tried to pull the same man-in-the-middle attack that she applied in the previous episode, by intercepting that certificate and by sending her own certificate she got from Trent: mallorycert_from_trent.pem (of course, she renamed that to bobcert_from_trent.pem, so that Alice won’t get suspicious). After all, mallorycert_from_trent.pem contained Mallory’s public key, and Trent’s signature, right?

Alice got the phony bobcert_from_trent.pem from Mallory, which was actually mallorycert_from_trent.pem. If Alice had not been really careful at this point, she could have fallen into a trap right here and there. Why? Well, her certificate verification software would have said: “signature OK”, because Trent certified that the enclosed public key really belonged to… Mallory. After all, Mallory was careful enough not to modify her mallorycert_from_trent.pem in any way, so Trent’s signature was indeed valid.

But Alice was careful: she not only checked Trent’s signature in an automated way, she actually looked at the certificate with her own eyes, and this is what she discovered:

“I, Trent, hereby certify until 31/12/2009 that the following public key really belongs to Mallory: (mallorypubkey.pem attached). Signed, Trent.”

What? Mallory and not Bob?” did Alice ask herself in shock. This can’t be Bob’s certificate. “Something is very fishy here! I won’t trust this public key, and won’t use it to send Bob the “cryptme” password. Who knows who that Mallory girl is, and what kind of trouble she could cause Bob?

Mallory’s attempt at substituting Bob’s certificate with her own certificate failed, because even though her certificate was valid too (it was signed by Trent),

  1. Trent was careful enough to add Mallory’s identity (name) to the certificate he issued Mallory, and
  2. Alice was careful enough to actually read the certificate’s content and do some thinking before using (or not using) the enclosed public key.

And if Marvin intercepted Bob’s certificate?

Marvin is Mallory’s colleague and fiercest competitor in the surveillance center. He also got his own public key certified by Trent as marvincert_from_trent.pem. If he intercepted Bob’s certificate bobcert_from_trent.pem on its way from Bob towards Alice, would he be just as impotent as Mallory? Let’s see! Instead of simply swapping marvincert_from_trent.pem for bobcert_from_trent.pem, Marvin knows full well that Alice would look at his certificate’s content, and smell a rat, just as she did with Mallory’s sneaky attempt.

So, Marvin fires up his editor, loads marvincert_from_trent.pem, and changes its content from

“I, Trent, hereby certify until 31/12/2009 that the following public key really belongs to Marvin: (marvinpubkey.pem attached). Signed, Trent.”

to

“I, Trent, hereby certify until 08/01/2010 that the following public key really belongs to Bob: (bobpubkey.pem attached). Signed, Trent.”

and saves that changed file as bobcert_from_trent.pem. Sneaky, eh? He then sends the phony bobcert_from_trent.pem to Alice. At the cafeteria, he is quite full of himself when talking to Mallory: “Hey, Mal, guess what I’ve done: Alice will never realize that I’m not Bob. She’ll look at the cert, and all fields will point to Bob. Hah! I’m a lot cleverer than you, you dimwhit!” Mallory, as always, keeps cool, and just sends him one of her infuriating sweet smiles, replying: “We’ll see who’s cleverer, Marv.

A few moments after Marvin sent his phony bobcert_from_trent.pem, Alice got it in her inbox. Sure enough, she had a look at it, and it really looked like it came from Bob. But was it legit? Alice’s certificates verification software checked the signature in Marv’s bobcert_from_trent.pem against Trent’s well-known public key, and surprise, surprise: the signature didn’t validate OK (her software showed her a big red stop sign and honked a loud and unmistakable alarm)! Hah! Someone must have changed this certificate en route, but one thing was certain: that’s not what Trent signed. Of course, Alice didn’t trust the included public key (which was Marvin’s pub key), and so, Marvin had to wait indefinitely for the mycrypt password.

Oh, just in case you care about office gossip: eventually Mallory got promoted (even though she wasn’t able to have Bob sent to jail for trafficking a single copyrighted MP3), and became Mavin’s supervisor… which irritated him tremendously, as she made sure to pay him pack his arrogance and to take his ego down a peg or two. Isn’t learning on the job (the hard way) wonderful? :)

So what have we learned so far?

Let’s summarize what we’ve learned so far.

  • Alice can’t trust Bob’s public key, because Mallory could have substituted it with her own.
  • However, Alice and Bob both trust Trent, and both have acquired Trent’s public key through a secure channel.
  • Trent issued a certificate consisting of Bob’s public key and Bob’s name, and signed this certificate with his private key.
  • Alice can verify Trent’s signature on that certificate using Trent’s widely available and well-known public key.
  • Alice can look at the (verified) certificate, and establish that the enclosed public key belongs to Bob, according to Trent.
  • Since Alice trusts Trent, she extends her Trust to Bob and extracts his public key from the certificate.
  • Mallory can’t substitute Bob’s certificate with her own, because her certificate will point to her name, not to Bob’s.
  • Marvin can’t substitute Bob’s certificate with a modified version of his own, because that would break Trent’s signature on his certificate.

All in all, as long as Alice and Bob:

  1. have a secure channel to obtain Trent’s public key,
  2. trust Trent’s integrity to verify the identity of the people who he issues certificates,

they can communicate safely across an insecure channel using the public keys enclosed in the Trent-issued certificates, without having to worry about Eve, Mallory or Marvin. This cryptographic protocol appears secure, as long as both preconditions above are fulfilled. But don’t take those preconditions lightly: in real life, they are hardly always met. Below, you’ll learn about a real life scenario where they are subverted.

Using X.509 certificates

The biggest drawback of the certificates that Trent issued so far is that they were difficult to process and verify automatically. After all, Alice had to verify Trent’s signature (that’s programmable), but she also had to actually eyeball the certificate, and manually extract Bob’s identity (name), his public key, and the date of expiry from that freely-formatted certificate (e.g. using an editor). Wouldn’t it be nice if Alice could do this automatically with a program?

Had Trent used a well-defined fixed format for his certificates, instead of freely formatting them at will, it would have been trivial to write a program that parses this format and extracts all the necessary fields such as signature, public key, identity, validity, etc…

Designing such a format in an ad hoc manner is easy enough, but for this format to be really useful, it shouldn’t be only understood by one specific program. Ideally, certificates would be written in an internationally recognized standard format that is widely implemented in e-mail clients and other software packages such as browsers. Fortunately, such a standard already exists by the name of X.509. As a big believer in standard formats, Trent decides to switch from manually created certificates to RFC-5280 compliant X.509v3 certificates, including X.509v2 CRL (that we’ll introduce below).

Trent’s sets up his own Certification Authority (CA)

To issue his own X.509v3 certificates, Trent needs to set up a certification authority (CA). This may sound impressive, but it’s not. Actually, it’s quite simple: all necessary functionality is contained in the openssl ca and openssl req commands. There are some frameworks to build a real-life CA, but most of them are based upon the openssl tool anyway.

Trent starts by creating a directory on his system (let’s say for the sake of this example /var/tmp/trentca), that will contain:

  • his private key
  • a self-signed root certificate
  • all X.509v3 certificates he issued
  • all revocation lists for invalidated certs

Setting the permissions of this directory very tightly is a must. So this is what Trent does:

(trent) $ mkdir /var/tmp/trentca
(trent) $ mkdir /var/tmp/trentca/certs /var/tmp/trentca/private
(trent) $ chmod 755 /var/tmp/trentca /var/tmp/trentca/certs
(trent) $ chmod 700 /var/tmp/trentca/private
(trent) $ echo '01' > /var/tmp/trentca/serial
(trent) $ touch /var/tmp/trentca/serial

Next, Trent creates a configuration file /var/tmp/trentca/openssl.conf that will contain suitable defaults for the openssl tool, when invoked by Trent:

[ ca ]
default_ca = trentca

[ trentca ]
root             = /var/tmp/trentca
certificate      = $root/cacert.pem
database         = $root/index.txt
new_certs_dir    = $root/certs
private_key      = $root/private/cakey.pem
serial           = $root/serial
 
default_crl_days = 7
default_days     = 365
default_md       = sha1

policy           = trentca_policy
x509_extensions  = certificate_extensions

[ trentca_policy ]
commonName             = supplied
stateOrProvinceName    = supplied
countryName            = supplied
emailAddress           = supplied
organizationName       = supplied
organizationalUnitName = optional

[ certificate_extensions ]
basicConstraints = CA:false

To use this file, Trent must point the environment variable OPENSSL_CONF to its absolute path:

(trent) $ OPENSSL_CONF=/var/tmp/trentca/openssl.conf; export OPENSSL_CONF

Finally, Trent needs a root certificate /var/tmp/trentca/cacert.pem and associated private key. In theory, he could obtain a personal certificate from another trusted CA for himself, and use that certificate as the root of his own CA (we’ll see how his sister Trustilla will do this below to establish her own CA business). However, obtaining certificates from those widely trusted commercial CAs, which can themselves be used to sign other certificates can prove extremely hard (not to mention expensive), so Trent decides to simply self-sign a root certificate of his own.

To save a lof of command line arguments to openssl, Trent extends /var/tmp/trentca/openssl.conf like this:

[ req ]
default_bits       = 4096
default_keyfile    = /var/tmp/trentca/private/cakey.pem
default_md         = sha1

prompt             = no
distinguished_name = root_ca_dn

x509_extensions    = root_ca_extensions

[ root_ca_dn ]
commonName          = Trent CA
stateOrProvinceName = Colorado
countryName         = US
emailAddress        = This email address is being protected from spambots. You need JavaScript enabled to view it.
organizationName    = Trent Root Certification Authority

[ root_ca_extensions ]
basicConstraints = CA:true

Now Trent is all set to create his self-signed root certificate, alongside a private/public key pair:

(trent) $ openssl req -x509 -newkey rsa:4096 -out cacert.pem -outform PEM
Generating a 4096 bit RSA private key
.........++
........................................................++
writing new private key to '/var/tmp/trentca/private/cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----

(We’ve used the pass phrase “super.trent” here, but of course, in real life this pass phrase needs to be a lot less guessable).

The newly created certificate looks like this:

(trent) $ ls -la
total 30
drwxr-xr-x   4 trent  wheel    512 Aug 10 17:38 .
drwxrwxrwt  35 root   wheel  17920 Aug 10 17:39 ..
-rw-r--r--   1 trent  wheel   2009 Aug 10 17:37 cacert.pem
drwxr-xr-x   2 trent  wheel    512 Aug 10 17:05 certs
-rw-r--r--   1 trent  wheel      0 Aug 10 17:05 index.txt
-rw-r--r--   1 trent  wheel   1148 Aug 10 17:31 openssl.conf
drwx------   2 trent  wheel    512 Aug 10 17:37 private
-rw-r--r--   1 trent  wheel      3 Aug 10 17:05 serial

(trent) $ cat cacert.pem
-----BEGIN CERTIFICATE-----
MIIFnTCCA4WgAwIBAgIJAPyd2y4LmFFRMA0GCSqGSIb3DQEBBQUAMIGEMREwDwYD
VQQDEwhUcmVudCBDQTERMA8GA1UECBMIQ29sb3JhZG8xCzAJBgNVBAYTAlVTMSIw

( ... a lot more lines snipped ... )

WG7ihEYYyox1Rp4S3VYa8VEtObICSX2CjCGmZUfY2ZEjci2muirZYqP+H2oIFYTI
5rmj0SZTUtEu6cxVrQHRBjNkjt2OGI2XQhCMxLqsgwxZ/OmG+mKG+iYldgTQKdGN
yA==
-----END CERTIFICATE-----

A human readable print out looks like this:

(trent) $ openssl x509 -in cacert.pem -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            fc:9d:db:2e:0b:98:51:51
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: CN=Trent CA, ST=Colorado, C=US/
                emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it.,
                O=Trent Root Certification Authority
        Validity
            Not Before: Aug 10 15:37:56 2009 GMT
            Not After : Sep  9 15:37:56 2009 GMT
        Subject: CN=Trent CA, ST=Colorado, C=US/
                 emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it.,
                 O=Trent Root Certification Authority
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (4096 bit)
                Modulus (4096 bit):
                    00:d3:4e:d2:f7:1a:d8:02:42:1e:84:c5:17:10:7d:
                    d6:58:ac:55:b1:15:6b:3e:a6:29:67:3b:0e:75:fb:
                     
                    ( ... snipped a lot of similar lines ... )
                     
                    fd:7b:c3:b8:d5:00:db:e0:1f:fd:67:55:75:a0:ac:
                    d7:2e:24:92:a0:61:af:24:ec:37:90:c7:b4:29:fb:
                    5e:a4:7d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: sha1WithRSAEncryption
        13:22:69:ce:f4:7c:b3:f0:ac:5c:d0:ea:08:1a:dd:ca:cf:91:
        c4:d7:28:f0:d3:7e:aa:66:70:23:cd:8f:9e:f2:b5:d7:6e:3f:
         
        ( ... snipped a lot of similar lines ... )
         
        53:52:d1:2e:e9:cc:55:ad:01:d1:06:33:64:8e:dd:8e:18:8d:
        97:42:10:8c:c4:ba:ac:83:0c:59:fc:e9:86:fa:62:86:fa:26:
        25:76:04:d0:29:d1:8d:c8

After sending cacert.pem all over the net, Trent is ready to accept certificate requests, based on this root certificate.

Bob requests a certificate from the CA

To obtain an X.509v3 certificate from Trent CA, Bob will need to create a special kind of certificate termed a certificate request and send that to Trent CA. This certificate request will contain Bob’s public key and a subject line containing Bob’s identity (name).

Let’s see how it’s done. Remember that unlike Trent, Bob doesn’t set his environment variable OPENSSL_CONF to a custom configuration file (Bob isn’t a CA, only Trent is). So from Bob’s perspective, this is what it looks like:

(bob) $ openssl req -newkey rsa:2048 -keyout bobskey.pem -keyform PEM \
?                   -out bobsreq.pem -outform PEM
Generating a 2048 bit RSA private key
..............................+++
....................+++
writing new private key to 'bobskey.pem'
Enter PEM pass phrase:
Verifying - 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]:DE
State or Province Name (full name) [Some-State]:NRW
Locality Name (eg, city) []:Cologne
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Private Home
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:Bob Crypto
Email Address []:This email address is being protected from spambots. You need JavaScript enabled to view it.

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:bobby
An optional company name []:

(bob) $ chmod 400 bobskey.pem

(bob) $ ls -l
total 6
-r--------  1 bob    wheel  1751 Aug 10 18:20 bobskey.pem
-rw-r--r--  1 bob    wheel  1058 Aug 10 18:20 bobsreq.pem

In this example, Bob created a new public/private RSA key pair with 2048 bits, and saved it into the file bobskey.pem. To make sure that nobody steals his precious key pair, he encrypted it with Triple DES (just as he did in the previous episode), using the extremely insecure pass phrase “bo.b” (of course, he’ll need a much more secure pass phrase in real life).

Then, openssl req asked Bob a lot of questions about his identity, which it encoded in the subject of the certificate request.

Bob, being the curious kind of guy, tries to peek inside bobskey.pem and bobsreq.pem:

(bob) $ cat bobskey.pem
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,779DCBC17442D888

8X7/J4YkBvELNYvGjv4Tn/flUKzHTtoFtFF0jVBwUZigH0dXroKrBy8de2Z8qrAX
AU2nPxZqUEuH64HEFLzjSxOZI4ftpDAeMiPxPR0MeL145TXLR2W6tvIumDOmVpS5

( ... a lot more similar lines ... )

9bloKFB0IVNIQJkWQbSfEuE46IHLyFf/JtvcDR+wgSn792N0iUsR3zRav7WNtT8Z
3b6nC1mNKrK54y368rpPEJJVZRlKER7ut1BapBDWc4uOP/Y0L0mxnngq909uz47T
-----END RSA PRIVATE KEY-----

(bob) $ cat bobsreq.pem
-----BEGIN CERTIFICATE REQUEST-----
MIIC1DCCAbwCAQAweTELMAkGA1UEBhMCREUxDDAKBgNVBAgTA05SVzEQMA4GA1UE
BxMHQ29sb2duZTEVMBMGA1UEChMMUHJpdmF0ZSBIb21lMRMwEQYDVQQDEwpCb2Ig

(... again a lot more similar lines ...)

VS/CLlvfQTsvPdR9aVuGQWg2IP+83LwQxY+jO0cAjgPnvUfBAya2/K5KNIwwxyRE
DvG0dUDG+Hssa3M8wZAjTGatQ3FCgkvMJrC2WSZ5OG5iCCum9BShiJwZiu1FzjpJ
T5n3mJHUhL0=
-----END CERTIFICATE REQUEST-----

Unsurprisingly, bobskey.pem was effectively an RSA public/private key pair, encrypted with Triple DES in CBC mode, and base-64 encoded.

What’s more interesting is of course the certificate request bobsreq.pem. To get a human readable interpretation of the gibberish between the BEGIN CERTIFICATE REQUEST and END CERTIFICATE REQUEST lines, Bob uses the openssl req command like this:

(bob) $ openssl req -in bobsreq.pem -text -noout
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=DE, ST=NRW, L=Cologne, O=Private Home, CN=Bob Crypto/
                 emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it.
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (2048 bit)
                Modulus (2048 bit):
                    00:cb:e5:cb:8d:bd:dd:93:21:95:d4:2f:e8:0e:b2:
                    99:c2:a9:5c:42:2f:c1:63:84:1e:48:9d:b6:a5:24:
                     
                    (... a lot more similar lines ...)
                     
                    cc:2a:04:0c:73:3c:27:87:cd:a3:f7:1f:3d:73:38:
                    a0:5a:2e:9d:1d:73:7e:7c:75:75:a9:b1:cd:2b:f2:
                    3b:d1
                Exponent: 65537 (0x10001)
        Attributes:
            challengePassword        :bobby
        Signature Algorithm: sha1WithRSAEncryption
            30:8f:5a:c1:ff:ce:88:9d:46:37:be:af:79:a6:dd:80:43:5e:
            ba:80:b9:cc:16:e2:59:01:f9:aa:56:1c:21:d2:6f:f0:bf:80:
             
            (... a lot more similar lines ...)
             
            66:ad:43:71:42:82:4b:cc:26:b0:b6:59:26:79:38:6e:62:08:
            2b:a6:f4:14:a1:88:9c:19:8a:ed:45:ce:3a:49:4f:99:f7:98:
            91:d4:84:bd

The certificate request obviously contains Bob’s RSA public key, and some details about Bob’s identity in the Subject field. Furthermore, Bob signed this request with his own private key. Oh, in case you were curious: the challengePassword field is not strictly required, but may be stored by Trent CA (or other CAs) and could be used as an out-of-band mechanism to reset passwords and certificates.

Finally, Bob sends bobsreq.pem to Trent CA, alongside a fax of his passport, drivers’ license, VISA card etc, to prove his identity in real life.

Trent CA issues a certificate to Bob

When Trent CA receives bobsreq.pem, allegedly from Bob, it will perform the following steps:

  • A representative of Trent CA will open bobsreq.pem and have a look at the Subject field.
  • That same rep. will also look at Bob’s fax documentation that was sent along bobsreq.pem to verify Bob’s identity.
  • Once Trent CA’s rep. is satisfied and convinced that bobsreq.pem was really issued by Bob and that Bob is who he claims to be, she’ll issue an X.509v3 certificate to Bob, and will sign that certificate with Trent CA’s private key. She’ll save this certificate in the certs subdirectory of /var/tmp/trentca.
  • Trent CA’s rep. will send that certificate to Bob.

This is how Trent CA’s representative will act:

(trent) $ OPENSSL_CONF=/var/tmp/trentca/openssl.conf; export OPENSSL_CONF

(trent) $ ls -la
total 32
drwxr-xr-x   4 trent  wheel    512 Aug 10 18:51 .
drwxrwxrwt  36 root   wheel  17920 Aug 10 18:51 ..
-rw-r--r--   1 trent  wheel   1058 Aug 10 18:51 bobsreq.pem
-rw-r--r--   1 trent  wheel   2009 Aug 10 17:37 cacert.pem
drwxr-xr-x   2 trent  wheel    512 Aug 10 17:05 certs
-rw-r--r--   1 trent  wheel      0 Aug 10 17:05 index.txt
-rw-r--r--   1 trent  wheel   1148 Aug 10 17:31 openssl.conf
drwx------   2 trent  wheel    512 Aug 10 17:37 private
-rw-r--r--   1 trent  wheel      3 Aug 10 17:05 serial

We see here Trent CA’s infrastructure, and bobsreq.pem. Using Trent CA’s private key (protected with the pass phrase “super.trent” in our example), Trent’s employee will include this certificate (request) into the Trent CA database, using the openssl ca command:

(trent) $ openssl ca -in bobsreq.pem
Using configuration from /var/tmp/trentca/openssl.conf
Enter pass phrase for /var/tmp/trentca/private/cakey.pem:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           : PRINTABLE :'DE'
stateOrProvinceName   : PRINTABLE :'NRW'
localityName          : PRINTABLE :'Cologne'
organizationName      : PRINTABLE :'Private Home'
commonName            : PRINTABLE :'Bob Crypto'
emailAddress          : IA5STRING :This email address is being protected from spambots. You need JavaScript enabled to view it.'
Certificate is to be certified until Aug 10 16:57:43 2010 GMT (365 days)
Sign the certificate? [y/n]:

At this point, Trent’s rep. will have to manually verify the data in the Subject’s DN, using the documentation that Bob sent along. This is an involved process, and may require interacting with some other parties such as a bank, a government database, calling Bob directly (using a phone number from a public directory and not only what Bob may have provided himself) to verify that Bob actually really issued the request…

When Trent’s rep. is convinced of Bob’s identity, she’ll sign the new certificate:

Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries

The certificate is immediately displayed, both in human-readable form:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: CN=Trent CA, ST=Colorado, C=US/
                emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it.,
                O=Trent Root Certification Authority
        Validity
            Not Before: Aug 10 16:57:43 2009 GMT
            Not After : Aug 10 16:57:43 2010 GMT
        Subject: CN=Bob Crypto, ST=NRW, C=DE/
                 emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it., O=Private Home
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public Key: (2048 bit)
                    Modulus (2048 bit):
                        00:cb:e5:cb:8d:bd:dd:93:21:95:d4:2f:e8:0e:b2:
                        99:c2:a9:5c:42:2f:c1:63:84:1e:48:9d:b6:a5:24:
                         
                        ( ... a lot more similar lines ...)
                         
                        cc:2a:04:0c:73:3c:27:87:cd:a3:f7:1f:3d:73:38:
                        a0:5a:2e:9d:1d:73:7e:7c:75:75:a9:b1:cd:2b:f2:
                        3b:d1
                    Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
    Signature Algorithm: sha1WithRSAEncryption
        17:23:f1:46:d7:99:78:b3:45:cf:a3:01:d8:02:ae:a1:8b:a3:
        8b:40:6f:48:12:d3:bd:28:1a:9a:2d:32:c9:57:8f:d9:e6:1c:
         
        ( ... etc, etc, etc. ... )
         
        a0:e7:d1:02:36:ae:e0:5c:8f:3d:eb:6c:ee:6b:f9:20:b3:11:
        67:5d:72:07:9e:d5:35:f0:94:00:5c:fd:04:cb:9a:db:1d:29:
        7e:d7:5e:d1:95:f2:44:b4

and in raw form:

-----BEGIN CERTIFICATE-----
MIIEdDCCAlygAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhDERMA8GA1UEAxMIVHJl
bnQgQ0ExETAPBgNVBAgTCENvbG9yYWRvMQswCQYDVQQGEwJVUzEiMCAGCSqGSIb3

(... a lot more similar lines ...)

/4+op5ADZZF5ggivNBn+R9g68eUiFn9waF9eZsMCeCgQCtPoru1UHJoGg9eg59EC
Nq7gXI8962zua/kgsxFnXXIHntU18JQAXP0Ey5rbHSl+117RlfJEtA==
-----END CERTIFICATE-----

Lastly, openssl ca exists, displaying:

Data Base Updated

Let’s look again at Trent CA’s files again:

(trent) $ ls -la
total 38
drwxr-xr-x   4 trent  wheel    512 Aug 10 19:02 .
drwxrwxrwt  36 root   wheel  17920 Aug 10 18:57 ..
-rw-r--r--   1 trent  wheel   1058 Aug 10 18:51 bobsreq.pem
-rw-r--r--   1 trent  wheel   2009 Aug 10 17:37 cacert.pem
drwxr-xr-x   2 trent  wheel    512 Aug 10 19:02 certs
-rw-r--r--   1 trent  wheel     99 Aug 10 19:02 index.txt
-rw-r--r--   1 trent  wheel     21 Aug 10 19:02 index.txt.attr
-rw-r--r--   1 trent  wheel      0 Aug 10 17:05 index.txt.old
-rw-r--r--   1 trent  wheel   1148 Aug 10 17:31 openssl.conf
drwx------   2 trent  wheel    512 Aug 10 17:37 private
-rw-r--r--   1 trent  wheel      3 Aug 10 19:02 serial
-rw-r--r--   1 trent  wheel      3 Aug 10 17:05 serial.old

We see that the database files index.txt and serial have been changed, and acquired a couple of companion files. Additionally, certs now contains a new file, which is the certificate that was just issued:

(trent) $ ls -l certs
total 6
-rw-r--r--  1 trent  wheel  5339 Aug 10 19:02 01.pem

For each certificate that Trent signs, the serial number will be bumped, and the certs will start accumulating in certs/ as 01.pem, 02.pem, 03.pem and so on. The main advantage of CA frameworks like OpenCA and others over barebones openssl as shown in this example, is flexibility, i.e. the use of a SQL or LDAP database to manage all those certificates, and a nice little GUI for Trent’s employees. But the basic functionality shown here is all that is necessary to run a small CA.

Anyway, Trent now sends certs/01.pem to Bob, and Bob can use it 365 days until it expires. Trent also deletes bobsreq.pem, which isn’t needed anymore:

(trent) $ rm bobsreq.pem

Alice verifies Bob’s certificate’s authenticity

Let’s look Alice over the shoulder. She’s got two certificates now:

(alice) $ ls -la
total 28
drwxr-xr-x   2 alice  wheel    512 Aug 10 19:55 .
drwxrwxrwt  37 root   wheel  17920 Aug 11 01:51 ..
-rw-r--r--   1 alice  wheel   5339 Aug 10 19:54 bobscert.pem
-rw-r--r--   1 alice  wheel   2009 Aug 10 19:55 cacert.pem

Alice got bobscert.pem from someone who claims to be Bob, and she obtained cacert.pem through a secure channel. If she trusts cacert.pem to really belong to Trent CA, she can verify the authenticity of bobscert.pem like this:

(alice) $ openssl verify -CAfile cacert.pem bobscert.pem
bobscert.pem: OK

What does this tell Alice? It simply says that if Alice trusts cacert.pem to really belong to Trent CA, then she can also trust bobscert.pem to have been signed and certified by Trent CA. So, if she trusts Trent CA, she can safely assume that the public key contained in bobscert.pem really belongs to the person whose identity Trent CA listed in the subject field of this certificate. But what subject field is it?

(alice) $ openssl x509 -in bobscert.pem -subject -noout
subject= /CN=Bob Crypto/ST=NRW/C=DE/emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it./O=Private Home

The subject line is encoded in a somewhat strange way, but Alice can clearly see that the commonName is “Bob Crypto” (her friend), and the address and contact data such as emailAddress and country etc. are all what they should be. A more human readable output can also be shown:

(alice) $ openssl x509 -in bobscert.pem -subject -nameopt multiline -noout
subject=
commonName                = Bob Crypto
stateOrProvinceName       = NRW
countryName               = DE
emailAddress              = This email address is being protected from spambots. You need JavaScript enabled to view it.
organizationName          = Private Home

But who issued that certificate? Alice can check that too:

(alice) $ openssl x509 -in bobscert.pem -issuer -noout
issuer= /CN=Trent CA/ST=Colorado/C=US/emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it.
/O=Trent Root Certification Authority

Apparently, the commonName is “Trent CA”, so chances are good that Trent CA effectively issued Bob’s certificate. Alice can’t be sure though, as this could be an impostor (CA-in-the-middle). However, the openssl verify command above at least established that bobscert.pem was indeed signed by someone who ultimately was certified by the one who issued cacert.pem… and this was allegedly Trent himself.

Alice could also check if bobscert.pem is still to be considered valid. After all, Trent CA only certified Bob’s public key for a certain time:

(alice) $ openssl x509 -in bobscert.pem -dates -noout
notBefore=Aug 10 16:57:43 2009 GMT
notAfter=Aug 10 16:57:43 2010 GMT

Bob may also have published the fingerprint of his certificate all over the Net, and Alice could double-check it:

(alice) $ openssl x509 -in bobscert.pem -fingerprint -noout
SHA1 Fingerprint=F5:06:AF:92:41:89:3A:77:A6:4A:74:E4:3A:35:4B:0F:EE:7D:4B:53

Alternatively, Alice could call Bob on the phone, and have Bob read the fingerprint of his certificate to Alice, who would verify it manually, comparing Bob’s fingerprint with the fingerprint she just displayed above.

But what’s the point of bobscert.pem to Alice, if she can’t extract Bob’s public key out of it? Let’s try it:

(alice) $ openssl x509 -in bobscert.pem -pubkey -noout > bobspubkey.pem

(alice) $ cat bobspubkey.pem
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy+XLjb3dkyGV1C/oDrKZ
wqlcQi/BY4QeSJ22pST/PYZnMi4icjcGiMuWOsozrlOx4Ef2DCuUtQ1chu7E98W0
HicFGJ88w4tN7dQzuF62Tj9ocYAU0S2v90Al3CsEjeIDNhT1LwDPQmdQgBIVbh/s
/00fssWhJrlXchupGDfBsrn2bLnxIPcUSrUqby9HRV+OD/RMoPx9l5yThmCG7iUx
Kxd4XWmUMsCkB0rNcwuE9hosrGt3JSKQIqsSyRi8vFupsrPY8ewcBQmp5THxCnke
g1C+AJpZ5moC2+rPD6TYL9zMKgQMczwnh82j9x89czigWi6dHXN+fHV1qbHNK/I7
0QIDAQAB
-----END PUBLIC KEY-----

From here on, Alice can use this public key to encrypt her ephemeral password cryptme, and send it to Bob. Bob can decrypt this ephemeral password, and finally decrypt ciphertext.asc to alicesong.mp3.

To summarize: Bob’s certificate bobscert.pem is merely a container that hosts his identity and RSA public key, signed by Trent CA’s private key. Alice can verify that signature because she has obtained Trent CA’s public key (actually Trent CA’s root certificate with its public key) cacert.pem through a secure channel, so that Mallory couldn’t interfere.

If both Trent CA and Bob are very careful to never leak their private keys, Alice can now safely send encrypted messages to Bob.

Bob’s certificate becomes compromised… and is revoked

A couple of days after Bob has sent bobscert.pem to Alice and they started communicating securely, his computer was stolen! Yes, someone had broken into his home while he was out shopping for some groceries, and took away his laptop (so much for the effectivity of his evil censoring government at combatting crimes in the real world). Now isn’t that’s chutzpah? Bob was just out for two hours, and it was in the middle of the day; yet still, the thief was so bold. He just walked in, took the laptop and left. Incredible!

“No big deal, I’ll simply replace my laptop with a newer one,” did Bob think, after the first shock subsided. “After all, it was long overdue.” Nobody likes their computers stolen, but that’s life: shit happens, and isn’t it a welcome pretext to buy oneself a newer and faster notebook?

But what about his crypto keys and certificates? Fortunately, Bob runs a regular backup schedule, and his backup drives were not stolen. Recovering from this annoying mishap seems quite easy. Just reload the last backup(s) onto the new laptop, and Bob would be up and running again. Said, and done: in a couple of hours, Bob was “back on” as if nothing happened.

Little did Bob know that the thief wasn’t some petty criminal seeking money for his next shot of heroin. Indeed, it was officer Plod from the local branch of the much feared DMCES (Decency, Morals, and Copyright Enforcement Squads), a semi-private security organization acting proactively on behalf of his Government in its “war on porn”, and also acting on behalf of the Entertainment Industry under an extended Anton Pillar order to seize evidence of Bob’s possible copyright infringement activities.

Well, Bob was lucky and escaped the gallows of the almighty Copyright Barons: he wasn’t a music or video buff, and after listening to Alice’s great country song, he securely deleted that file from his laptop. He was also careful enough to stash his huge collection of erotica in a secure place. There was not much Plod could do to have Bob hanged… this time. No multimedia files? No porn? No death sentence!

Still, Bob felt increasingly insecure. He knew full well that his private key wasn’t protected by a strong pass phrase. Just in case, he decided to create a new private/public key pair, and obtain a new certificate from Trent CA… and he sent that new certificate to Alice. At least, Alice and Bob were still able to communicate securely, despite Plod’s attempt at stealing Bob’s private key.

However, his old certificate bobscert.pem was still out in the wild… and to make things worse, it was still valid and had many more months to go until it would expire. Up to a year can be an awful lot of time! As mischance would have it, a few weeks after the DMCES raid, Bob’s sister-in-law Irene used that (compromised) certificate to email him a PDF copy of her newest favorite eBook. With a little bit of effort, Plod was able to crack open Bob’s private key, and Eve had easy access to it. As soon as Irene sent that PDF copy to Bob, Eve was able to read the encrypted communication, and Bob was, again, flagged as copyright infringer, the worst crime a society that produces nothing more than so called “intellectual property” could possibly imagine. Needless to say, he met his fate in a supermax prison just like in the last episode.

So what could Bob have done to avoid this nightmare?

As soon as his certificate (or rather the private key associated with his certificate) became compromised, Bob should have immediately notified the issuing CA (if possible). Trent CA would have revoked this certificate, by including it in a certificate revocation list (CRL). Ideally, Irene’s S/MIME email software would then have checked Trent CA’s CRLs before sending an encrypted mail to Bob. The email client would have detected that bobscert.pem was compromised, and refused to encrypt anything with it. Irene would have been aware of the problem, and would have made sure to get Bob’s new certificate.

Let’s see how this scenario would have played out. At Trent CA, this is what happens as soon as they receive Bob’s notification that his certificate was compromised:

(trent) $ cd /var/tmp/trentca

(trent) $ OPENSSL_CONF=/var/tmp/trentca/openssl.conf; export OPENSSL_CONF

(trent) $ cp /var/tmp/bobscert.pem .

(trent) $ openssl ca -revoke bobscert.pem
Using configuration from /var/tmp/trentca/openssl.conf
Enter pass phrase for /var/tmp/trentca/private/cakey.pem:
Revoking Certificate 01.
Data Base Updated

Up until now, only Bob and Trent CA know that bobscert.pem has been revoked. Nobody else in the world knows that yet. After all, bobscert.pem is already out in the wild, and it can’t be modified either. The only effect of the revoke command was to mark certs/01.pem as revoked in Trent CA’s database index.txt.

For the rest of the world to be aware of the problem, Trent CA needs to publish the revoked certificates in certificate revocation lists (CRLs), and to sign this list with its own private key. Let’s do this now:

(trent) $ openssl ca -gencrl -out invalidcerts.pem
Using configuration from /var/tmp/trentca/openssl.conf
Enter pass phrase for /var/tmp/trentca/private/cakey.pem:

This creates a CRL in PEM format, which looks like this:

(trent) $ cat invalidcerts.pem
-----BEGIN X509 CRL-----
MIIC4TCByjANBgkqhkiG9w0BAQUFADCBhDERMA8GA1UEAxMIVHJlbnQgQ0ExETAP
BgNVBAgTCENvbG9yYWRvMQswCQYDVQQGEwJVUzEiMCAGCSqGSIb3DQEJARYTdHJl
bnRjYUBleGFtcGxlLmNvbTErMCkGA1UEChMiVHJlbnQgUm9vdCBDZXJ0aWZpY2F0
aW9uIEF1dGhvcml0eRcNMDkwODExMTgwOTMzWhcNMDkwODE4MTgwOTMzWjAUMBIC
AQEXDTA5MDgxMTE4MDE0NFowDQYJKoZIhvcNAQEFBQADggIBAG58tm/ZJ6HD+gg/
Yf/+HLxBUEhoXqBCAMi5jSbawDtSn5/7kBgOsEPXw6zLn9zRF7lRl5NwaA3ruENJ
vZ0/IaY1e5QZVbpeHLlh3Q/3hNdwE0uY6OAz1dEX2rwUv8Y+33c+yWy7eRNj7z5n
6ZQUABvIaZI8VW8L8eUDkz45RHqyXX6RNeHljPqRXXFyX/BiPhAlHkRdwmGbFUKp
MaA6ihMIqSVc1WFBFm3Cn7ej3W5NWbS5tGY7j912M364Y1hMoTk+LNak9ngJweFO
rJwykbaT5pJ9TLiyZX+yC3h9DoAiYHvmNvEQ+fO/FLxJpHMyRc7jlHkgDo8kdHtM
L2oTV753vrkNYkwqjctJNiAbtxaV+XNRBPs8e6EFvi7W0BafRU3aZ9ImzwsCellm
e43kDTY/LCtfmJ7e9Vs3cmZH4hi31EjOLVZUJIUXkc0EMwOXcEjMyR/5KFzBOM0l
Wf1EHkmEZUo70jaoXFv7Dz2T5oV0iZ+jke7ad4/vGUAv8Cvz8lmgZO8efJgiAGbJ
tFDUJ+PMQPpR0CWO+0na5cUHVgOMU8S+2ZJX8SrRVgkrwXhn1d6lfiOzUf/NFdgh
QHbQfll1oCg2FC7dLClIfPoz9In1rLnEuIvK5xTx9pC5+/jugdjl565yjXF1rG75
HVpKk0/9ACGknhKIgVcROvX79Q/q

And here is a human readable form of this certificate list:

(trent) $ openssl crl -in invalidcerts.pem -text -noout
Certificate Revocation List (CRL):
    Version 1 (0x0)
    Signature Algorithm: sha1WithRSAEncryption
    Issuer: /CN=Trent CA/ST=Colorado/C=US
            /emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it.
            /O=Trent Root Certification Authority
    Last Update: Aug 11 18:09:33 2009 GMT
    Next Update: Aug 18 18:09:33 2009 GMT
    Revoked Certificates:
        Serial Number: 01
            Revocation Date: Aug 11 18:01:44 2009 GMT
    Signature Algorithm: sha1WithRSAEncryption
        6e:7c:b6:6f:d9:27:a1:c3:fa:08:3f:61:ff:fe:1c:bc:41:50:
        48:68:5e:a0:42:00:c8:b9:8d:26:da:c0:3b:52:9f:9f:fb:90:
         
        ( ... many more similar lines ... )
         
        8b:ca:e7:14:f1:f6:90:b9:fb:f8:ee:81:d8:e5:e7:ae:72:8d:
        71:75:ac:6e:f9:1d:5a:4a:93:4f:fd:00:21:a4:9e:12:88:81:
        57:11:3a:f5:fb:f5:0f:ea

What we see here is a CRL (of type version 1), which revokes the certificate with the serial number 01 (which happens to be Bob’s compromised cert). We also see that this CRL is valid for 7 days (that’s the parameter default_crl_days in /var/tmp/trentca/openssl.conf). Trent CA must now create a new CRL every 7 days, ideally with a cron(1) job. Last, but not least, the CRL is digitally signed with Trent CA’s private key.

Even though this particular CRL contains only one revoked key, typical CRLs contain a whole list of revoked keys (i.e. all compromised keys that have not expired yet).

Trent CA publishes invalidcerts.pem on the web (on a HTTPS server), and makes sure to update that certificate every 7 days at least. Of course, nothing prevents Trent CA from issuing additional “emergency” CRLs at an earlier date, if some of its clients asked really nicely.

Irene’s S/MIME software would fetch invalidcerts.pem from Trent CA’s HTTPS server, and will first proceed to check Trent CA’s signature, using the widely available cacert.pem self-signed certificate from Trent CA:

(irene) $ ls -la
total 30
drwxr-xr-x   2 irene  wheel    512 Aug 11 20:22 .
drwxrwxrwt  38 root   wheel  17920 Aug 11 20:21 ..
-rw-r--r--   1 irene  wheel   5339 Aug 11 20:22 bobscert.pem
-rw-r--r--   1 irene  wheel   2009 Aug 11 20:22 cacert.pem
-rw-r--r--   1 irene  wheel   1052 Aug 11 20:22 invalidcerts.pem

(irene) $ openssl crl -in invalidcerts.pem -CAfile cacert.pem -noout
verify OK

This means that invalidcerts.pem wasn’t tampered with, and was indeed issued by the instance whose private key matches the public key in cacert.pem, i.e. by Trent CA.

Irene’s email software would now check bobscert.pem against this revocation list:

(irene) $ cat cacert.pem invalidcerts.pem > CACertAndCRLs.pem

(irene) $ openssl verify -CAfile CACertAndCRLs.pem -crl_check bobscert.pem
bobscert.pem: /CN=Bob Crypto/ST=NRW/C=DE
/emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it./O=Private Home
error 23 at 0 depth lookup:certificate revoked

By concatenating Trent CA’s self-signed root certificate cacert.pem and Trent CA’s latest revocation list invalidcerts.pem to a single PEM file CACertAndCRLs.pem, and by using the -crl_check flag, Irene was able to determine that bobscert.pem was invalidated.

To summarize: If Bob’s certificate becomes compromised, Trent CA can, upon notification, issue revocation lists that contain among others the serial numbers of all revoked certificates (that haven’t expired yet). Anyone wishing to use a certificate, should download those CRLs from Trent CA, and use them, together with the root certificate of the CA (cacert.pem) to verify if that certificate hasn’t been revoked in the mean time.

A few words about caching: Since revocation lists are valid for 7 days, an S/MIME email or SSL client could choose to fetch those lists only every 7 days, relying on the fact that a particular CA would only issue CRLs no more than every 7 days. This can be dangerous, as this client would miss possible “emergency” CRL issues that the CA could choose to publish out-of-schedule.

Trent delegates some work

Due to increasingly aggressive internet surveillance activities, people were literally compelled to switch to strong cryptography as an act of self-defense. Trent CA was put under a lot of strain, as the number or certificate requests increased daily. Eventually, the time came where Trent CA wasn’t able to satisfy its customers immense need for certificates anymore.

In a bold move, Trent decided to delegate some work to his sister Trustilla, who also happens to live in another country. Trent blindly trusts Trustilla, and is willing to put his whole reputation on the line by recommending his sister to his clients.

According to plan, Trustilla would create the new company Trustilla CA, and would also start issuing certificates to her new clients. But there’s a problem here: unlike Trent and Trent CA, Trustilla CA hasn’t yet established the kind of trust that is needed to act as a public CA. In particular, if she issued a self-signed root certificate, who would put his trust in this certificate? After all, everybody could set up a CA and self-sign its root cert, right?

The solution to this problem is simple: instead of self-signing her own root certificate, Trustilla would ask Trent to sign this certificate for her. This way, everybody checking the authenticity of Trustilla CA’s root certificate wouldn’t have to blindly accept it, but could check it against Trent CA’s root certificate, since Trent CA would have signed it.

What this means is that Trustilla’s root certificate won’t have to be self-signed: it would be signed by another trusted CA (in this case Trent CA). Everyone checking a Trustilla CA’s issued certificate would have to walk up a chain by first verifying Trustilla CA’s signature on the certificate, and then by verifying Trent CA’s signature on Trustilla’s root certificate. Ideally, this chain of certificates would be verified automatically, because every certificate down the chain would point back to the CA that issued it… all the way up to Trent CA’s self-signed root certificate.

Let’s see how it’s done. First, Trustilla starts by creating a certificate request, just like every other client of Trent CA:

(trustilla) $ openssl req -newkey rsa:4096 -keyout trustillaskey.pem \
?                         -keyform PEM -out trustillasreq.pem \
?                         -outform PEM
Generating a 4096 bit RSA private key
..................................++
..++
writing new private key to 'trustillaskey.pem'
Enter PEM pass phrase:
Verifying - 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]:JP
State or Province Name (full name) [Some-State]:Kyoto
Locality Name (eg, city) []:Kyoto
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Trustilla CA
Organizational Unit Name (eg, section) []:Certification Authority
Common Name (eg, YOUR name) []:Trustilla, Sister of Trent
Email Address []:This email address is being protected from spambots. You need JavaScript enabled to view it.

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

(trustilla) $ chmod 400 trustillaskey.pem

In our example, Trustilla used the weak password “trust.illa” to protect her private/public key pair trustillaskey.pem. Next time she meets Trent personally, she hands him trustillasreq.pem over on a USB stick.

Trent could sign his sister’s certificate with Trent CA’s private key just as he did with every other client of Trent CA. But there’s a catch here: the certificate he’d sign would be a leaf certificate, i.e. Trustilla couldn’t use this certificate to sign other certificates, defeating the whole point of this exercise.

Why is that so? Let’s look at the relevant section of Trent CA’s configuration file openssl.conf:

[ ca ]
default_ca = trentca

[ trentca ]
x509_extensions = certificate_extensions

[ certificate_extensions ]
basicConstraints = CA:false

The final line is the culprit here: Trent CA generates only certificates that can’t be used for subsequent certification authories like Trustilla CA. This is the way it should be: personal certificates shouldn’t be CA certificates.

However, since Trent really trusts his sister Trustilla, he temporarily changes that last line to:

<code)basicConstraints = CA:true

before signing trustillasreq.pem like this:

(trent) $ OPENSSL_CONF=/var/tmp/trentca/openssl.conf; export OPENSSL_CONF

(trent) $ cd /var/tmp/trentca

(trent) $ cp /path/to/trustillasreq.pem .

(trent) $ openssl ca -in trustillasreq.pem
Using configuration from /var/tmp/trentca/openssl.conf
Enter pass phrase for /var/tmp/trentca/private/cakey.pem:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           : PRINTABLE :'JP'
stateOrProvinceName   : PRINTABLE :'Kyoto'
localityName          : PRINTABLE :'Kyoto'
organizationName      : PRINTABLE :'Trustilla CA'
organizationalUnitName: PRINTABLE :'Certification Authority'
commonName            : PRINTABLE :'Trustilla, Sister of Trent'
emailAddress          : IA5STRING :This email address is being protected from spambots. You need JavaScript enabled to view it.'
Certificate is to be certified until Aug 13 20:55:18 2010 GMT (365 days)
Sign the certificate? [y/n]:y

Because Trent knows his sister very well, and because he got her certificate request (in /path/to/trustillasreq.pem), he knows that he can sign this certificate. So he answers ‘y’:

Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y

(... certificate here ...)
Data Base Updated

Finally, he resets that line in /var/tmp/trentca/openssl.conf to:

basicConstraints = CA:false

as it should be, because Trent CA will continue to issue personal (non-CA) certificates in the future.

Finally, Trent gives the signed certificate to Trustilla as the file trustillaca.pem:

(trent) $ cp certs/03.pem /path/to/trustillaca.pem

Trustilla can now check her signed certificate against Trent CA’s root certificate cacert.pem:

(trustilla) $ ls -l
total 34
drwxr-xr-x   2 trustilla  wheel    512 Aug 13 22:58 .
drwxrwxrwt  40 root       wheel  17920 Aug 13 22:59 ..
-rw-r--r--   1 trustilla  wheel   2009 Aug 14 01:31 cacert.pem
-rw-r--r--   1 trustilla  wheel   6946 Aug 13 22:58 trustillaca.pem
-r--------   1 trustilla  wheel   3311 Aug 13 22:37 trustillaskey.pem
-rw-r--r--   1 trustilla  wheel   1797 Aug 13 22:37 trustillasreq.pem

(trustilla) $ openssl verify -CAfile cacert.pem trustillaca.pem
trustillaca.pem: OK

Her certificate looks like this:

(trustilla) $ cat trustillaca.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 3 (0x3)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: CN=Trent CA, ST=Colorado, C=US/
                emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it.,
                O=Trent Root Certification Authority
        Validity
            Not Before: Aug 13 20:55:18 2009 GMT
            Not After : Aug 13 20:55:18 2010 GMT
        Subject: CN=Trustilla, Sister of Trent, ST=Kyoto, C=JP/
                 emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it.,
                 O=Trustilla CA, OU=Certification Authority
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public Key: (4096 bit)
                    Modulus (4096 bit):
                        00:c7:b5:0e:7f:54:a2:4a:0c:ca:d9:36:aa:c1:56:
                        4b:f3:80:10:c5:ca:43:e3:ee:45:52:35:d9:93:68:
                         
                        ( ... etc ... )
                         
                        cc:ab:74:e2:6f:66:13:7c:f9:30:9a:2d:93:f5:55:
                        c8:62:ab
                    Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:TRUE
    Signature Algorithm: sha1WithRSAEncryption
        a9:2f:e2:df:17:62:f0:7d:38:18:9e:38:e8:29:c9:fc:5a:0e:
        82:95:2a:c1:68:e9:4f:08:5d:42:2e:18:fe:28:49:70:08:69:
         
        ( ... etc ... )
         
        c1:84:3c:63:db:46:2f:16:91:d0:ba:ef:2a:99:6d:49:73:ac:
        02:30:01:1b:cf:e4:fe:1d:79:3e:b2:f1:ff:31:1e:da:94:41:
        4d:1e:2b:19:6b:04:06:34
-----BEGIN CERTIFICATE-----
MIIFsjCCA5qgAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBhDERMA8GA1UEAxMIVHJl
bnQgQ0ExETAPBgNVBAgTCENvbG9yYWRvMQswCQYDVQQGEwJVUzEiMCAGCSqGSIb3

( ... etc ... )

HiR6X1l/y/v0EQen7jOt4l0u13PkGAr+FnfOgUA/BNt1GSpHpfXb9fOJjEApFhLJ
+bgxg3vnuqweqJ7uuLvs7GHnkI7000Er9lPBhDxj20YvFpHQuu8qmW1Jc6wCMAEb
z+T+HXk+svH/MR7alEFNHisZawQGNA==
-----END CERTIFICATE-----

Pay particular attention to the Issuer (Trent CA), to the Subject (owner, Trustilla), and to the X509v3 extension CA:TRUE (a CA-enabled certificate). Please note also that unlike normal certificates, Trustilla’s CA certificate has again a large 4096-bit RSA key for maximum security.

Now, everything else is easy. Trustilla can use the following modified openssl.conf file:

[ ca ]
default_ca = trustillaca

[ trustillaca ]
root             = /var/tmp/trustillaca
certificate      = $root/trustillaca.pem
database         = $root/index.txt
new_certs_dir    = $root/certs
private_key      = $root/private/cakey.pem
serial           = $root/serial

default_crl_days = 7
default_days     = 365
default_md       = sha1

policy           = trustillaca_policy
x509_extensions  = certificate_extensions

[ trustillaca_policy ]
commonName             = supplied
stateOrProvinceName    = supplied
countryName            = supplied
emailAddress           = supplied
organizationName       = supplied
organizationalUnitName = optional

[ certificate_extensions ]
basicConstraints = CA:false

[ req ]
default_bits       = 4096
default_keyfile    = /var/tmp/trustillaca/private/cakey.pem
default_md         = sha1

prompt             = no
distinguished_name = root_ca_dn

x509_extensions    = root_ca_extensions

[ root_ca_dn ]
commonName          = Trustilla CA
stateOrProvinceName = Kyoto
countryName         = JP
emailAddress        = This email address is being protected from spambots. You need JavaScript enabled to view it.
organizationName    = Trustilla CA

[ root_ca_extensions ]
basicConstraints = CA:false

Of course, the paths should also be adjusted, and a few files created:

(trustilla) $ mkdir private certs
(trustilla) $ chmod 700 private
(trustilla) $ mv trustillaskey.pem private/cakey.pem
(trustilla) $ rm trustillasreq.pem

(trustilla) $ echo '01' > serial
(trustilla) $ touch index.txt

To complete our example, Bob will request a new certificate from Trustilla CA, since his old certificate has been revoked (remember that Bob doesn’t set OPENSSL_CONF):

(bob) $ openssl req -newkey rsa:2048 -out bobsreq.pem
Generating a 2048 bit RSA private key
........+++
.................+++
writing new private key to 'privkey.pem'
Enter PEM pass phrase:
Verifying - 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]:DE
State or Province Name (full name) [Some-State]:NRW
Locality Name (eg, city) []:Cologne
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bob's Home
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:Bob Crypto
Email Address []:This email address is being protected from spambots. You need JavaScript enabled to view it.

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

Bob sends bobsreq.pem to Trustilla CA, which will sign his request like this:

(trustilla) $ OPENSSL_CONF=/var/tmp/trustillaca/openssl.conf; export OPENSSL_CONF

(trustilla) $ cd /var/tmp/trustillaca

(trustilla) $ cp /path/to/bobscert.pem .

(trustilla) $ openssl ca -in bobscert.pem
Using configuration from /var/tmp/trustillaca/openssl.conf
Enter pass phrase for /var/tmp/trustillaca/private/cakey.pem:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           : PRINTABLE :'DE'
stateOrProvinceName   : PRINTABLE :'NRW'
localityName          : PRINTABLE :'Cologne'
organizationName      : PRINTABLE :'Bob's Home'
commonName            : PRINTABLE :'Bob Crypto'
emailAddress          : IA5STRING :This email address is being protected from spambots. You need JavaScript enabled to view it.'
Certificate is to be certified until Aug 13 21:19:28 2010 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y

(... bob's certificate ...)

Trustilla sends certs/01.pem to Bob as bobscert.pem.

Now, Bob can have a look at his new certificate:

(bob) $ cat bobscert.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: CN=Trustilla, Sister of Trent, ST=Kyoto, C=JP/
                emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it.,
                O=Trustilla CA, OU=Certification Authority
        Validity
            Not Before: Aug 13 21:19:28 2009 GMT
            Not After : Aug 13 21:19:28 2010 GMT
        Subject: CN=Bob Crypto, ST=NRW, C=DE/
                 emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it., O=Bob's Home
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public Key: (2048 bit)
                    Modulus (2048 bit):
                        00:cb:7b:97:fc:45:e5:2b:51:ce:8d:af:87:3f:d3:
                        41:93:a7:a8:ef:3d:7f:92:99:c6:ad:cb:06:c6:75:
                         
                        ( ... etc ... )
                         
                        dc:16:38:fa:5a:68:af:12:50:33:af:11:8b:51:98:
                        66:2e:ad:31:ae:9f:6a:5d:cd:72:26:ff:22:fe:ad:
                        b0:d5
                    Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
    Signature Algorithm: sha1WithRSAEncryption
        74:4c:c6:97:a3:27:b9:2d:88:27:43:86:44:6b:78:7b:2a:2e:
        95:4a:98:36:77:ca:01:74:a7:af:87:3f:61:60:2f:6c:b3:74:
         
        ( ... etc ... )
         
        e0:e1:cb:d9:12:7d:1b:ce:d5:f2:0c:24:bd:cf:f1:6e:78:01:
        73:e3:1f:c2:3a:f4:80:46:59:99:77:dc:43:c8:33:a0:1e:f0:
        ee:12:50:a9:da:84:84:74
-----BEGIN CERTIFICATE-----
MIIEjzCCAnegAwIBAgIBATANBgkqhkiG9w0BAQUFADCBoTEjMCEGA1UEAxMaVHJ1
c3RpbGxhLCBTaXN0ZXIgb2YgVHJlbnQxDjAMBgNVBAgTBUt5b3RvMQswCQYDVQQG

( ... etc ... )

0UcztRAVoTyn5KTcCpo/gOwAN9qHPbRxsKZXNRlSC2idduWp8R+6UMjy4UAcc/Nv
Kshii0gze+vbNA00o1jGdU4uyw3O0gvg4cvZEn0bztXyDCS9z/FueAFz4x/COvSA
RlmZd9xDyDOgHvDuElCp2oSEdA==
-----END CERTIFICATE-----

Bob can now use this certificate to encrypt and sign any message he wants.

Last, but not least, let Irene verify Bob’s brand new certificate. She first checks the signature using Trustilla CA’s certificate:

(irene) $ openssl verify -CAfile cacert.pem trustillaca.pem
trustillaca.pem: OK

(irene) $ openssl verify -CAfile trustillaca.pem bobscert.pem
bobscert.pem: /CN=Trustilla, Sister of Trent/ST=Kyoto/C=JP/
emailAddress=This email address is being protected from spambots. You need JavaScript enabled to view it./
O=Trustilla CA/OU=Certification Authority
error 2 at 1 depth lookup:unable to get issuer certificate

First of all, trusting Trent CA’s self-signed certificate cacert.pem, Irene was able to verify Trustilla CA’s certificate trustillaca.pem, because the latter was signed by the former.

However, Irene was not able to verify Bob’s certificate using Trustilla CA’s certificate… because while climbing up the chain of issuers, the verification process stopped when Irene tried to verify Trent CA’s signature on Trustilla CA’s certificate. The problem was that trustillaca.pem alone was not enough, because it depends on cacert.pem as well.

So to check the whole chain of certificates up to Trent CA, Irene had to concatenate all CA certificates (in the chain) to a composite file allca.pem, and check Bob’s certificate against that file:

(irene) $ cat cacert.pem trustillaca.pem > allca.pem

(irene) $ openssl verify -CAfile allca.pem bobscert.pem
bobscert.pem: OK

There’s an equivalent in real life for this situation: suppose you want to get a book from your city library. You present a library card as proof of your identity. The librarian trusts the information on that library card, because in order to obtain it, you had to present another proof of ID (e.g. a driving license, or a passport). Since the librarian trusts the state to verify your ID before issuing you a driving license or passport, and because she trusts the library administration to check your identity with those state-issued certificates before issuing you a library card, she can (transitively) assume that you are who you pretend to be.

Is Mallory now out of business?

It may appear as if a public key infrastructure would put Mallory out of business. Is that really so?

The only attack that Mallory could mount, is acting as a CA-in-the-middle. As long as Alice and Bob have a way to obtain Trent CA’s public key through a secure channel or out-of-band methods, Mallory couldn’t act as impostor-CA, because that would immediately show.

However, Mallory isn’t entirely out of the loop. She could for instance obtain a CA certificate from Trent CA, just as Trustilla did (assuming that Trent was not totally reluctant to issue CA certificates for the right amount of money). But then, Bob would still notice that his certificate wasn’t signed by Trent CA anymore, but by Mallory CA. He may (rightly) decide not to extend his trust to Mallory CA, and Mallory would be out of the loop.

But let’s not forget that Bob is up against a formidable opponent: his own evil government. And here lies one big problem: Trent himself didn’t trust Bob enough to blindly issue him a certificate. Indeed, Trent needed to see Bob’s documentation as proof of identity; and one crucial piece of documentation was Bob’s passport. In other words, Trent trusted the issuer of Bob’s passport first, before trusting Bob. And guess who that issuer was? Right: Bob’s (evil) government!

If Bob’s government was really hell-bent on convicting Bob of copyright infrigement for a single MP3 file, it could issue a (false) passport to Mallory, who would use that passport to identify herself to Trent as Bob. Trent, trusting Bob’s government, would issue Mallory a Bob-certificate, and therefore, Mallory could again act as man-in-the-middle. Mallory couldn’t impersonate Alice, but she definitely could impersonate Bob: everything that Alice sends to Bob would be intercepted by Mallory.

There we have it again, the problem of trusting that Bob is really who he claims to be. FWIW, Bob could be kept living in Plato’s cave indefinitely, if the interceptor is resourceful enough.

Hierarchies of Trust

What can we learn from all this? A PKI is based upon a hierarchy of trust. At the very top, is an authority that is trusted by everyone. This authority extends its trust down to a couple of other authorities, until a leaf is reached.

To verify a certificate, one would climb up the tree up to the root certificate authority, which would be the ultimate authority, trusted by everyone.

A PKI doesn’t exist all by itself, it has to extend to the real world. As the example with the passport shows, even Trent CA had to trust the government(s) that issue passports and other real-life authorites that issue other documentation like banks etc. If any one of those authorities is corrupted, the whole chain of trust breaks down (or so it should). And we’ve not even covered the fact that a CA is at the mercy of at least one government (the one that rules the place where it operates from and where its employees are located). That makes CAs quite vulnerable against scare tactics of their governments.

The morale of the story: PKIs are “good enough” to prevent private and commercial interference, but they are only of limited reliability if they are manipulated by governments and by other extremely powerful entities.

A PKI may be incorruptible enough to preserve its reputation, but it can’t stay that way if its very own survival, or the survival of its operatives is at stake.

There’s one possible remedy against this real-life problem: multi-issuer certificates. If multiple CAs in different jurisdictions would collaboratively issue a certificate, the trust one could put on that certificate would be a function of the trust one puts in each individual CA. However, this is still a research area, and AFAIK, nobody has came up with a working multi-issuer scheme yet.

Practical use of X.509 certificates: S/MIME

Trent switched from his manually crafted certificates to standards-compliant X.509v3 certificates for a reason: people should be able to extract all fields of a certificate with a program (or, more precisely, with any X.509v3 aware program). This is obviously a good idea, and is much preferable to any hard to parse manual format.

Now, how about e-mail? When Alice wanted to send countrysong.mp3 to Bob, she had to jump through a lot of hoops:

  • Alice encrypted countrysong.mp3 with a symmetric cipher, using an ephemeral password into ciphertext.asc.
  • Alice sent ciphertext.asc to Bob.
  • Alice RSA-encrypted a little message containing the ephemeral password using Bob’s public key (which she could have extracted from Bob’s certificate).
  • Alice sent the RSA-encrypted ephemeral password to Bob.

Bob’s steps to decrypt countrysong.mp3 were the exact opposite.

All those manual steps are cumbersome and error-prone. Couldn’t Alice send a specially crafted email consisting of the equivalent of ciphertext.asc, and the RSA-encrypted ephemeral password? After all, she could have packed the encrypted payload and the RSA-encrypted ephemeral key into 2 MIME attachments of a regular mail.

That’s exactly the purpose of the S/MIME standard, which has been implemented in a lot of MUAs (email clients). Let’s demonstrate how Alice and Bob can communicate securely over S/MIME, using certificates from Trent CA.

We start with a clean slate with Alice. Assume that she doesn’t have a certificate yet, let’s request one from Trent CA:

(alice) $ openssl req -newkey rsa:2048 -keyout aliceskey.pem -keyform PEM \
?                     -out alicesreq.pem -outform PEM
Generating a 2048 bit RSA private key
............................................+++
...............+++
writing new private key to 'aliceskey.pem'
Enter PEM pass phrase:
Verifying - 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]:CA
Locality Name (eg, city) []:San Francisco
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Alice's Home
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:Alice, the Crypto-Queen
Email Address []:This email address is being protected from spambots. You need JavaScript enabled to view it.

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

(alice) $ chmod 400 aliceskey.pem

Alice encrypted her public/private key pair with the weak pass phrase “al.ice“. She sends alicesreq.pem to Trent CA. Trent will verify this request using Alice’s attached documentation (e.g. a fax of her VISA card and driving license), and he issues Alice a certificate:

(trent) $ OPENSSL_CONF=/var/tmp/trentca/openssl.conf; export OPENSSL_CONF

(trent) $ cd /var/tmp/trentca

(trent) $ openssl ca -in alicesreq.pem
Using configuration from /var/tmp/trentca/openssl.conf
Enter pass phrase for /var/tmp/trentca/private/cakey.pem:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           : PRINTABLE :'US'
stateOrProvinceName   : PRINTABLE :'CA'
localityName          : PRINTABLE :'San Francisco'
organizationName      : PRINTABLE :'Alice's Home'
commonName            : PRINTABLE :'Alice, the Crypto-Queen'
emailAddress          : IA5STRING :This email address is being protected from spambots. You need JavaScript enabled to view it.'
Certificate is to be certified until Aug 14 16:38:44 2010 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y

(... certificate display omitted ...)

Data Base Updated

(trent) $ rm alicesreq.pem

Trent sends the resulting certificate certs/04.pem to Alice, which saves it as alicecert.pem. Moreover, Alice saves Trent CA’s self-signed root certificate as cacert.pem. She can also delete the original certificate request alicesreq.pem, which she doesn’t need anymore. All in all, Alice has the following files in her directory:

(alice) $ ls -la
drwxr-xr-x   2 alice  wheel      512 Aug 14 18:41 .
drwxrwxrwt  39 root   wheel    17920 Aug 14 18:40 ..
-rw-r--r--   1 alice  wheel     5370 Aug 14 18:40 alicecert.pem
-r--------   1 alice  wheel     1751 Aug 14 18:34 aliceskey.pem
-rw-r--r--   1 alice  wheel     2009 Aug 14 18:41 cacert.pem
-r--r--r--   1 alice  wheel  8306321 Aug 14 18:31 countrysong.mp3

Up to now, Alice can’t send encrypted mails to Bob, because she doesn’t have Bob’s public key (or certificate) yet. She could send signed mails though, but let’s postpone this for a moment.

Now, it’s Bob’s turn. Here too, we start with a clean slate, and have Bob create a new certificate request:

(bob) openssl req -newkey rsa:2048 -keyout bobskey.pem -keyform PEM \
?                 -out bobsreq.pem -outform PEM
Generating a 2048 bit RSA private key
.................................+++
...........+++
writing new private key to 'bobskey.pem'
Enter PEM pass phrase:
Verifying - 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]:DE
State or Province Name (full name) [Some-State]:NRW
Locality Name (eg, city) []:Cologne
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bob's Home
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:Bob Crypto
Email Address []:This email address is being protected from spambots. You need JavaScript enabled to view it.

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

(bob) $ chmod 400 bobskey.pem

Bob encrypted his public/private key pair bobskey.pem with the extremely weak pass phrase “bo.b“. Of course, he now sends bobsreq.pem together will all necessary documentation (e.g. a fax of his national ID card) to Trent CA. Theoretically, Bob could also have used Trustilla CA’s services, but we’ll keep things simple for now.

Armed with bobsreq.pem and all those faxes, Trent CA issues Bob a new certificate. Note that there’s nothing wrong with a CA issuing multiple certificates to a single person: all certificates issued by a CA have distinct serial numbers anyway:

(trent) $ OPENSSL_CONF=/var/tmp/trentca/openssl.conf; export OPENSSL_CONF

(trent) $ cd /var/tmp/trentca

(trent) $ openssl ca -in bobsreq.pem
Using configuration from /var/tmp/trentca/openssl.conf
Enter pass phrase for /var/tmp/trentca/private/cakey.pem:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           : PRINTABLE :'DE'
stateOrProvinceName   : PRINTABLE :'NRW'
localityName          : PRINTABLE :'Cologne'
organizationName      : PRINTABLE :'Bob's Home'
commonName            : PRINTABLE :'Bob Crypto'
emailAddress          : IA5STRING :This email address is being protected from spambots. You need JavaScript enabled to view it.'
Certificate is to be certified until Aug 14 16:51:29 2010 GMT (365 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y

(... certificate output omitted ...)

Data Base Updated

(trent) $ rm bobsreq.pem

Trent sends the newly created certificate certs/05.pem to Bob, who saves it as bobcert.pem in his own directory. Bob (and Trent) now delete their copy of bobscert.pem which are not needed anymore. Of course, Bob needs Trent CA’s cacert.pem as well.

This is Bob’s directory right now:

(bob) $ ls -la
total 30
drwxr-xr-x   2 bob    wheel    512 Aug 14 18:54 .
drwxrwxrwt  40 root   wheel  17920 Aug 14 18:54 ..
-rw-r--r--   1 bob    wheel   5333 Aug 14 18:52 bobcert.pem
-r--------   1 bob    wheel   1751 Aug 14 18:45 bobskey.pem
-rw-r--r--   1 bob    wheel   2009 Aug 14 18:54 cacert.pem

Last, but not least, Alice and Bob exchange their certificates: Bob sends bobcert.pem to Alice, and Alice sends alicecert.pem to Bob.

Alice and Bob’s final directories are now:

(alice) $ ls -l
total 8144
-rw-r--r--  1 alice  wheel     5370 Aug 14 18:40 alicecert.pem
-r--------  1 alice  wheel     1751 Aug 14 18:34 aliceskey.pem
-rw-r--r--  1 alice  wheel     5333 Aug 14 18:56 bobcert.pem
-rw-r--r--  1 alice  wheel     2009 Aug 14 18:41 cacert.pem
-r--r--r--  1 alice  wheel  8306321 Aug 14 18:31 countrysong.mp3

and

(bob) $ ls -l
total 16
-rw-r--r--  1 bob    wheel  5370 Aug 14 18:56 alicecert.pem
-rw-r--r--  1 bob    wheel  5333 Aug 14 18:52 bobcert.pem
-r--------  1 bob    wheel  1751 Aug 14 18:45 bobskey.pem
-rw-r--r--  1 bob    wheel  2009 Aug 14 18:54 cacert.pem

Now, everything is set for Alice and Bob to communicate securely using S/MIME.

Because OpenSSL 0.9.7X’s S/MIME implementation doesn’t work very well with binary files (the -binary flag), Alice will convert countrysong.mp3 to base-64 encoded contrysong.asc first, before even thinking of encrypting it. Alternatively, she could use an external MIME parser such as a MUA, but we’ll go the Base-64 encoded way here:

(alice) $ openssl base64 -e -in countrysong.mp3 countrysong.asc

Alice now encrypts countrysong.asc using Bob’s public key, which is contained in his certificate bobcert.pem. The output will be mail_to_bob.asc:

(alice) $ openssl smime -encrypt -aes256 -in countrysong.asc -text \
?                       -out mail_to_bob.asc -outform SMIME \
?                       -to This email address is being protected from spambots. You need JavaScript enabled to view it. -from This email address is being protected from spambots. You need JavaScript enabled to view it. \
?                       -subject "Something nice for you" \
?                       -rand /dev/random \
?                       bobcert.pem
2048 semi-random bytes loaded

(alice) $ ls -la
total 34308
drwxr-xr-x   2 alice  wheel       512 Aug 14 20:25 .
drwxrwxrwt  40 root   wheel     17920 Aug 14 20:25 ..
-rw-r--r--   1 alice  wheel      5370 Aug 14 18:40 alicecert.pem
-r--------   1 alice  wheel      1751 Aug 14 18:34 aliceskey.pem
-rw-r--r--   1 alice  wheel      5333 Aug 14 18:56 bobcert.pem
-rw-r--r--   1 alice  wheel      2009 Aug 14 18:41 cacert.pem
-rw-r--r--   1 alice  wheel  11248145 Aug 14 20:23 countrysong.asc
-r--r--r--   1 alice  wheel   8306321 Aug 14 18:31 countrysong.mp3
-rw-r--r--   1 alice  wheel  15467209 Aug 14 20:25 mail_to_bob.asc

As we can see, the output mail_to_bob.asc is slightly longer than countrysong.asc. The reason for this is not very clear to me, but that’s the way it is.

(alice) $ head mail_to_bob.asc
To: This email address is being protected from spambots. You need JavaScript enabled to view it.
From: This email address is being protected from spambots. You need JavaScript enabled to view it.
Subject: Something nice for you
MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"
Content-Transfer-Encoding: base64

MIOuSCcGCSqGSIb3DQEHA6CDrkgXMIOuSBICAQAxggGnMIIBowIBADCBijCBhDER
MA8GA1UEAxMIVHJlbnQgQ0ExETAPBgNVBAgTCENvbG9yYWRvMQswCQYDVQQGEwJV

Alice sends mail_to_bob.asc to Bob. Eve can’t read its contents, because she doesn’t have Bob’s private key.

From Bob’s perspective, this is what we have prior to decryption:

(bob) $ ls -la
total 15172
drwxr-xr-x   2 bob    wheel       512 Aug 14 20:27 .
drwxrwxrwt  40 root   wheel     17920 Aug 14 20:26 ..
-rw-r--r--   1 bob    wheel      5370 Aug 14 18:56 alicecert.pem
-rw-r--r--   1 bob    wheel      5333 Aug 14 18:52 bobcert.pem
-r--------   1 bob    wheel      1751 Aug 14 18:45 bobskey.pem
-rw-r--r--   1 bob    wheel      2009 Aug 14 18:54 cacert.pem
-rw-r--r--   1 bob    wheel  15467209 Aug 14 20:27 mail_to_bob.asc

Bob can decrypt the message like this:

(bob) $ openssl smime -decrypt -in mail_to_bob.asc -out alicesong.asc \
?                     -inkey bobskey.pem -text
Enter pass phrase for bobskey.pem:

(bob) $ ls -la
total 26356
drwxr-xr-x   2 bob    wheel       512 Aug 14 20:32 .
drwxrwxrwt  40 root   wheel     17920 Aug 14 20:26 ..
-rw-r--r--   1 bob    wheel      5370 Aug 14 18:56 alicecert.pem
-rw-r--r--   1 bob    wheel  11421194 Aug 14 20:32 alicesong.asc
-rw-r--r--   1 bob    wheel      5333 Aug 14 18:52 bobcert.pem
-r--------   1 bob    wheel      1751 Aug 14 18:45 bobskey.pem
-rw-r--r--   1 bob    wheel      2009 Aug 14 18:54 cacert.pem
-rw-r--r--   1 bob    wheel  15467209 Aug 14 20:27 mail_to_bob.asc

Of course, the result alicesong.asc needs to be Base64-decoded:

(bob) $ openssl base64 -d -in alicesong.asc -out alicesong.mp3

(bob) $ ls -la
total 34484
drwxr-xr-x   2 bob    wheel       512 Aug 14 20:32 .
drwxrwxrwt  40 root   wheel     17920 Aug 14 20:26 ..
-rw-r--r--   1 bob    wheel      5370 Aug 14 18:56 alicecert.pem
-rw-r--r--   1 bob    wheel  11421194 Aug 14 20:32 alicesong.asc
-rw-r--r--   1 bob    wheel   8306321 Aug 14 20:32 alicesong.mp3
-rw-r--r--   1 bob    wheel      5333 Aug 14 18:52 bobcert.pem
-r--------   1 bob    wheel      1751 Aug 14 18:45 bobskey.pem
-rw-r--r--   1 bob    wheel      2009 Aug 14 18:54 cacert.pem
-rw-r--r--   1 bob    wheel  15467209 Aug 14 20:27 mail_to_bob.asc

(bob) $ mplayer alicesong.mp3

As we’ve seen, Eve can’t read what Alice sent to Bob. But Bob isn’t sure that mail_to_bob.asc really came from Alice. It could also have been a troyan from Mallory. After all, Mallory knows Bob’s certificate (and public key), and can therefore send Bob encrypted messages too, just like Alice.

Neither Alice nor Bob can prevent Mallory from intercepting mail_to_bob.asc and from replacing it with an encrypted troyan. But Alice could sign her mail before sending it, and Bob could verify that signature. This is how it’s done:

Alice encrypts and signs countrysong.asc:

(alice) $ openssl smime -sign -signer alicecert.pem -inkey aliceskey.pem \
?                       -in countrysong.asc -text \
?       | openssl smime -encrypt -aes256 \
?                       -to This email address is being protected from spambots. You need JavaScript enabled to view it. -from This email address is being protected from spambots. You need JavaScript enabled to view it. \
?                       -subject "Something nice for you" -rand /dev/random \
?                       -out signed_mail_to_bob.asc \
?                       bobcert.pem
Enter pass phrase for aliceskey.pem:
2048 semi-random bytes loaded

The resulting file is signed_mail_to_bob.asc:

(alice) $ ls -la
total 49444
drwxr-xr-x   2 alice  wheel       512 Aug 14 20:35 .
drwxrwxrwt  40 root   wheel     17920 Aug 14 20:26 ..
-rw-r--r--   1 alice  wheel      5370 Aug 14 18:40 alicecert.pem
-r--------   1 alice  wheel      1751 Aug 14 18:34 aliceskey.pem
-rw-r--r--   1 alice  wheel      5333 Aug 14 18:56 bobcert.pem
-rw-r--r--   1 alice  wheel      2009 Aug 14 18:41 cacert.pem
-rw-r--r--   1 alice  wheel  11248145 Aug 14 20:23 countrysong.asc
-r--r--r--   1 alice  wheel   8306321 Aug 14 18:31 countrysong.mp3
-rw-r--r--   1 alice  wheel  15467209 Aug 14 20:25 mail_to_bob.asc
-rw-r--r--   1 alice  wheel  15471260 Aug 14 20:35 signed_mail_to_bob.asc

which looks a lot like the unsigned mail_to_bob.asc:

(alice) $ head signed_mail_to_bob.asc
To: This email address is being protected from spambots. You need JavaScript enabled to view it.
From: This email address is being protected from spambots. You need JavaScript enabled to view it.
Subject: Something nice for you
MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"
Content-Transfer-Encoding: base64

MIOuU9cGCSqGSIb3DQEHA6CDrlPHMIOuU8ICAQAxggGnMIIBowIBADCBijCBhDER
MA8GA1UEAxMIVHJlbnQgQ0ExETAPBgNVBAgTCENvbG9yYWRvMQswCQYDVQQGEwJV

Anyway, Alice sends signed_mail_to_bob.asc. Bob will first decrypt it, using his private key bobskey.pem:

(bob) $ openssl smime -decrypt -inkey bobskey.pem \
?                     -in signed_mail_to_bob.asc -out mail_from_alice.asc
Enter pass phrase for bobskey.pem:

The next step is to verify Alice’s signature on the decrypted mail_from_alice.asc. Verifying signatures requires us to have a copy of Alice’s certificate. We could provide this copy on the command line with the -signer flag (assuming that we got alicecert.pem from Alice previously), or we could hope that Alice had included her certificate in the S/MIME message as well, while signing it. Either way, the verification can only be successuful, if we also provide Trent CA’s self-signed root certificate cacert.pem with the -CAfile flag. If we didn’t provide this, anybody could have forged Alice’s certificate, and the verification would be meaningless. So this is how Bob can verify Alice’s signature, and how he can extract the signed message into alicesong.asc:

(bob) $ openssl smime -verify -in mail_from_alice.asc \
?                -signer alicecert.pem -CAfile cacert.pem \
?                -text -out alicesong.asc
Verification successful

That’s very good! Bob still has to Base64-decode alicesong.asc into alicesong.mp3 and enjoy it with his MP3 player (e.g. mplayer):

(bob) $ openssl base64 -d -in alicesong.asc -out alicesong.mp3

(bob) $ mplayer alicesong.mp3

Let’s look againt at Bob’s files:

(bob) $ ls -la
total 45664
drwxr-xr-x   2 bob    wheel       512 Aug 14 20:43 .
drwxrwxrwt  40 root   wheel     17920 Aug 14 20:26 ..
-rw-r--r--   1 bob    wheel      1623 Aug 14 20:43 alicecert.pem
-rw-r--r--   1 bob    wheel  11421194 Aug 14 20:43 alicesong.asc
-rw-r--r--   1 bob    wheel   8306321 Aug 14 20:43 alicesong.mp3
-rw-r--r--   1 bob    wheel      5333 Aug 14 18:52 bobcert.pem
-r--------   1 bob    wheel      1751 Aug 14 18:45 bobskey.pem
-rw-r--r--   1 bob    wheel      2009 Aug 14 18:54 cacert.pem
-rw-r--r--   1 bob    wheel  11424220 Aug 14 20:39 mail_from_alice.asc
-rw-r--r--   1 bob    wheel  15471260 Aug 14 20:37 signed_mail_to_bob.asc

Bob (and Alice) can now clean up any intermediary files if they wanted.

In the real world, all this encoding and decoding would have been done by an S/MIME-compliant MUI behind the scenes. All that’s needed for S/MIME to be used effectively, is for Alice and Bob to obtain certificates from a CA, and to install both the Root CA’s certificate as well as those certificates into their S/MIME enabled email clients. Everything else is then automatic.

S/MIME scales very well to a huge number of people, because all those people only need to obtain a certificate from the CA, and distribute it any way they like (on their web sites, in emails etc…).

A solution without PKI: OpenPGP’s web of trust

You may now think that every secure E-Mail platform needs a PKI, but that’s far from true. The main competitor to S/MIME is the OpenPGP standard (e.g. as implemented by GnuPG), which implements a different model of trust: a mesh (also called a web of trust). With OpenPGP people can sign the public keys of people they know and trust personally, and distribute those signed keys or key servers or other keys. Trust is established transitively: bascially if you trust the one who signed a key, you can also trust the signed key itself.

OpenPGP is easier to set up and use than S/MIME, because it doesn’t require someone from obtaining a certificate from a PKI. But it doesn’t scale well: the bigger the group of people communicating with PGP, the larger the key rings become, because they gather more and more signatures (e.g. during key signing parties but also in day-to-day operations).

I’ll eventually show how OpenPGP and GnuPG are used in another post.

Conclusion

Alice and Bob can only communicate securely with Public Key Cryptography if they either have a way to exchange their public keys over a secure channel, or if they let a Certification Authority certify their private keys for them. A CA establishes and certifies that a public key really belongs to a specific person by doing a couple of background checks. Certificates are signed by the CA, so they can’t be forged or replaced by Mallory. The whole PKI works only, if all parties trust the CA, and have a way to obtain the CA’s self-signed root certificate through a secure channel (e.g. as part of a software distribution etc.).