Deferred Credential Response encrypted when encryption was requested
OID4VCI 1.0 §9.2MUSTRoles: issuer
Requirement as recorded in the ProtocolSoup registry
If the Client requested an encrypted response by including the credential_response_encryption object in the request, the Credential Issuer MUST encode the information in the Deferred Credential Response as specified by Section 10, using the parameters from the credential_response_encryption object.
Read §9.2 in OID4VCI 1.0Self-test verdict
PassCommit 011029cEvaluated
This is ProtocolSoup's result against its own implementation at the commit shown. It is not a certification of ProtocolSoup or of any other product.
Tests
- TestDeferredPendingResponseIsEncryptedWhenRequested
./internal/protocols/oid4vci
Pass
Implementation
Explainer
What this requires
Section 9.2 applies requested encryption to the Deferred Credential Response and adds "Note that this is done regardless of the content." The response is encrypted when it delivers Credentials, and also when it only reports that issuance is still pending and the Wallet should poll again. The key to use is the one in the Deferred Credential Request itself: "The credential_response_encryption object may be different from the one included in the initial Credential Request so the Credential Issuer MUST use the newly provided one."
Why it exists
A Wallet that asked for encryption expects every answer in that form. If the pending answer comes back as plaintext JSON while the final one is a JWE, the Wallet's handling depends on content it cannot see until it has parsed the response. A Wallet that accepts both forms can also be fed a forged plaintext answer. Using one encoding for every response keeps the rule simple: once encryption is requested, nothing comes back in the clear.
What non-compliance looks like
The Issuer encrypts only the response that delivers Credentials. The pending answer, with transaction_id and interval, comes back as application/json even though the request carried credential_response_encryption. A related failure is encrypting a deferred response with the key from the original Credential Request instead of the one the Deferred Credential Request supplied.
How ProtocolSoup tests it
handleDeferredCredential validates the Deferred Credential Request's own credential_response_encryption object and writes every successful answer through writeCredentialResponse. When the Credential is not ready, that is an HTTP 202 with transaction_id, interval and a Retry-After header. Given an encryption object, it encodes the body as a JWE with Content-Type: application/jwt; without one it returns JSON.
TestDeferredPendingResponseIsEncryptedWhenRequested starts a deferred issuance and receives a transaction_id. It then polls before the Credential is ready, with an encrypted request carrying a fresh response key. It asserts HTTP 202, Content-Type: application/jwt and a Retry-After header, then decrypts the body with that key. The decrypted body must carry the same transaction_id and an interval of at least one second.