rpcert

package module
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 18, 2026 License: MIT Imports: 21 Imported by: 0

README

go-eudi-rpcert

Regulatory identity for EUDI Wallet relying parties:

  • WRPAC — access-certificate profile checks (ETSI TS 119 411-8 V1.1.1: NCP/QCP-n/l-eudiwrp policy OIDs, contact SAN, KU/EKU, entitlement OIDs) and chain validation against AccessCA trust anchors.
  • WRPRC — registration certificates as JWT (JOSE typ rc-wrp+jwt) or CWT (COSE typ label-16 media type application/rc-wrp+cwt) per ETSI TS 119 475 V1.2.1 §5.2: issuer signature via WRPRCIssuer anchors, validity window (exp ≤ iat + 12 months), Annex A.2 entitlements, registered credential/claim extraction for scope checks.
  • RegistrationRef — the ARF RPRC_19a registration reference (client name, unique ID, registry URI, intended-use identifier) always embedded in authorization requests.
  • ts5 — data model + typed client for the ARF TS5 v1.3 Registrar API (GET /wrp, GET /wrp/{identifier}, GET /wrp/check-intended-use), JWS-signed responses, cursor pagination, per-registry key pinning.

Framework-free: injectable HTTP doer and clock, typed errors, no logging. All JOSE/COSE/X.509 via github.com/gmb-eudi/go-eudi-crypto; trust anchors only via github.com/gmb-eudi/go-eudi-trust.

Status: pre-v1 (not yet tagged/published — CI resolves sibling gmb-eudi modules once they are). Functionally, WP-07 is complete (T-07.1–T-07.9):

  • ts5 data model — golden-decode + schema-drift tests + fuzz target (T-07.1).
  • LoadWRPAC profile checks: policy OID, contact SAN, KU/EKU, Annex A.2 entitlement extraction, plus the internal/testpki synthetic CA builder reused by every later task's tests (T-07.2).
  • WRPAC.ValidateAgainst, chaining the WRPAC to AccessCA trust anchors via go-eudi-trust (granted + time-valid anchors only, issuing-territory- then-EU order, fail closed on cache expiry or no trust path — T-07.3).
  • ParseWRPRC + WRPRC.Verify for the JWT form (rc-wrp+jwt): parse-without-trust then verify-before-trust — chain to WRPRCIssuer anchors, issuer-signature check via go-eudi-crypto, validity window (exp ≤ iat + 12 months), Annex A.2 entitlement and wrprc policy-OID checks, plus registered credential/claim extraction for downstream scope checks (T-07.4).
  • The CWT form over COSE_Sign1 (RFC 8392/9052/9360) — the same ParseWRPRC/Verify matrix with hardened CBOR decoding and the COSE typ label 16 carried as the full media type application/rc-wrp+cwt (T-07.5).
  • RegistrationRef builder/serializer for the ARF RPRC_19a registration reference, always embedded in built requests (T-07.6, pulled forward for WP-08).
  • RegistrarClient.GetWRP/GetWRPByID: ARF TS5 v1.3 GET /wrp + GET /wrp/{identifier}, cursor-paginated, JWS-signed-response verified (per-registry key pinning, Provenance in the report), physicalAddress/ postalAddress rejected before it can enter a struct (T-07.7).
  • RegistrarClient.CheckIntendedUse (JWS-signed boolean) + IntendedUseActive/ IntendedUseStatus, the revokedAt monitoring predicate driving err:registrar:intended-use-revoked (T-07.8).
  • RegistrarClient.VerifyIntermediaryLinkage: confirms via the Registrar API that a client's usesIntermediary lists the operator by identifier — the only way to check this (ARF TS5 v1.3 §2.1 Note; not present in any certificate) — superseding WRPAC.IsIntermediaryCapable as the authoritative check (T-07.9).

See SPECREFS.md for pinned spec versions.

Documentation

Overview

Package rpcert implements the regulatory-identity layer of an EUDI Wallet relying party (verifier): WRPAC access-certificate profile checks and trust-anchor validation (ETSI TS 119 411-8 V1.1.1), WRPRC registration certificates in JWT and CWT form (ETSI TS 119 475 V1.2.1), the ARF RPRC_19a registration reference embedded in every authorization request, and a typed client for the ARF TS5 v1.3 Registrar API (CIR (EU) 2025/848).

Dual path: validate + attach WRPRCs where a Member State issues them; always embed the RegistrationRef; consume the Registrar API directly for onboarding verification, intended-use lifecycle monitoring and intermediary-linkage checks.

Index

Constants

View Source
const (
	EntitlementServiceProvider           = "https://uri.etsi.org/19475/Entitlement/Service_Provider"
	EntitlementQEAAProvider              = "https://uri.etsi.org/19475/Entitlement/QEAA_Provider"
	EntitlementNonQEAAProvider           = "https://uri.etsi.org/19475/Entitlement/Non_Q_EAA_Provider"
	EntitlementPubEAAProvider            = "https://uri.etsi.org/19475/Entitlement/PUB_EAA_Provider"
	EntitlementPIDProvider               = "https://uri.etsi.org/19475/Entitlement/PID_Provider"
	EntitlementQCertESealProvider        = "https://uri.etsi.org/19475/Entitlement/QCert_for_ESeal_Provider"
	EntitlementQCertESigProvider         = "https://uri.etsi.org/19475/Entitlement/QCert_for_ESig_Provider"
	EntitlementRQSealCDsProvider         = "https://uri.etsi.org/19475/Entitlement/rQSealCDs_Provider"
	EntitlementRQSigCDsProvider          = "https://uri.etsi.org/19475/Entitlement/rQSigCDs_Provider"
	EntitlementESigESealCreationProvider = "https://uri.etsi.org/19475/Entitlement/ESig_ESeal_Creation_Provider"
)

Entitlement URIs — ETSI TS 119 475 V1.2.1 Annex A.2 (exhaustive; also the vocabulary of ARF TS5 v1.3 `entitlements`).

View Source
const (
	FormatJWT = "jwt"
	FormatCWT = "cwt"
)

WRPRC serialization formats (public interface).

View Source
const (
	CredentialFormatSDJWTVC = "dc+sd-jwt" //nolint:gosec // G101: OpenID4VP data-format identifier, not a credential (name matches gosec's "cred" heuristic)
	CredentialFormatMdoc    = "mso_mdoc"
)

Credential format identifiers used in WRPRC/ARF TS5 credential entries — OpenID4VP 1.0 Annex B format ids (data formats, not crypto algorithms; the no-algorithm-literal rule concerns algorithms only).

View Source
const WRPRCPolicyOID = "0.4.0.19475.3.1"

WRPRCPolicyOID — [ETSI TS 119 475 §6.1.3]: itu-t(0) identified-organization(4) etsi(0) eudiwrpa(19475) policy-identifiers(3) wrprc(1). policy_id must reference it (OVR-6.1.3-01/-02).

Variables

View Source
var (
	ErrMalformed = errors.New("rpcert: malformed input")

	// WRPAC profile checks ([ETSI TS 119 411-8 §6.6.1] / TS 119 475 Annex A)
	ErrChainEmpty         = errors.New("rpcert: certificate chain is empty")
	ErrPolicyOID          = errors.New("rpcert: no eudiwrp certificate policy OID (TS 119 411-8 GEN-6.6.1-03)")
	ErrContactSAN         = errors.New("rpcert: no contact SAN - URI, email or telephone otherName (TS 119 411-8 GEN-6.6.1-07)")
	ErrKeyUsage           = errors.New("rpcert: keyUsage lacks digitalSignature (WP-07 Decision 3)")
	ErrExtKeyUsage        = errors.New("rpcert: extended key usage restricts wallet-facing use (WP-07 Decision 3)")
	ErrUnknownEntitlement = errors.New("rpcert: unknown OID under id-etsi-wrpa-entitlement arc (TS 119 475 Annex A.2)")

	// Trust-anchor validation (fail closed — trust is anchored, never from the token)
	ErrNoTrustPath = errors.New("rpcert: no chain to a valid trust anchor")

	// WRPRC ([ETSI TS 119 475 §5.2 / §6.1.3])
	ErrWRPRCFormat  = errors.New("rpcert: WRPRC is neither a compact JWS nor a COSE_Sign1 (GEN-5.2.1-01)")
	ErrWRPRCType    = errors.New("rpcert: WRPRC typ header mismatch (GEN-5.2.2-01 / GEN-5.2.3-01)")
	ErrClaimMissing = errors.New("rpcert: required WRPRC claim missing (GEN-5.2.4-01/-02)")
	ErrSignature    = errors.New("rpcert: WRPRC signature verification failed")
	ErrExpired      = errors.New("rpcert: WRPRC expired")
	ErrValidity     = errors.New("rpcert: WRPRC validity window violated (GEN-5.2.4-08)")
	ErrEntitlement  = errors.New("rpcert: WRPRC lacks a TS 119 475 Annex A.2 entitlement (GEN-5.2.4-03)")
	ErrPolicyID     = errors.New("rpcert: WRPRC policy_id lacks the wrprc policy OID (TS 119 475 OVR-6.1.3-01)")

	// RegistrationRef (ARF RPRC_19a)
	ErrRegistrationRef = errors.New("rpcert: incomplete registration reference")

	// ARF TS5 Registrar API client
	ErrNoRegistrarKey       = errors.New("rpcert: no verification key configured for registry")
	ErrResponseSignature    = errors.New("rpcert: registrar response JWS verification failed")
	ErrStaleResponse        = errors.New("rpcert: registrar response too old")
	ErrRegistrarStatus      = errors.New("rpcert: registrar returned an error status")
	ErrRegistrarUnavailable = errors.New("rpcert: registrar unreachable")
	ErrWRPNotFound          = errors.New("rpcert: wallet-relying party not found in registry")
	ErrPagination           = errors.New("rpcert: inconsistent pagination in registrar response")
	ErrTooManyPages         = errors.New("rpcert: registrar pagination exceeded page cap")
	ErrIntendedUseNotFound  = errors.New("rpcert: intended use not found on registered WRP")
	ErrIntendedUseRevoked   = errors.New("rpcert: intended use revoked or not yet active")
	ErrNotLinked            = errors.New("rpcert: client does not list operator as intermediary (TS5 v1.3 usesIntermediary)")
)

Sentinel errors. Services map them to err:domain:reason problem codes ErrIntendedUseRevoked → err:registrar:intended-use-revoked; ErrRegistrarUnavailable/-Status → err:registrar:unavailable; ErrWRPNotFound/ErrNotLinked → err:client:not-registered; ErrNoTrustPath (or a propagated trust.ErrCacheExpired) → err:trust:anchor-unavailable. No HTTP semantics here (framework-free); no attribute values in messages, ever. NOTE: this var block is the complete sentinel set for the whole library. The WRPRC/registrar-linkage paths consume the sentinels already declared below — do not redefine ErrRegistrationRef or replace this file.

Functions

func IntendedUseActive

func IntendedUseActive(iu ts5.IntendedUse, at time.Time) (bool, error)

IntendedUseActive evaluates the intended-use lifecycle window (ETSI TS 119 475 / ARF TS5 IntendedUse): active iff createdAt <= at and (revokedAt absent OR at < revokedAt-day-midnight). Revocation is effective from 00:00:00 UTC of revokedAt (fail-closed reading of "end date for the validity"): the entire revokedAt calendar day already counts as revoked. A revoked/not-yet-active use returns (false, ErrIntendedUseRevoked); malformed dates — including an empty createdAt — fail closed with ErrMalformed (never silently treated as active; RevokedAt stays optional and absent-means-not-revoked).

Types

type Doer

type Doer interface {
	Do(req *http.Request) (*http.Response, error)
}

Doer is the injected HTTP client (framework-free: no global http.DefaultClient). Services wire the platform-kit correlation-propagating client here; tests wire httptest.Server.Client().

type IntendedUseQuery

type IntendedUseQuery struct {
	RPIdentifier          string // rpidentifier (required)
	IntendedUseIdentifier string // intendeduseidentifier
	CredentialFormat      string // credentialformat
	ClaimPath             string // claimpath
	CredentialMeta        string // credentialmeta
	PolicyURL             string // policyurl
}

IntendedUseQuery mirrors GET /wrp/check-intended-use (ARF TS5 v1.3 OpenAPI): rpidentifier is mandatory; the other five are optional narrowing filters.

type IntermediaryRef

type IntermediaryRef struct {
	Subject string
	Name    string
}

IntermediaryRef identifies the intermediary the WRP acts through (TS 119 475 Table 10 `intermediary`; Annex C uses subfield "name", Table 10 says "sname" — both accepted, see README corrections).

type KeyProvenance

type KeyProvenance string

KeyProvenance records how a registrar verification key was obtained, for the verification report's provenance (per-registry key pinning).

const (
	// ProvenancePinned — key came from explicit per-registry config
	// (until MS registrars publish keys uniformly).
	ProvenancePinned KeyProvenance = "pinned"
	// ProvenanceTrustService — key resolved via the trust service
	// wrprc_issuer/registrar metadata (wired by the verifier service).
	ProvenanceTrustService KeyProvenance = "trust-service"
)

type LangValue

type LangValue struct {
	Lang  string `json:"lang"`
	Value string `json:"value"`
}

LangValue is a [ETSI TS 119 475 §5.2.4] localized string ({lang, value} — note: the WRPRC uses "value" where ARF TS5's MultiLangString uses "content").

type LinkageResult

type LinkageResult struct {
	Linked     bool
	OperatorID string
	ClientID   string
	Provenance Provenance
}

LinkageResult reports whether a client registers the operator as one of its intermediaries ([ARF TS5 v1.3 §2.1] usesIntermediary). Provenance carries the registry + key trust basis for the verification report.

type PinnedRegistrarKeys

type PinnedRegistrarKeys struct {
	// contains filtered or unexported fields
}

PinnedRegistrarKeys is the config-driven pinning implementation: one public key per registry base URL ([ARF TS5 §3.2.2] leaves key discovery to deployment).

func NewPinnedRegistrarKeys

func NewPinnedRegistrarKeys(keys map[string]crypto.PublicKey) *PinnedRegistrarKeys

NewPinnedRegistrarKeys copies the provided registry-URI → key map.

func (*PinnedRegistrarKeys) KeyFor

func (p *PinnedRegistrarKeys) KeyFor(registryURI, _ string) (crypto.PublicKey, KeyProvenance, error)

KeyFor returns the pinned key for registryURI (kid ignored — one key per registry in the pinned model).

type Provenance

type Provenance struct {
	RegistryURI   string
	KeyProvenance KeyProvenance
}

Provenance is attached to the verification report so an operator can see which registry answered and how its signing key was trusted.

type RegisteredCredential

type RegisteredCredential struct {
	Format         string
	DoctypesOrVCTs []string
	AllClaims      bool
	Claims         []ts5.ClaimPath
}

RegisteredCredential mirrors one WRPRC credentials/provides_attestations entry (TS 119 475 Tables 8/9). It maps 1:1 onto dcql.RegisteredCredential (go-dcql) for WithinScope checks; AllClaims=true when the claim list is absent ([OID4VP §6.1] semantics).

type RegistrarClient

type RegistrarClient struct {
	// contains filtered or unexported fields
}

RegistrarClient is a typed ARF TS5 v1.3 Registrar API client with JWS response verification. Framework-free: injected Doer + clock.

func NewRegistrarClient

func NewRegistrarClient(doer Doer, keys RegistrarKeys, opts ...RegistrarOption) *RegistrarClient

NewRegistrarClient builds the client.

func (*RegistrarClient) CheckIntendedUse

func (c *RegistrarClient) CheckIntendedUse(ctx context.Context, registryURI string, q IntendedUseQuery) (bool, error)

CheckIntendedUse calls GET /wrp/check-intended-use and returns the JWS-signed boolean result ([ARF TS5 v1.3 §3.2.2]: "JWS-signed boolean TRUE or FALSE response, based on if the queried parameter set can be found in the Registrar's Intended use information"). Verification reuses the same fetch/verifyResponse wiring as GetWRP/GetWRPByID — one trust decision path for every registrar endpoint (alg selection stays inside eudicrypto.VerifyJWS via c.fetch).

func (*RegistrarClient) GetWRP

func (c *RegistrarClient) GetWRP(ctx context.Context, registryURI string, q WRPQuery) ([]ts5.WalletRelyingParty, error)

GetWRP queries GET /wrp and joins all cursor pages ([ARF TS5 v1.3 §3.2.2]).

func (*RegistrarClient) GetWRPByID

func (c *RegistrarClient) GetWRPByID(ctx context.Context, registryURI, identifier string) (*ts5.WalletRelyingParty, error)

GetWRPByID queries GET /wrp/{identifier} ([ARF TS5 v1.3 §3.2.2]).

func (*RegistrarClient) IntendedUseStatus

func (c *RegistrarClient) IntendedUseStatus(ctx context.Context, registryURI, rpIdentifier, intendedUseID string) error

IntendedUseStatus resolves the WRP via GET /wrp/{identifier}, locates the named intended use and evaluates its lifecycle. Returns nil when active, ErrIntendedUseRevoked when revoked/not-yet-active (-> err:registrar:intended-use-revoked), ErrIntendedUseNotFound when the id is absent. Used by the portal's periodic monitoring.

func (*RegistrarClient) LastProvenance

func (c *RegistrarClient) LastProvenance() Provenance

LastProvenance returns the provenance of the most recent verified response (for the report). Safe for concurrent use.

func (*RegistrarClient) VerifyIntermediaryLinkage

func (c *RegistrarClient) VerifyIntermediaryLinkage(ctx context.Context, registryURI, clientIdentifier, operatorIdentifier string) (LinkageResult, error)

VerifyIntermediaryLinkage confirms, via the Registrar API, that the client's usesIntermediary array lists the operator by identifier. Per [ARF TS5 v1.3 §2.1] (Note: "isIntermediary … available for verification only via the Registrar's API") this relationship is NOT in any certificate, so this API call is the authoritative check (supersedes WRPAC.IsIntermediaryCapable). Fail closed: ErrNotLinked when the operator is absent, ErrWRPNotFound when the client is unknown.

type RegistrarKeys

type RegistrarKeys interface {
	KeyFor(registryURI, kid string) (crypto.PublicKey, KeyProvenance, error)
}

RegistrarKeys resolves a registrar's JWS verification key. kid is the JWS "kid" header (may be empty when a registry publishes a single key).

type RegistrarOption

type RegistrarOption func(*RegistrarClient)

RegistrarOption configures a RegistrarClient.

func WithClock

func WithClock(clock func() time.Time) RegistrarOption

WithClock injects the clock (no ambient time).

func WithMaxPages

func WithMaxPages(n int) RegistrarOption

WithMaxPages caps cursor pagination (fail closed against a runaway registrar).

func WithMaxResponseAge

func WithMaxResponseAge(d time.Duration) RegistrarOption

WithMaxResponseAge sets the freshness window for the response iat.

type RegistrationRef

type RegistrationRef struct {
	ClientName    string
	ClientID      string
	RegistryURI   string
	IntendedUseID string
}

RegistrationRef is the ARF RPRC_19a registration reference embedded in EVERY authorization request — with or without an attached WRPRC — so wallets can query the registrar themselves: the client's display name, its registered unique identifier, the national registry API URL (CIR (EU) 2025/848 Art. 3(5)) and the intended-use identifier.

func NewRegistrationRef

func NewRegistrationRef(clientName, clientID, registryURI, intendedUseID string) (RegistrationRef, error)

NewRegistrationRef validates and builds the reference. All four fields are required (all four fields); an incomplete reference cannot be built, so the request builder can guarantee "always present" structurally.

func (RegistrationRef) Claims

func (r RegistrationRef) Claims() (map[string]any, error)

Claims returns the reference as request-object claim values for the request builder (ARF RPRC_19a extension).

func (RegistrationRef) MarshalJSON

func (r RegistrationRef) MarshalJSON() ([]byte, error)

MarshalJSON serializes the reference; an incomplete reference fails, so a half-built RegistrationRef can never reach a request object.

func (*RegistrationRef) UnmarshalJSON

func (r *RegistrationRef) UnmarshalJSON(data []byte) error

UnmarshalJSON parses the wire shape written by MarshalJSON and validates completeness, so a corrupted or truncated stored value fails loudly rather than silently decoding to a zero-value reference (fail closed, fail closed) — MarshalJSON alone made RegistrationRef write-only under encoding/json (the default field-name-matching reflection cannot map "registry_uri" etc. back onto ClientName/ClientID/RegistryURI/ IntendedUseID), which broke the verifier's Session/SessionStore JSON round-trip contract (Session embeds RegistrationRef directly).

func (RegistrationRef) Validate

func (r RegistrationRef) Validate() error

Validate re-checks completeness (called before request build).

type StatusRef

type StatusRef struct {
	Index int64  `json:"idx"`
	URI   string `json:"uri"`
}

StatusRef points into the issuer's Token Status List (TS 119 475 GEN-6.2.6.1-04: status.status_list.{idx,uri}). Checked by the service via go-statuslist — revocation is surfaced, not resolved, here.

type SupervisoryContact

type SupervisoryContact struct {
	Email string `json:"email,omitempty"`
	Phone string `json:"phone,omitempty"`
	URI   string `json:"uri,omitempty"`
}

SupervisoryContact — TS 119 475 Table 7 supervisory_authority.

type WRPAC

type WRPAC struct {
	Chain                 []*x509.Certificate
	Entitlements          []string
	IsIntermediaryCapable bool
}

WRPAC is the operator's (or an intermediary's) wallet-relying party access certificate (CIR (EU) 2025/848 Art. 7 / Annex IV).

func LoadWRPAC

func LoadWRPAC(chain [][]byte) (*WRPAC, error)

LoadWRPAC parses a WRPAC chain (leaf first; each element PEM or DER) and runs the TS 119 411-8 profile checks. Each broken element yields its own sentinel:

  • certificatePolicies includes an eudiwrp policy OID (TS 119 411-8 GEN-6.6.1-03, OIDs from [ETSI TS 119 411-8 §5.3]) → ErrPolicyOID
  • contact SAN: URI / rfc822Name / telephone otherName (TS 119 411-8 GEN-6.6.1-07 [CHOICE]) → ErrContactSAN
  • keyUsage includes digitalSignature ( the WRPAC signs OID4VP request objects) → ErrKeyUsage
  • EKU absent, anyExtendedKeyUsage or clientAuth → ErrExtKeyUsage
  • entitlement OIDs under 0.4.0.19475.1 map to Annex A.2 URIs; unknown arc children rejected (fail closed) → ErrUnknownEntitlement

func (*WRPAC) ValidateAgainst

func (w *WRPAC) ValidateAgainst(src trust.AnchorSource) error

ValidateAgainst chains the WRPAC to AccessCA trust anchors from the trust service (CIR (EU) 2025/848 Art. 7 — access-certificate providers operate under Member State supervision, their CAs are the AccessCA anchor set). Uses the package clock (clock.go).

type WRPQuery

type WRPQuery struct {
	Identifier            string
	LegalName             string
	TradeName             string
	Policy                string
	Entitlement           string
	CredentialMeta        string
	CredentialFormat      string
	UsesIntermediary      string
	IsIntermediary        *bool
	IntendedUseIdentifier string
	Limit                 int
}

WRPQuery mirrors the GET /wrp query parameters (ARF TS5 v1.3 OpenAPI). Empty fields are omitted; IsIntermediary is a *bool so "unset" ≠ "false".

type WRPRC

type WRPRC struct {
	Raw    []byte
	Format string // FormatJWT | FormatCWT
	Chain  []*x509.Certificate

	Name                  string
	LegalName             string // sub_ln (legal person)
	GivenName             string // sub_gn (natural person)
	FamilyName            string // sub_fn (natural person)
	Subject               string // sub — registered WRP identifier (GEN-5.2.4-02)
	Country               string
	RegistryURI           string
	SrvDescription        [][]LangValue
	Entitlements          []string
	PrivacyPolicy         string
	InfoURI               string
	SupportURI            string
	SupervisoryAuthority  SupervisoryContact
	PolicyIDs             []string
	CertificatePolicy     string
	PublicBody            bool
	IssuedAt              time.Time
	ExpiresAt             time.Time // zero = no exp claim
	Status                *StatusRef
	Purpose               []LangValue
	IntendedUseID         string
	RegisteredCredentials []RegisteredCredential
	ProvidesAttestations  []RegisteredCredential
	Intermediary          *IntermediaryRef
}

WRPRC is a parsed wallet-relying party registration certificate ([ETSI TS 119 475 §5.2]; CIR (EU) 2025/848 Art. 8 / Annex V).

func ParseWRPRC

func ParseWRPRC(raw []byte) (*WRPRC, error)

ParseWRPRC parses a WRPRC in JWT or CWT form WITHOUT verifying its signature — call (*WRPRC).Verify next (TS 119 475 GEN-5.2.1-01: "signed JSON Web Token (JWT) or CBOR Web Token (CWT)").

func (*WRPRC) Verify

func (r *WRPRC) Verify(src trust.AnchorSource, clock func() time.Time) error

Verify validates the WRPRC end-to-end, fail closed:

  1. signer chain (x5c/x5chain, leaf first) to WRPRCIssuer anchors — trust anchored, never from the token; ETSI TS 119 475 GEN-5.2.1-03 (the provider's signing certificate is published on a trusted list)
  2. token signature with the leaf key via go-eudi-crypto — GEN-5.2.1-04 (JAdES B-B) / GEN-5.2.1-05 (COSE per RFC 9052/9360)
  3. validity window — GEN-5.2.4-01 iat, GEN-5.2.4-07/-08 exp ≤ iat+12mo
  4. entitlements include ≥1 Annex A.2 entitlement — GEN-5.2.4-03
  5. policy_id references the wrprc policy OID — OVR-6.1.3-01/-02

Verify-before-trust: no payload-derived field (validity, entitlements, policy_id, credential list) is acted upon until the chain (1) and the cryptographic signature (2) both pass — the extraction that ParseWRPRC performed is only trustworthy after this point.

Status-list state (status.status_list) is NOT checked here — services check it via go-statuslist; Verify only surfaces StatusRef (revocation is surfaced, not resolved, here).

Directories

Path Synopsis
internal
testpki
Package testpki generates the test PKI at test runtime: an access-CA / WRPRC-issuer CA and end-entity certificates with every TS 119 411-8 profile knob the certificate-profile matrix mutates.
Package testpki generates the test PKI at test runtime: an access-CA / WRPRC-issuer CA and end-entity certificates with every TS 119 411-8 profile knob the certificate-profile matrix mutates.
Package ts5 models the ARF TS5 v1.3 "Common formats and API for Relying Party Registration information" data model ([ARF TS5 §2]) and the JWS payload envelopes of its Registrar API (Annex A OpenAPI).
Package ts5 models the ARF TS5 v1.3 "Common formats and API for Relying Party Registration information" data model ([ARF TS5 §2]) and the JWS payload envelopes of its Registrar API (Annex A OpenAPI).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL