Skip to main content

AttestationVerdict

Enum AttestationVerdict 

Source
pub enum AttestationVerdict {
    Valid,
    ValidIdentityOnly,
    CommitmentMismatch {
        expected: String,
        signed: String,
    },
    BadSignature,
    UnknownAlgorithm(String),
    MalformedKey,
    MalformedSignature,
    MalformedCommitment,
}
Expand description

The outcome of checking a ProvenanceAttestation (SPEC.md §6.5.4).

Every failure is named. A boolean would collapse “this signature is forged” into “I was handed a truncated key,” and those call for opposite responses: the first is an incident, the second is a configuration bug.

Variants§

§

Valid

The signature verifies against the recomputed commitment, and that commitment binds the frame’s content.

§

ValidIdentityOnly

The signature verifies, but over a preimage that does not bind the frame’s content: the frame declared no content_digest, so frame_commitment hashed the absence of one (SPEC.md §6.5.2).

What this does and does not prove is the whole reason the variant exists. It proves the named provider issued a frame with this id and this provenance chain. It does not prove the bytes served under that id are the bytes that were signed — the provider can serve one document today and a different one tomorrow, and this same signature keeps verifying, because the content was never in the preimage.

Before this variant existed, that case returned Valid and a verifier had no way to tell the two apart (#128). A host that rendered such a frame as “signed” was making a claim the signature did not support.

is_valid is false here, so the default answer is the safe one. A host that has its own reason to accept an identity-only attestation must say so by matching this variant or calling signature_verifies — which is the point: the decision becomes visible in the code that makes it.

A conformant attester does not produce this. SPEC.md §6.5.2 requires a provider that signs a frame to populate content_digest; encountering this verdict means the frame was signed by a non-conformant attester, or predates that requirement.

§

CommitmentMismatch

The signature is well-formed and verifies, but over a different commitment than this frame produces — the frame or its provenance was altered after signing. The loudest possible finding.

Fields

§expected: String

The commitment recomputed from the frame in hand.

§signed: String

The commitment the attestation claims to sign.

§

BadSignature

The commitment matches but the signature does not verify under the supplied key: a forgery, or the wrong key.

§

UnknownAlgorithm(String)

The named algorithm is not one this build can check. Not a failure to validate — a refusal to guess.

§

MalformedKey

The public key was not a well-formed key for the named algorithm.

§

MalformedSignature

The signature field was not well-formed for the named algorithm.

§

MalformedCommitment

signed_commitment was not a well-formed sha256:<hex> digest.

Implementations§

Source§

impl AttestationVerdict

Source

pub fn is_valid(&self) -> bool

Whether this verdict is Valid — the signature checks out and it binds the frame’s content.

A host MUST NOT treat any other verdict as provisionally acceptable: the point of an attestation is that “I could not check it” and “it is good” are never the same answer.

That includes ValidIdentityOnly, which is deliberately not valid here. Its signature does verify, but over a preimage that says nothing about the bytes in hand, and a host asking “is this good?” is asking about the bytes. Use signature_verifies to ask the narrower question on purpose.

Source

pub fn signature_verifies(&self) -> bool

Whether the signature itself checked out, whatever it covers.

True for Valid and ValidIdentityOnly. This is the question to ask when the caller genuinely wants provider identity and provenance without a claim about content — an audit trail of who answered, say, rather than a check that an answer is unaltered.

It is a separate method rather than a looser is_valid because the difference between them is the whole of #128: one accepts a frame whose content can be swapped without disturbing the signature, and the other does not. Whichever a caller wants, it should be legible at the call site which one they asked for.

Source

pub fn binds_content(&self) -> bool

Whether the verified commitment binds the frame’s content bytes.

Only Valid does. A verdict that did not verify at all binds nothing, so this is false for every failure too.

Trait Implementations§

Source§

impl Clone for AttestationVerdict

Source§

fn clone(&self) -> AttestationVerdict

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for AttestationVerdict

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for AttestationVerdict

Source§

impl PartialEq for AttestationVerdict

Source§

fn eq(&self, other: &AttestationVerdict) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for AttestationVerdict

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.