85.1.26. pepsi-stage-autocrypt-learn¶
learn correspondents” keys from the mail they send
- Section du manuel:
1
85.1.26.1.1. Nom¶
pepsi-stage-autocrypt-learn - l’étape d’apprentissage de clés du pipeline Pepsi.
85.1.26.1.2. Synopsis¶
pepsi-stage-autocrypt-learn [GLOBAL-OPTIONS] worker
85.1.26.1.3. Description¶
pepsi-stage-autocrypt-learn est un programme d’étape exécuté par pepsi-dispatch(1) comme un worker persistant lisant les identifiants de message sur l’entrée standard. Il charge cette ligne pepsi.workqueue (refusant d’agir sauf si son status est running) et lit sa section [stage-<stage>].
C’est là qu’un message entrant enseigne une clé publique à Pepsi. Quatre sources, toutes des choses qu’un correspondant a mises dans un message qu’il nous a envoyé :
l’en-tête Autocrypt: de l’expéditeur (Autocrypt Level 1 §2.1) ;
une partie application/pgp-keys jointe ;
les certificats portés par une signature S/MIME ;
les champs Autocrypt-Gossip: d’un message arrivé chiffré, qui présentent les clés des autres destinataires (Level 1 §5.3).
Tout ce qu’elle apprend est écrit dans pepsi.peer_key par le même chemin keydisc_resolve qu’utilise pepsi-keydisc(1), de sorte qu’une clé apprise ici libère aussi tout message garé en attente de la clé de cette adresse.
L’étape n’abandonne, ne met en pause, ne fait rebondir ni ne réécrit jamais un message. Elle apprend et avance, donc NEXT_STAGE est obligatoire.
Elle note aussi la direction opposée : qu’un correspondant détient de manière prouvée l’une de nos clés (voir Preuve qu’un correspondant détient notre clé).
85.1.26.1.4. Où la placer¶
C’est le placement qui en fait une étape à part entière plutôt qu’une partie de pepsi-stage-decrypt(1), et le manquer l’annule silencieusement :
Après
pepsi-stage-decrypt. Les champs de gossip résident à l’intérieur du texte chiffré, il n’y a donc rien à lire tant que le message n’a pas été ouvert.Après toute étape susceptible de décider qu’un message est indésirable — pepsi-stage-check-whitelist(1) et toute autre étape qui définit
state.spam. Autocrypt Level 1 §5.3 dit que l’état de pair SHOULD être ignoré pour un message que le client croit être du spam, et une étape placée avant que cette croyance existe ne peut pas l’honorer. pepsi-stage-decrypt(1) s’exécute en premier sur le chemin entrant par conception, cette croyance n’y existe donc pas encore.Avant tout ce qui répond ou remet — pepsi-stage-vacation(1), les étapes de relais, les étapes de remise locale. Une clé apprise après l’envoi de la réponse est une clé apprise trop tard pour chiffrer celle-ci.
pepsi-setup --wizard la place correctement lorsque la cryptographie de bout en bout est activée.
85.1.26.1.5. Ce qu’elle n’apprendra pas¶
Les barrières sont celles d’Autocrypt Level 1, plus celles de Pepsi là où Pepsi est délibérément plus strict. Un champ ou une clé qui échoue à l’une d’elles est ignoré ; le message n’est jamais mis en échec pour autant.
Aucune clé du tout lorsque LEARN_KEYS est désactivé : l’étape n’apprend rien, gossip compris — le gossip est un élargissement de ce qu’un message peut enseigner, il ne peut donc pas être actif tant que l’échelon plus étroit est inactif. (La preuve décrite sous Preuve qu’un correspondant détient notre clé est toujours enregistrée.)
Rien d’un message classé comme spam, sauf si LEARN_FROM_SPAM en décide autrement.
Seulement la clé propre de l’expéditeur pour les trois premières sources : un message peut légitimement porter un trousseau de tiers, et stocker celles-ci comme si l’expéditeur s’en portait garant permettrait à un seul correspondant de semer le magasin pour tout le monde. Présenter un tiers est précisément le rôle du gossip, et cela atterrit sur un échelon à part.
Du gossip seulement depuis un message arrivé chiffré, et seulement si le bloc d’en-têtes à l’arrivée ne portait aucun champ
Autocrypt-Gossip:propre — n’importe quoi sur le chemin de remise peut en écrire un, un tel message n’enseigne donc aucun gossip. Aucun de ces deux faits n’est visible dans le texte clair écrit en base, pepsi-stage-decrypt(1) note donc les deux sousstate.crypto.inet cette étape les y lit. Un message qui n’a jamais rencontré d’étape de déchiffrement ne porte pas cette note, et absent signifie non : un tel déploiement apprend les en-têtes et les clés jointes, et aucun gossip.Pas de gossip pour une adresse que le message ne nomme pas visiblement : l”
addrd’un champ doit figurer dans leTo:, leCc:ou leReply-To:du message lui-même (la règle du récepteur du §5.3 du Level 1). Sans cela, un expéditeur pourrait présenter une clé pour n’importe quelle adresse au monde en la mentionnant dans un en-tête que personne ne lit.Jamais une clé de gossip pour une adresse que cet hôte dessert. Une clé de pair pour une adresse locale est ce avec quoi notre propre courrier sortant vers cet utilisateur serait chiffré ; un champ de gossip qui en nomme une est donc une substitution de clé, pas une présentation. Le test est
LOCAL_DOMAINS, et il ne s’applique qu’au gossip : le matériel propre à l’expéditeur est filtré par adresse plutôt que par localité (voir ci-dessous ce qui empêche unFrom:falsifié d’avoir de l’importance).Jamais l’adresse propre de l’expéditeur par gossip (sa propre clé relève de l’échelon supérieur), jamais deux champs nommant une même adresse (rien ici ne peut arbitrer entre deux affirmations au sujet d’un inconnu), et rien d’un message portant plus de 50 champs de gossip (ils sont alors tous ignorés), chaque champ portant au plus 16 Kio de
keydata=(une clé transférable minimale fait moins de 4 ko en base64 même pour RSA-4096, c’est donc généreux d’un facteur quatre ; un champ surdimensionné est ignoré, pas fatal). La limite distincte de 10 Kio que certains lecteurs auront rencontrée est le plafond d’Autocrypt Level 1 §2.1 sur l”en-têteAutocrypt:lui-même, et ne s’applique jamais à un champ de gossip.
85.1.26.1.6. Ce que vaut une clé apprise¶
Peu, à dessein. Les clés moissonnées se situent au rang inbound et celles issues du gossip au rang gossip, les deux échelons inférieurs de l’échelle de confiance (voir pepsi-keydisc(1)) :
une telle clé ne peut jamais déloger une clé issue de la découverte ou d’un opérateur ;
une signature vérifiée contre une telle clé est rapportée
valid-untrustedau mieux, jamaisvalid, elle ne définit donc jamaisstate.signature_verified— la clé sur laquelle pepsi-stage-check-whitelist(1) conditionne une lignesignature_required;une ligne
peer_keyest entièrement ignorée pour une adresse dont cet hôte détient unecrypto_identity— la recherche qu’emploient les étapes cryptographiques remplace les clés en cache d’une telle adresse par la moitié publique de l’identité — si bien qu’un message falsifiant unFrom:d’utilisateur local peut laisser une ligne derrière lui, mais ne peut jamais la faire utiliser pour cet utilisateur.
Au sein de ces deux échelons, la règle de conflit est le plus récent gagne sur la date d’effet Autocrypt du message, de sorte qu’un correspondant qui réinstalle son client cesse de recevoir du courrier chiffré vers une clé qu’il ne détient plus. C’est un compromis délibéré : la protection ne vaut que contre un adversaire passif, ce qui est tout ce qu’Autocrypt revendique. Un opérateur qui veut du chiffrement opportuniste mais pas de présentations par des tiers règle [pepsi-keydiscovery] MIN_TRUST = harvested.
85.1.26.1.7. Lorsque la clé d’un correspondant change¶
Le « plus récent gagne » repose sur l’en-tête From:, que l’expéditeur écrit, et l’authentification entrante est fail-open — de sorte qu’un message qui se contente de prétendre venir d’un correspondant peut remplacer la clé avec laquelle nous lui chiffrons. Autocrypt l’accepte ; Pepsi l’accepte aussi, mais jamais en silence :
Une ligne d’audit. La base de données écrit une ligne
key.peer.rotatedanspepsi.event_log(sévériténotice, acteurautocrypt:inboundouautocrypt:gossip, sujet l’adresse du correspondant) dans la même instruction que le remplacement, avec le protocole, l’empreinte évincée et la nouvelle, et les deux dates d’effet. Il n’y a pas de rotation sans sa ligne. Elle est listée parGET /api/v1/eventset par le journal d’événements de la console, et résumée par pepsi-status(1) sous Correspondent key changes.Un avis aux personnes concernées. Avec RESPONSE_STAGE défini, chaque destinataire d’enveloppe local du message qui a provoqué le changement — les personnes auxquelles ce correspondant vient d’écrire, dont la réponse sera chiffrée pour la nouvelle clé — reçoit un avis nommant le correspondant et les deux empreintes, et indiquant si la nouvelle clé était celle du correspondant lui-même ou introduite par gossip (et par qui). Il est à expéditeur nul,
Auto-Submitted: auto-generated,From: postmaster@<recipient's domain>, rendu à partir du modèlekey-rotation.<lang>.bodysous[pepsi] TEMPLATE_DIRpour lastate.languagedétectée du message, avec un repli en anglais (dont pepsi-setup(1) exige l’existence), et injecté à RESPONSE_STAGE. « Local » désigne un destinataire d’un domaine deLOCAL_DOMAINS; personne ailleurs ne reçoit jamais de courrier, et personne n’est informé au sujet de sa propre adresse. Les utilisateurs locaux qui correspondent avec l’adresse mais n’ont pas reçu ce message ne sont pas informés : Pepsi ne garde aucune trace de qui correspond avec qui, et en constituer une pour cela serait le pire compromis. La ligne d’audit les couvre. Un avis qui ne peut pas être mis en file (un modèle illisible, une erreur de base de données) est journalisé au niveauwarnet n’est pas réessayé : une seconde passe trouverait la nouvelle clé déjà stockée et n’aurait aucun changement à signaler, la ligne d’audit est donc alors la seule trace.Une ligne de journal et un compteur de télémétrie (
autocrypt-rotation).
Un remplacement par une source strictement meilleure — une réponse WKD ou DANE évinçant une clé moissonnée, ou l’en-tête Autocrypt: du propriétaire lui-même évinçant une clé issue du gossip — est l’échelle qui fonctionne comme prévu et n’est pas une rotation.
Une clé issue du gossip que son propriétaire confirme est promue. Lorsque l’en-tête Autocrypt: propre à l’expéditeur (ou une clé jointe le nommant) porte la même clé que le gossip a déjà stockée pour lui, la ligne passe de l’échelon gossip à inbound — la promotion de l’Autocrypt Level 1 §5.3. Comme la clé n’a pas changé, ce n’est ni une rotation ni une offre retenue, et personne ne reçoit d’avis ; la base de données écrit une ligne key.peer.promote (sévérité info, acteur autocrypt:inbound, détail : le protocole, l’empreinte, from_source gossip, source inbound et les deux dates d’effet) dans la même instruction, et l’étape la journalise. La date d’effet de la ligne devient celle de l’expéditeur lui-même, de sorte qu’une rotation ultérieure de sa part est jugée par rapport à sa propre revendication et non à la date que portait le message d’un tiers. Le verdict qu’une signature peut atteindre est inchangé — valid-untrusted au mieux, comme pour toute clé moissonnée — mais la ligne se défend désormais au rang inbound, de sorte qu’un champ gossip ultérieur proposant une autre clé pour l’adresse est refusé, et MIN_TRUST = harvested l’admet. ACCEPT_ROTATION ne joue aucun rôle : rien n’est évincé.
ACCEPT_ROTATION = expired restreint la règle pour un opérateur qui préfère refuser une rotation authentique plutôt qu’en accepter une falsifiée : la clé plus récente n’est prise que lorsque chaque clé stockée pour cette adresse et ce protocole est morte — sa validité revoked ou expired, ou son expires_at dans le passé. Sinon, la clé stockée est conservée et l’offre est retenue : une ligne key.peer.rotate.held (sévérité warning, nommant l’empreinte conservée et celle proposée), le même avis indiquant que la nouvelle clé n’a pas été acceptée, et le compteur autocrypt-rotation-held. La mort d’une clé est lue dans ce qui est stocké, et chaque clé apprise est stockée avec l’expiration que son propre matériel indique — pour OpenPGP la date de l’auto-signature courante de la clé primaire, pour S/MIME le notAfter du certificat — de sorte qu’une clé échue est morte dès cet instant. Une clé qui n’indique aucune expiration n’est morte qu’une fois marquée révoquée ou expirée, ou lorsqu’un opérateur la retire (pepsi-keys peer remove) ou importe la nouvelle à la main (pepsi-keys peer import, qui surclasse l’échelon moissonné). La politique est lue à travers la section de l’étape, de sorte qu’une surcharge pepsi.settings pour un destinataire s’applique à une étape listée dans EDITABLE_STAGES.
85.1.26.1.8. Preuve qu’un correspondant détient notre clé¶
Lorsque [stage-encrypt] ATTACH_KEYS_AS_FILES est activé, pepsi-stage-encrypt(1) joint la clé publique de l’expéditeur sous forme de fichier jusqu’à ce que le correspondant la détienne de manière prouvée. Cette étape écrit cette preuve, une ligne par (fingerprint, peer_address) dans pepsi.peer_has_own_key, lorsqu’un message entrant la montre :
il a été déchiffré avec l’une de nos clés (
state.crypto.in.decryptedetdecrypted_with), et n’a pas simplement été transmis au propre client de messagerie d’un utilisateur ;il porte une signature dont le verdict est
validouvalid-untrustedet qui couvre le texte en clair (signature.covers_plaintext), de sorte qu’un inconnu qui enveloppe le texte chiffré de quelqu’un d’autre dans sa propre signature ne prouve rien ;le signataire est l’adresse
From:elle-même (jamais le repli sur l’enveloppe utilisé pour l’apprentissage des clés), de sorte qu’unFrom:falsifié ne peut pas supprimer la pièce jointe.
Le stockage revérifie ensuite que l’empreinte désigne une clé MTA active (custody = local) de l’adresse pour laquelle le message a été déchiffré, et élague, dans la même instruction, les lignes dont l’empreinte ne désigne plus une identité active. L’enregistrement est indexé sur l’empreinte, de sorte qu’une nouvelle clé recommence à être jointe. Un correspondant qui chiffre sans signer continue de recevoir le fichier, ce qui ne fait aucun mal.
Ceci s’exécute avant toute barrière d’apprentissage de clés : cela note quelque chose au sujet de notre propre clé, pas de la leur, de sorte que ni LEARN_KEYS ni l’opinion sur l’indésirable n’ont rien à en dire. Comme tout le reste ici, cela ne fait jamais échouer le message.
85.1.26.1.9. Configuration¶
Les options résident dans la propre section [stage-<name>] de l’étape (PROGRAM = pepsi-stage-autocrypt-learn) : LEARN_KEYS, LEARN_GOSSIP, LEARN_FROM_SPAM, ACCEPT_ROTATION (newest, la valeur par défaut, ou expired), le RESPONSE_STAGE optionnel pour les avis de changement de clé, les options de localité partagées LOCAL_DOMAINS, TARGETS et RECIPIENT_DELIMITER (analysées, mais seul LOCAL_DOMAINS est consulté), et un NEXT_STAGE obligatoire. L’étape analyse également [pepsi-keydiscovery], dont elle transmet le NEGATIVE_TTL au chemin partagé de stockage et de libération. Elles sont documentées dans pepsi.conf(5).
L’étape est non privilégiée : elle n’écrit que du matériel de clé public (et le fait qu’un correspondant détient notre clé publique), elle s’exécute donc sous le compte de service pepsi ordinaire et est pliée dans le binaire multi-appel pepsi. Elle ne porte aucun bit setuid ni setgid.
85.1.26.1.10. État¶
Entrées : state.spam (la croyance que notent les étapes amont) ; state.crypto.in.encrypted, state.crypto.in.decrypted et state.crypto.in.outer_gossip, écrits par pepsi-stage-decrypt(1), qui décident ensemble si le gossip de ce message peut être cru. L’expéditeur est pris dans la colonne from_header, à défaut dans l’expéditeur d’enveloppe.
Sorties : aucune sur le message — son state est laissé intact. Les effets de bord sont les lignes pepsi.peer_key, les lignes pepsi.peer_has_own_key, les lignes key.peer.rotate/key.peer.rotate.held/key.peer.promote dans pepsi.event_log, et les avis de changement de clé injectés à RESPONSE_STAGE (jeton <token>-key-rotation-<n>). La preuve lit en outre state.crypto.in.decrypted_with, state.crypto.in.for_client et state.crypto.in.signature. La disposition de l’état est décrite dans pepsi.state(7).
Transitions : avance toujours vers NEXT_STAGE. Il n’y a pas de branche ; l’étape ne met jamais en pause, n’échoue jamais, ne réachemine ni ne termine jamais. Chaque erreur d’apprentissage est journalisée puis ignorée : un message est en cours de remise, et rien de ce qui concerne le matériel de clé d’un inconnu ne doit lui faire obstacle. Un matériel de clé qui ne s’analyse pas est l’affaire de l’expéditeur et est journalisé au niveau debug ; un matériel analysé qui n’a pas pu être stocké (une erreur de base de données) est l’affaire de cet hôte, et est journalisé au niveau warn, afin qu’un opérateur remarque un magasin qui a cessé d’apprendre. La configuration fait exception : la section de l’étape et [pepsi-keydiscovery] sont vérifiées au démarrage du worker (une configuration cassée lui fait refuser de démarrer, sortie 78, et le dispatcher retient la file), et une section qui cesse de s’analyser sous un worker en cours d’exécution est réessayée plutôt qu’ignorée en silence.
85.1.26.1.11. Commandes¶
- worker
Exécuté comme un worker persistant de pepsi-dispatch(1), lisant les identifiants de message sur l’entrée standard.
85.1.26.1.12. Options globales¶
- -c FILE, –config FILE
Lit la configuration depuis FILE au lieu de parcourir les emplacements par défaut.
- -L LOGLEVEL, –log LOGLEVEL
Règle la verbosité de journalisation (par défaut
info).- -v, –verbose
Affiche les messages de journal de toutes les sources.
- -h, –help ; -V, –version
Affiche un résumé d’utilisation / la version et quitte.
85.1.26.1.13. Code de sortie¶
- 0
Le message a été traité (quoi qu’il ait enseigné, ou rien) et avancé.
- 1
Une erreur s’est produite (message introuvable ou non
running, étape mal configurée — par exemple un NEXT_STAGE manquant — ou une erreur de base de données). La raison est écrite dans le journal.- 78
Le worker a refusé de démarrer : sa section ou
[pepsi-keydiscovery]ne s’analyse pas. Le dispatcher remet en file ce qu’il lui avait confié et réessaie l’étape plus tard.
85.1.26.1.14. Exemples¶
Apprendre depuis le message 42 (il doit être running)
echo 42 | pepsi-stage-autocrypt-learn -c /etc/pepsi/pepsi.conf worker
Un pipeline entrant qui la place après les contrôles de spam et avant la remise
[stage-check-whitelist]
PROGRAM = pepsi-stage-check-whitelist
NEXT_STAGE = autocrypt-learn
WHITELIST_NAME = correspondents
[stage-autocrypt-learn]
PROGRAM = pepsi-stage-autocrypt-learn
NEXT_STAGE = local
Informer les destinataires lorsque la clé d’un correspondant change, et n’accepter un changement qu’une fois l’ancienne clé morte
[stage-autocrypt-learn]
PROGRAM = pepsi-stage-autocrypt-learn
NEXT_STAGE = local
RESPONSE_STAGE = dkim-sign
ACCEPT_ROTATION = expired
Conserver le chiffrement opportuniste mais refuser les présentations par des tiers
[stage-autocrypt-learn]
PROGRAM = pepsi-stage-autocrypt-learn
NEXT_STAGE = local
LEARN_GOSSIP = no
85.1.26.1.15. Voir aussi¶
pepsi-stage-decrypt(1), pepsi-stage-encrypt(1), pepsi-keydisc(1), pepsi-keys(1), pepsi-stage-check-whitelist(1), pepsi-dispatch(1), pepsi-status(1), pepsi.conf(5), pepsi.state(7), pepsi-setup(1)
85.1.26.1.16. Bogues¶
Signalez les bogues au gestionnaire de tickets de Pepsi.