33. pepsi-stage-encrypt

Ausgehende Mail als ihr Autor signieren und an jeden Empfänger verschlüsseln.

33.1. Rolle

pepsi-stage-encrypt ist die ausgehende Hälfte von Pepsis Ende-zu-Ende-Kryptographie. Für jede lokal eingelieferte Nachricht löst es auf, welcher Schutz verlangt wurde, wendet ihn an — Signieren mit dem Schlüssel des From:-Autors, dann Verschlüsseln an den des Empfängers — und routet jeden Empfänger weiter. Es betreibt keine Netzwerk-E/A: Ein Empfänger, dessen Schlüssel nicht zwischengespeichert ist, pausiert die Nachricht, und ein pepsi-keydisc-Dienst gibt sie frei. Referenz: pepsi-stage-encrypt(1).

Es schreibt dieselben zwei Standards, die pepsi-stage-decrypt liest — RFC 9580 mit den PGP/MIME-Containern von RFC 3156 für OpenPGP, und RFC 5652 CMS mit dem RFC-8551-Profil für S/MIME —, aber die schreibende Seite hat zwei Wahlmöglichkeiten, die die lesende nicht hat, und beide sind in der Konfiguration sichtbar:

  • In welchen Container verschlüsselt wird. Für OpenPGP ist das verhandelbar: Ein Zertifikat gibt an, welche SEIPD-Versionen sein Eigentümer lesen kann, sodass CRYPTO_ALLOW_DOWNGRADE = negotiate SEIPDv2 nach RFC 9580 (AEAD) an einen Korrespondenten ausgibt, dessen Schlüssel sagt, dass er es lesen kann, und SEIPDv1+MDC an einen, dessen Schlüssel sagt, dass er es nicht kann. Für S/MIME gibt es nichts zu verhandeln — ein X.509-Zertifikat kündigt keine Inhaltsverschlüsselungsfähigkeit an —, daher gibt der Code standardmäßig AuthEnvelopedData nach RFC 5083/5084 (AES-256-GCM) aus, und nur eine globale Einstellung stuft es auf AES-CBC nach RFC 3565 herab. Eine Paketinstallation setzt sie sehr wohl, in ${DATADIR}/config.d/thunderbird.conf, weil Thunderbird AuthEnvelopedData nicht lesen kann; diese Datei zu löschen stellt AEAD wieder her. Interoperabilität mit Clients hält fest, von welchen Clients bekannt ist, dass sie was lesen.

  • Welche Recipient-Info gebaut wird, was keine Wahl ist: Es folgt aus dem Schlüsseltyp im Zertifikat des Empfängers. RSA bekommt ein KeyTransRecipientInfo nach RFC 5652 §6.2.1 (RFC 4055 RSAES-OAEP, oder PKCS#1 v1.5, wo verlangt), ein EC-Zertifikat ein KeyAgreeRecipientInfo nach RFC 5753 mit dem Inhaltsschlüssel nach RFC 3394 verpackt.

Inline-OpenPGP (nicht MIME) wird nie geschrieben; alles Ausgegebene ist PGP/MIME.

Warnung

Setzen Sie diese Stage vor die DKIM-Signier-Stage. Die empfohlene ausgehende Kette ist submission → … → encrypt → srs → dkim-sign → relay. DKIM muss die tatsächlich übertragenen Bytes signieren; umgekehrt entsteht gültig aussehende Mail, deren Signatur nicht verifiziert, was schlimmer ist als gar keine Signatur. pepsi-setup warnt, wenn es die beiden in der falschen Reihenfolge vorfindet.

33.2. Funktionen

  • Der Signierende ist der Autor. Signiert wird mit dem Schlüssel der From:-Adresse, nie mit dem des Umschlagabsenders: Die Signatur handelt von dem Autor, den der Empfänger sieht. Ein Autor, den diese Installation nicht bedient oder für den sie kein Material hält, wird unsigniert gesendet, statt einen Bounce zu erzeugen — das ist immer noch legitime Mail, und DKIM trägt den Anspruch auf Domainebene bereits.

  • Ein Chiffrat je Empfänger. Jeder verschlüsselte Empfänger bekommt sein eigenes Chiffrat auf seinem eigenen Warteschlangendatensatz. Keine Offenlegung der Empfängerliste, kein geteilter Inhaltsschlüssel, und ein Bcc-Leck ist strukturell unmöglich. Wenn die Empfänger einer Nachricht auseinandergehen, teilt die Stage sie auf je einen Datensatz auf — state.dsn.rcpt im Gleichschritt zerteilt — und jeder Datensatz betritt diese Stage allein erneut. Empfänger, die alle ein Ergebnis teilen, werden nie aufgeteilt.

  • Protokoll je Empfänger. OpenPGP (PGP/MIME, RFC 3156) oder S/MIME (CMS, RFC 8551), gewählt durch PREFER, wenn ein Korrespondent beides hat. Ein Autor, der mit dem einen Protokoll signiert und an das andere verschlüsselt, signiert dennoch innerhalb des Chiffrats.

  • Containeraushandlung je Empfänger. Unter dem Standardwert CRYPTO_ALLOW_DOWNGRADE = negotiate fällt OpenPGP nur dann auf SEIPDv1+MDC zurück, wenn das eigene Zertifikat des Empfängers belegt, dass er AEAD nicht lesen kann — eine Tatsache über den Korrespondenten, protokolliert und festgehalten, nie stillschweigend.

  • Eine ausdrückliche Richtlinie für „kein Schlüssel“. ON_NO_KEY leitet sich aus ENCRYPT ab: opportunistic sendet gewöhnliche Mail, required nutzt das Secure-Link-Portal, wenn eines konfiguriert ist, und erzeugt sonst einen Bounce. required fällt nie auf Klartext zurück.

  • Anfrage-Header erreichen nie die Leitung. X-Pepsi-Sign und X-Pepsi-Encrypt (vom Outlook-Add-in gesetzt) werden aus jeder ausgehenden Nachricht entfernt, gleich was sie sagten, und werden gänzlich ignoriert, sofern die Nachricht nicht lokalen Ursprungs ist. Ein getroffenes Betreff-Schlüsselwort wird ebenfalls aus dem Subject entfernt.

  • Eine sichtbare Größenobergrenze. MAX_SIZE (Standardwert 25 MB) begrenzt, was verschlüsselt wird: Weder der CMS-Builder noch die OpenPGP-Pfade streamen, sodass die gesamte Nachricht je Empfänger einmal resident ist. Oberhalb der Grenze entscheidet ON_OVERSIZE.

  • Die pEp-Voreinstellung. ENABLE_PEP (Standardwert an) ist eine Voreinstellung von Standardwerten, kein erzwingender Modus: Sie lässt SIGN standardmäßig encrypted-only sein (nur signieren, was verschlüsselt wird, innerhalb des Chiffrats) und erzeugt für einen lokalen Absender an einer bedienten Domain bei seiner ersten Einlieferung einen OpenPGP-Schlüssel, wenn die Adresse keinerlei Identität hat und [pepsi-crypto] AUTO_CREATE_IDENTITY es erlaubt. Mit ENABLE_PEP = no wird ein Schlüssel nur erzeugt, wenn ein Verfasser ausdrücklich Schutz verlangt (eine Signatur oder nur Verschlüsselung) oder unter SIGN = always. Der besitzende Login des Schlüssels wird über die Lokalitätsoptionen von [pepsi-crypto] aufgelöst, wie bei pepsi-keys. Jede ausdrücklich ausgeschriebene Option hat weiterhin Vorrang.

  • Der eigene Schlüssel des Benutzers. Ein lokaler Absender, der für die From:-Adresse sprechen darf, kann den Schlüssel, den sein Mail-Client hält (aus dessen Autocrypt:-Header oder aus einem angehängten Schlüssel für den ersten Schlüssel der Adresse), als MUA-Schlüssel (custody = client) registrieren. Er wird zum öffentlichen Gesicht der Adresse: Lokale Post wird an ihn verschlüsselt, WKD liefert ihn aus, und Pepsi fügt dann keinen eigenen Autocrypt:-Header und keine eigene Schlüsseldatei hinzu.

  • Post, die der Client bereits geschützt hat, bleibt unangetastet. Eine Einlieferung, deren äußerste Schicht Chiffrat ist, wird nicht ein zweites Mal verschlüsselt, signiert oder mit einem Schlüssel versehen (state.crypto.out.client_protected); eine, die der Client signiert hat, kann noch verschlüsselt werden, erhält aber keine Signatur von Pepsi.

  • Der Schlüssel als Datei. ATTACH_KEYS_AS_FILES (Standardwert aus) hängt zusätzlich OpenPGP_0x<long key ID>.asc an – beim Verschlüsseln innerhalb des Chiffrats –, bis jeder Empfänger nachgewiesen hat, dass er den Schlüssel besitzt.

  • Schlüssel per E-Mail. Ist RESPONSE_STAGE gesetzt, ist eine Nachricht an KEYS_CONTROL_LOCAL_PART@<served domain> (Standardwert pepsi-keys@) ein Schlüsselbefehl (status, generate, register, publish, retire) und wird beantwortet statt weitergeleitet.

  • Sie kündigt den Schlüssel des Verfassers an. AUTOCRYPT (Standardwert an) fügt einen Autocrypt:-Header nach Autocrypt Level 1 hinzu, der den minimalen übertragbaren öffentlichen Schlüssel einer OpenPGP-Identität trägt, deren private Hälfte diese Installation noch hält — bei jeder lokal eingelieferten Nachricht, die sie festschreibt, das schlichte Klartext-Durchreichen eingeschlossen, denn ein Korrespondent muss den Schlüssel lernen, bevor es überhaupt etwas gibt, womit sich verschlüsseln ließe. Er wird nie über einen Header gesetzt, den das eigene MUA des Verfassers gesetzt hat, und auch nicht, wenn das öffentliche Gesicht ein MUA-Schlüssel ist, und prefer-encrypt=mutual wird nur beansprucht, wenn das konfigurierte ENCRYPT required ist. Auf dem verschlüsselnden Pfad kommt das Feld in den äußeren Header-Block.

  • Gossip ist Opt-in. AUTOCRYPT_GOSSIP (Standardwert aus) rendert zusätzlich je anderem Empfänger ein Autocrypt-Gossip:-Feld innerhalb des geschützten Teils, denn dies verteilt das Schlüsselmaterial Dritter an Korrespondenten weiter, die nie darum gebeten haben. Die Subjekte stammen allein aus den geparsten To:/Cc:-Headern, sodass ein Bcc-Empfänger niemals per Gossip zugetragen werden kann; nur OpenPGP; keine Entdeckung (eine nicht zwischengespeicherte Adresse wird ausgelassen, nie geparkt); und oberhalb von 50 sichtbaren Empfängern überhaupt keines. GOSSIP_MIN_TRUST ist seine eigene Untergrenze (Standardwert owner-confirmed), bewusst nicht von MIN_TRUST geerbt: Einen Schlüssel weiterzuveröffentlichen ist nicht dieselbe Handlung, wie einen zu verwenden.

33.3. Wo sie sitzt

submission → aliases → anti-spam → detect-language → encrypt → srs → dkim-sign → relay

Die beiden Nachbarn, die den Nachrichtentext lesen — die Pay-to-Send-Schranke und die Spracherkennung —, wollen Klartext, und sie bekommen ihn, weil die Verschlüsselung zuletzt kommt. ARC greift nicht: Es ist für Mail gedacht, die im Auftrag eines anderen weitergeleitet wird, und diese Stage berührt nur Mail, die Pepsi selbst erzeugt hat.

Eine Nachricht, die nicht lokalen Ursprungs ist, wird unberührt weitergeschaltet (mit entfernten X-Pepsi-*-Headern): Eine weitergeleitete Drittnachricht zu verschlüsseln würde die DKIM-Signatur und die ARC-Kette des Urhebers ungültig machen.

33.4. Konfiguration

[stage-<name>]: PROGRAM = pepsi-stage-encrypt, NEXT_STAGE (erforderlich) und BOUNCE_STAGE, dazu ENABLE_PEP, SIGN, ENCRYPT, ATTACH_KEYS_AS_FILES, KEYS_CONTROL_LOCAL_PART, RESPONSE_STAGE, PREFER, ON_NO_KEY, ON_OVERSIZE, MIN_TRUST, SUBJECT_KEYWORDS_SIGN / _ENCRYPT / _BOTH, STRIP_REQUEST_HEADERS, PROTECT_HEADERS, MAX_SIZE, AUTOCRYPT, AUTOCRYPT_GOSSIP, GOSSIP_MIN_TRUST, SECURE_LINK_STAGE, DISCOVERY und DISCOVERY_TIMEOUT. pepsi-setup verlangt ein BOUNCE_STAGE, sobald ON_NO_KEY/ON_OVERSIZE zu bounce auflösen, und prüft, dass SECURE_LINK_STAGE und RESPONSE_STAGE echte Stages benennen. Alle sind in pepsi.conf(5) dokumentiert.

Das sind Verhaltens-Optionen und je Adresse über die Tabelle pepsi.settings überschreibbar (für ausgehende Mail mit dem Umschlagabsender als Schlüssel). Die kryptographische Richtlinie — welche Algorithmen, ob ein herabgestufter Container ausgegeben werden darf, Mindestschlüssellängen — liegt in den CRYPTO_*-Optionen von [pepsi] und in [pepsi-crypto], ist ausschließlich Sache des Systemadministrators und ist bewusst weder aus pepsi.settings noch aus pepsi-stage-edit-settings erreichbar.

33.5. Privilegien

Installiert setuid pepsi-crypto, Modus 4750 pepsi-crypto:pepsi, und daher eigenständig statt in das vereinheitlichte pepsi-Binärprogramm eingefaltet.

Beide Hälften der Schlüsselverwahrungsgrenze richten sich nach dieser Identität: Die Datenbankrolle pepsi-crypto ist die einzige, der crypto_identity.private_wrapped gewährt ist, und die Peer-Authentifizierung von PostgreSQL richtet sich nach der effektiven uid; der Schlüsselverschlüsselungsschlüssel ist ein 0640-Fragment, das demselben Konto gehört. Ein setgid-Binärprogramm erreichte das Fragment und authentifizierte sich gegenüber der Datenbank dennoch als pepsi — der Rolle, der die Spalte verwehrt ist. Siehe Schlüsselverwaltung für das Verwahrungsmodell.

33.6. State

Schreibt state.crypto.out: ob die Nachricht signiert wurde, mit welcher Identität, und je Empfänger einen Eintrag mit outcome, protocol, fingerprint, key_source, trust, content_algorithm und downgraded, dazu key_attached und client_protected, wenn sie zutreffen. Setzt state.encrypted = true, wenn etwas verschlüsselt wurde — der Schlüssel, den pepsi-stage-auto-whitelist für seine signature_required-Spalte liest. Bei einem Richtlinien-Bounce schreibt es state.bounce mit dem erweiterten Status 5.7.0.

Jedes Klartextergebnis, das erreicht wird, während Verschlüsselung gewünscht war, wird auf WARN protokolliert: Ungeschützte Mail zu senden ist nie ein stillschweigendes Ereignis.

33.7. Siehe auch

pepsi-stage-decrypt (die eingehende Hälfte), pepsi-stage-secure-link (wohin der secure-link-Weg ohne Schlüssel führt), pepsi-stage-dkim-sign, pepsi-keys, pepsi-keydisc, Schlüsselverwaltung (Identitäten, Verwahrung und die Vertrauensleiter, auf der das MIN_TRUST dieser Stage auswählt), Das Secure-Link-Ausweichportal, Interoperabilität mit Clients (welche Clients gegen das gemessen wurden, was diese Stage ausgibt), RFC-Index, pepsi.conf(5), pepsi.state(7)