Die Verschlüsselung von E-Mails war schon immer etwas unhandlich, weil sie dem E-Mailsystem als Erweiterung erst nach vielen Jahren hinzugefügt wurde und sie oft durch Zusatzprogramme umgesetzt wird. Bei Thunderbird war dies zum Beispiel die Erweiterung Enigmail, aber seit der Version 78 ist die Verschlüsselung in Thunderbird integriert.

Ein Problem ist, dass man oft gar nicht weiß, dass der andere einen PGP-Schlüssel anbietet und man muss beim Schreiben daran denken, die Verschlüsselung zu aktivieren. Ich selbst verwende Neomutt als E-Mailprogramm und hatte mir schon vor Jahren ein Programm geschrieben, das den Eingriffspunkt send-hook nutzt, um die Einstellung crypt_autoencrypt zu setzen. Das System hat auch recht zuverlässig (aber nicht immer) funktioniert.

Letztens habe ich Web Key Directory (WKD) für PGP-Schlüssel entdeckt, was wesentlich schneller geht als eine Abfrage eines PGP-Schlüsselservers. Mit gpg --locate-keys … lässt sich die Verfügbarkeit anhand des lokalen Speichers oder per WKD prüfen; andere Quellen kann man mit --auto-key-locate local,wkd,keyserver,… einstellen.

Daher war meine Idee, Emacs zu nutzen, um die Verfügbarkeit der Schlüssel zu prüfen, während ich den Text schreibe. Grob gesagt ist der Ablauf folgender: Beim Öffnen der E-Mail (message-mode-hook) in Emacs, um den Text zu verfassen, starte ich im Hintergrund die Abfrage der Schlüssel für die genannten Empfänger. Wenn beim Speichern (before-save-hook) die Abfrage für alle Schlüssel ein Ergebnis geliefert hat (Exitcode 0), wird das Feld Pgp: ES eingefügt. Dieser Eintrag sagt Neomutt, dass die E-Mail verschlüsselt und signiert werden soll.

(add-hook
 'message-mode-hook
 (lambda ()
   (setq-local
    gpg-key-locate
    (let ((addrs
           (delq
            nil
            (mapcar
             (lambda (el)
               (when (string-match "[^ <]+@[^ >]+" el) (match-string 0 el)))

             (nconc
              (split-string (or (message-field-value "To") "") ",\s*")
              (split-string (or (message-field-value "Cc") "") ",\s*")
              )))
           ))

      ;; Use to blacklist some addresses
      ;; (delete-if
      ;;  (lambda (el) (find el '("foo@example.org") :test #'string=))
      ;;  addrs)

      (when addrs
        (start-process-shell-command
         "gpg-key-locate"
         nil
         (concat
          "gpg --locate-keys "
          (mapconcat 'shell-quote-argument addrs " ")
          )))
      ))

   (add-hook
    'before-save-hook
    (lambda ()
      (when (and gpg-key-locate
                 (string= "exit" (process-status gpg-key-locate))
                 (= 0 (process-exit-status gpg-key-locate)))
        (save-excursion
          (message-goto-eoh)
          (insert "Pgp: ES\n")
          (setq gpg-key-locate nil)
          )
        ))
    t t)
   ))

Use Emacs to autoencrypt emails

Gpg offers the option to lookup a key in the local key storage or via Web Key Directory (WKD). The WKD lookup is pretty fast and could be done for every email. Hence, I'm using Emacs to do the lookup while I'm composing the message and if a key is available for all recipients, I add the header field Pgp: ES which tells neomutt to enable encryption.

I'm also using trust-model tofu+pgp in gpg.conf to use the Trust on first use model to ease key verification.