86. Index des RFC¶
Pepsi vise à être un MTA conforme aux normes et une passerelle cryptographique de bout en bout conforme aux normes. Ce chapitre associe chaque RFC que Pepsi implémente (ou délibérément pas encore) à l”endroit du système où elle est réalisée, afin qu’un relecteur puisse passer d’une norme à son code et à sa configuration.
Le tableau récapitulatif liste d’un coup d’œil chaque RFC applicable ; les notes par RFC ci-dessous en donnent le détail. Les RFC planifiées mais pas encore implémentées sont regroupées sous RFC applicables pas encore implémentées.
Tout ce qui est indexé ici n’est pas une RFC. Le Web Key Directory OpenPGP est un Internet-Draft ; Autocrypt et le protocole de serveur de clés VKS sont des normes de fait ; NTLM est une Microsoft Open Specification ; XOAUTH2 n’a aucun organisme de spécification ; SRS et Maildir sont des schémas publiés qui n’ont jamais été soumis à l’IETF ; FIPS 186-4 est une publication du NIST. Chacun est ce que le monde déployé parle réellement. Ils sont listés après les RFC, en italique, avec leur statut nommé.
Implémenter une norme n’est pas la même chose qu’interopérer avec les clients qui prétendent l’implémenter. Interopérabilité des clients consigne lesquelles ont été mesurées face à de vrais logiciels, lesquelles sont des observations ponctuelles, et lesquelles n’ont jamais été exécutées.
« Implémenté dans » nomme le module ou le programme où la norme est réalisée, non chaque appelant. Là où une norme n’est que partiellement implémentée — le BINARYMIME de la RFC 3030 — la case le dit. Les normes que Pepsi n’implémente délibérément pas figurent sous RFC applicables pas encore implémentées avec la raison.
86.1. Tableau récapitulatif¶
RFC |
Titre (sujet) |
Implémenté dans |
|---|---|---|
RFC 1035 |
Noms de domaine — implémentation et spécification (DNS) |
Toutes les recherches DNS ; syntaxe de domaine/label dans |
RFC 1870 |
Extension de service SMTP pour la déclaration de taille de message ( |
Annoncée et appliquée par pepsi-ingress ; le client sortant honore la limite annoncée par le saut suivant, |
RFC 1918 |
Attribution d’adresses pour les internets privés |
Avec les RFC 6598 et 2544, les plages d’adresses qu’une récupération sortante refuse afin qu’une URL de découverte de clés ne puisse pas atteindre l’intérieur du déploiement (la protection SSRF de |
RFC 1951 |
Format de données compressées |
La borne appliquée à la décompression du matériel de clé OpenPGP — une bombe de compression est refusée plutôt que déployée ( |
RFC 1153 |
Format de message de résumé |
La forme simple (non MIME) du résumé, |
RFC 2033 |
Local Mail Transfer Protocol (LMTP) |
Remise locale vers un MDA (Dovecot), pepsi-stage-relay-to-lmtp |
RFC 2034 |
Extension de service SMTP pour le renvoi de codes d’erreur étendus |
|
RFC 2045 |
MIME, première partie : format des corps de message (codages de transfert) |
Rétrogradation de corps 8 bits→7 bits, |
RFC 2046 |
MIME deuxième partie : types de média ( |
Analyse de l’arbre MIME et validation des frontières, |
RFC 2047 |
MIME, troisième partie : extensions d’en-tête de message (mots encodés) |
Rétrogradation d’en-têtes UTF-8, |
RFC 2104 |
HMAC : hachage à clé pour l’authentification de messages |
Le MAC de l’expéditeur d’enveloppe SRS ( |
RFC 2195 |
Extension |
|
RFC 2231 |
Extensions de valeurs de paramètres MIME et de mots encodés |
Lu (continuations, valeurs étendues et jeux de caractères, §3–§4.1) par |
RFC 2392 |
Localisateurs uniformes de ressources Content-ID et Message-ID |
La référence |
RFC 2831 |
Utilisation de l’authentification digest comme mécanisme SASL ( |
|
RFC 2920 |
Extension de service SMTP pour le pipelinage des commandes |
|
RFC 2986 |
PKCS #10 : syntaxe des demandes de certification |
Demandes de signature de certificat pour des certificats S/MIME délivrés à l’extérieur, |
RFC 3030 |
Extensions de service SMTP pour les messages volumineux et binaires ( |
pepsi-ingress ( |
RFC 3156 |
Sécurité MIME avec OpenPGP (PGP/MIME) |
Conteneurs |
RFC 3207 |
Extension de service SMTP pour SMTP sécurisé via TLS ( |
Listeners de pepsi-ingress ; client SMTP sortant |
RFC 3339 |
Date et heure sur Internet : horodatages |
Horodatages de génération des rapports, |
RFC 3370 |
Algorithmes de la Cryptographic Message Syntax (CMS) |
Identifiants d’algorithmes de condensat et de signature S/MIME, |
RFC 3394 |
Algorithme d’enveloppement de clé de l’Advanced Encryption Standard (AES) |
L’enveloppement de la clé de chiffrement de contenu dans un |
RFC 2369 |
L’usage des URL comme métasyntaxe des commandes principales de listes de diffusion |
Les en-têtes |
RFC 3461 |
Extension de service SMTP pour les notifications d’état de remise ( |
|
RFC 3463 |
Codes d’état étendus du système de messagerie |
Codes d’état DSN, |
RFC 3464 |
Un format de message extensible pour les notifications d’état de remise |
Génération de |
RFC 3492 |
Punycode |
Encodage IDNA des étiquettes pour les domaines internationalisés, |
RFC 3565 |
Usage du chiffrement AES dans CMS |
|
RFC 3676 |
Le type de média text/plain format=flowed |
Extraction du texte du corps et coupure de signature |
RFC 3834 |
Recommandations pour les réponses automatiques au courrier électronique |
L’ensemble de règles partagé « ne pas répondre automatiquement à ceci », |
RFC 3848 |
Types de transmission ESMTP et LMTP (clause |
En-tête |
RFC 3864 |
Procédures d’enregistrement des champs d’en-tête de message |
La procédure sous laquelle les deux champs d’en-tête privés de Pepsi (Extensions du protocole SMTP) ne sont pas enregistrés ; les deux sont non enregistrés à dessein |
RFC 4013 |
SASLprep : profil stringprep pour les noms d’utilisateur et les mots de passe |
Préparation nom d’utilisateur/mot de passe SCRAM, |
RFC 4055 |
Algorithmes et identifiants supplémentaires pour RSA dans PKIX |
Encodage des paramètres RSAES-OAEP et RSASSA-PSS, |
RFC 4121 |
Le mécanisme GSS-API de Kerberos 5, v2 |
|
RFC 4155 |
Le type de média application/mbox |
Lecture de boîtes aux lettres |
RFC 4422 |
Simple Authentication and Security Layer (SASL) — mécanisme |
|
RFC 4511 |
LDAP : le protocole |
Découverte de clés par LDAP, le module |
RFC 4514 |
LDAP : représentation textuelle des noms distinctifs |
Rendu des DN de sujet et d’émetteur des certificats, |
RFC 4515 |
LDAP : représentation textuelle des filtres de recherche |
Échappement des filtres pour la requête de découverte LDAP — la protection contre l’injection, |
RFC 4616 |
Le mécanisme SASL |
|
RFC 4648 |
Les codages de données Base16, Base32 et Base64 |
Encodage du hachage SRS ( |
RFC 4752 |
Le mécanisme SASL Kerberos V5 ( |
|
RFC 4954 |
Extension de service SMTP pour l’authentification ( |
|
RFC 5083 |
Le type de contenu CMS |
Le conteneur de chiffrement S/MIME par défaut (AES-256-GCM), |
RFC 5084 |
Usage d’AES-CCM et d’AES-GCM dans CMS |
|
RFC 5064 |
Le champ d’en-tête de message Archived-At |
L’URL d’archives par message qu’un message de liste porte, ajoutée par |
RFC 5228 |
Sieve : un langage de filtrage du courrier |
Exécuté par le MDA (Dovecot) lors de la remise LMTP ; Pepsi n’implémente lui-même aucun Sieve |
RFC 5280 |
Profil des certificats et CRL de l’ICP X.509 pour Internet |
Analyse des certificats, traitement des extensions et validation de chemin — contraintes de noms et de politiques comprises, avec une conformité testée contre NIST PKITS — |
RFC 5321 |
Simple Mail Transfer Protocol |
Cœur de l’ingress et des deux étapes de relais ; gestion d’enveloppe, MX, expéditeur nul |
RFC 5322 |
Internet Message Format |
Modèle en-tête/corps ( |
RFC 5480 |
Subject Public Key Information pour la cryptographie à courbes elliptiques |
Encodage des clés publiques EC dans les certificats, |
RFC 5652 |
Cryptographic Message Syntax (CMS) |
|
RFC 5753 |
Usage des algorithmes ECC dans CMS |
|
RFC 5758 |
Algorithmes et identifiants supplémentaires pour DSA et ECDSA dans PKIX |
Identifiants de signature |
RFC 5802 |
Salted Challenge Response Authentication Mechanism ( |
|
RFC 5890 |
Noms de domaine internationalisés pour les applications (IDNA2008) : définitions |
Traitement des domaines partout, via le crate |
RFC 5915 |
Structure des clés privées à courbes elliptiques |
Encodage des clés privées EC, |
RFC 5929 |
Liaisons de canal pour TLS ( |
Liaison de canal SCRAM |
RFC 5937 |
Utilisation des contraintes d’ancre de confiance lors du traitement du chemin de certification |
Les |
RFC 5958 |
Paquets de clés asymétriques (PKCS #8) |
Encodage des clés privées au repos, |
RFC 6125 |
Identité de service dans TLS (vérification du nom de certificat) |
Validation de certificat MTA-STS, |
RFC 6152 |
Extension de service SMTP pour le transport MIME 8 bits ( |
Annoncé par l’ingress ; ré-annonce/rétrogradation par saut dans les étapes de relais |
RFC 6265 |
Mécanisme de gestion d’état HTTP (cookies) |
Le cookie de session d’administration et celui du portail à lien sécurisé, tous deux préfixés par |
RFC 6331 |
Passage de |
La raison pour laquelle |
RFC 6376 |
Signatures DomainKeys Identified Mail (DKIM) |
Vérification (ingress) et signature ( |
RFC 6409 |
Soumission de messages pour le courrier |
Listeners de soumission ( |
RFC 6531 |
Extension SMTP pour le courrier internationalisé ( |
Annoncé par l’ingress ; ré-annonce/rétrogradation par saut dans les étapes de relais |
RFC 6598 |
Préfixe IPv4 réservé par l’IANA pour l’espace d’adressage partagé |
Partie de la protection d’adresses pour les récupérations sortantes ; voir la RFC 1918 |
RFC 6648 |
Abandon du préfixe |
Pourquoi |
RFC 6698 |
Authentification d’entités nommées fondée sur le DNS (DANE) : TLSA |
Types d’enregistrement |
RFC 6749 |
Le cadre d’autorisation OAuth 2.0 |
Obtention et renouvellement des jetons de smarthost, |
RFC 6750 |
Le cadre d’autorisation OAuth 2.0 : usage des jetons porteurs |
La forme |
RFC 6761 |
Noms de domaine à usage spécial |
|
RFC 6840 |
Clarifications et notes d’implémentation pour DNSSEC |
Le bit |
RFC 6891 |
Mécanismes d’extension pour le DNS (EDNS(0)) |
Taille de charge utile UDP des requêtes sortantes, |
RFC 6979 |
Usage déterministe de DSA et d’ECDSA |
Génération du nonce pour les signatures ECDSA, |
RFC 7208 |
Sender Policy Framework (SPF) pour autoriser l’usage des domaines |
Vérification SPF entrante (ingress, via |
RFC 7235 |
HTTP/1.1 : authentification |
Le schéma |
RFC 7489 |
Domain-based Message Authentication, Reporting, and Conformance (DMARC) |
Évaluation DMARC entrante et application facultative (ingress) |
RFC 7505 |
Un enregistrement de ressource « Null MX » d’absence de service |
Classification MX, |
RFC 7595 |
Lignes directrices et procédures d’enregistrement des schémas d’URI |
La procédure sous laquelle le schéma |
RFC 7628 |
Un ensemble de mécanismes SASL pour OAuth ( |
|
RFC 7672 |
Sécurité SMTP via DANE TLS opportuniste ( |
|
RFC 7677 |
Mécanismes SASL |
|
RFC 7748 |
Courbes elliptiques pour la sécurité (X25519) |
Accord de clé Curve25519 dans OpenPGP et TLS |
RFC 7929 |
Authentification d’entités nommées fondée sur le DNS (DANE) : liaisons pour OpenPGP |
Enregistrements |
RFC 8017 |
PKCS #1 v2.2 : spécification de la cryptographie RSA |
Primitives de signature et de transport de clé RSA (via le crate |
RFC 8018 |
PKCS #5 : cryptographie fondée sur mot de passe (PBKDF2) |
Dérivation du mot de passe salé |
RFC 8162 |
Usage du DNS sécurisé pour associer des certificats à des noms de domaine pour S/MIME |
Enregistrements |
RFC 8187 |
Indication du codage des caractères et de la langue pour les paramètres de champs d’en-tête HTTP (rend obsolète la RFC 5987) |
Le paramètre |
RFC 8314 |
Le texte clair considéré comme obsolète : usage de TLS pour la soumission et l’accès |
Listener de soumission en TLS implicite ( |
RFC 8446 |
Le protocole Transport Layer Security (TLS) version 1.3 |
Chaque listener et client TLS, via |
RFC 8058 |
Signalement de la fonction en un clic pour les en-têtes de courrier de liste |
|
RFC 8460 |
SMTP TLS Reporting (TLSRPT) |
Enregistrement de session TLS sortante (étapes de relais) + rapports quotidiens ( |
RFC 8461 |
SMTP MTA Strict Transport Security (MTA-STS) |
Application de la politique ( |
RFC 8463 |
Une nouvelle méthode de signature cryptographique pour DKIM (Ed25519) |
Clés/signatures DKIM Ed25519, |
RFC 8550 |
Traitement des certificats S/MIME 4.0 |
Construction de chemin, EKU |
RFC 8551 |
Spécification des messages S/MIME 4.0 |
|
RFC 8601 |
Champ d’en-tête de message indiquant l’état d’authentification du message |
|
RFC 8617 |
Le protocole Authenticated Received Chain (ARC) |
Vérification/signature/scellement ARC, pepsi-stage-arc |
RFC 8905 |
Le schéma d’URI |
Cibles de virement dans la réponse du libre-service de wallet, |
RFC 8959 |
Le schéma d’URI |
La forme du jeton d’accès marchand, |
RFC 9051 |
Internet Message Access Protocol (IMAP) version 4rev2 |
Balayage de boîte aux lettres en lecture seule pour l’import de liste blanche ( |
RFC 9106 |
Argon2, fonction à coût mémoire pour le hachage de mots de passe et la preuve de travail |
La clé de contenu du lien sécurisé dérivée du code PIN du destinataire ( |
RFC 9110 |
Sémantique HTTP |
Traitement des requêtes et des réponses dans pepsi-httpd |
RFC 9112 |
HTTP/1.1 |
Le protocole sur le fil servi par pepsi-httpd, via |
RFC 9580 |
OpenPGP (la « crypto refresh » ; successeur de la RFC 4880) |
|
RFC 9989 |
Domain-based Message Authentication, Reporting, and Conformance (DMARCbis) |
Le parcours de l’arbre DNS (découverte de la politique et domaine organisationnel pour l’alignement relâché) derrière l’évaluation DMARC de l’ingress, effectué par le |
Autocrypt Level 1 |
L’en-tête d’annonce de clé |
Moissonné dans le courrier entrant par |
FIPS 186-4 |
Digital Signature Standard (une publication du NIST) |
La règle de troncature |
draft-ietf-mailmaint-autoconfig |
Autoconfiguration des comptes de courrier (un Internet-Draft du groupe de travail IETF |
Le document |
MS-NLMP |
Le protocole d’authentification NT LAN Manager (une Microsoft Open Specification, non une RFC) |
|
Maildir |
Le format de boîte aux lettres de D. J. Bernstein (une spécification, non une RFC — |
pepsi-stage-relay-to-maildir via le helper setuid ; récursion Maildir++ lors du balayage pour l’import de liste blanche |
SRS |
Le Sender Rewriting Scheme (un schéma publié sans RFC ; le format d’adresse d’enveloppe |
|
VKS ( |
Le protocole HTTP |
Consultation par |
XOAUTH2 |
Le mécanisme SASL à jeton porteur préalable aux normes de Google et de Microsoft (aucun organisme de spécification ; supplanté par l” |
|
draft-koch-openpgp-webkey-service |
Web Key Directory OpenPGP (un Internet-Draft, non une RFC) |
Côté client : |
86.2. Notes par RFC¶
86.2.1. RFC 1035 — Noms de domaine (DNS)¶
Toute la résolution DNS (MX, A/AAAA, TXT pour SPF/DKIM/DMARC/MTA-STS, et PTR inverse) suit la RFC 1035. Les limites de syntaxe des noms de domaine et des labels sont appliquées dans pepsi-common::domain. Le DNS est utilisé par l’ingress (authentification), l’étape ARC (re-vérification) et pepsi-stage-relay-to-internet (découverte MX et mise en cache d’adresses dans la table pepsi.dns_address).
86.2.2. RFC 2045 / RFC 2047 — Corps MIME et mots encodés d’en-tête¶
Lorsqu’un saut suivant n’annonce pas 8BITMIME (RFC 6152), pepsi-common::mime parcourt l’arbre MIME et ré-encode chaque feuille 8 bits avec un codage de transfert de contenu 7 bits (RFC 2045 : quoted-printable pour text/*, base64 sinon). Lorsqu’un saut n’annonce pas SMTPUTF8 (RFC 6531), les champs d’en-tête UTF-8 sont réécrits en mots encodés RFC 2047 — uniquement là où le §5 en permet un (le corps d’un champ non structuré, une phrase de nom affiché, l’intérieur d’un comment), de sorte qu’une chaîne entre guillemets devient un seul mot encodé sans ses guillemets. Un paramètre MIME non ASCII prend à la place la forme étendue de la RFC 2231, dans le bloc d’en-têtes de chaque partie, et un boundary= non ASCII est remplacé par un nouveau délimiteur ASCII dans toute sa partie multipart. Voir pepsi-stage-relay-to-internet.
86.2.3. RFC 3030 — CHUNKING / BDAT¶
L’ingress annonce CHUNKING et accepte les corps de message découpés en blocs BDAT (en plus de DATA). La valeur de corps BODY=BINARYMIME de la même RFC n’est pas annoncée ni acceptée. Voir pepsi-ingress.
86.2.4. RFC 3207 — STARTTLS¶
Les listeners d’ingress en mode starttls annoncent le verbe STARTTLS et mettent à niveau une session en clair sur place. Le client SMTP sortant utilise STARTTLS de façon opportuniste (ou comme l’exige MTA-STS). Le TLS implicite est régi par la RFC 8314 à la place.
86.2.5. RFC 3461 / RFC 3463 / RFC 3464 — Notifications d’état de remise¶
L’ingress annonce l’extension DSN et valide/stocke RET/ENVID/NOTIFY/ORCPT sous state.dsn (pepsi-common::dsn). Les étapes de relais propagent les paramètres à un saut suivant qui annonce lui aussi DSN (RFC 3461 §5–6). pepsi-stage-bounce émet la notification sous forme de multipart/report RFC 3464 avec des codes d’état étendus RFC 3463, en honorant NOTIFY (échec par défaut ; succès/délai uniquement sur demande explicite). Voir Fonctionnalités prises en charge et pepsi-stage-bounce.
86.2.6. RFC 3834 — Réponses automatiques¶
Les réponses automatiques que Pepsi génère — parmi lesquelles l’avis d’absence de pepsi-stage-vacation, le défi de pepsi-stage-secretary, le message de demande de paiement de pepsi-stage-anti-spam et les réponses de confirmation/erreur de pepsi-stage-edit-settings — positionnent Auto-Submitted conformément à la RFC 3834 et sont envoyées avec l’expéditeur nul. Un message qui est lui-même une réponse automatique (expéditeur nul / Auto-Submitted) n’est jamais soumis à une barrière, ne fait jamais l’objet d’un rebond et ne reçoit jamais de réponse automatique, de sorte que les étapes ne peuvent former de boucle de réponse.
Les règles de suppression sont partagées, dans pepsi-common::autoreply, plutôt que redérivées par étape : elles ne sont pas redérivables à partir de principes premiers, et s’y tromper est la manière dont un répondeur automatique construit une boucle de courrier. suppress_reason refuse de répondre à un expéditeur nul, à un Auto-Submitted autre que no, à un Precedence: bulk|list|junk, à un X-Auto-Response-Suppress nommant All, OOF ou AutoReply, à tout champ List-*, à un expéditeur de service (y compris un VERP <list>-bounces+…), à un multipart/report, au courrier adressé à soi-même et à un message déjà marqué state.spam. L’étape de vacances ajoute le test « le répondeur est-il réellement destinataire ? » du §3 de la RFC 3834 derrière REQUIRE_ADDRESSED_TO, ainsi que sa propre limite de fréquence par correspondant (SUPPRESS_DAYS, le vacation :days de Sieve). Voir pepsi-stage-vacation et pepsi-stage-anti-spam.
86.2.7. RFC 3848 — Types de transmission ESMTP¶
L’en-tête de trace Received: que l’ingress ajoute en tête note le transport dans la clause with sous SMTP, ESMTP, ESMTPS, ESMTPA ou ESMTPSA, conformément à la RFC 3848. Le A est ajouté dès que la session porte une identité authentifiée : avec TLS c’est ESMTPSA (AUTH SMTP), et sans lui ESMTPA, ce que produit la socket UNIX de soumission en clair pour le courrier soumis localement.
86.2.8. RFC 4648 — Base16/Base32/Base64¶
Les adresses SRS encodent leur HMAC tronqué en base32 (RFC 4648) afin que le jeton soit insensible à la casse et compatible avec les adresses ; le matériel de clé utilise base64. Voir pepsi-stage-srs.
86.2.9. RFC 4954 — SMTP AUTH¶
Les deux directions sont prises en charge. Entrant : l’ingress implémente le verbe AUTH avec les mécanismes PLAIN (RFC 4616) et LOGIN (réponse initiale SASL PLAIN et l’échange LOGIN à invites). Il n’est annoncé et accepté que sur une session chiffrée (TLS implicite ou après STARTTLS) ; une tentative AUTH en clair est refusée par 504 5.5.4 (RFC 4954 §4 ; le §1 déprécie l’ancien 538). Les identifiants sont vérifiés contre un backend SASL configuré (la socket auth-client de Dovecot, SASL_TYPE/SASL_PATH) ; un AUTH réussi marque la session comme d’origine locale, lui permet de relayer vers n’importe quel domaine et appose ESMTPSA dans la clause with du Received:.
Sortant : le client SMTP s’authentifie auprès d’un smarthost via l’option AUTH d’une section […-mta-*]. La suite complète de mécanismes (tous dans pepsi-common::smtp::sasl, codés à la main sur les primitives RustCrypto déjà présentes dans l’arbre — pas de crate SASL/SCRAM) est :
plain—PLAIN(RFC 4616) etlogin—LOGIN(mot de passe en clair à l’intérieur du tunnel TLS).cram-md5—CRAM-MD5(RFC 2195), défi-réponse HMAC-MD5.scram-sha-1/scram-sha-256et leurs variantes-plus—SCRAM(RFC 5802) etSCRAM-SHA-256(RFC 7677) ; les formes-PLUSajoutent la liaison de canaltls-server-end-point(RFC 5929). La signature du serveur est vérifiée pour une authentification mutuelle ; les noms d’utilisateur/mots de passe sont passés par SASLprep (RFC 4013).digest-md5—DIGEST-MD5(RFC 2831), déprécié (la RFC 6331 l’a passé au statut Historic) : pris en charge pour les smarthosts hérités mais exclu deautoet signalé par un avertissement tant à la validationpepsi-setupqu’à l’exécution.oauth—OAUTHBEARER(RFC 7628), avec repli sur leXOAUTH2de facto ; le jeton porteur est lu depuisTOKEN_FILE(voir pepsi-helper-token-refresh).external— SASLEXTERNAL(RFC 4422), authentifié par le certificat client TLS configuré plutôt que par un mot de passe.ntlm— le mécanisme MicrosoftNTLMde facto (sans RFC ; NTLMv2 uniquement). Exécuté uniquement sous TLS, il porte donc toujours l’Extended Protection for Authentication : la liaison de canaltls-server-end-point(RFC 5929) et les paires AV de SPNsmtp/<host>plus le MIC. Faible et sans authentification du serveur — signalé parpepsi-setup.gssapi— SASLGSSAPI/ Kerberos (RFC 4752, sur le mécanisme GSS Kerberos 5 de la RFC 4121), via la bibliothèque Kerberos système (pepsi-common::smtp::gssapi). Le ticket provient d’un cache d’identifiants maintenu à jour hors bande ; la couche de sécurité SASL est négociée à aucune couche de sécurité (TLS protège déjà la session).auto— négocier le mécanisme le plus fort offert par l’EHLO du smarthost (SCRAM-SHA-256-PLUS>SCRAM-SHA-256>SCRAM-SHA-1-PLUS>SCRAM-SHA-1>CRAM-MD5>LOGIN>PLAIN;DIGEST-MD5,NTLMetGSSAPIne sont jamais auto-sélectionnés).
Comme en entrant, le client sortant refuse d’envoyer des identifiants sur une connexion non chiffrée. Un rejet 5xx d’un mécanisme à mot de passe est traité comme un échec permanent (rebond). Voir pepsi-ingress et pepsi-stage-relay-to-smarthost.
GSSAPI/Kerberos est le seul mécanisme qui n’est pas codé à la main : il lie l’implémentation GSS Kerberos système (MIT krb5 / Heimdal). Le paquet Debian a donc une build-dependency sur libkrb5-dev et une dépendance sur libgssapi-krb5-2.
86.2.10. RFC 2369 / RFC 5064 / RFC 1153 / RFC 8058 – listes de diffusion¶
Les quatre normes que le sous-système de listes implémente et dont rien d’autre dans Pepsi n’a besoin. Ensemble, elles sont ce qui rend un message de liste reconnaissable comme message de liste par un client de messagerie qui n’a jamais entendu parler de Pepsi.
La RFC 2369 est la famille d’en-têtes List-*. Le gestionnaire rfc-2369 de pepsi-stage-list-post écrit List-Id, List-Help, List-Subscribe, List-Unsubscribe, List-Post et List-Owner d’après les adresses propres de la liste, et List-Archive lorsque la liste est archivée. Ce sont aussi ces en-têtes que le jeu de règles partagé de la RFC 3834 examine lorsqu’il refuse de répondre automatiquement : tout en-tête List-* supprime un avis d’absence, et c’est ainsi qu’une réponse d’absence est tenue à l’écart d’une liste de diffusion.
La RFC 5064 est Archived-At, l’URL d’archives par message. Pepsi la dérive du Message-ID-Hash du message : l’URL dans une copie remise et l’URL que les archives servent sont donc la même chaîne calculée deux fois, et non une paire stockée qui peut diverger. Voir Archives.
La RFC 1153 est le format de résumé simple : un message par série de séparateurs, une table des matières, et la numérotation de volume et de livraison que le client de messagerie d’un abonné replie depuis trente ans. Pepsi construit celui-là et l’alternative MIME multipart/digest, selon le delivery_mode de l’abonné ; voir Listes de diffusion.
La RFC 8058 est le désabonnement en un clic, et c’est le seul endroit où Pepsi va plus loin qu’amont : pepsi-stage-list-deliver ajoute List-Unsubscribe-Post: List-Unsubscribe=One-Click à côté d’une URI https: scellée par une clé que pepsi-httpd honore par un unique POST – aucune étape de confirmation, aucune session, et aucune politique qui puisse passer outre, car le bouton de désabonnement d’un fournisseur de boîtes est une requête à un coup, qui n’a pas de seconde occasion d’interagir avec un humain. Le jeton est un condensé à clé sur la liste, l’adresse et un numéro de série que l’on peut faire tourner, et non un enregistrement stocké ; voir Listes de diffusion.
86.2.11. RFC 2033 / RFC 5228 — Remise locale LMTP et Sieve¶
pepsi-stage-relay-to-lmtp remet un message à un Mail Delivery Agent local — typiquement Dovecot — via LMTP (RFC 2033) : il propose chaque destinataire dans une seule transaction LMTP (LHLO, STARTTLS et SASL facultatifs, DATA à réponses multiples) et achemine chaque destinataire plus loin selon la réponse par destinataire du MDA (remis, ou classé selon son statut RFC 3463). C’est le MDA, et non Pepsi, qui exécute le filtre Sieve (RFC 5228) de chaque destinataire lors du classement du courrier ; Pepsi n’implémente lui-même aucun Sieve. Le client LMTP partagé est pepsi-common::smtp::deliver_lmtp. Comme le MDA abandonne ses privilèges, cette étape n’a besoin d’aucun helper setuid/setgid (contrairement à pepsi-stage-relay-to-maildir). Voir Fonctionnalités prises en charge et pepsi-stage-relay-to-lmtp.
86.2.12. RFC 5321 — SMTP¶
La RFC 5321 est l’épine dorsale : la grammaire de commandes et les réponses de l’ingress ; l’enveloppe (MAIL FROM/RCPT TO, l’expéditeur nul <>) ; la boîte aux lettres <Postmaster> sans domaine (§4.5.1) ; l’en-tête de trace Received: (§4.4) ; le MX implicite via les enregistrements d’adresse (§5.1) ; et la règle « ne jamais faire rebondir un rebond » (§6.1). Elle régit l’ingress et les deux étapes de relais.
86.2.13. RFC 5322 — Internet Message Format¶
Les messages sont stockés scindés en un bloc d’en-têtes et un corps à la première ligne vide (pepsi-common::message) ; la sélection d’en-têtes pour la signature et les From:/Subject: analysés suivent la RFC 5322. La sélection h= de DKIM/ARC se fait de bas en haut, de sorte qu’un en-tête ajouté en tête ne perturbe jamais une signature existante.
86.2.14. RFC 3156 / RFC 9580 — OpenPGP et PGP/MIME¶
La RFC 9580 est la spécification OpenPGP de 2024 (la « crypto refresh », succédant à la RFC 4880) ; la RFC 3156 dit comment un message OpenPGP est porté dans MIME. Pepsi implémente les deux au-dessus de la bibliothèque sequoia-openpgp, dans pepsi-crypto::pgp (cryptographie) et pepsi-crypto::mime (conteneurs).
La moitié MIME (RFC 3156). Le chiffrement émet multipart/encrypted; protocol="application/pgp-encrypted" avec la partie de contrôle Version: 1 et une partie de texte chiffré application/octet-stream (§4). La signature détachée émet multipart/signed; protocol="application/pgp-signature" avec le paramètre micalg calculé d’après le condensat réellement employé (§5) — pgp-sha256 par défaut. Les deux formes sont reconnues à l’entrée, tout comme l’armure en ligne non MIME, que [pepsi] CRYPTO_INLINE_PGP peut refuser.
La question du conteneur (RFC 9580). Le choix entre le conteneur SEIPDv2 de la RFC 9580 (AEAD) et le conteneur SEIPDv1 de la RFC 4880 (un MDC) est fait explicitement d’après les capacités déclarées des clés du destinataire plutôt que laissé à la bibliothèque, de sorte qu’une rétrogradation soit une décision notée plutôt qu’une décision silencieuse ; [pepsi] CRYPTO_ALLOW_DOWNGRADE régit si elle est permise du tout. Lire un message SEIPDv1+MDC n’est jamais conditionné — l’essentiel du parc installé en produit encore — mais le paquet SED antérieur au MDC est refusé d’emblée.
Voir Gestion des clés, pepsi-stage-encrypt et pepsi-stage-decrypt ; Interopérabilité des clients consigne ce qui a été mesuré face à gpg.
86.2.15. RFC 5280 — certificats X.509 et validation de chemin¶
Chaque décision S/MIME repose sur celle-ci. pepsi-crypto::trust analyse les certificats, applique les extensions qui comptent pour le courrier (basicConstraints — y compris le pathLenConstraint qui borne le nombre d’intermédiaires qu’une CA a autorisés sous elle — keyUsage, l’usage de clé étendu emailProtection du §4.2.1.12, et le nom alternatif de sujet rfc822Name qui lie un certificat à une adresse) et construit un chemin vers une ancre configurée. Sur ce chemin, il exécute ensuite la moitié à états du §6.1 : nameConstraints (§4.2.1.10), policyConstraints (§4.2.1.11) et inhibitAnyPolicy (§4.2.1.14), ainsi que l’arbre certificatePolicies / policyMappings sur lequel elles agissent. La suite NIST PKITS (sections 4.6 et 4.8–4.13) est versionnée dans le dépôt et passe, y compris chaque réglage d’entrée non par défaut qu’elle énumère.
Quatre limites :
Le magasin de confiance est fouillé avant les certificats propres au message. Un
SignerIdentifierCMS nomme un certificat par émetteur et numéro de série : un message peut donc porter un certificat falsifié arborant l’émetteur et le numéro de série d’un certificat épinglé, avec une clé différente. Un vérificateur qui regarderait d’abord le message l’accepterait.La révocation n’est pas vérifiée. Ni le profil CRL du §5 ni OCSP (RFC 6960) ne sont consultés — voir RFC applicables pas encore implémentées. La valeur
Revocationd’un chemin validé est toujoursNotChecked, ce qui est rapporté honnêtement plutôt que rendu comme « non révoqué ».Les contraintes d’une CA lient chaque certificat situé sous elle — celles de l’ancre comprises. Les sous-arbres permis sont intersectés et les sous-arbres exclus réunis le long de la chaîne, pour le DN du sujet, chaque nom alternatif de sujet et chaque attribut
emailAddressdu DN du sujet (toujours, et pas seulement en l’absence de SAN comme l’exige le §4.2.1.10, car Pepsi lie un message à cet attribut lorsque le SAN ne nomme aucune boîte aux lettres). Les propresnameConstraintset extensions de politique d’une ancre sont appliquées comme le prescrit la RFC 5937, de sorte qu’ancrer directement une CA partenaire à noms contraints conserve sa limite. Une violation donnepolicy-rejected. Pepsi n’impose aucune politique de certificat qui lui soit propre (user-initial-policy-setvaut any-policy), de sorte que l’arbre des politiques ne décide de quelque chose que là où une CA exige une politique explicite.Une extension critique que Pepsi ne sait pas traiter entraîne un refus. Un certificat portant une extension critique que Pepsi ne reconnaît pas — ou dont il ne sait pas décoder la valeur — est refusé d’emblée (
policy-rejected). Pour les contraintes de noms, cela couvre un sous-arbre avec unminimumou unmaximum, unx400Addresset une extension vide ; un sous-arbre d’une forme que Pepsi ne sait pas comparer (otherName,ediPartyName,registeredID) n’est refusé que lorsqu’un certificat situé sous lui porte un nom de cette forme, comme le permet le §4.2.1.10. UnnameConstraints,policyConstraintsouinhibitAnyPolicymal formé est refusé même lorsqu’il n’est pas critique : l’émetteur a écrit une restriction, et une restriction illisible ne peut pas être écartée. Toute autre extension non critique non reconnue est ignorée, comme il se doit : les vrais certificats en sont remplis.
Un certificat qui ne remonte à aucune ancre configurée est non digne de confiance, non invalide (Verdict::Untrusted) : l’essentiel du courrier signé du monde remonte à une autorité dont personne ne nous a remis l’ancre, et rapporter cela comme un échec rendrait l’indicateur inutile.
86.2.16. RFC 5652 / 5083 / 5753 / 8550 / 8551 — CMS et S/MIME¶
S/MIME est le second protocole de bout en bout de Pepsi, et ses normes se partagent le travail proprement.
La RFC 5652 (CMS) est la syntaxe des conteneurs. pepsi-crypto::smime construit et ouvre SignedData (détachée et opaque), EnvelopedData, et la forme certs-only employée pour publier un certificat. Le crate cms ne fournit que les définitions de types ASN.1 ; les constructeurs et les ouvreurs sont ceux de Pepsi, de sorte que ce qui est émis et ce qui est accepté soit décidé ici plutôt qu’hérité.
La RFC 5083 (``AuthEnvelopedData``) est le conteneur de chiffrement authentifié, et c’est ce que Pepsi émet par défaut (AES-256-GCM). L”EnvelopedData de la RFC 5652 avec AES-CBC demeure comme voie de rétrogradation pour un destinataire qui ne peut faire mieux — de nouveau conditionnée par [pepsi] CRYPTO_ALLOW_DOWNGRADE. Quels clients savent réellement lire AuthEnvelopedData est la plus grande question d’interopérabilité ouverte de l’arbre ; voir La question des AuthEnvelopedData.
La RFC 5753 couvre le RecipientInfo à courbes elliptiques : accord de clé ECDH sur P-256/P-384 avec le KDF X9.63 et l’enveloppement de clé AES, aux côtés des formes RSA (RSAES-OAEP-SHA-256, et PKCS#1 v1.5 pour un destinataire qui en a besoin).
La RFC 8550 (traitement des certificats) est pepsi-crypto::trust : construction de chemin vers une ancre configurée, dates de validité, basicConstraints, keyUsage face à l’opération effectuée, l’usage de clé étendu id-kp-emailProtection, et le nom alternatif de sujet rfc822Name qui lie un certificat à l’adresse du From:. La révocation est à trois états — « non vérifiée » n’est jamais rendue comme « non révoquée » — et le module n’ouvre aucune socket : il n’y a ni OCSP ni récupération de CRL, seulement les CRL qu’on lui fournit — et les étapes n’en fournissent aucune.
La RFC 8551 (spécification des messages) est la surface MIME : application/pkcs7-mime avec le paramètre smime-type (signed-data/enveloped-data/authEnveloped-data/certs-only) et application/pkcs7-signature à l’intérieur de multipart/signed, avec les noms de fichier conventionnels smime.p7m/smime.p7s/smime.p7c. Les anciennes graphies application/x-pkcs7-* sont reconnues en entrée (par le classificateur qu’utilise l’étape de déchiffrement, et par la moisson de clés) mais jamais émises.
Les certificats des utilisateurs propres à ce déploiement sont délivrés par pepsi-crypto::keygen à travers l’autorité locale de pepsi-keys. Voir Gestion des clés ; Interopérabilité des clients consigne ce qui a été mesuré face à OpenSSL.
86.2.17. RFC 6125 — Identité de service TLS¶
Lorsque MTA-STS exige un TLS authentifié, le certificat du MX destinataire est vérifié pour valider le nom d’hôte attendu conformément à la RFC 6125. Voir pepsi-stage-relay-to-internet.
86.2.18. RFC 6152 — 8BITMIME¶
L’ingress annonce 8BITMIME et note la valeur BODY= sous state.origin. Chaque étape de relais ré-annonce BODY=8BITMIME à un saut qui le prend en charge et rétrograde sinon le corps (RFC 2045), puis réexamine le résultat : le §3 interdit de tenter de transférer du contenu 8 bits « en aucune circonstance », de sorte qu’un corps que la rétrogradation n’a pas su convertir est un échec permanent plutôt qu’un envoi malgré tout. Voir Fonctionnalités prises en charge.
86.2.19. RFC 6376 / RFC 8463 — DKIM (RSA et Ed25519)¶
L’ingress vérifie les signatures DKIM entrantes ; pepsi-stage-dkim-sign signe le courrier sortant. Chaque domaine possède à la fois une clé RSA-2048 (RFC 6376) et une clé Ed25519 (RFC 8463), provisionnées par pepsi-setup ; les deux signatures sont ajoutées, sauf si [pepsi] DKIM_ALGORITHMS n’en nomme qu’une. Le tag de longueur de corps l= n’est jamais émis : les vérificateurs stricts rejettent d’emblée une telle signature, et le §8.2 de la RFC 6376 met en garde contre lui. Voir pepsi-stage-dkim-sign.
86.2.20. RFC 6409 — Soumission de messages¶
Un listener marqué SUBMISSION = yes agit comme Message Submission Agent. Il exige AUTH comme l’attend la RFC 6409 (un MAIL FROM non authentifié est refusé par 530 ; voir RFC 4954 — SMTP AUTH) et applique les corrections de soumission à chaque message accepté : un Date: manquant est ajouté (§8.2) et un Message-ID: manquant est généré (§8.3). L’application de l’identité de soumission (§6) et la correction Sender: (§8.1) sont pilotées par le mappage USERNAME_MAP de l’utilisateur SASL authentifié vers ses adresses autorisées : un MAIL FROM d’enveloppe ou un From: que l’utilisateur n’a pas le droit d’utiliser est refusé par 550, et un From: autorisé qui diffère de l’identité canonique de l’utilisateur reçoit un en-tête Sender: nommant cette identité. Voir pepsi-ingress.
86.2.21. RFC 6531 — SMTPUTF8¶
L’ingress annonce SMTPUTF8 et accepte l’UTF-8 dans les en-têtes et l’enveloppe. Chaque étape de relais le ré-annonce à un saut compatible et rétrograde sinon les en-têtes UTF-8 (RFC 2047) ; une adresse non ASCII qui ne peut être représentée vers un saut non-SMTPUTF8 est un échec permanent (rebond). Voir Fonctionnalités prises en charge.
86.2.22. RFC 7208 — SPF¶
L’ingress vérifie SPF sur l’identité MAIL FROM en utilisant l’IP du client connecté (via la bibliothèque mail_auth) et note le verdict dans Authentication-Results et sous state.auth.spf.
86.2.23. RFC 7489 — DMARC¶
L’ingress évalue DMARC et note le verdict. Avec DMARC_ENFORCE activé, un échec DMARC certain sous une politique quarantine/reject est rejeté au moment SMTP (550) ; sinon le verdict d’échec est noté et le courrier est accepté (fail-open).
Le domaine organisationnel auquel l’alignement relâché se compare est trouvé par le parcours d’arbre de la RFC 9989 (DMARCbis), que mail_auth effectue en interne ; voir ci-dessous.
86.2.24. RFC 9989 — DMARCbis¶
La bibliothèque mail_auth vendorisée implémente le parcours de l’arbre DNS de DMARCbis (§4.10) : l’enregistrement de politique est recherché au domaine du From: puis en remontant ses étiquettes parentes, et le domaine organisationnel auquel l’alignement relâché se compare est déterminé de la même manière plutôt qu’à partir d’une liste de suffixes publics. Le DMARC_ENFORCE de l’ingress et le verdict noté s’appuient sur les résultats SPF et DKIM alignés qu’elle produit.
86.2.25. RFC 7505 — Null MX¶
pepsi-stage-relay-to-internet classe un échange 0 . comme un échec permanent (un rebond immédiat, jamais un réessai).
86.2.26. RFC 7672 — DANE / TLSA pour SMTP¶
Les deux étapes de relais prennent en charge DANE opportuniste : une option DANE = off|warn|strict (par défaut warn) recherche les enregistrements TLSA du saut suivant — par MX pour pepsi-stage-relay-to-internet, par […-mta-*] pour pepsi-stage-relay-to-smarthost — et les compare à la chaîne de certificats présentée. Le vérificateur et les types TLSA résident dans pepsi-common::smtp::dane ; les recherches TLSA/MX conscientes du bit AD dans pepsi-common::dns (Pepsi fait confiance à un résolveur validant et lit le bit AD de la réponse plutôt que de valider DNSSEC lui-même). DANE a priorité sur MTA-STS et TLS_VERIFY ; une non-concordance d’enregistrement utilisable diffère en strict et n’avertit qu’en warn.
86.2.27. RFC 7929 / RFC 8162 — enregistrements de clés OPENPGPKEY et SMIMEA¶
Pepsi implémente les deux moitiés : publier les enregistrements de clés de nos propres adresses, et consulter ceux d’un correspondant.
Publier. pepsi-keys dns <address> imprime les enregistrements DNS qui publient le matériel de clé publique stocké d’une adresse : un enregistrement OPENPGPKEY (RFC 7929) portant une clé publique transférable OpenPGP, et un enregistrement SMIMEA (RFC 8162) portant un certificat S/MIME sous la forme TLSA (usage, selector, matching-type) — 3 0 0 (certificat délivré par le domaine, certificat complet, correspondance exacte), la forme que prend un certificat auto-signé ou directement épinglé. Seules les identités publiées et actives sont émises. pepsi-setup run imprime les mêmes enregistrements pour chaque identité publiée, aux côtés de ceux de DKIM, SPF et MTA-STS.
Consulter. L’instance de découverte pepsi-keydisc@dane interroge ces deux mêmes types d’enregistrement pour l’adresse d’un correspondant, OPENPGPKEY d’abord et SMIMEA si le domaine ne publie aucun enregistrement OpenPGP. Elle se classe deuxième sur l’échelle de confiance — sous le seul matériel qu’un opérateur a saisi à la main — parce que DNSSEC est l’unique source à provenance cryptographique.
Les deux sens emploient le même nom de propriétaire haché — l’hexadécimal des 28 premiers octets du SHA-256 de la partie locale, suivi de ._openpgpkey. ou de ._smimecert. — de sorte qu’une zone n’énumère pas les adresses qu’elle sert. Cette empreinte distingue la casse (RFC 7929 §3), contrairement à l’empreinte Web Key Directory ci-dessous.
Les deux normes présupposent une zone signée par DNSSEC, et Pepsi traite cela comme contraignant dans les deux sens. pepsi-keys dns le dit dans sa propre sortie, et une consultation est conditionnée au bit AD : une réponse que le résolveur n’a pas validée est refusée d’emblée plutôt qu’acceptée à un rang inférieur, car un enregistrement de clé non signé est une clé fournie par quiconque peut répondre pour la zone. Pepsi fait confiance à un résolveur validant plutôt que de valider DNSSEC lui-même : un déploiement qui n’en a pas n’obtient donc aucun résultat DANE — pepsi-setup sonde cela et le rapporte. Voir pepsi-keys, pepsi-keydisc et Gestion des clés.
86.2.28. Web Key Directory OpenPGP (draft-koch-openpgp-webkey-service)¶
Le Web Key Directory est la moitié HTTPS du même travail : la clé d’un correspondant est récupérée depuis le domaine propre à l’adresse, sous une empreinte de sa partie locale. Pepsi calcule cette empreinte dans pepsi_common::keystore::wkd_local_part_hash — z-base-32 du SHA-1 de la partie locale mise en minuscules — et la stocke, indexée, sur chaque identité, de sorte qu’une requête soit satisfaite par une seule consultation au lieu de hacher chaque ligne candidate. (Le SHA-1 employé là est une fonction de nommage que la spécification fixe, non une fonction de sécurité : il n’est donc délibérément pas soumis à CRYPTO_ALLOW_WEAK_DIGESTS.)
Le côté client est implémenté : pepsi-keydisc@wkd-advanced interroge openpgpkey.<domain> et pepsi-keydisc@wkd-direct le domaine lui-même. Ce sont des rangs distincts et donc des consultations concurrentes distinctes plutôt qu’une chaîne de repli, puisque n’exécuter direct que « si advanced échoue » accepterait la réponse la plus faible chaque fois que la plus forte serait simplement lente. La récupération est durcie au-delà des exigences propres au draft : HTTPS uniquement avec validation de certificat et sans mode non sûr, au plus une redirection HTTPS vers HTTPS vers le même hôte, refus de se connecter à des adresses de boucle locale, privées ou lien-local, un plafond de corps appliqué pendant la diffusion, une échéance à chaque étape, et conversion IDNA en étiquettes A. Une clé renvoyée dont l’identifiant utilisateur ne nomme pas l’adresse interrogée est écartée — sans quoi un domaine pourrait répondre à chaque requête par une clé de son choix — et les directives mailbox-only et dane-only du fichier de politique sont honorées.
Le côté service est implémenté aussi, par pepsi-httpd : les formes directe et avancée du chemin de clé comme du chemin de politique, satisfaites par une consultation indexée (domain, local-part hash) sur les identités que ce déploiement détient et a marquées published. La réponse est la clé transférable binaire avec Access-Control-Allow-Origin: * ; le fichier de politique est un 200 de longueur nulle, qui doit exister parce que GnuPG lit son absence comme « pas de Web Key Directory ici » ; une empreinte inconnue donne un 404 au corps vide. Le paramètre ?l= est lu et ignoré — l’honorer transformerait le point de terminaison en une consultation par adresse fournie par l’appelant plutôt que par une empreinte que l’appelant devait connaître.
Deux propriétés du côté service sont délibérées. Il ne sert jamais une clé de correspondant en cache, seulement nos propres identités : publier du matériel que nous n’avons pas vérifié, sous notre propre nom de domaine, est ce que fait un serveur de clés, et nous n’en sommes pas un. Et il n’applique aucune limitation de débit, car un Web Key Directory est un oracle public par construction — voir Gestion des clés.
La spécification est un Internet-Draft et non une RFC.
86.2.29. Autocrypt — l’en-tête Autocrypt:¶
Autocrypt n’est pas une RFC mais une norme de fait, et c’est ainsi que la plupart des clients de messagerie utilisant PGP annoncent aujourd’hui une clé. Pepsi moissonne l’en-tête — avec les parties application/pgp-keys et les certificats de signataire d’un SignedData S/MIME — dans le courrier déjà arrivé.
La moisson n’est délibérément pas un service de découverte : elle ne coûte aucune entrée-sortie réseau puisque le matériel est déjà devant elle, elle s’exécute donc en ligne plutôt que comme instance de pepsi-keydisc, et inbound est rejeté dans [pepsi-keydiscovery] SOURCES. Elle écrit tout de même par le même chemin, de sorte qu’une clé moissonnée libère aussi tout message garé en attente sur cette adresse.
Une clé moissonnée siège près du bas de l’échelle de confiance — confiance au premier usage ; seule une clé introduite par le champ Autocrypt-Gossip: d’un tiers se classe plus bas (voir ci-dessous) — et la règle de conflit côté serveur l’empêche de déloger quoi que ce soit de mieux attesté. La distinction est un réglage réel : MIN_TRUST = harvested signifie exactement le rang 7, ce qui conserve le chiffrement opportuniste tout en excluant les présentations par des tiers. Une clé moissonnée reste néanmoins utilisable par défaut, car l’alternative au chiffrement vers une clé TOFU est l’envoi en clair. Voir Gestion des clés.
Pepsi écrit aussi l’en-tête. Sauf si [stage-encrypt] AUTOCRYPT est désactivé, pepsi-stage-encrypt annonce la clé OpenPGP propre à l’auteur du From: sur chaque message soumis localement — y compris le courrier en clair, qui est le cas qui compte, puisqu’un correspondant doit apprendre la clé avant qu’il n’y ait quoi que ce soit à chiffrer. Ce qui est annoncé est la clé publique transférable minimale à cinq paquets du Level 1 §2.1.1, seulement pour une identité qui détient encore son matériel privé, et jamais sur un message portant déjà un champ Autocrypt: venu du client propre à l’expéditeur. Comme l’étape s’exécute juste avant la signature DKIM, l’en-tête est couvert par notre propre signature.
prefer-encrypt=mutual n’est revendiqué que lorsque la politique ENCRYPT effective vaut required. Le Level 1 §2.4 fait que le client d’un correspondant ne chiffre par défaut que lorsque les deux extrémités disent mutual : le revendiquer sous une politique opportuniste — une politique dont le ON_NO_KEY = cleartext dit que le courrier non chiffré est acceptable — annoncerait donc une préférence que le déploiement n’applique pas.
Le gossip de clés du Level 1 §5.3 — le mécanisme par lequel un message annonce les clés des autres destinataires, afin que deux correspondants qui ne se sont jamais écrit puissent néanmoins se répondre en chiffré — est implémenté également, sous [stage-encrypt] AUTOCRYPT_GOSSIP. Il est désactivé par défaut : contrairement à l’en-tête Autocrypt:, qui publie une clé dont le propriétaire a demandé à ce déploiement de la détenir, le gossip redistribue du matériel de clé de tiers mis en cache à des correspondants qui ne l’ont pas demandé, et c’est une décision qu’un opérateur doit prendre délibérément.
Deux propriétés rendent la fonctionnalité sûre à activer. Les champs voyagent à l’intérieur du texte chiffré et seulement là — un champ extérieur publierait l’ensemble des destinataires d’un message chiffré à chaque relais du chemin — de sorte qu’il n’y a pas de gossip sur du courrier en clair, sur du courrier seulement signé, ni dans un conteneur S/MIME, qu’Autocrypt ne définit pas. Et les adresses gossipées sont lues dans les seuls champs To: et Cc: du message : la liste des destinataires d’enveloppe, qui porte les destinataires Bcc, n’est consultée que pour retirer une adresse de l’ensemble. Un destinataire en copie cachée ne peut donc jamais apparaître dans aucune copie, ce qui est exactement la règle que le Level 1 §5.3 impose aussi à un destinataire.
La moitié réceptrice est implémentée elle aussi, dans pepsi-stage-autocrypt-learn sous LEARN_GOSSIP (activé par défaut) — une étape à part afin de s’exécuter après les contrôles anti-spam, ce que le §5.3 demande également et que pepsi-stage-decrypt, première du chemin entrant par conception, ne peut pas faire. Le §5.3 exige qu’une clé gossipée soit conservée dans un état de pair distinct d’une clé apprise d’un en-tête Autocrypt:, afin que la présentation d’un tiers ne puisse jamais déloger ce que le propriétaire d’une adresse a dit de lui-même ; Pepsi réalise cela comme un échelon à part au bas de l’échelle de confiance de la découverte (gossip, rang 8, sous harvested), que la règle de conflit de la base sait déjà appliquer. Un champ ne compte que s’il était vraiment à l’intérieur du texte chiffré — un champ extérieur aurait pu être écrit par n’importe quoi sur le chemin —, seulement si son addr figure dans les To:/Cc: propres au message, jamais pour l’adresse de l’expéditeur lui-même, et jamais pour une adresse que cet hôte sert. Il ne porte jamais prefer-encrypt, et une signature vérifiée face à une clé gossipée revient valid-untrusted : une présentation n’ouvre donc aucune porte.
86.2.30. VKS — le protocole du serveur de clés vérificateur¶
keys.openpgp.org et ses équivalents parlent un petit protocole HTTP sous /vks/v1, et ce n’est délibérément pas HKP : une clé n’est servie pour une adresse qu’une fois que le titulaire de l’adresse a répondu à un courrier de confirmation, ce qui rend la réponse plus précieuse que « quelqu’un a téléversé ceci ».
Pepsi parle les deux moitiés. pepsi-keydisc@vks consulte un correspondant par adresse, en écartant une clé dont l’identifiant utilisateur ne nomme pas l’adresse interrogée et en sautant une clé révoquée ; il se classe sous DANE, les deux méthodes de Web Key Directory et LDAP, car la confirmation prouve le contrôle de la boîte aux lettres et rien de plus. pepsi-keys téléverse nos propres identités et demande la vérification — désactivé par défaut ([pepsi-keys] VKS_PUBLISH), car publier l’adresse d’un utilisateur chez un tiers est une décision d’opérateur et, contrairement au Web Key Directory, cela ne peut être défait. Le courrier de confirmation du serveur doit alors recevoir une réponse, ce qui est tout le travail de pepsi-stage-vks-confirm — une étape qui ne suit un lien qu’après six vérifications indépendantes, dont le fait que l’hôte de l’expéditeur d’enveloppe soit exactement le serveur de clés configuré et que chaque lien du corps y pointe aussi.
86.2.31. RFC 8446 — TLS 1.3¶
Chaque connexion protégée par TLS dans Pepsi — les listeners STARTTLS entrants et à TLS implicite, le client de relais sortant, LMTP, le serveur HTTP et le client de découverte LDAP — s’exécute au-dessus de rustls, qui parle TLS 1.3 et 1.2 et rien de plus ancien. Il n’y a aucun réglage de configuration pour réactiver SSLv3 ou TLS 1.0/1.1, car rustls ne les implémente pas.
Ce qui varie entre ces connexions n’est pas le protocole mais quelle authentification est exigée du pair, et c’est là que les normes propres au courrier prennent le relais : la RFC 6125 pour la correspondance d’identité, la RFC 7672 pour DANE, la RFC 8461 pour MTA-STS, et l’option TLS_VERIFY pour le cas où un opérateur la relâche en connaissance de cause. Le STARTTLS opportuniste vers un MX quelconque n’authentifie rien par conception — c’est le modèle de la RFC 3207, non une faiblesse d’ici — c’est pourquoi DANE et MTA-STS existent et pourquoi l’issue de chaque tentative est notée pour les rapports de la RFC 8460.
86.2.32. RFC 8314 — TLS implicite¶
Un listener avec MODE = tls effectue la poignée de main TLS avant la salutation SMTP (TLS implicite, par exemple le port submissions 465), comme le recommande la RFC 8314.
Conformément à la RFC 8314 §4.3, l’ingress note aussi la version TLS et la suite de chiffrement négociées dans l’en-tête de trace Received: qu’il ajoute en tête — sous forme d’un commentaire (version=… cipher=…) après le mot-clé ESMTPS — puisque le simple type de transmission ESMTPS n’indique pas quels paramètres ont été utilisés.
86.2.33. RFC 8460 — SMTP TLS Reporting (TLSRPT)¶
Lorsque [pepsi-tlsrpt] SEND_REPORTS est activé, les étapes de relais notent l’issue de chaque session TLS sortante dans la table de compteurs agrégés pepsi.tls_session. pepsi-tlsrpt(1), exécuté quotidiennement depuis cron, regroupe les lignes d’une journée en un rapport JSON RFC 8460 par domaine de politique, le compresse en gzip, recherche le rua du _smtp._tls du domaine et l’expédie par mailto: (réinjecté dans le pipeline pour être signé et relayé) ou par POST HTTPS. Le volet d’annonce est pepsi-setup qui imprime notre propre enregistrement TXT _smtp._tls à partir de [pepsi-tlsrpt] RUA. Les types partagés, le classificateur d’échecs et les constructeurs de rapports résident dans pepsi-common::tlsrpt. Voir pepsi-tlsrpt.
86.2.34. RFC 8461 — MTA-STS¶
pepsi-stage-relay-to-internet découvre et applique les politiques MTA-STS du domaine destinataire : une politique enforce restreint la remise aux hôtes MX listés via un STARTTLS authentifié. pepsi-setup publie notre propre enregistrement TXT _mta-sts et imprime le fichier de politique. Voir pepsi-setup.
86.2.35. RFC 8601 — Authentication-Results¶
L’ingress ajoute en tête un en-tête Authentication-Results autonome portant les verdicts SPF, DKIM, DMARC et iprev (FCrDNS), avec le nom d’hôte de l’ingress comme authserv-id. L’étape ARC reproduit la même évaluation dans son AAR.
86.2.36. RFC 8617 — ARC¶
pepsi-stage-arc vérifie toute chaîne ARC entrante et scelle le message en tant que notre ADMD en ajoutant en tête un ensemble AAR/AMS/AS, signé avec l’unique ARC_ALGORITHM. Cela permet au destinataire final de faire confiance au verdict rendu à la limite même après que la redirection de Pepsi a cassé l’alignement SPF/DKIM. Les paramètres RFC 6376 de l’ARC-Message-Signature — canonicalisation (c=), en-têtes couverts (h=) et une expiration x= — sont configurables sur l’étape (comme ils le sont sur pepsi-stage-dkim-sign) ; le tag de longueur de corps l= n’est jamais émis, car il rendrait la chaîne invalidable.
86.2.37. RFC 9051 / RFC 4155 — lire une boîte aux lettres (IMAP et mbox)¶
Pepsi ne sert aucun des deux protocoles : ce n’est pas un magasin de courrier. Il lit des boîtes aux lettres à deux endroits : pepsi-helper-mailbox-scan, qui sème une liste blanche à partir du courrier qu’un utilisateur a déjà envoyé (voir pepsi-whitelist), et pepsi-archive, qui importe et exporte une archive de liste au format mbox. Le reste de cette section concerne le premier.
Le client IMAP est en lecture seule au sens strict — il émet EXAMINE plutôt que SELECT et récupère BODY.PEEK[HEADER], de sorte qu’aucun message ne soit marqué \Seen et qu’aucun état de boîte aux lettres ne change. Seuls les blocs d’en-tête sont lus ; chaque lecteur s’arrête à la ligne vide, si bien que les corps de messages n’entrent jamais dans le processus. Le même helper lit du mbox local (RFC 4155) et du Maildir, et peut consommer un flux doveadm -f json.
LMTP (RFC 2033) est la contrepartie de remise et n’a aucun verbe de récupération, raison pour laquelle une boîte aux lettres sur un MDA purement LMTP ne peut pas être balayée ; IMAP est l’option réseau.
86.2.38. RFC 9106 — Argon2¶
Argon2id apparaît deux fois, pour deux menaces différentes.
Dans le portail à lien sécurisé (Le portail de repli par lien sécurisé), il dérive la clé qui chiffre un message stocké à partir du code PIN du destinataire, plus un sel par message et un poivre côté serveur conservé hors de la base. Les paramètres de coût sont choisis pour qu’un code PIN assez court pour être lu au téléphone reste coûteux à essayer en force, et le poivre est ce qui rend une base dérobée insuffisante à elle seule — d’où le fait que sa divulgation soit prise aussi au sérieux que celle des messages.
Dans l’API d’administration, il hache les mots de passe des comptes. Les deux instances coûtent 19 Mio par dérivation, ce qui explique que les deux chemins soient limités en débit : un attaquant non authentifié qui pourrait réessayer librement consommerait de la mémoire aussi vite qu’il consomme des essais.
86.3. RFC applicables pas encore implémentées¶
Ces normes entrent dans le périmètre d’un MTA ou d’une passerelle cryptographique mais ne sont pas implémentées, certaines par décision. Plusieurs sont partielles d’une manière précise : un objet de statut existe et est rapporté, ce qu’on prend aisément pour une vérification effectuée.
RFC |
Titre |
Statut dans Pepsi |
|---|---|---|
RFC 3030 |
valeur de corps |
|
RFC 6960 |
Online Certificate Status Protocol (OCSP) |
Non implémenté, et c’est ce qui risque le plus d’être mal lu. |
RFC 2634 |
Enhanced Security Services pour S/MIME (triple enveloppement) |
Non émis, par décision : Pepsi signe puis chiffre (la signature à l’intérieur du texte chiffré), jamais signer-chiffrer-signer. Un message à triple enveloppe qui arrive est ouvert (RFC 8551 §3.7), et c’est sa signature intérieure qui compte. Les accusés de réception signés et les étiquettes de sécurité sont absents. |
RFC 3161 |
Time-Stamp Protocol (TSP) |
Non implémenté. L’attribut S/MIME |
RFC 6541 |
DKIM Authorized Third-Party Signatures (ATPS) |
Non implémenté. Le |
RFC 6651 |
Extensions à DKIM pour les rapports d’échec |
Non implémenté. Le tag |
RFC 5321 |
|
Non implémenté et non prévu. La file de Pepsi est une table de base de données que le dispatcher vide ; il n’y a pas de file par domaine à libérer. |
Autocrypt Level 1 |
Promotion d’état de pair pour le gossip (§5.3) |
Les deux moitiés du gossip sont implémentées, mais une nuance du modèle d’état de pair ne l’est pas : le Level 1 permet à un client de promouvoir une clé gossipée lorsque le propriétaire de l’adresse la confirme plus tard, et Pepsi n’a pas une telle transition. Une réponse de meilleure source remplace purement et simplement la ligne gossipée (ce qui est le sens sûr), et tant qu’il n’en arrive pas, la clé reste sur l’échelon |