[Mailman-Developers] GSoC 2017 - Encrypted lists draft

Jan Jancar johny at neuromancer.sk
Mon Mar 13 13:26:23 EDT 2017


Hi Mailman developers.

My name is Jan Jancar and I study IT Security at the Masaryk university
in Brno, Czech republic. I'm interested in this years Mailman
GSoCproject, as encryption/security is a topic I'm familiar with and
interested in.

I'm currently working on an Elliptic Curve domain parameter generator
<https://neuromancer.sk/git/ecgen.git/about/>, as well as some other
crypto/security related projects, and my site <https://neuromancer.sk>
runs on Python.
I have started working on SMTPS/STARTTLS support for Mailman Core as my
GSoC micro-project and currently it's almost done:

https://gitlab.com/J08nY/mailman/commits/mta-smtps-starttls

Tests not yet done, as the SMTP test layer doesn't currently support
SMTPS, more changes to it will be required.

I've read through some past discussions on this list about PGP
integration, went through Mailman Core code and started writing a draft
of a project proposal (appended). An up to date version is also on:

https://neuromancer.sk/page/gsoc/mailman

I also have a question regarding project requirements:
  1) What priority does accommodating naive users (without PGP setup)
have for this project? As I haven't found a solution that wouldn't have
a significant security impact, other than: install gnupg and setup a
keypair.

Please let me know what you think about my proposal so far,
thanks!

Jan

#######################################################################

# Mailman - encrypted lists

## Threat model

### Assets

  - Message body
  - Message metadata (headers + existence)
  - Subscriber's identity (list of subscribers of a given list + their
public keys as described in this proposal)
    - Existence of subscription for a given address
    - Existence of subscription for a given key
  - Keyrings (and keypairs in them, as described in this proposal)

### Adversary

We assume that an adversary:

  - Can read, write, alter, drop any data passed between:
    - Mailman Core and it's outgoing and incoming MTA
    - outgoing and incoming MTA and lists subscribers
    - HyperKitty and Mailman Core (mailman-hyperkitty)
  - Is not a subscriber of the list / can not subscribe to the list, as
it it's moderated.
  - Can not gain access into a subscriber's mailbox as well as his
private part of a PGP key
  - Can not gain physical access to the machine running Mailman Core or
HyperKitty. (RAM access, Coldboot mitigation out of scope)
 - Can not get access to the machine running Mailman Core as the Mailman
core user or root
 - Can gain filesystem access to HyperKitty's archive

Optional assumptions, these can be somewhat protected against and thus
become real assumptions, see Attacks and Mitigations:

 - Can get filesystem access with enough permissions to access
(read/write) Mailman Core queues with Mailman offline
 - Can get filesystem access to keyrings described in this proposal

## Design

  - On top of PGP/MIME

### List

  - has a list keypair stored in *core keyring*
  - has a list archive keypair, which is stored in *archive keyring*
  - public key from lists archive keypair also stored in  *core keyring*

### User workflow

#### List key
  - User gains knowledge of lists public key:
    - Through Postorious
    - Sends mail to `list_id`-key at domain.tld, receives the lists public
key, signed by users that chose to publicly sign it. _TODO:_ not the
best solution, the problem of binding the list key to a list, and in
general key management, is key for this project (see what I did there? :)

#### Subscription
  - Public key a required argument on list subscription, confirmation
token sent encrypted with given key to subscribed address, signed
confirmation token required (binds users public key with email address
used for subscription)

#### List moderation
  - Subscription moderation required for an encrypted list, otherwise,
what's the point?

#### Commands
  - Required to be signed by user's private key, otherwise
discard/bounce (configurable)
  - New command for key management
     - `key`
        - `change` - would require signature with old key, also a new
key as an argument
        - `sign` - would require one argument, list's public key signed
with users private key, this list key with users signature will be
distributed as the list public key (if the signature is valid and from
the correct subscriber of the list). Users who do this have to
understand that their signature of the lists public key will be public,
thus their subscription will also be public. _TODO:_ It may be possible
to allow non-subscribers to sign the lists public key, thus subscibers
get some deniability of being a subscriber.

#### Posting
  - Based on list configuration, posting should be encrypted with list
pubkey and signed with users privkey

#### Unsubscription
  - Same as now, signature required as for other commands

### Technical details

  - Will use OpenPGP at a low-level(OpenPGP packet manipulation) to:
    - keep the original user's signature
    - re-encrypt the message to the list's recipients (in configurable
size batches)
    - re-encrypt in a way that strips key-ids (not to compromise privacy)
    - additionally sign with the list's private key (configurable)
    - currently most promising python lib ->
https://github.com/mitchellrj/python-pgp
    - All possible, see rfc4880
  - Considered SELS http://sels.ncsa.illinois.edu/ or similiar proxy
encryption scheme (see references), however:
    - In SELS the list server has no access to the message plaintext,
which is great for confidentiality but not for list
archiving/moderation/many Mailman features.
    - In SELS the list server generates the users private key or at
least has to have some information derived from subscribers private keys
to work.
    - In SELS, many tasks are offset from the list server to the list
manager, which actually enables the level of confidentiality the list
server has in that model, however seems very impractical.
    - General conclusion, SELS doesn't satisfy Mailman's needs for this
project idea

### What and where?

  - Mailman Core
    - *core keyring* - (gnupg keyring) contains list keypairs, and list
archive public keys
    - *users keyring* - (gnupg keyring) contains users public keys (for
all lists in a given Mailman instance)
    - rules in chain, will enforce list configuration such as:
        - discard/bounce non-encrypted
        - discard/bounce non-signed
    - handlers
        - to decrypt PGP/MIME message content
        - to strip additional header data leaks
        - to re-rencrypt and sign PGP/MIME message content for
subscribers, in batches
    - runners
        - possibly a new runner to send dummy messages to subscribers to
mitigate traffic analysis (anonymity is not a requirement here/nor a
goal, but message existence and list traffic pattern is data that can
not be "encrypted" yet can leak)
    - REST api
        - list key management
        - user key management
        - _TODO:_ this gives the BASIC AUTH required to access the REST
api pretty huge permissions, a more granular access control would be
beneficial
    - mta
        - SMTPS/STARTLS support
    - models/db
        - address <-> key fingerprint (to find key in *users keyring*)
        - list <-> list key fingerprint
        - list <-> list archive key fingerprint
    - commands
        - `key` command for key management
    - new module -> security
        - provides interface to manage the *core* and *users keyrings*
to rest of Mailman core

  - Mailman client
    - binding of
        - list key management REST api
        - user key management REST api

  - HyperKitty
    - *archive keyring* - (gnupg keyring) contains list archive keypairs
    - decrypts messages received from Mailman-HyperKitty using list
archive private keys

  - Mailman-HyperKitty
    - has access to the *core keyring* with list archive public keys,
uses them to encrypt before sending to HyperKitty

  - Postorius
    - list configuration
        - list key management (possibly too dangerous if not run behind
HTTPS, and even then), only accessible to list owners
    - list subscription
        - public key a required argument
    - user key management
        - _TODO:_ doesn't have the same level of security when done
through Postorious, with just mail + password, as when done through list
(signed), what do?

## Performance

  - Message encryption an obvious bottle-neck
  - Working with OpenPGP packets brings a speedup since the message
itself is encrypted only once for a batch, but many PKESK packets will
need to be created (this is unavoidable).
  - Current Mailman Core architecture with runners being separate
processes adapts to this nicely

## Attacks and mitigations

  - User -> MTA
     - sniffing, altering:
        - Messages encrypted with list pubkey
     - dropping:
        - No mitigation
     - writing:
        - List configured to require subscribers signature

  - MTA -> Mailman
     - sniffing, altering, dropping, writing:
        - same as above

  - Mailman -> MTA
     - sniffing, altering:
        - Messages encrypted with users public keys
     - dropping:
        - No mitigation
     - writing:
        - Messages signed with list private key (in addition to any
user's original signature)

  - MTA -> User
     - sniffing, altering:
        - Messages encrypted with users pubkey
     - dropping:
        - No mitigation
     - writing:
        - Messages signed with list private key (in addition to any
user's original signature)

  - Replay attacks
    - Since user signature is kept, when the list is set to discard
non-signed messages a replay attack without list subscribers noticing is
not possible (as the signature couldn't be stripped). The signature of
the original and replayed message would be the same, which would alert
the subscribers that the message was replayed.

  - list <-> list pubkey binding
      - _TODO:_ very important, have some ideas

  - filesystem access:
      - Mailman Core queues
          - Put Mailman queue_dir or possibly the whole var_dir into an
encrypted fs, mount on start (admin enters passphrase), unmount on quit
      - Mailman core keyring/HyperKitty archive keyring
          - Use a passphrase encrypted keyring, enter passphrase
manually on Mailman start, use gpg-agent. _TODO:_ gpg-agent doesn't have
infinite ttl support, try merge upstream?

## References

  - SELS: A Secure E-mail List Service - Khurana, Slagell, Bonilla:
https://pdfs.semanticscholar.org/fbc2/f88ccc19eaf864171554e52af66b31bb1e91.pdf
  - SELS slides - Khurana:
http://www.ncsa.illinois.edu/People/hkhurana/UIUCSecurity.pdf
  - From Proxy Encryption Primitives to a Deployable Secure-Mailing-List
Solution - Khurana, Heo, Pant:
http://www.ncsa.illinois.edu/People/hkhurana/ICICS.pdf
  - Multiplex Encryption: A Practical Approach to Encrypting
Multi-Recipient Emails - Wei, Ding, Chen:
http://www.mysmu.edu/faculty/xhding/publications/m-enc.pdf
  - On the Security of a Multi-party Certified Email Protocol - Zhou:
https://pdfs.semanticscholar.org/faa0/2c9e25afcee3e357a321ca323bfbeddefd9c.pdf)

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 862 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/mailman-developers/attachments/20170313/009e9f16/attachment.sig>


More information about the Mailman-Developers mailing list