Table of Contents

Class ResponseEncryptionKeyStore

Namespace
Tessio.Verifier.AspNetCore
Assembly
Tessio.Verifier.AspNetCore.dll

Holds one response-encryption key pair per session, for the lifetime of that session.

public sealed class ResponseEncryptionKeyStore : IDisposable
Inheritance
ResponseEncryptionKeyStore
Implements
Inherited Members

Remarks

The key must be ephemeral per authorization request: OpenID4VP 1.0 §8.3 and HAIP 1.0 §5 require it, and the conformance suite fails a verifier that reuses one. The reasons are real rather than procedural. A single long-lived key means its compromise retrospectively exposes every response ever encrypted against it, and a stable advertised public key is a correlation handle that ties separate presentations to one verifier.

The private half never leaves memory and never reaches disk. It exists from {prefix}/start until the wallet responds or the session expires, typically minutes. This mirrors Tessio.Verifier.AspNetCore.RequestObjectStore, which holds the signed request the same way and for the same span.

Single process only. A second instance cannot decrypt a response encrypted against a key it never generated. Multi-instance deployments need one of the options in docs/going-live.md; the recommended one derives the key per session from a single master secret so nothing per-session is stored anywhere. Failing loudly is deliberate: a silent fallback to a shared key would quietly reintroduce exactly the defect this type exists to remove.

Constructors

ResponseEncryptionKeyStore(TimeProvider)

public ResponseEncryptionKeyStore(TimeProvider clock)

Parameters

clock TimeProvider

Methods

CreateForRequest(DateTimeOffset)

Creates a fresh key pair for one authorization request, held until expiresAt.

public ResponseEncryptionKeyProvider CreateForRequest(DateTimeOffset expiresAt)

Parameters

expiresAt DateTimeOffset

Returns

ResponseEncryptionKeyProvider

Remarks

Keyed by the key's own kid (RFC 7638 thumbprint) rather than by session id, because for direct_post.jwt the session correlation handle (state) is inside the encrypted payload: at decryption time the only identifier available is the kid the wallet echoes back in the JWE header. SPEC: OpenID4VP 1.0 §5 requires every advertised JWK to carry a kid and §8.3 then requires the wallet to echo it, so requiring it here (no fallback) only rejects a non-conformant response; Get(string?) returns null for an absent or unknown kid.

Dispose()

Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.

public void Dispose()

Get(string?)

The key with this kid, or null when it is unknown or expired.

public ResponseEncryptionKeyProvider? Get(string? keyId)

Parameters

keyId string

Returns

ResponseEncryptionKeyProvider