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
/__\/__\  #


Attachment: 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

Reply via email to