Table of Contents

Class IssuerTrustStatus

Namespace
Tessio.Verifier.Trust
Assembly
Tessio.Verifier.Trust.dll

Outcome of trust-list resolution for a credential issuer.

public sealed record IssuerTrustStatus : IEquatable<IssuerTrustStatus>
Inheritance
IssuerTrustStatus
Implements
Inherited Members

Remarks

FROZEN contract (contracts-v0). Forward-compatible: new optional inputs may be added as init-only properties, which is how TrustAnchorSubject, TrustAnchorThumbprint and TrustListExpired arrived. No existing member changes.

Properties

Reason

Human-readable reason when Trusted is false; null when trusted.

public string? Reason { get; init; }

Property Value

string

TrustAnchorSubject

Subject of the trust anchor the chain actually anchored on, when it anchored on one.

public string? TrustAnchorSubject { get; init; }

Property Value

string

Remarks

Null on the identifier route: a key resolved from issuer metadata is trusted because its identifier is on the list, so no certificate vouched for it and there is no anchor to name. Null on a refusal where nothing matched, which is most of them. NOT null on the one refusal that knows which anchor it matched and then rejected, a pinned certificate outside its own validity window: "we trusted this exact certificate and its window had closed" is a different fact from "nothing matched", and this field is what tells them apart.

A SUBJECT IS NOT AN IDENTITY. Distinguished names are not unique, a certificate authority may be reissued under the same name with a new key, and a same-name impostor is exactly the case a name-based check accepts. This field is for a human reading a record; TrustAnchorThumbprint is the identity. It is also the platform's RENDERING of the name rather than its DER, so two operating systems may format the same anchor differently.

Init-only and optional, so every existing construction still compiles unchanged.

TrustAnchorThumbprint

SHA-256 over the trust anchor's DER bytes, uppercase hex, when the chain anchored on one.

public string? TrustAnchorThumbprint { get; init; }

Property Value

string

Remarks

SHA-256 over the raw certificate rather than the platform's Thumbprint property, which is SHA-1. This field exists to answer "which anchor, exactly" for a record that may be read years after the presentation, so the comparison it supports has to be one worth making.

TrustListExpired

True when the refusal is because the trust list itself is no longer current, not because of the issuer: its next update has passed, or its operator has closed it.

public bool TrustListExpired { get; init; }

Property Value

bool

Remarks

SPEC: ETSI TS 119 612 V2.4.1 section 5.3.15: "TL with a Next update occurring in the past shall be discarded as expired". A resolver that follows it refuses every issuer on such a list, and this flag lets the verifiers report trust_list_expired rather than issuer_untrusted (or status_invalid for a status or revocation list signer), which would send the reader looking at the party refused when the cause is the list's publisher.

A closed list is a different case in the same clause: its Next update is null, and its final version marks every service "expired". Setting this flag for one too is the resolver's choice; the code then names the list as the cause, which it is.

Meaningful only when Trusted is false. Init-only and optional, so every existing construction still compiles unchanged and still reports issuer_untrusted.

TrustListSource

Identifier of the trust list that produced the verdict (URI, file path, or implementation-defined).

public string? TrustListSource { get; init; }

Property Value

string

Trusted

True when the issuer chains to a trusted root.

public required bool Trusted { get; init; }

Property Value

bool