Skip to content

Commit a52c612

Browse files
committed
feat: return decryption jwk in verified jarm response
Signed-off-by: Timo Glastra <timo@animo.id>
1 parent 0ee7211 commit a52c612

1 file changed

Lines changed: 19 additions & 7 deletions

File tree

packages/openid4vp/src/jarm/jarm-authorization-response/verify-jarm-authorization-response.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
zCompactJwt,
1010
zJwtHeader,
1111
} from '@openid4vc/oauth2'
12+
import { stringToJsonWithErrorHandling } from '@openid4vc/utils'
1213
import z from 'zod'
1314
import type { Openid4vpAuthorizationRequest } from '../../authorization-request/z-authorization-request'
1415
import type { Openid4vpAuthorizationRequestDcApi } from '../../authorization-request/z-authorization-request-dc-api'
@@ -69,7 +70,10 @@ const decryptJarmAuthorizationResponseJwt = async (options: {
6970
throw new Oauth2Error('Failed to decrypt jarm auth response.')
7071
}
7172

72-
return result.payload
73+
return {
74+
decryptionJwk: result.decryptionJwk,
75+
payload: result.payload,
76+
}
7377
}
7478

7579
export interface VerifyJarmAuthorizationResponseOptions {
@@ -104,9 +108,9 @@ export async function verifyJarmAuthorizationResponse(options: VerifyJarmAuthori
104108
callbacks,
105109
authorizationRequestPayload,
106110
})
107-
: jarmAuthorizationResponseJwt
111+
: { payload: jarmAuthorizationResponseJwt, decryptionJwk: undefined }
108112

109-
const responseIsSigned = zCompactJwt.safeParse(decryptedRequestData).success
113+
const responseIsSigned = zCompactJwt.safeParse(decryptedRequestData.payload).success
110114
if (!requestDataIsEncrypted && !responseIsSigned) {
111115
throw new Oauth2Error('Jarm Auth Response must be either encrypted, signed, or signed and encrypted.')
112116
}
@@ -115,15 +119,15 @@ export async function verifyJarmAuthorizationResponse(options: VerifyJarmAuthori
115119

116120
if (responseIsSigned) {
117121
const { header: jwsProtectedHeader, payload: jwsPayload } = decodeJwt({
118-
jwt: decryptedRequestData,
122+
jwt: decryptedRequestData.payload,
119123
headerSchema: z.object({ ...zJwtHeader.shape, kid: z.string() }),
120124
})
121125

122126
const response = zJarmAuthorizationResponse.parse(jwsPayload)
123127
const jwtSigner = jwtSignerFromJwt({ header: jwsProtectedHeader, payload: jwsPayload })
124128

125129
const verificationResult = await options.callbacks.verifyJwt(jwtSigner, {
126-
compact: decryptedRequestData,
130+
compact: decryptedRequestData.payload,
127131
header: jwsProtectedHeader,
128132
payload: jwsPayload,
129133
})
@@ -134,7 +138,10 @@ export async function verifyJarmAuthorizationResponse(options: VerifyJarmAuthori
134138

135139
jarmAuthorizationResponse = response
136140
} else {
137-
const jsonRequestData: unknown = JSON.parse(decryptedRequestData)
141+
const jsonRequestData = stringToJsonWithErrorHandling(
142+
decryptedRequestData.payload,
143+
'Unable to parse decrypted JARM JWE body to JSON'
144+
)
138145
jarmAuthorizationResponse = zJarmAuthorizationResponseEncryptedOnly.parse(jsonRequestData)
139146
}
140147

@@ -150,5 +157,10 @@ export async function verifyJarmAuthorizationResponse(options: VerifyJarmAuthori
150157
: JarmMode.Signed
151158

152159
const issuer = jarmAuthorizationResponse.iss
153-
return { jarmAuthorizationResponse, type, issuer }
160+
return {
161+
jarmAuthorizationResponse,
162+
type,
163+
issuer,
164+
decryptionJwk: decryptedRequestData.decryptionJwk,
165+
}
154166
}

0 commit comments

Comments
 (0)