Hi all. This update goes with my latest blog post about finding a good PGP python library:
https://neuromancer.sk/article/7 (!the blog posts content is not equal to this post!) Along with that I also implemented list keypair generation in the mailman_pgp plugin. It is configurable (key type, key size) in the plugin config and currently produces keys such as this one: pub rsa4096/0x539FD576AA401697 2017-06-19 [SC] 5B810BA0660C2EBCF46B3354539FD576AA401697 uid [ unknown] Zzz <zzz-requ...@example.com> uid [ unknown] Zzz <z...@example.com> sub rsa4096/0x0AC655A0580B8CE6 2017-06-19 [E] This keypair generation is done via spawning another process on encrypted list creation. Since the process might take quite some time, it would create problems if, for example, the encrypted list was created by the REST runner which would then go off to create the keypair for a few seconds while requests keep timing out. I also implemented PGP/MIME and inline PGP utilities. They can check whether a message is signed/encrypted as per RFC1847+RFC3156 for the former, and per some custom strict rules for the latter(inline PGP). They can verify/decrypt both PGP/MIME and inline PGP messages. These use the PGPy library I found and blogged about. After reading through some more of the discussion on mailman-developers around GSoC 2013 OpenPGP integration, I've chosen to refine some of the handling of both signatures and encryption in the PGP plugin, to address some of the questions/concerns. Here I specify a high level overview of signature handling, i.e. what should happen, not how should it be implemented. Signature handling ================== Per-list configuration ---------------------- Option Default -------------------- ------- - unsigned_msg_action bounce - inline_pgp_action None (pass-through) - expired_sig_action bounce - revoked_sig_action bounce - duplicate_sig_action bounce - malformed_sig_action bounce - strip_original_sig False - sign_outgoing False Posting to ---------- # Assumes mailman_pgp already has a confirmed users public key. 1. User signs his message, either via PGP/MIME or inline PGP. 2. Sends to list posting address. 3. mailman_pgp - checks if the message is for a PGP enabled mailing list. If not, passed it directly to the default incoming runner. Else go-on. - checks if the message is signed or not. If unsigned, the `unsigned_msg_action` is taken. Else go-on. - checks if the message is inline PGP signed. If so, the `inline_pgp_action` is taken. Else go-on. - checks if the signature verifies with the users public key. If not, the `malformed_sig_action` is taken. Else go-on. - checks if the users public key that signed the message has been revoked or expired. If so the `revoked_sig_action` and `expired_sig_action` is taken, respectively. Else go-on. - looks up the signature hash and timestamp in the collection of all of them mailman_pgp ever saw. If it finds it, then the `duplicate_sig_action` is taken. Else go-on. ^^ I am not sure about this step ^^. It was proposed in the 2013 discussion, to avoid replay attacks on posting (replay attacks on commands are solved by requiring confirmation). 4. If it reached this step, with no actions being taken then the message is considered a good posting as far as mailman_pgp is concerned. - If it is inline signed, the signature ASCII-armor is moved from the message body and stored in `msgdata` and the cleartext of the message remains in the message body. - If it is MIME signed, the signature bodypart is "unwrapped" from the multipart/signed (as per RFC1847) with the signature ASCII-armor stored in `msgdata` and only the inner part of the first payload as the message body. 5. Continue message processing as any other list. Outgoing posts -------------- 1. If the list is configured to `strip_original_sig`, go-on. If not attach the signature from `msgdata` back to create a PGP/MIME signed message. (don't output inline PGP...) 2. If the list is configured to `sign_outgoing` add another signature packet from of the mailing lists private key signing the message body, to the signature ASCII-armor. 3. Send out. Questions / Discussion points ========= - Should mailman_pgp keep all the signature hashes and timestamps it received to stop replay attacks on posting? A replay attack on posting without it is trivial. - Should the users keys be per user or per address? From a PGP perspective per user makes more sense, as PGP keys have more user-ids, so a user just sets up his key once, and it covers addresses in all his user-ids. However per-address is more flexible, and the keypair must be confirmed per-address anyways. A subscription is also per-address(a user through a preferred address). - Aren't the options specified for signature handling too much? revoked and expired sig_action could be merged, maybe even malformed. - Should we "unwrap" the signed message, as I propose, before passing it to the rest of Mailman core? Cheers, -- Jan ______________________________________________________ /\ # PGP: 362056ADA8F2F4E421565EF87F4A448FE68F329D /__\ # https://neuromancer.sk /\ /\ # Eastern Seaboard Phishing Authority /__\/__\ #
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Mailman-Developers mailing list Mailman-Developers@python.org https://mail.python.org/mailman/listinfo/mailman-developers Mailman FAQ: http://wiki.list.org/x/AgA3 Searchable Archives: http://www.mail-archive.com/mailman-developers%40python.org/ Unsubscribe: https://mail.python.org/mailman/options/mailman-developers/archive%40jab.org Security Policy: http://wiki.list.org/x/QIA9