[OID4VCI] Fix c_nonce replay protection#50120
Open
forkimenjeckayang wants to merge 2 commits into
Open
Conversation
Signed-off-by: forkimenjeckayang <forkimenjeckayang@gmail.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes OID4VCI c_nonce replay protection by introducing explicit nonce consumption (single-use enforcement) after successful credential issuance, preventing replay of captured proof JWTs within the nonce validity window.
Changes:
- Adds
CNonceHandler.consumeCNonce()and implements it inJwtCNonceHandlerusingSingleUseObjectProvider.putIfAbsent()with TTL derived from remaining nonce validity plus clock skew. - Consumes distinct proof nonces once at the credential request boundary in
OID4VCIssuerEndpoint(while keepingverifyCNonce()side-effect free for multi-proof flows). - Removes prior (incorrect) attestation nonce replay handling and adds regression coverage for consumption semantics.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/base/src/test/java/org/keycloak/tests/oid4vc/NonceEndpointTest.java | Adds a regression test for single-use nonce consumption behavior (provider-level). |
| services/src/main/java/org/keycloak/protocol/oid4vc/issuance/OID4VCIssuerEndpoint.java | Consumes proof c_nonce values once per successful credential request to block replay. |
| services/src/main/java/org/keycloak/protocol/oid4vc/issuance/keybinding/JwtCNonceHandler.java | Implements single-use consumption via SingleUseObjectProvider with hashed key and TTL. |
| services/src/main/java/org/keycloak/protocol/oid4vc/issuance/keybinding/CNonceHandler.java | Introduces the consumeCNonce() API (default throws when unsupported). |
| services/src/main/java/org/keycloak/protocol/oid4vc/issuance/keybinding/AttestationProofValidator.java | Removes earlier attestation-specific replay handling to centralize consumption at request boundary. |
4 tasks
Awambeng
suggested changes
Jun 18, 2026
Signed-off-by: forkimenjeckayang <forkimenjeckayang@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes OID4VCI
c_noncereplay protection by marking verified proof nonces as consumed after successful credential request processing.The nonce is stored in
SingleUseObjectProviderusing a hashed key, with the cache lifetime calculated from the remaining nonce validity plus clock skew. This prevents a captured proof JWT from being replayed within the nonce validity window.Details
CNonceHandler.consumeCNonce()for explicit nonce consumption.JwtCNonceHandlerwithputIfAbsent().exp - now + clockSkew.verifyCNonce()side-effect free so multi-proof and key-attestation flows can validate the same nonce during one request.closes #48043