summaryrefslogtreecommitdiff log msg author committer range
path: root/original.tex
blob: 50caa76ab4da06d44ac25a0c6cc4c57e159c97b4 (plain)
 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910  % !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}