% !TeX encoding = windows-1250
% !TeX spellcheck = sk_SK

\documentclass[a4paper,12pt]{article}
\usepackage[english]{babel}
\usepackage[cp1250]{inputenc}
\usepackage[IL2]{fontenc}
\usepackage{lmodern}

\usepackage[pdftex,unicode]{hyperref}
\hypersetup{pdftitle={Mailman: Encrypted lists},
	pdfauthor={Ján Jančár},
	pdfsubject={},
	pdfkeywords={Python Software Foundation, GNU Mailman, GSOC},
	pdfcreator={pdflatex},
	pdfproducer={}}

\usepackage{geometry}
\geometry{a4paper, top=1in, bottom=1.20in, left=1.20in, right=1.20in, headheight=15pt}


\pagestyle{plain}
\setlength{\parindent}{0pt}
\providecommand{\tightlist}{%
	\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}

\title{Mailman: Encrypted lists}
\author{\href{https://neuromancer.sk}{Ján Jančár}}

\begin{document}

\maketitle

\begin{abstract}
This proposal aims to design and implement support for encrypted mailing lists into GNU Mailman using PGP/MIME and GNUPG.
\end{abstract}

\section{General info}
\textbf{Sub-org:} GNU Mailman

\textbf{Name:} Ján Jančár

\textbf{Alternate names:} \href{https://github.com/J08nY}{J08nY}, johny

\textbf{Email:} \href{mailto:johny@neuromancer.sk}{johny@neuromancer.sk} or \href{mailto:jancar.jj@gmail.com}{jancar.jj@gmail.com}

\textbf{Telephone:} +421 948 133 762

\textbf{Time Zone:} UTC+1

\textbf{GSoC Blog:} \href{https://neuromancer.sk}{neuromancer.sk} or \href{https://neuromancer.sk/recent.atom}{RSS}

\textbf{Patches submitted (current work on Mailman):}
\begin{itemize}
	\tightlist
	\item
	\href{https://gitlab.com/mailman/mailman/merge_requests/253}{Mailman Core} - 253 -Made EmailCommands aware of their argument length, for administrivia
	\item
	\href{https://gitlab.com/J08nY/mailman/commits/mta-smtps-starttls}{Mailman Core} - - Add SMTPS/STARTTLS support to Mailman Core
\end{itemize}

\section{Project}
\textbf{Project title:} Mailman: Encrypted lists design + implementation

\textbf{Project abstract:} This proposal aims to design and implement support for encrypted mailing lists into GNU Mailman using PGP/MIME and GNUPG.

\subsection{Benefits}\label{benefits}

Email is generally sent unencrypted (apart from TLS/SSL). It can pass
through many potentially compromised or malicious servers. Users with
PGP can use it to encrypt one-to-one messages or even group messages,
provided they have a web-of-trust. However, encrypting mailing list
conversations this way, without the mailing list server support, would
be very tedious, if not impossible for most cases. This proposal adds
support for encrypted mailing lists to one of the most widely used
mailing list servers, GNU Mailman.

\subsection{Threat model}\label{threat-model}

\subsubsection{Assets}\label{assets}

\begin{itemize}
	\tightlist
	\item
	Message body
	\item
	Message metadata (headers + existence)
	\item
	Subscriber's identity (list of subscribers of a given list + their
	public keys as described in this proposal)
	
	\begin{itemize}
		\tightlist
		\item
		Existence of subscription for a given address
		\item
		Existence of subscription for a given key
	\end{itemize}
	\item
	Keyrings (and keypairs in them, as described in this proposal)
\end{itemize}

\subsubsection{Adversary}\label{adversary}

We assume that an adversary:

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

Optional assumptions, these can be somewhat protected against and thus
become real assumptions, see
\protect\hyperlink{attacks-and-mitigations}{Attacks and Mitigations}:

\begin{itemize}
	\tightlist
	\item
	Can get filesystem access with enough permissions to access
	(read/write) Mailman Core queues with Mailman offline
	\item
	Can get filesystem access to keyrings described in this proposal
\end{itemize}

\subsection{Design}\label{design}

\begin{itemize}
	\tightlist
	\item
	On top of PGP/MIME
	\item
	Uses GNUPG keyrings
\end{itemize}

\subsubsection{List}\label{list}

\begin{itemize}
	\tightlist
	\item
	has a list keypair stored in \textbf{core keyring}
	\item
	has a list archive keypair, which is stored in \textbf{archive
		keyring}
	\item
	public key from lists archive keypair also stored in \textbf{core
		keyring}
\end{itemize}

\subsubsection{User workflow}\label{user-workflow}

\paragraph{List key}\label{list-key}

\begin{itemize}
	\tightlist
	\item
	User gains knowledge of lists public key:
	
	\begin{itemize}
		\tightlist
		\item
		Through Postorious
		\item
		Sends mail to \texttt{list\_id}-key@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
		\emph{(see what I did there? :)}
	\end{itemize}
\end{itemize}

\paragraph{Subscription}\label{subscription}

\begin{itemize}
	\tightlist
	\item
	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)
	\item
	List owner has to have a way to verify that the public key presented
	as well as the address which subscription was requested is valid and
	that it is the correct pair (address, pubkey)
\end{itemize}

\paragraph{List moderation}\label{list-moderation}

\begin{itemize}
	\tightlist
	\item
	Subscription moderation required for an encrypted list, otherwise,
	what's the point?
\end{itemize}

\paragraph{Commands}\label{commands}

\begin{itemize}
	\tightlist
	\item
	Required to be signed by user's private key, otherwise discard/bounce
	(configurable), confirmation with a signed confirmation token required
	for every command, essentially all commands will need to have a
	workflow attached to them as \texttt{subscribe} has (to protect
	against replay attacks)
	\item
	New command for key management
	
	\begin{itemize}
		\tightlist
		\item
		\texttt{key}
		
		\begin{itemize}
			\tightlist
			\item
			\texttt{change} - would require signature with old key, also a new
			key as an argument
			\item
			\texttt{revoke} - would require a key revocation certificate, it
			would redo the challenge response confirmation to set the users
			key (essentially re-subscription)
			\item
			\texttt{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.
		\end{itemize}
	\end{itemize}
\end{itemize}

\paragraph{Posting}\label{posting}

\begin{itemize}
	\tightlist
	\item
	Based on list configuration, posting should be encrypted with list
	pubkey and signed with users privkey
\end{itemize}

\paragraph{Unsubscription}\label{unsubscription}

\begin{itemize}
	\tightlist
	\item
	Same as now, signature required as for other commands
\end{itemize}

\subsubsection{Technical details}\label{technical-details}

\begin{itemize}
	\tightlist
	\item
	Will use OpenPGP at a low-level (OpenPGP packet manipulation) to:
	
	\begin{itemize}
		\tightlist
		\item
		keep the original user's signature
		\item
		re-encrypt the message to the list's recipients (in configurable
		size batches)
		\item
		re-encrypt in a way that strips key-ids (not to compromise privacy)
		\item
		optionally strip the sender's signature
		\item
		additionally sign with the list's private key
		\item
		currently most promising python lib -\textgreater{}
		\href{https://github.com/mitchellrj/python-pgp}{py-pgp} \emph{(GPL
			v3)}
		\item
		All possible, see \href{https://tools.ietf.org/html/rfc4880}{RFC
			4880}
	\end{itemize}
	\item
	Considered \href{http://sels.ncsa.illinois.edu/}{SELS} or similiar
	proxy encryption scheme (see references), however:
	
	\begin{itemize}
		\tightlist
		\item
		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.
		\item
		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.
		\item
		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.
		\item
		General conclusion: SELS doesn't satisfy Mailman's needs for this
		project idea
	\end{itemize}
\end{itemize}

\subsubsection{What and where?}\label{what-and-where}

\begin{itemize}
	\tightlist
	\item
	Mailman Core
	
	\begin{itemize}
		\tightlist
		\item
		\textbf{core keyring} - (gnupg keyring) contains list keypairs, and
		list archive public keys
		\item
		\textbf{users keyring} - (gnupg keyring) contains users public keys
		\emph{(for all lists in a given Mailman instance)}
		\item
		rules in chain, will enforce list configuration such as:
		
		\begin{itemize}
			\tightlist
			\item
			discard/bounce non-encrypted
			\item
			discard/bounce non-signed
		\end{itemize}
		\item
		handlers
		
		\begin{itemize}
			\tightlist
			\item
			to strip additional header data leaks
			\item
			to strip the original signature (if configured for anonymous
			lists)
		\end{itemize}
		\item
		runners
		
		\begin{itemize}
			\tightlist
			\item
			incoming runner needs to decrypt the message if its PGP/MIME
			encrypted since rules generally require access to the plaintext
			body of the message and separate the signature into
			\texttt{msgdata}
			\item
			outgoing runner needs to attach the signature to the message, add
			lists signature and reencrypt for users
			\item
			possibly a new runner to send dummy messages to subscribers to
			mitigate traffic analysis
		\end{itemize}
		\item
		REST API
		
		\begin{itemize}
			\tightlist
			\item
			list key management
			\item
			user key management
			\item
			TODO: this gives the BASIC AUTH required to access the REST api
			pretty huge permissions, a more granular access control would be
			beneficial
		\end{itemize}
		\item
		mta
		
		\begin{itemize}
			\tightlist
			\item
			SMTPS/STARTLS support (Already started working on this, will be
			ready for a MR after writing tests {[}need to change up the
			SMTPLayer test layer a bit{]})
		\end{itemize}
		\item
		models/db
		
		\begin{itemize}
			\tightlist
			\item
			address \textless{}-\textgreater{} key fingerprint (to find key in
			\textbf{users keyring})
			\item
			list \textless{}-\textgreater{} list key fingerprint
			\item
			list \textless{}-\textgreater{} list archive key fingerprint
		\end{itemize}
		\item
		commands
		
		\begin{itemize}
			\tightlist
			\item
			\texttt{key} command for key management
		\end{itemize}
		\item
		new module -\textgreater{} security
		
		\begin{itemize}
			\tightlist
			\item
			provides interface to manage the \textbf{core} and \textbf{users
				keyrings} to rest of Mailman Core
		\end{itemize}
	\end{itemize}
	\item
	Mailman client
	
	\begin{itemize}
		\tightlist
		\item
		binding of
		
		\begin{itemize}
			\tightlist
			\item
			list key management REST API
			\item
			user key management REST API
		\end{itemize}
	\end{itemize}
	\item
	HyperKitty
	
	\begin{itemize}
		\tightlist
		\item
		\textbf{archive keyring} - (gnupg keyring) contains list archive
		keypairs
		\item
		decrypts messages received from Mailman-HyperKitty using list
		archive private keys
		\item
		provides API to get list archive public key from the \textbf{archive
			keyring}
		\item
		stores messages as received, encrypted by list archive key, decrypt
		when serving to subscribed users?
		\item
		docs
		
		\begin{itemize}
			\tightlist
			\item
			strongly advise running HyperKitty behind https
		\end{itemize}
	\end{itemize}
	\item
	Mailman-HyperKitty
	
	\begin{itemize}
		\tightlist
		\item
		has access to the \textbf{core keyring} with list archive public
		keys, uses them to encrypt before sending to HyperKitty
	\end{itemize}
	\item
	Postorius
	
	\begin{itemize}
		\tightlist
		\item
		list public key displayed
		\item
		list configuration
		
		\begin{itemize}
			\tightlist
			\item
			list key management (possibly too dangerous if not run behind
			HTTPS, and even then), only accessible to list owners
		\end{itemize}
		\item
		list subscription
		
		\begin{itemize}
			\tightlist
			\item
			public key a required argument
		\end{itemize}
		\item
		user key management / user account management
		
		\begin{itemize}
			\tightlist
			\item
			all of user's actions for an address that is subscribed to an
			encrypted list will generate a confirmation token/text that will
			need to be:
			
			\begin{itemize}
				\tightlist
				\item
				signed by subscriber's key and pasted into Postorious
				\item
				signed by subscriber's key and sent to
				\texttt{list-id}-request@domain.tld
			\end{itemize}
		\end{itemize}
		\item
		docs
		
		\begin{itemize}
			\tightlist
			\item
			strongly advise running Postorious behind https
		\end{itemize}
	\end{itemize}
\end{itemize}

\subsection{Performance}\label{performance}

\begin{itemize}
	\tightlist
	\item
	Message encryption an obvious bottle-neck
	\item
	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).
	\item
	Current Mailman Core architecture with runners being separate
	processes adapts to this nicely
\end{itemize}

\hypertarget{attacks-and-mitigations}{\subsection{Attacks and
		mitigations}\label{attacks-and-mitigations}}

\begin{itemize}
	\tightlist
	\item
	User -\textgreater{} MTA
	
	\begin{itemize}
		\tightlist
		\item
		sniffing:
		
		\begin{itemize}
			\tightlist
			\item
			Messages encrypted with list pubkey
		\end{itemize}
		\item
		dropping:
		
		\begin{itemize}
			\tightlist
			\item
			No mitigation
		\end{itemize}
		\item
		writing, altering:
		
		\begin{itemize}
			\tightlist
			\item
			List configured to require subscribers signature
		\end{itemize}
	\end{itemize}
	\item
	MTA -\textgreater{} Mailman
	
	\begin{itemize}
		\tightlist
		\item
		sniffing, altering, dropping, writing:
		
		\begin{itemize}
			\tightlist
			\item
			same as above
		\end{itemize}
	\end{itemize}
	\item
	Mailman -\textgreater{} MTA
	
	\begin{itemize}
		\tightlist
		\item
		sniffing:
		
		\begin{itemize}
			\tightlist
			\item
			Messages encrypted with users public keys
		\end{itemize}
		\item
		dropping:
		
		\begin{itemize}
			\tightlist
			\item
			No mitigation
		\end{itemize}
		\item
		writing, altering:
		
		\begin{itemize}
			\tightlist
			\item
			Messages signed with list private key (in addition to any user's
			original signature)
		\end{itemize}
	\end{itemize}
	\item
	MTA -\textgreater{} User
	
	\begin{itemize}
		\tightlist
		\item
		sniffing:
		
		\begin{itemize}
			\tightlist
			\item
			Messages encrypted with users pubkey
		\end{itemize}
		\item
		dropping:
		
		\begin{itemize}
			\tightlist
			\item
			No mitigation
		\end{itemize}
		\item
		writing, altering:
		
		\begin{itemize}
			\tightlist
			\item
			Messages signed with list private key (in addition to any user's
			original signature)
		\end{itemize}
	\end{itemize}
	\item
	Replay attacks
	
	\begin{itemize}
		\tightlist
		\item
		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.
	\end{itemize}
	\item
	list \textless{}-\textgreater{} list pubkey binding
	
	\begin{itemize}
		\tightlist
		\item
		list key signed with list owners key, from that users that trust the
		list owner might also sign it and hopefully reach nice web-of-trust
		coverage to verify the list key
		\item
		key also available on Postorious
		\item
		TODO: very important, have some ideas
	\end{itemize}
	\item
	filesystem access:
	
	\begin{itemize}
		\tightlist
		\item
		Mailman Core queues (Mailman offline)
		
		\begin{itemize}
			\tightlist
			\item
			Put Mailman \texttt{queue\_dir} or possibly the whole
			\texttt{var\_dir} into an encrypted fs, mount on start (admin
			enters passphrase), unmount on quit
		\end{itemize}
		\item
		Mailman core keyring/HyperKitty archive keyring
		
		\begin{itemize}
			\tightlist
			\item
			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?
		\end{itemize}
	\end{itemize}
\end{itemize}

\subsection{Deliverables}\label{deliverables}

\begin{itemize}
	\tightlist
	\item
	Mailman Core
	
	\begin{itemize}
		\tightlist
		\item
		Working encrypted lists implementation, that follows the design
		above
		\item
		Accepts PGP/MIME encrypted/signed incoming mail, does checks as
		specified by requirements and config
		\item
		Processes the message as usual
		\item
		Sends the message to HyperKitty encrypted
		\item
		Sends the message to users PGP/MIME encrypted + signed
		\item
		Provides REST API access to list and user key management
	\end{itemize}
	\item
	Postorious
	
	\begin{itemize}
		\tightlist
		\item
		Provides list and user key management features
		\item
		Commands confirmed by signing a confirmation token
	\end{itemize}
	\item
	HyperKitty
	
	\begin{itemize}
		\tightlist
		\item
		Provides API to get list archive public key
		\item
		Receives messages encrypted with list archive public key
		\item
		Stores them encrypted
	\end{itemize}
\end{itemize}

\subsubsection{Stretch/Optional}\label{stretchoptional}

\begin{itemize}
	\tightlist
	\item
	Mitigate the attacks with the stronger filesystem access assumptions
	by either creating docs on how to setup such a Mailman instance or add
	some mechanism so that Mailman does it itself.
\end{itemize}

\subsection{Timeline}\label{timeline}

\begin{itemize}
	\tightlist
	\item
	Before May 30
	
	\begin{itemize}
		\tightlist
		\item
		Setup full working dev env (I currently have everything except
		working Postfix server)
		\item
		Study Mailman sources, refine and collaborate on this proposal and
		design of encrypted lists, produce a more concrete design spec
		\item
		Finish implementing SMTPS/STARTLS support and merge to Mailman Core
	\end{itemize}
	\item
	May 30 - June 26/30
	
	\begin{itemize}
		\tightlist
		\item
		Implement security module, to abstract working with keyrings, make
		changes to models to reflect the existence of encrypted lists,
		potentially create an encrypted list style?
		\item
		Make Incoming runner decrypt a PGP/MIME encrypted message to an
		encrypted list
		\item
		Add rules to chain that enforce encrypted lists configuration
		(discard/bounce non-encrypted etc.)
		\item
		Modify commands to work with encrypted lists and require signed
		confirmation / additional arguments
		\item
		Make Outgoing runner sign and encrypt to users
	\end{itemize}
	\item
	June 26/30 - July 24/28
	
	\begin{itemize}
		\tightlist
		\item
		Expose list and user key management to the REST API
		\item
		Add bindings to the new API functions to mailman-client
		\item
		Add list and user key management to Postorious
	\end{itemize}
	\item
	July 24/28 - August 21/29
	
	\begin{itemize}
		\tightlist
		\item
		Add keyring handling to HyperKitty
		\item
		Expose list archive public key from HyperKitty's API
		\item
		Make mailman-hyperkitty collect the list archive public key, save it
		and use it to encrypt when sending to HyperKitty
	\end{itemize}
\end{itemize}

\subsection{References}\label{references}

\begin{itemize}
	\tightlist
	\item
	\href{https://pdfs.semanticscholar.org/fbc2/f88ccc19eaf864171554e52af66b31bb1e91.pdf}{SELS:
		A Secure E-mail List Service - {[}Khurana, Slagell, Bonilla{]}}
	\item
	\href{http://www.ncsa.illinois.edu/People/hkhurana/UIUCSecurity.pdf}{SELS
		slides - {[}Khurana{]}}
	\item
	\href{http://www.ncsa.illinois.edu/People/hkhurana/ICICS.pdf}{From
		Proxy Encryption Primitives to a Deployable Secure-Mailing-List
		Solution - {[}Khurana, Heo, Pant{]}}
	\item
	\href{http://www.mysmu.edu/faculty/xhding/publications/m-enc.pdf}{Multiplex
		Encryption: A Practical Approach to Encrypting Multi-Recipient Emails
		- {[}Wei, Ding, Chen{]}}
	\item
	\href{https://pdfs.semanticscholar.org/faa0/2c9e25afcee3e357a321ca323bfbeddefd9c.pdf}{On
		the Security of a Multi-party Certified Email Protocol - {[}Zhou{]}}
	\item
	\href{https://schleuder.nadir.org/}{Schleuder - A gpg-enabled
		mailinglist with remailing-capabilities.}
\end{itemize}

\subsubsection{Other commitments}
\begin{itemize}
	\item 
	Maybe a day or two at the beginning of June for some final exams that I might be unable to schedule before May 30th.
	\item
	3 days at the end of August (24th - 27th), will deliver final work product before August 24th with possibility of changes after the 27th.
\end{itemize}

\section{Additional info}
\textbf{Education:} 2nd year of Bachelor's in IT Security at Faculty of Informatics at Masaryk University in Brno, Czech republic.

\textbf{Related experience:} 
\begin{itemize}
	\item 
	Security research: I cracked and reverse-engineered the contactless-card public transport system in my home city (\href{https://neuromancer.sk/static/presentation.pdf}{slides}). 
	\item
	Python: Most of my Python projects are private, most notably my site runs on Flask.
	\item
	Crypto: I work with Elliptic Curve Cryptography, currently building an ECC tester for smart-cards \href{https://github.com/J08nY/ECTester}{ECTester} for my faculty's security lab \href{https://crcs.cz}{CRoCS}. I also develop an Ellitpic Curve Domain parameters generator  \href{https://github.com/J08nY/ecgen}{ecgen}.
\end{itemize}

\textbf{Site:} \url{https://neuromancer.sk}

\textbf{Personal git:} \url{https://neuromancer.sk/git/}

\textbf{Twitter:} \url{https://twitter.com/j08ny}

\textbf{Github:} \url{https://github.com/J08nY}

\textbf{Gitlab:} \url{https://gitlab.com/J08nY}

\textbf{Keybase:} \url{https://keybase.io/j08ny}

\section{Feedback}
Feedback to any of the mail addresses provided, or to \texttt{johny} in \#mailman on irc.freenode.org is appreciated.

\end{document}