33. pepsi-stage-encrypt¶
Signer le courrier sortant au nom de son auteur, et le chiffrer pour chaque destinataire.
33.1. Rôle¶
pepsi-stage-encrypt est la moitié sortante de la cryptographie de bout en bout de Pepsi. Pour chaque message soumis localement, elle résout quelle protection a été demandée, l’applique — en signant avec la clé de l’auteur du From:, puis en chiffrant vers celle du destinataire — et achemine chaque destinataire plus loin. Elle ne fait aucune E/S réseau : un destinataire dont la clé n’est pas en cache met le message en pause, et un service pepsi-keydisc le libère. Référence : pepsi-stage-encrypt(1).
Elle écrit les deux mêmes normes que pepsi-stage-decrypt lit — la RFC 9580 avec les conteneurs PGP/MIME de la RFC 3156 pour OpenPGP, et le CMS de la RFC 5652 avec le profil de la RFC 8551 pour S/MIME — mais le côté écriture a deux choix que le côté lecture n’a pas, et tous deux sont visibles dans la configuration :
Vers quel conteneur chiffrer. Pour OpenPGP c’est négociable : un certificat déclare quelles versions de SEIPD son propriétaire sait lire, de sorte que
CRYPTO_ALLOW_DOWNGRADE = negotiateémet du SEIPDv2 RFC 9580 (AEAD) vers un correspondant dont la clé dit qu’il sait le lire, et du SEIPDv1+MDC vers un correspondant dont la clé dit le contraire. Pour S/MIME il n’y a rien à négocier — un certificat X.509 n’annonce aucune capacité de chiffrement de contenu — aussi le code émet-il par défaut de l”AuthEnvelopedDataRFC 5083/5084 (AES-256-GCM), et seul un réglage global le rabaisse à l’AES-CBC de la RFC 3565. Une installation par paquet le règle bel et bien, dans${DATADIR}/config.d/thunderbird.conf, parce que Thunderbird ne sait pas lire l”AuthEnvelopedData; supprimer ce fichier restaure l’AEAD. Interopérabilité des clients consigne quels clients sont connus pour lire quoi.Quelle recipient info construire, ce qui n’est pas un choix : cela découle du type de clé dans le certificat du destinataire. RSA reçoit un
KeyTransRecipientInfode la RFC 5652 §6.2.1 (RSAES-OAEP de la RFC 4055, ou PKCS#1 v1.5 là où c’est exigé), un certificat EC unKeyAgreeRecipientInfode la RFC 5753 avec la clé de contenu enveloppée selon la RFC 3394.
L’OpenPGP en ligne (non MIME) n’est jamais écrit ; tout ce qui est émis est du PGP/MIME.
Avertissement
Placez cette étape avant l’étape de signature DKIM. La chaîne sortante recommandée est submission → … → encrypt → srs → dkim-sign → relay. DKIM doit signer les octets réellement transmis ; dans l’autre sens on produit du courrier d’apparence valide dont la signature ne se vérifie pas, ce qui est pire que pas de signature du tout. pepsi-setup avertit lorsqu’il trouve les deux dans le mauvais ordre.
33.2. Fonctionnalités¶
Le signataire est l’auteur. La signature emploie la clé de l’adresse
From:, jamais celle de l’expéditeur d’enveloppe : la signature porte sur l’auteur que voit le destinataire. Un message dont l’auteur n’est pas servi par ce déploiement, ou pour lequel il ne détient aucun matériel, part non signé au lieu de rebondir — c’est du courrier légitime malgré tout, et DKIM porte déjà la revendication au niveau du domaine.Un texte chiffré par destinataire. Chaque destinataire chiffré obtient son propre texte chiffré sur sa propre ligne de file d’attente. Aucune divulgation de la liste des destinataires, aucune clé de contenu partagée, et une fuite de
Bccstructurellement impossible. Lorsque les destinataires d’un message divergent, l’étape les scinde à raison d’un par ligne —state.dsn.rcptdécoupé en parallèle — et chaque ligne réintègre seule cette étape. Les destinataires qui partagent tous une même issue ne sont jamais scindés.Protocole par destinataire. OpenPGP (PGP/MIME, RFC 3156) ou S/MIME (CMS, RFC 8551), choisi par
PREFERlorsqu’un correspondant dispose des deux. Un auteur qui signe avec un protocole et chiffre vers l’autre signe tout de même à l’intérieur du texte chiffré.Négociation de conteneur par destinataire. Sous la valeur par défaut
CRYPTO_ALLOW_DOWNGRADE = negotiate, OpenPGP ne retombe sur SEIPDv1+MDC que lorsque le certificat propre du destinataire prouve qu’il ne sait pas lire l’AEAD — un fait concernant le correspondant, journalisé et noté, jamais silencieux.Une politique explicite pour « pas de clé ».
ON_NO_KEYdécoule deENCRYPT:opportunisticenvoie du courrier ordinaire,requiredemploie le portail de lien sécurisé lorsqu’un tel portail est configuré, et fait rebondir le message sinon.requiredne se dégrade jamais en clair.Les en-têtes de demande n’atteignent jamais le fil.
X-Pepsi-SignetX-Pepsi-Encrypt(posés par le module complémentaire Outlook) sont retirés de chaque message sortant quoi qu’ils aient dit, et sont entièrement ignorés à moins que le message ne soit d’origine locale. Un mot-clé de sujet reconnu est retiré duSubjectégalement.Un plafond de taille visible.
MAX_SIZE(25 Mo par défaut) borne ce qui est chiffré : ni le constructeur CMS ni les chemins OpenPGP ne travaillent en flux, de sorte que le message entier est résident une fois par destinataire. Au-delà du plafond,ON_OVERSIZEdécide.Le préréglage pEp.
ENABLE_PEP(activé par défaut) est un préréglage de valeurs par défaut, et non un mode contraignant : il fait valoirSIGNpar défautencrypted-only(ne signer que ce qui est chiffré, à l’intérieur du texte chiffré) et crée une clé OpenPGP pour un expéditeur local d’un domaine servi à sa première soumission, lorsque l’adresse n’a aucune identité d’aucune sorte et que[pepsi-crypto] AUTO_CREATE_IDENTITYle permet. AvecENABLE_PEP = no, une clé n’est créée que lorsqu’un auteur demande explicitement une protection (une signature ou un chiffrement seul) ou sousSIGN = always. Le login propriétaire de la clé est résolu au moyen des options de localité de[pepsi-crypto], comme pourpepsi-keys. Toute option écrite explicitement l’emporte toujours.La propre clé de l’utilisateur. Un expéditeur local habilité à parler pour l’adresse
From:peut enregistrer la clé que détient son client de messagerie (à partir de son en-têteAutocrypt:, ou d’une clé jointe pour la première clé de l’adresse) comme clé MUA (custody = client). Elle devient la face publique de l’adresse : le courrier local est chiffré vers elle, WKD la sert, et Pepsi n’ajoute alors ni en-têteAutocrypt:ni fichier de clé qui lui soit propre.Le courrier que le client a déjà protégé est laissé tel quel. Une soumission dont la couche la plus externe est du texte chiffré n’est pas chiffrée, signée ni dotée d’une clé une seconde fois (
state.crypto.out.client_protected) ; une soumission que le client a signée peut encore être chiffrée, mais ne reçoit aucune signature de Pepsi.La clé sous forme de fichier.
ATTACH_KEYS_AS_FILES(désactivé par défaut) joint aussiOpenPGP_0x<long key ID>.asc– à l’intérieur du texte chiffré lors du chiffrement – jusqu’à ce que chaque destinataire ait prouvé qu’il détient la clé.Les clés par e-mail. Avec
RESPONSE_STAGEdéfini, un message adressé àKEYS_CONTROL_LOCAL_PART@<served domain>(par défautpepsi-keys@) est une commande de clé (status,generate,register,publish,retire) et reçoit une réponse au lieu d’être relayé.Elle annonce la clé de l’auteur.
AUTOCRYPT(par défaut activé) ajoute un en-têteAutocrypt:d’Autocrypt Level 1 portant la clé publique transférable minimale d’une identité OpenPGP dont ce déploiement détient encore la moitié privée — sur chaque message soumis localement qu’elle valide, y compris le passage en clair sans traitement, puisqu’un correspondant doit apprendre la clé avant qu’il n’y ait quoi que ce soit à chiffrer. Il n’est jamais ajouté par-dessus un en-tête posé par le MUA de l’auteur, ni lorsque la face publique est une clé MUA, etprefer-encrypt=mutualn’est revendiqué que lorsque leENCRYPTconfiguré vautrequired. Sur le chemin chiffrant, le champ va sur le bloc d’en-têtes extérieur.Le gossip est sur consentement explicite.
AUTOCRYPT_GOSSIP(par défaut désactivé) rend en outre un champAutocrypt-Gossip:par autre destinataire à l’intérieur de la partie protégée, car cela redistribue le matériel de clé de tiers à des correspondants qui ne l’ont jamais demandé. Les adresses des sujets proviennent uniquement desTo:/Cc:analysés, de sorte qu’un destinataire enBccne peut jamais être gossipé ; OpenPGP seulement ; aucune découverte (une adresse non mise en cache est abandonnée, jamais mise en attente) ; et aucun gossip du tout au-delà de 50 destinataires visibles.GOSSIP_MIN_TRUSTest son propre plancher (par défautowner-confirmed), délibérément non hérité deMIN_TRUST: republier une clé n’est pas le même acte que d’en utiliser une.
33.3. Où elle se situe¶
submission → aliases → anti-spam → detect-language → encrypt → srs → dkim-sign → relay
Les deux voisines qui lisent le corps du message — la barrière de péage à l’envoi et la détection de langue — veulent du texte clair, et elles l’obtiennent parce que le chiffrement vient en dernier. ARC ne s’applique pas : il vise le courrier relayé pour le compte d’autrui, et cette étape ne touche jamais que du courrier émis par Pepsi.
Un message qui n’est pas d’origine locale est avancé sans être touché (ses en-têtes X-Pepsi-* retirés) : chiffrer un message tiers relayé invaliderait la signature DKIM et la chaîne ARC de l’auteur.
33.4. Configuration¶
[stage-<name>] : PROGRAM = pepsi-stage-encrypt, NEXT_STAGE (requis) et BOUNCE_STAGE, plus 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 et DISCOVERY_TIMEOUT. pepsi-setup exige un BOUNCE_STAGE dès que ON_NO_KEY/ON_OVERSIZE se résolvent en bounce, et vérifie que SECURE_LINK_STAGE et RESPONSE_STAGE nomment des étapes réelles. Toutes sont documentées dans pepsi.conf(5).
Ce sont des options de comportement, redéfinissables par adresse via la table pepsi.settings (indexée, pour le courrier sortant, sur l’expéditeur d’enveloppe). La politique cryptographique — quels algorithmes, si un conteneur rétrogradé peut être émis, les tailles de clé minimales — réside dans les options CRYPTO_* de [pepsi] et dans [pepsi-crypto], relève du seul administrateur système, et est délibérément inatteignable depuis pepsi.settings ou depuis pepsi-stage-edit-settings.
33.5. Privilège¶
Installée setuid pepsi-crypto, mode 4750 pepsi-crypto:pepsi, et donc autonome plutôt que pliée dans le binaire pepsi unifié.
Les deux moitiés de la frontière de garde des clés reposent sur cette identité : le rôle de base de données pepsi-crypto est le seul à détenir le droit sur crypto_identity.private_wrapped, et l’authentification par pair de PostgreSQL se fonde sur l”uid effectif ; la clé de chiffrement de clés est un fragment 0640 appartenant au même compte. Un binaire setgid atteindrait le fragment et s’authentifierait tout de même auprès de la base en tant que pepsi — le rôle à qui la colonne est refusée. Voir Gestion des clés pour le modèle de garde.
33.6. État¶
Écrit state.crypto.out : si le message a été signé, par quelle identité, et une entrée par destinataire portant outcome, protocol, fingerprint, key_source, trust, content_algorithm et downgraded, plus key_attached et client_protected lorsqu’ils s’appliquent. Positionne state.encrypted = true lorsque quelque chose a été chiffré — la clé que pepsi-stage-auto-whitelist lit pour sa colonne signature_required. Sur un rebond de politique, elle écrit state.bounce avec un code d’état étendu 5.7.0.
Chaque issue en clair atteinte alors que le chiffrement était souhaité est journalisée en WARN : envoyer du courrier non protégé n’est jamais un événement silencieux.
33.7. Voir aussi¶
pepsi-stage-decrypt (la moitié entrante), pepsi-stage-secure-link (où mène la route secure-link en l’absence de clé), pepsi-stage-dkim-sign, pepsi-keys, pepsi-keydisc, Gestion des clés (identités, garde et échelle de confiance sur laquelle le MIN_TRUST de cette étape sélectionne), Le portail de repli par lien sécurisé, Interopérabilité des clients (quels clients ont été mesurés face à ce qu’émet cette étape), Index des RFC, pepsi.conf(5), pepsi.state(7)