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
clockTimeProvider
Methods
CreateForRequest(DateTimeOffset)
Creates a fresh key pair for one authorization request, held until expiresAt.
public ResponseEncryptionKeyProvider CreateForRequest(DateTimeOffset expiresAt)
Parameters
expiresAtDateTimeOffset
Returns
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
keyIdstring