[Mailman-Developers] OpenPGP Mailman integration discussion [was: Re: GSoc - Requirement from Mentor to complete the project]

Daniel Kahn Gillmor dkg at fifthhorseman.net
Thu May 23 20:26:46 CEST 2013


On 05/23/2013 12:06 PM, Abhilash Raj wrote:

> For the encrypted lists yes, the key will be marked as 'encryption
> capable'. The list owner has to upload the public-private keypair for
> the list.
> 
>> [dkg wrote:]
>> ***SIGNED_POSTS***
>>
>> Might there be a reason for the list to have a keypair associated
>> with it even for cleartext messages?  e.g. might the list send out
>> signed messages that users might want to verify?
> 
> Yes I think this would be a good point to include but we cannot make
> this a default option. We ask the list owner to upload the pub-private
> keypair for any new list that is created. If he does not want signing
> of messages he might not want to deal with keys at all?

sure, but if we introduce this as an option, then we need to make sure
that we've thought through all the consequences.  If the list has a key
for use with administrative requests (e.g. subscription, unsubscription,
etc) is that the same key that it would use for message signing?  or a
different key?  What are the advantages of each scheme?  Given that the
list administrative requests go to different e-mail addresses than the
regular posting, how would the User ID(s) look on a single key used for
both interfaces provided by the list?

Is implementing this option something that would be part of the first
phase of the work, or should it be part of a later phase?

>> Well, it could be a replay of an old message from 5 years ago from 
>> another list member.  Should it be sent to the list again?
> 
> It cannot be from another list member, before posting we check that
> the key that signed the message belongs to the sender( the address in
> the "From" header and key are same).

sure, but the From: header is forgeable, right?  so if Alice knows that
Bob was subscribed to list X in the past, and is subscribed to list Y
today, then she could dig up his old posts in list X, and forward them
(From: header intact!) directly to list Y.  Should list Y publish them?

> If someone tries to post his own
> 5yr old message then we should bounce back the message and ask him to
> resign the message before sending if incase he wants that old message
> posted. Sounds okay?

sounds like we agree that a message whose signature is 5 years old is
"too old" -- what about 1 year old?  1 month old? 1 week?  It sounds
like you're proposing a cutoff somewhere; where is the cutoff?  is this
something that would be adjustable by the list admin?  if so, what
should the default be?

(note also that this assumes that the clock on the server is aligned
with the clock used on the machine where the messages were signed; i
think this is OK, but maybe there's some scenario where it might cause
trouble?)

>> it could be a replay of a recent message, which would naturally use
>> the same signature.  But the headers could be modified.  For
>> example, the Message-ID isn't contained in the signature.
> 
> Is it feasible to check each message against previously posted
> messages? I mean let's say if the list is 5yrs old then can we check
> every incoming message against all those previous messages for
> matching signatures?

With the appropriate data structures, such a check isn't infeasible
(e.g. you could maintain a binary tree of the digests of all message
signatures; then if you have N messages in your archive, you have to do
log(N) digest comparisons when a new message comes it to be sure that it
isn't a replay of an old message.

Maybe the mailman devs can answer this question: does mailman already do
something like this to check against message-ids that have already been
delivered to prevent duplicate delivery?  this sounds like a similar
problem to me (just with stronger cryptographic verifiability in the
OpenPGP-signed case); if such a system already exists, maybe it could be
amended to address these issues in the same way.

> I think we cannot check if a user picks up his own 5yrs old message
> and sends it after changing the headers.

remember it's not just the user re-sending their own message -- it could
be *anyone* re-sending the old message.

Note also that the OpenPGP signature itself has a timestamp embedded in
it, which is not modifiable without invalidating the signature.  I think
you might be assuming that we're checking the date of the signature via
the (forgeable) Date: header on the message; i think it would make more
sense to use the OpenPGP signature timestamp.  What if the signature
timestamp and the Date: header differ by a few seconds?  what if they
differ by months?

>> What if the message signature has a date that precedes the key
>> expiry?
> 
> In this case I think we can keep a threshold for posting. If a message
> was signed within 2 days of key expiry then it could be allowed for
> posting. But then the key should have expired also 2-3 days before the
> message was received.

where does the 2 day cutoff come from?  i'm asking about a timeline like
this:

(if < means "is earlier than": X < Y < Z)

   X: message signature created (according to OpenPGP timestamp)
   Y: key expired
   Z: message received by mailman


SMTP delivery can take up to 4 days, depending on network and machine
failures.  but my point here is not to build in a fudge factor around
the actual expiration date (which is explicit and i think needs no fudge
factor), but rather to point out that the "is the message signature
expired" calculation has to do with several different timestamps and how
they relate to each other.

> My doubt is that how do we actually decide what is the best policy for
> us to follow? One person may agree to my point, other may not, third
> may have a different point and so on and so forth. So how do we decide
> upon one point? Voting?

This is a good question :)

I think you should propose a reasonable approach for handling all these
various corner cases, and where your approach has some arbitrary cutoffs
(e.g. messages with signatures older than K days will not be accepted
for delivery), you make the arbitrary cutoff tuneable by the list
administrator and choose a sensible default.

Then you solicit and accept patches from people who have a strong
argument that your implementation isn't aligned with a reasonable policy
they would like to pursue :)

>> What kind of messages look like D?  where do they come from?
>> (hint: examine the MIME structure of this message itself)
> 
> Are you referring to the quoted texts in this message? Those lines are
> written by me but the application/pgp-signature part only verifies
> that the new content is written by you. Also after mailman adds
> headers and footers each of your fresh posts will also look like D to
> each subscribers. Is this what you wanted me to see?

yep, mailman generates messages of this form from PGP/MIME-signed
messages.  That said, mailman's generated messages aren't usually sent
to mailman as input; maybe mailman shouldn't process these as signed
messages?

> I think can use this to filter email commands, the message of type D
> will not be accepted as a valid email command. About the regular posts
> considering quoted texts I think we have to allow the message of type D.

if we allow a message of type D, then Alice could simply find a recent
PGP/MIME-signed message from Bob (from somewhere else), wrap it in a
multipart/mixed part, append her own footer to it (part H) containing
arbitrary text, and send the message on to mailman, using a
trivially-forged From: Bob header.

If mailman is willing to replay that message (with alice's arbitrary H
intact) to all its subscribers, that seems like an easy way around the
"signed-messages-only" constraint, which seems like a failure.

So what are some other options?

 0) mailman could ignore all messages except those that are fully signed
(this is probably the easiest)

 1) mailman could strip off all outer layers until it finds an inner
part that is itself fully signed, and then process that part as though
it were the entire message

 2) ... other ideas?


>> And here you've lst me again.  the lists's secret key (LK_sec) is
>> by definition for use in asymmetric cryptographic schemes.  why are
>> you saying "using a symmetric key encryption algorithm" here?
> 
> Sorry for this part, actually I was of the opinion that list's secret
> key can be used in any other encryption also as a key, but guess I am
> wrong. What my intention was is to to move the message between the
> queues in encrypted format so as to prevent it from getting stored in
> the disk( in queue as pickles ) in clear text format. And I wanted to
> use symmetric algorithm as it is faster than asymmetric and needs only
> one key( no two like pub and private in asymmetric ) for encryption
> and decryption. The thing I did wrong was to assume we can use the
> private key( as it is already stored safely ) for encrypting.

you can use the public key for encrypting, and the secret key for
decrypting.  that still uses asymmetric encryption, though.  anyway,
this is probably a question for the larger-scope project, so we should
probably drop it for now to avoid distracting from the other matters at
hand.

>> This hand-waves around the difficult question: how do we know what
>> the user's pub-key is?
> 
> User uploads his pub-key when he signs up for any such list that
> forces encryption.

so anyone can sign up for the list with any key?  if the list is open
for arbitrary, unmoderated subscription, then what does it say about the
confidentiality of the list?  setting aside confidentiality (e.g. in the
***SIGNED_POSTS*** limited-scope), what does it say about the
restrictions the list is able to enforce if arbitrary keys can be signed
up?  If the list admin/moderator has to approve new subscriptions, are
they also approving the choice of keys as well?  if so, how do you
expect a list moderator to tell that the key in question is the right one?

What happens if a list member revokes their key, or lets it expire?  can
that member upload a new one?  how does the list know that this key
replacement is legitimate, and not being done by an adversary or an
impersonator?

>> Why would mailman *not* check the public keyservers?  why should
>> this be an option?
> 
> As a user I might not want to use the key I use everywhere to sign the
> message to a particular list? I guess a keyserver keeps only one key
> corresponding to one email id?

ah, this is not the case :)  keyservers can store an arbitrary number of
keys that are (or claim to be) associated with a single e-mail address.

OpenPGP keyservers are functionally agnostic -- they don't make any
claims themselves about which keys belong to which e-mail addresses (or
other forms of user ID).  they just publish all the keys, and expect
their clients to do the verification and certification path analysis
themselves, based on client-specific perspectives on whose
certifications are reliable and whose should be ignored.

>> Will that confirmation link be sent in the clear, or will it be 
>> encrypted to the user's public key?
> 
> Since here we are not dealing with encryption, we can send the link in
> clear-text message and then expect him to send a signed reply verify
> the key. Also the key might not be encryption enabled so we can't
> always encrypt using it.

does the signed reply need to be of a given form?  does it need to
contain a particular arbitrary string, like the confirmation (e.g. like
the string in
example-confirm+8d6e100d2d168ed0837d8d2b2e6e1db2b51b8877 at lists.example.org)?

how can we be sure that the confirmation verification is safe from
replay attacks (from the perspective of both the subscriber and the list
administrator)?

For example:

----------------------
Let's say Alice wants to sign Bob up to a list X that Bob would find
distasteful to be on.

Alice creates a phony mailman instance with a list Y that Bob *does*
want to subscribe to;  Bob tries to sign up for list Y, expecting a
challenge that he will sign and respond to.

When the request from Bob for List Y comes in, Alice spoofs a
subscription attempt "From: Bob" to list X, harvests list X's
(legitimate) challenge to Bob, and has List Y replay it to Bob as the
challenge for List Y.  Bob signs the challenge, returns it to list Y
(which is still operated secretly by Alice), and Alice in turn replays
Bob's signed response to list X.

List X administrators now believe that Bob has legitimately signed up.
They even have "cryptographic proof" of his intent to participate in List X!
----------------------

How can such a challenge/response system be designed to protect both Bob
and the List X operators from people like Alice?



One other question just occurred to me:  Once these features
(signed-messages-only) are implemented, hould existing
(non-OpenPGP-enabled) lists be able to be upgraded to use these new
features?  Or is this something that is decided at list creation time
and never changed?  If list upgrading is possible, what sort of work
needs to be done on an upgrade?  Should this be part of the first phase
of work?  Even if not, it's worth keeping the possibility of a list
upgrade in mind as you're designing the data structures and UI/UX
adjustments that you want to make.

> I am really thankful for your questions and suggestions. I tried to
> answer them with some thought. Please correct me if I am wrong.

Thanks, I really appreciate your engagement with these questions.  There
are a lot of finicky details to keep track of, and you're coming up to
speed fast on questions that most people haven't thought about at all.
Keep it up!


Regards,

	--dkg

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 1027 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/mailman-developers/attachments/20130523/1f204663/attachment-0001.pgp>


More information about the Mailman-Developers mailing list