Skip to content

Commit

Permalink
Allow null apu or apv in OpenID4VP Response (#813)
Browse files Browse the repository at this point in the history
When a wallet did not provide the apu or apv JWE header
parameters in the response, the verifier would respond with
status code (400). To instead allow the verifier to continue
parsing the response, the apu and apv are checked to see if
null and if so, are not added to the sessionTranscript.

Tested manually against a modified wallet which did
not set apu and apv.

Signed-off-by: Suzanna Jiwani <[email protected]>
  • Loading branch information
suzannajiwani authored Dec 4, 2024
1 parent a2fa0ed commit a366d57
Showing 1 changed file with 24 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1000,11 +1000,22 @@ lrW+vvdmRHBgS+ss56uWyYor6W7ah9ygBwYFK4EEACI=
session.deviceResponse = vpToken.toByteArray()
}

// According to ISO 23220-4, the mdoc profile is required to have the apv and apu params
// set in the JWE header. However, there is no such requirement for the sd-jwt profile.
val apv = encryptedJWT.header.agreementPartyVInfo
val apu = encryptedJWT.header.agreementPartyUInfo
if (session.requestFormat == "mdoc") {
if ((apu == null) or (apv == null)) {
// Log a warning here instead of throwing an error since apu + apv are not req
// for functionality.
Logger.w(TAG, "Mdoc wallet did not provide both apu and apv JWE headers as expected.")
}
}
session.sessionTranscript = createSessionTranscriptOpenID4VP(
clientId = clientId,
responseUri = session.responseUri!!,
authorizationRequestNonce = encryptedJWT.header.agreementPartyVInfo.toString(),
mdocGeneratedNonce = encryptedJWT.header.agreementPartyUInfo.toString()
authorizationRequestNonce = apv?.toString(),
mdocGeneratedNonce = apu?.toString()
)

// Save `deviceResponse` and `sessionTranscript`, for later
Expand Down Expand Up @@ -1178,35 +1189,27 @@ lrW+vvdmRHBgS+ss56uWyYor6W7ah9ygBwYFK4EEACI=
private fun createSessionTranscriptOpenID4VP(
clientId: String,
responseUri: String,
authorizationRequestNonce: String,
mdocGeneratedNonce: String
authorizationRequestNonce: String?,
mdocGeneratedNonce: String?
): ByteArray {
val clientIdToHash = Cbor.encode(CborArray.builder()
.add(clientId)
.add(mdocGeneratedNonce)
.end()
.build())
val clientIdHash = Crypto.digest(Algorithm.SHA256, clientIdToHash)
val clientIdBuilder = CborArray.builder().add(clientId)
mdocGeneratedNonce?.let { clientIdBuilder.add(it) }
val clientIdHash = Crypto.digest(Algorithm.SHA256, Cbor.encode(clientIdBuilder.end().build()))

val responseUriToHash = Cbor.encode(CborArray.builder()
.add(responseUri)
.add(mdocGeneratedNonce)
.end()
.build())
val responseUriHash = Crypto.digest(Algorithm.SHA256, responseUriToHash)
val responseUriBuilder = CborArray.builder().add(responseUri)
mdocGeneratedNonce?.let { responseUriBuilder.add(it) }
val responseUriHash = Crypto.digest(Algorithm.SHA256, Cbor.encode(responseUriBuilder.end().build()))

val oid4vpHandover = CborArray.builder()
val oid4vpHandoverBuilder = CborArray.builder()
.add(clientIdHash)
.add(responseUriHash)
.add(authorizationRequestNonce)
.end()
.build()
authorizationRequestNonce?.let { oid4vpHandoverBuilder.add(it) }

return Cbor.encode(
CborArray.builder()
.add(Simple.NULL)
.add(Simple.NULL)
.add(oid4vpHandover)
.add(oid4vpHandoverBuilder.end().build())
.end()
.build()
)
Expand Down

0 comments on commit a366d57

Please sign in to comment.