PGP/GPG for VM in Emacs, v2.2.2 =============================== Per-Erik Martin, 2001-01-27, 2002-07-21, 2002-11-28, 2002-12-03, 2004-05-29, 2006-10-29. Content: Synopsis Usage Configuration Known issues Change history This Implements RFC 2015, "MIME Security with Pretty Good Privacy (PGP)", which is based on RFC 1847, "Security Multiparts for MIME: Multipart/Signed and Multipart/Encrypted". This has been tested with VM 6.90-7.19 in Emacs 19.34.1-21.2.1 with PGP 6.58 (international source distribution) and Gnu PG 1.0.7-1.2.4. All running on Solaris 7/8 (x86), Linux RedHat 7.3, SuSE 10, MacOS X. Synopsis: Constant: pgp-vm-version Configuation variables: pgp-tmp-directory pgp-program gpg-program PGP functions: pgp-vm-sign pgp-vm-verify-signature pgp-vm-encrypt pgp-vm-both-sign-and-encrypt pgp-vm-decrypt GnuGP functions: gpg-vm-sign gpg-vm-verify-signature gpg-vm-encrypt gpg-vm-both-sign-and-encrypt gpg-vm-decrypt gpg-vm-verify-cleartext gpg-verify-cleartext Usage: First, you need to set up PGP or Gnu PG (of course) and generate your keys as usual. (See the relevant documentation.) You may need to set the variable pgp-program/gpg-program to point to the pgp command line program. There are two versions of each command, prefixed "pgp" and "gpg" for PGP and GnuPG respectively. Below, we will use a "*" as a marker for the prefix. Note: It has been considered to let the decrypt and verify function automatically detect if it should use pgp or gpg, but it was deemed to be a little hairy and unreliable. It might be a change in the future, but for now you'll have to know how a message was encrypted or signed. If you don't, you can inspect the attachment in VM in clear-text using the D command. Signing and verifying a signature When you have composed your email (using M-x vm-mail) and want to sign it, do M-x *-vm-sign. This will prompt for your private key passphrase and sign the buffer. After this, you must of course not modify the signed content, or the signature will become invalid. Do M-x undo (or C-_ or C-x u) if you change your mind, or need to modify the message. To verify the signature on an incoming message, do M-x *-vm-verify-signature when the message is displayed in VM. The result will be displayed in a new buffer. Obviously, you'll need the sender's public key for this to succeed. (See the relevant documentation again.) For convenience, there is also a function for verifying inline GnuPG signatures ("clearsign"), gpg-vm-verify-cleartext, since some mailers insists on using this ugly, non-standard (and probably sometimes faulty) way of signing. See also the utility function gpg-verify-cleartext below. Encryption and decryption When you have composed your email (using M-x vm-mail) and want to encrypt it, do M-x *-vm-encrypt. Do M-x und (or C-_ or C-x u) if you change your mind, or need to modify the message. Do not attempt to modify the encrypted messages as this is likely to make future decryption impossible. A prefix argument will also sign the message (in the same step as the encryption; for PGP v2.x is required). This is also available as M-x *-vm-both-sign-and-encrypt. (Note: This is different from first signing and then encrypting. If you do it that way, PGP/GPG will be called twice.) Decryption is supported, but following full MIME decoding of the decrypted message is not yet completely implemented. (Normal, plain text, emails work fine, but some MIME messages, esp. multi-part, might be handled less gracefully.) To decrypt a message, do M-x *-vm-decrypt when the message is displayed in VM. This will prompt for your private key passphrase and display the decrypted contents in a new buffer. Information about the key is displayed in a second buffer. You are then prompted for whether the buffers should be kept or not. If the message was also signed, the signature is checked too. Utility function gpg-verify-cleartext will attempt to locate a clear text signed GnuPG message in the current buffer, and verify it. It searches first forwards from point, and then backwards. Gnu PG clear text messages are generated by the gpg --clearsign option and are wrapped by the strings "-----BEGIN PGP SIGNED MESSAGE-----", "-----BEGIN PGP SIGNATURE-----", and "-----END PGP SIGNATURE-----". Configuration: Variable: pgp-tmp-directory Default: "/tmp/" Description: The directory where incoming emails are saved temporarily while verifying a signature. Files are removed after verification, but you might want to make sure this is somewhere private anyway. Variable: pgp-program Default: "/usr/local/bin/pgp" Description: The command line PGP program. If it is not an explicit path, it must be found in the PATH of the caller. Variable: gpg-program Default: "/usr/local/bin/gpg" Description: The command line GPG program. If it is not an explicit path, it must be found in the PATH of the caller. Known issues: There are MTA's (mail transfer agents) that do horrible things to emails. For instance, there are some that think they should "fix" the multip-part boundaries in already correct emails by replacing some of the boundary tags, rendering the signed message useless. An example: This multipart message, originally containing of a plain text section and a binary attachment, and then signed, should look like this: |Content-Type: multipart/signed; boundary=EaciTGyczV; micalg=pgp-sha1; | protocol="application/pgp-signed" | |--EaciTGyczV |Content-Type: multipart/mixed; boundary="M4RxsWrlDE" |Content-Transfer-Encoding: 7bit | |--M4RxsWrlDE |Content-Type: text/plain; charset=us-ascii |Content-Description: message body text |Content-Transfer-Encoding: 7bit | |Blah, blah... | |--M4RxsWrlDE |Content-Type: application/octet-stream |Content-Disposition: attachment; filename="foo" |Content-Transfer-Encoding: base64 | |I2luY2x... |--M4RxsWrlDE-- | |--EaciTGyczV |Content-Type: application/pgp-signature | |-----BEGIN PGP SIGNATURE----- |Version: GnuPG v1.2.4 (Darwin) | |iD8D... |-----END PGP SIGNATURE----- | |--EaciTGyczV-- The faulty MTAs will replace the last two (toplevel) boundary tags with the the one of the original message (inner level), and then add an extra final toplevel tag, so the end becomes: |... |--M4RxsWrlDE-- | |--M4RxsWrlDE |Content-Type: application/pgp-signature | |-----BEGIN PGP SIGNATURE----- |Version: GnuPG v1.2.4 (Darwin) | |iD8D... |-----END PGP SIGNATURE----- | |--M4RxsWrlDE-- | |--EaciTGyczV-- I have no idea why any MTA would do this, but there it is. The message is corrupted. Change history: Changes in 2.2.2: Fixed bug in multipart boundary generation. Can't use the vm function since it resets the pseudo random number generator, which might make it generate the same boundary when signing already multiparted messages (when it's called twice within the same second). Instead we use our own function. Changes in 2.2.1: Fixed bug in finding header values with wrapped lines beginning witn space (and not TAB). Added defconst pgp-vm-version. Changes in 2.2: Added gpg-vm-verify-cleartext, gpg-verify-cleartext, and gpg-verify-region. Changes in 2.1: Fixed two bugs: - Now always finds the beginning and end of messages. - Removed the hard-wired buffer names, using the real ones instead.