The purpose of this guide is to show the configuration and usage of mutt with GnuPG. A working knowledge of mutt, gnupg,and concepts of mail security and encryption are assumed.
see Prerequisites, below, if you are not familiar with gpg.
gpg.rc
Find your gpg.rc
FC 21:
/usr/share/doc/mutt/gpg.rc
OpenBSD 5.4-Current:
/usr/local/share/examples/mutt/gpg.rc
Debian:
/usr/share/doc/mutt/examples/gpg.rc
Latest Mutt stable release:
https://gitlab.com/muttmua/mutt/blob/stable/contrib/gpg.rc
If you are using a distro package, be aware some of them install pgpewrap outside of $PATH and modify their version of gpg.rc to point directly to that location.
Copy it someplace sane
cp /usr/share/doc/mutt-1.5.21/gpg.rc ~/.gpg.rc or cp `locate gpg.rc` ~/.gpg.rc
cp /usr/share/doc/mutt-1.5.21/gpg.rc ~/.mutt/gpg.rc
Make mutt aware of it by adding 'source $FILE' to your .muttrc:
echo "source ~/.gpg.rc" >> ~/.muttrc
The pgp menu (p) option in the compose menu controls encryption and signing for a message.
GPG variables you'll probably want to define in your muttrc
You should set the following:
pgp_default_key
pgp_sign_as (only if you have a separate signing key)
pgp_use_gpg_agent (however see below)
Note that GPG 2.1 now include an auto-spawning agent, and so requires
pgp_use_gpg_agent
to be set. If you are using GPG 1.x without an agent
running you'll need to unset pgp_use_gpg_agent
. See
OpenPGP Configuration in the manual.
You may want to adjust the value of these, depending on your preferences:
crypt_autosign
crypt_opportunistic_encrypt
crypt_replysign
crypt_replysignencrypted
postpone_encrypt
See the manual for variable values or others variables.
Mailing your key using mutt
- Launch mutt and compose an email.
- After you're finished and you're in the compose menu hit the "?" key to see a list of all keybindings.
- Search for "attach a PGP public key".
- Exit the help menu and hit the key combination it lists for that option.
- It will then prompt you "Please enter the key ID:". Enter the keyid (email works) and you'll be prompted with a key selection menu.
- Pick your key (it must be in your keyring).
- Follow the escape prompt in the context-help menu at the top of the screen.
- Hit "send". You will then have emailed your gpg key using mutt.
Mutt UI Notes
The mutt UI idea while dealing with encrypted mails is to automatically decrypt an encrypted message when it is opened. In a similar way it will optionally verify the authenticity of a signed message (depending on the crypt_verify_sig variable) when it is opened.
The status flag defined in the $index_format variable for the index, will show a relevant flag for each signed/encrypted message. They are:
- s if the message is signed and not yet verified
- S if the message is signed and the signature is successfully verified
- P if the message is PGP encrypted
In order to be considered completely sure, all the parts of the message have to be signed. If this is not the case mutt won't consider the message completely sure, and the flag will stay "s": this happens for example when a signed message is processed by a mailing-list software and a trailing mailing-list signature is applied to it.
Publication of your public key
NOTE: This section is somewhat out of date. Please refer to Riseup's OpenPGP Best Practices for a better discussion of key generation, management, and keyservers.
There are different public keyservers, each one implementing one or more different access methods: HKP, WWW, FTP, mail, LDAP. An important thing to understand about keyservers is that they're synchronized, i.e. they tend to share the same public keys.
So in order to get published your public key in just one of these you only need to publicize it in just one keyserver, the key will eventually be propagated through all the keyservers.
Here it is a list of public keyservers (from the default gpg.conf file):
hkp://subkeys.pgp.net
hkp://wwwkeys.pgp.net
mailto:pgp-public-keys@keys.nl.pgp.net
ldap://pgp.surfnet.nl:11370
ldap://keyserver.pgp.com
Add it to a keyserver via http://sks-keyservers.net/i/ or other method. and the corresponding key will be published in the specified keyserver (and in all others). Now your public key is public, congratulations!
The publication on a public keyserver is not definitively the only method possible: there is the possibility to use a web page, to send it through ordinary mail or email, or via web. Note that all of these methods are subject to a man in the middle attack: the more the number of methods you'll use, the less are the chances that some very determined malicious individual will stole your identity. Note also that the shared publication of your public key highly decreases the possibility of your public key be compromised, since the attacker should compromise at the same time all the keyservers.
In case of web publication you can attach an header to your outgoing mail as this:
X-PGP-Key: http://example.com/pubkey.asc
in order to inform your recipient of the web address of your public key. The content of the page can be generated with:
gpg --export --armor
In mutt you can set this with the command:
my_hdr="X-PGP-Key: http://example.com/pubkey.asc"
Retrieval of keys from a keyserver
In order to verify or decrypt a message you need the public key of the sender.
Manually you can do this in this way:
gpg --recv-keys <names>
or even with:
gpg --search-keys <names>
and then selecting the number of the public key you want to add to your local keyring.
You might need to configure GnuPG to automatically do it for you every time a private key is not present in the local keyring.
This comes in very handy with Mutt, as you won't have to go and download and import a key manually in another terminal. In order to do this, add this line to your ~/.gnupg/gpg.conf file:
keyserver <keyserver address>
keyserver-options auto-key-retrieve
with the uri of your preferred keyserver. In this way every time a key is not present in your local keyring gnupg will try to fetch it from the keyserver specified in the gpg.conf file.
Verifying messages signatures
The %Z flag (status flag) in the $index_format tell you when a message is signed. If the message is signed (and it hasn't still been verified either it has a bad signature) a "s" character will appear in the corresponding line of the index, if the message signature has been verified then will appear a "S" character.
In order to verify a message you need the corresponding public key of the sender being in your keyring, or setup gpg to automatically retrieve a corresponding key from a public keyserver (remember to setup the auto-key-retrieve keyserver-option as explained in the previous section).
In order to verify a message mutt runs the $pgp_verify_command and check the exit of the command.
If $crypt_verify_sig is set to yes, mutt will run the pgp_verify_command on every opened message, and the output of this command will be displayed in the pager, before the message itself.
Verifying a message signature on the fly
You could be interested in verifying the signature of just a specific message. The following macros let you force the variable value of crypt_verify_sig to yes in order to get mutt verify the message, and then restore the previous value (you need mutt >= 1.5.12 with $my_variable support to get these macros working).
Please do not forget the "\" in the following macros code at the end of each line (or put all the text of each macro in one line).
macro index \Cv \
"<enter-command> set my_crypt_verify_sig=\$crypt_verify_sig<enter> \
<enter-command> set crypt_verify_sig=yes<enter> \
<display-message><enter-command> set crypt_verify_sig=\$my_crypt_verify_sig<enter>" \
'Verify PGP signature and open the message'
macro pager \Cv \
"<exit><enter-command> set my_crypt_verify_sig=\$crypt_verify_sig<enter> \
<enter-command> set crypt_verify_sig=yes<enter> \
<display-message><enter-command> set crypt_verify_sig=\$my_crypt_verify_sig<enter>" \
'Verify PGP signature'
Signing messages
$pgp_sign_as let you specify the uid to use when signing (since you can have different uids depending on the context). The corresponding public key will be extracted from your current keyring. You can set up some hook to customize the uid to use according to each particular situation.
You can automatically sign all outgoing messages setting
set crypt_autosign=yes
or simply selecting the pgp-menu (bound to "p") in the compose menu. You can use send-hook or folder-hook to setup the security criterion in a context dependent fashion.
Encrypting messages
To automatically encrypt messages to specific recipients use
send-hook . 'reset crypt_autoencrypt'
send-hook "!~l ~t onemail@example\\.org" "set crypt_autoencrypt crypt_autosign"
send-hook "!~l ~t another@example\\.org" "set crypt_autoencrypt crypt_autosign"
where the first global send-hook always resets crypt settings and a
following matching, if any, send-hook sets crypt for that recipient.
Note the double escaped backslash inside double quotes, "\\"
. The
!~l
pattern is to not activate encryption if the mail is also
addressed to a known mailing list.
A handy script to generate such hooks for each active UID of keys in a public keyring can be retrieved as http://erack.de/download/generate_pgp_auto
An alternative is to set the crypt_opportunistic_encrypt
variable. This will automatically enable encryption whenever all recipients are in your keyring.
Prerequisites
gpg & mutt
In order to become familiar with issues around gpg & mutt, please read one or both of these documents:
- http://www.gnupg.org/gph/en/manual.html
- Understanding of mail encryption and the web of trust
- Have both mutt and gnupg installed and working properly.
- A keyring with both public and private keys.
You can list all the keys in your gnupg keyring with:
gpg --list-keys
Typically the output consists of lines of the type:
pub 2048R/DEADBEEF 2010-05-01 [expired: 2012-04-30]
uid Alice Glass <alice@example.net>
pub 2048R/1234ABCD 2012-12-18 [expires: 2014-12-18]
uid Alice Glass <alice@example.net>
The key ID (identifier) is the sequence of hexadecimal digits which
comes after the "/", for example in these cases they are DEADBEEF
and
1234ABCD
. You should verify that your key is not expired.
To publicize your public key by sending it to a keyserver do this:
gpg --send-key <key id>
Before sending a key via email you need an "ascii armored" version:
gpg --armor --export YOURKEYID > username_pubkey.ascii