Holy 🔑: Mutt and S/MIME emails through the ages
As might be apparent from my blogging oeuvre, I like to cryptographically sign and encrypt emails to my friends and family. And while it’s true that I’ve set up a personal PKI so I can cheaply and easily manage my correspondents’ credentials for them, I also buy my own certificate every 3 years so that I can keep signing turned on, even for recipients who don’t have my root certificate installed.
With my strong and perhaps eccentric appreciation of email, I occasionally like to be able to go back and re-read messages from a while ago. This is quite straightforward to do in most of my applications, but my favourite client Mutt demands that you either:
-
Set a single value for
smime_default_key
, or; -
Keep
unset smime_decrypt_use_default_key
in your ~/.muttrc, and choose the right key each time you need to decrypt.
Neither of these is really satisfactory
smime_keys
is the programme that mutt uses to manage keys, and when a new key is added, it is placed in the directory specified under smime_certificates
in your ~/.muttrc
.
Provided that you keep the same certificate subject and certificate password, the naming convention used for each certificate can be exploited; each subsequent certificate is called something like a1b2c3.0, a1b2c3.1, a1b2c3.2 and so on.
I have written a bash script that assumes Mutt is configured to use your latest certificate by default, and if the associated key fails to decrypt your message, goes back through time and checks for matches with previous keys:
#!/bin/bash
password=$(cat - )
keybase=${2%.*}
extension=${2##*.}
certbase=${3%.*}
while : ; do
if [[ -f ${1} && -f ${keybase}.${extension} && -f ${certbase}.${extension} ]]; then
openssl smime -decrypt -passin pass:${password} -inform DER -in ${1} -inkey ${keybase}.${extension} -recip ${certbase}.${extension} 2>/dev/null
openssl_exit=$?
extension=$(expr ${extension} - 1)
else
openssl_exit=1
fi
[[ $openssl_exit -ne 0 && $extension -ge 0 ]] || break
done
if [[ $openssl_exit -ne 0 ]]; then
openssl smime -decrypt -passin pass:${password} -inform DER -in ${1} -inkey ${2} -recip ${3} 2>/dev/null
fi
If this file is called ~/bin/smime_decrypt.sh
, it can be referred to in your ~/.muttrc
with:
set smime_decrypt_command="~/bin/smime_decrypt.sh %f %k %c"
And that’s it! Simple, single-password entry for all of your keys through the ages.