From aa56dbfc49b46fc559f4e4d2affcb20ddd91a525 Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Thu, 5 Sep 2024 14:00:29 +0200 Subject: [PATCH 1/2] fix: changes for oid4vc conformance tests Signed-off-by: Timo Glastra --- packages/common/lib/jwt/JwtVerifier.ts | 17 ++++++++++++++--- .../lib/authorization-response/Payload.ts | 3 +-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/common/lib/jwt/JwtVerifier.ts b/packages/common/lib/jwt/JwtVerifier.ts index ec446987..71834743 100644 --- a/packages/common/lib/jwt/JwtVerifier.ts +++ b/packages/common/lib/jwt/JwtVerifier.ts @@ -75,11 +75,22 @@ export const getX5cVerifier = (jwt: { header: JwtHeader; payload: JwtPayload }, throw new Error(`Received an invalid JWT.. '${type}' contains an invalid x5c header.`); } - if (typeof jwt.payload.iss !== 'string') { - throw new Error(`Received an invalid JWT. '${type}' contains an invalid iss claim.`); + let issuer: string; + + // For 'request-object' the `iss` value is not required + if (type !== 'request-object') { + if (typeof jwt.payload.iss !== 'string') { + throw new Error(`Received an invalid JWT. '${type}' contains an invalid iss claim.`); + } + + issuer = jwt.payload.iss; + } else { + if (!jwt.payload.client_id) throw new Error('Missing required field client_id in request object JWT'); + + issuer = jwt.payload.client_id; } - return { method: 'x5c', x5c: jwt.header.x5c, issuer: jwt.payload.iss, type: type, alg: jwt.header.alg }; + return { method: 'x5c', x5c: jwt.header.x5c, issuer, type: type, alg: jwt.header.alg }; }; export const getJwkVerifier = async (jwt: { header: JwtHeader; payload: JwtPayload }, options: { type: JwtType }): Promise => { diff --git a/packages/siop-oid4vp/lib/authorization-response/Payload.ts b/packages/siop-oid4vp/lib/authorization-response/Payload.ts index 83997190..bdd7cc80 100644 --- a/packages/siop-oid4vp/lib/authorization-response/Payload.ts +++ b/packages/siop-oid4vp/lib/authorization-response/Payload.ts @@ -21,10 +21,9 @@ export const createResponsePayload = async ( const state: string | undefined = await authorizationRequest.getMergedProperty('state') const responsePayload: AuthorizationResponsePayload = { - ...(responseOpts.accessToken && { access_token: responseOpts.accessToken }), + ...(responseOpts.accessToken && { access_token: responseOpts.accessToken, expires_in: responseOpts.expiresIn || 3600 }), ...(responseOpts.tokenType && { token_type: responseOpts.tokenType }), ...(responseOpts.refreshToken && { refresh_token: responseOpts.refreshToken }), - expires_in: responseOpts.expiresIn || 3600, state, } From ead518e72f1fd8a8c88adab4fd073199ee2ea52b Mon Sep 17 00:00:00 2001 From: Timo Glastra Date: Tue, 17 Sep 2024 17:19:45 +0200 Subject: [PATCH 2/2] chore: resolve feedback Signed-off-by: Timo Glastra --- packages/common/lib/jwt/JwtVerifier.ts | 38 +++++++++++++++----------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/packages/common/lib/jwt/JwtVerifier.ts b/packages/common/lib/jwt/JwtVerifier.ts index 71834743..732a5d53 100644 --- a/packages/common/lib/jwt/JwtVerifier.ts +++ b/packages/common/lib/jwt/JwtVerifier.ts @@ -66,6 +66,21 @@ export const getDidJwtVerifier = (jwt: { header: JwtHeader; payload: JwtPayload return { method: 'did', didUrl: jwt.header.kid, type: type, alg: jwt.header.alg }; }; +const getIssuer = (type: JwtType, payload: JwtPayload): string => { + // For 'request-object' the `iss` value is not required so we map the issuer to client_id + if (type === 'request-object') { + if (!payload.client_id) { + throw new Error('Missing required field client_id in request object JWT'); + } + return payload.client_id as string; + } + + if (typeof payload.iss !== 'string') { + throw new Error(`Received an invalid JWT. '${type}' contains an invalid iss claim or it is missing.`); + } + return payload.iss; +}; + export const getX5cVerifier = (jwt: { header: JwtHeader; payload: JwtPayload }, options: { type: JwtType }): X5cJwtVerifier => { const { type } = options; if (!jwt.header.x5c) throw new Error(`Received an invalid JWT. Missing x5c header.`); @@ -75,22 +90,13 @@ export const getX5cVerifier = (jwt: { header: JwtHeader; payload: JwtPayload }, throw new Error(`Received an invalid JWT.. '${type}' contains an invalid x5c header.`); } - let issuer: string; - - // For 'request-object' the `iss` value is not required - if (type !== 'request-object') { - if (typeof jwt.payload.iss !== 'string') { - throw new Error(`Received an invalid JWT. '${type}' contains an invalid iss claim.`); - } - - issuer = jwt.payload.iss; - } else { - if (!jwt.payload.client_id) throw new Error('Missing required field client_id in request object JWT'); - - issuer = jwt.payload.client_id; - } - - return { method: 'x5c', x5c: jwt.header.x5c, issuer, type: type, alg: jwt.header.alg }; + return { + method: 'x5c', + x5c: jwt.header.x5c, + issuer: getIssuer(type, jwt.payload), + type: type, + alg: jwt.header.alg, + }; }; export const getJwkVerifier = async (jwt: { header: JwtHeader; payload: JwtPayload }, options: { type: JwtType }): Promise => {