Skip to main content

Module verification

Module verification 

Source
Expand description

Structural verification of an envelope’s proof block — spec §7.1.11, §7.1.7.1, §7.2.1 and §8.3.1 steps 1a, 1d, 1e.

This module answers one question: is this envelope’s proof structure well formed, and does it say what it is? It is deliberately PURE — no cryptography, no key resolution, no network, no clock. Signature checking belongs to crate::crypto; key discovery belongs to crate::discovery; deciding which mode a deployment demands belongs to the caller.

The reason these checks are separated out and made mandatory is stated in §7.1.11: without them attestationMode is a self-asserted string. A holder of a notary key could write PrincipalSigned above a single notary proof whose proofPurpose is assertionMethod — indistinguishable from a principal proof by purpose alone — and a verifier that trusted the label would report a forged authorization as the human’s own signature. Every rule below exists to make the label unforgeable by a notary.

Order of use, mirroring §8.3.1:

  1. require_mode — step 1a. Refuse an envelope weaker than policy demands BEFORE doing any work on unauthenticated input.
  2. verify_proof_structure — steps 1a (label/structure agreement) and 1e (chain linkage). Returns the mode the envelope is actually in.
  3. verify_embedded_mandate_binding — step 1d, the non-cryptographic half: is the embedded mandate THIS envelope’s parent?
  4. verify_timestamp_order — the issuance order §7.2.1 makes normative.

Timestamps are compared by parsing them with chrono, which is what crate::delegation_mandate::DelegationMandate::is_valid_at and crate::discovery::dns_txt already do, and every comparison fails CLOSED on an unparseable value. No date library is introduced: chrono is already a dependency of this crate for exactly this purpose.

Structs§

InMemoryConsumedEnvelopeLedger
The single-process ledger: a set. Exists so the obligation is testable here and so a caller with one process needs no ceremony; anything distributed brings its own implementation of the trait.

Traits§

ConsumedEnvelopeLedger
The single-use record §8.3’s final step obliges a recipient to keep (RFC 0003 §2): id is spent at ACCEPTANCE, and a second presentation of the same id is refused with APH_E018.

Functions§

enforce_single_use
§8.3’s single-use step: call this AT THE MOMENT the verifier commits to the act — acceptance, in the RFC 5321 §6.1 sense — after every other check has passed. Calling it earlier consumes the envelope on a presentation that some LATER check may still refuse, and RFC 0003 is explicit that a verifier which rejects for any other reason has not consumed the id.
require_mode
Refuses an envelope weaker than the caller’s policy demands (§8.3.1 1a).
verify_audience
§8.3’s audience step (RFC 0003 §1): when the envelope names who may accept it, this verifier had better be that party.
verify_embedded_mandate_binding
Binds an embedded Delegation Mandate to the envelope carrying it (§7.1.7.1 steps 3-4, §8.3.1 step 1d). Signature checking is NOT here.
verify_envelope_window
The envelope’s OWN validity window, judged against a clock the CALLER supplies (RFC 0003’s APH_E019; §8.3 step 2’s check finally has its code). Distinct from anything mandate-shaped: APH_E003 is a mandate consulted past its expiry, and routing an expired ENVELOPE there was the miscite this crate’s own tests nearly shipped.
verify_proof_structure
Verifies the structural rules of §7.1.11 and returns the mode the envelope is actually in.
verify_timestamp_order
Pins the issuance order §7.2.1 makes normative: decisionTimestamp <= principal.created <= notary.created.