Although PGP may be nice, the unfortunate fact is that it doesn't just "hook in" nicely to most MUA (mail user agent) programs. There are hacks that make it acceptable for pine, but there's no nice easy way to hook it into Outlook, Netscape, etc. The track favored by the industrial giants is S/MIME, which is what Outlook and Netscape use. OpenSSL also includes the basic plumbing to do S/MIME stuff. I've recently gone through the trippy task of getting it all to work. Here's what I found.

Part of the whole procedure is to get an RSA keypair and a signed x509 certificate. The easiest and cheapest way to do this is with Thawte's FreeMail program.

Making a new X509 Thawte certificate

First, get and install the latest version of OpenSSL (if your OS doesn't already come with it). Next, you'll need to make a keypair:

% openssl genrsa -des3 -out keyfile 1024

This will make a key pair file. The private key will be encrypted with Triple DES. This means that anytime you do anything with the private key (like sign a message), you'll have to provide a passphrase (which you set at generation time). If you don't want to do this, then leave -des3 out, but just know that anyone who gets a copy of your key file can sign messages from you and read your encrypted mail.

Next, go sign up with Thawte's Freemail program and request a new certificate. At this point, go to the bottom of the form where it says "Developers of New Security Applications ONLY". Check the box that says "Paste in CSR Certificate Enrollment". Then click the button right below.

On the next screen there's probably nothing to do but hit "next>" when it asks about your name.

On the next screen there's probably nothing you should do but choose all of your e-mail addresses and hit "next>". Thawte advises that not all mail clients can handle having multiple e-mail addresses attached to a certificate, which means that if you send e-mail to someone using one of these clients, they may get a warning that the certificate doesn't match the message's From: line.

Same thing on the next screen.

On the next screen, accept the default extensions.

On the next screen, you'll see instructions telling you to make your certificate request, with a 16 character garbage string as the Common Name. At this point, you should go back to the shell window and do % openssl req -new -key keyfile

Answer all the questions that openssl asks, but be sure and paste in the 16 character garbage string Thawte gave you for the Common Name. Copy and paste the certificate request into the box on the Thawte form and hit "Next>".

Make sure everything looks ok on the last screen and hit "Finish".

A short time later, you should get an e-mail telling you your new certificate is done. Go to the page (link) in the e-mail and you'll get two large base64 encoded chunks of stuff. Take the second one (the PKCS encoded data) and save it to a file.

Carefully change the BEGIN and END lines to say simply BEGIN PKCS7 and END PKCS7 (leaving all of the dashes intact) instead of the longer string. Next, type

% openssl pkcs7 -print_certs -in file (where file is the name of the file with the PKCS7 stuff)

You should get out a bunch of certificates. You'll need to look at the text above each one to find the one that is your certificate. The rest are part of Thawte's Certifying Authority. It turns out that if you want your messages to verify correctly, you must also include Thawte's intermediate CA key.

There should be 3 certificates. The one whose identity is your e-mail address is your certificate. The one whose subject and issue are identical is the Thawte CA root. You won't need that one, since we'll include it in the trusted root file later. The 3rd one will have the CA root as the issuer and something else as the subject (which will be the same as the issuer of your certificate). You need to save that vertificate as an additional certificate for signing. We'll refer to the file containing this cert as othercert.

When you're done with all of that the pieces you need to keep are the key file you generated at the begining (remembering the passphrase, if you set one), the intermediate cert between the Thawte CA root and your cert, and the certificate chunk for your e-mail address you got out of the last step. You're now ready to use S/MIME!

Importing and exporting Netscape certs

Netscape uses the pkcs12 format. OpenSSL can import and export certificates and private keys so that you can use the same cert and key pair on all your mail clients.

To move a keypair and cert from OpenSSL to Netscape, you need to export it:

% openssl pkcs12 -export -inkey keyfile -certfile othercertfile -in certfile -out mycert.p12

This will ask you for a passphrase. This phrase locks the .p12 file. Netscape will ask this passphrase later. Open up Netscape and click on one of the padlocks to bring up the security manager. From the left side, select "Certificates / Yours", then click on "import". When asked, give it the .p12 file you made and the pass phrase. That should be it.

To go the other way, select a cert in the security manager and click on export. Give it a passphrase and save it to a .p12 file.

% openssl pkcs12 -in p12file -out tempfile

This will ask you for the pass phrase for the .p12 file, then it will ask you for a pass phrase to encrypt the private key. If you don't want the private key to be encrypted, add the -nodes flag.

In the resulting file, you'll find the complete certificate chain (your cert, any intermediate certs and finally the CA root cert) and the private key. You should throw away the CA root cert, save your cert into one file and any intermediate certs into another file, and the private key into a third.

I believe OpenSSL can also import and export certs compatible with Outlook, but have not tried it. I suspect that the -keyex and -keysig arguments might have to do with it.

Using openssl S/MIME

To send signed mail,

% openssl smime -sign -inkey keyfile -signer certfile -certfile othercertfile -in messagefile | sendmail recipient

To send encrypted mail,

% openssl smime -encrypt -in messagefile recipientcertfile | sendmail recipient

To send signed and encrypted mail you have to first sign, then encrypt:

% openssl smime -sign -inkey keyfile -signer certfile -certfile othercertfile -in messagefile | openssl smime -encrypt recipientcertfile | sendmail recipient

To decrypt encrypted mail sent to you, save it to a file, then:

% openssl smime -decrypt -in messagefile -inkey keyfile -recip certfile

To save the decryption to a file, you can add -out savefile

If someone sends you signed mail, you can extract their certificate so that you can send them encrypted mail. To do this, save their signed message and do:

% openssl smime -pk7out -in messagefile | openssl pkcs7 -print_certs

Verifying signed mail is a little trickier. First, you need a file with all of the trusted root certificates in it. The good folks who make the Apache mod_ssl module include a file in their distribution called 'ca-bundle.crt'. This file includes all of the trusted roots that come with Netscape's browser. I've put a copy of it here (note that it's renamed so as to not get a more convenient MIME type) for your downloading pleasure, but you should probably verify that it's correct if you're paranoid.

So, to verify a signed message:

% openssl smime -CAfile path/ca-bundle.crt -verify -in messagefile

NOTE I believe there is a bug that affects at least version 0.95a of OpenSSL (they may call it a feature. I'm not so sure). You must start the plaintext of a signed or encrypted message with a blank line. I suppose you're really supposed to start it with MIME headers or some such. Whatever. If you start it with a non-blank line that it doesn't like, the resulting message will not be properly signed.