UNPKG

@sphereon/oid4vc-common

Version:

OpenID 4 Verifiable Credentials Common

1 lines 32.8 kB
{"version":3,"sources":["../lib/index.ts","../lib/jwt/Jwt.types.ts","../lib/jwt/JwkThumbprint.ts","../lib/hasher.ts","../lib/jwt/JwtVerifier.ts","../lib/jwt/jwtUtils.ts","../lib/dpop/DPoP.ts"],"sourcesContent":["import { Loggers } from '@sphereon/ssi-types';\r\n\r\nexport const VCI_LOGGERS = Loggers.DEFAULT;\r\nexport const VCI_LOG_COMMON = VCI_LOGGERS.get('sphereon:oid4vci:common');\r\n\r\nexport * from './types';\r\nexport * from './jwt';\r\nexport * from './dpop';\r\nexport * from './oauth';\r\n\r\nexport { v4 as uuidv4 } from 'uuid';\r\nexport { defaultHasher } from './hasher';\r\n","import { JwtHeader as jwtDecodeJwtHeader, JwtPayload as jwtDecodePayload } from 'jwt-decode';\r\n\r\nimport { JWK } from './Jwk.types';\r\n\r\nexport type JwtHeader = jwtDecodeJwtHeader & {\r\n alg?: string;\r\n x5c?: string[];\r\n kid?: string;\r\n jwk?: JWK;\r\n jwt?: string;\r\n} & Record<string, unknown>;\r\n\r\nexport type JwtPayload = jwtDecodePayload & {\r\n client_id?: string;\r\n nonce?: string;\r\n request_uri?: string;\r\n client_id_scheme?: string;\r\n} & Record<string, unknown>;\r\n\r\nexport enum SigningAlgo {\r\n EDDSA = 'EdDSA',\r\n RS256 = 'RS256',\r\n PS256 = 'PS256',\r\n ES256 = 'ES256',\r\n ES256K = 'ES256K',\r\n}\r\n","// eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n// @ts-ignore\r\nimport * as u8a from 'uint8arrays';\r\n\r\nimport { defaultHasher } from '../hasher';\r\nimport { DigestAlgorithm } from '../types';\r\n\r\nimport { JWK } from './Jwk.types';\r\n\r\nconst check = (value: unknown, description: string) => {\r\n if (typeof value !== 'string' || !value) {\r\n throw Error(`${description} missing or invalid`);\r\n }\r\n};\r\n\r\nexport async function calculateJwkThumbprint(jwk: JWK, digestAlgorithm?: DigestAlgorithm): Promise<string> {\r\n if (!jwk || typeof jwk !== 'object') {\r\n throw new TypeError('JWK must be an object');\r\n }\r\n const algorithm = digestAlgorithm ?? 'sha256';\r\n if (algorithm !== 'sha256' && algorithm !== 'sha384' && algorithm !== 'sha512') {\r\n throw new TypeError('digestAlgorithm must one of \"sha256\", \"sha384\", or \"sha512\"');\r\n }\r\n let components;\r\n switch (jwk.kty) {\r\n case 'EC':\r\n check(jwk.crv, '\"crv\" (Curve) Parameter');\r\n check(jwk.x, '\"x\" (X Coordinate) Parameter');\r\n check(jwk.y, '\"y\" (Y Coordinate) Parameter');\r\n components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y };\r\n break;\r\n case 'OKP':\r\n check(jwk.crv, '\"crv\" (Subtype of Key Pair) Parameter');\r\n check(jwk.x, '\"x\" (Public Key) Parameter');\r\n components = { crv: jwk.crv, kty: jwk.kty, x: jwk.x };\r\n break;\r\n case 'RSA':\r\n check(jwk.e, '\"e\" (Exponent) Parameter');\r\n check(jwk.n, '\"n\" (Modulus) Parameter');\r\n components = { e: jwk.e, kty: jwk.kty, n: jwk.n };\r\n break;\r\n case 'oct':\r\n check(jwk.k, '\"k\" (Key Value) Parameter');\r\n components = { k: jwk.k, kty: jwk.kty };\r\n break;\r\n default:\r\n throw Error('\"kty\" (Key Type) Parameter missing or unsupported');\r\n }\r\n return u8a.toString(defaultHasher(JSON.stringify(components), algorithm), 'base64url');\r\n}\r\n\r\nexport async function getDigestAlgorithmFromJwkThumbprintUri(uri: string): Promise<DigestAlgorithm> {\r\n const match = uri.match(/^urn:ietf:params:oauth:jwk-thumbprint:sha-(\\w+):/);\r\n if (!match) {\r\n throw new Error(`Invalid JWK thumbprint URI structure ${uri}`);\r\n }\r\n const algorithm = `sha${match[1]}` as DigestAlgorithm;\r\n if (algorithm !== 'sha256' && algorithm !== 'sha384' && algorithm !== 'sha512') {\r\n throw new Error(`Invalid JWK thumbprint URI digest algorithm ${uri}`);\r\n }\r\n return algorithm;\r\n}\r\n\r\nexport async function calculateJwkThumbprintUri(jwk: JWK, digestAlgorithm: DigestAlgorithm = 'sha256'): Promise<string> {\r\n const thumbprint = await calculateJwkThumbprint(jwk, digestAlgorithm);\r\n return `urn:ietf:params:oauth:jwk-thumbprint:sha-${digestAlgorithm.slice(-3)}:${thumbprint}`;\r\n}\r\n","import { HasherSync } from '@sphereon/ssi-types';\r\nimport sha from 'sha.js';\r\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n// @ts-ignore\r\nimport * as u8a from 'uint8arrays';\r\n\r\nconst supportedAlgorithms = ['sha256', 'sha384', 'sha512'] as const;\r\ntype SupportedAlgorithms = (typeof supportedAlgorithms)[number];\r\n\r\nexport const defaultHasher: HasherSync = (data, algorithm) => {\r\n const sanitizedAlgorithm = algorithm.toLowerCase().replace(/[-_]/g, '');\r\n if (!supportedAlgorithms.includes(sanitizedAlgorithm as SupportedAlgorithms)) {\r\n throw new Error(`Unsupported hashing algorithm ${algorithm}`);\r\n }\r\n\r\n return new Uint8Array(\r\n sha(sanitizedAlgorithm as SupportedAlgorithms)\r\n .update(typeof data === 'string' ? u8a.fromString(data) : data)\r\n .digest(),\r\n );\r\n};\r\n","import { JWK } from './Jwk.types';\r\nimport { JwtHeader, JwtPayload, SigningAlgo } from './Jwt.types';\r\nimport { JwtProtectionMethod, JwtType } from './jwtUtils';\r\n\r\nexport interface JwtVerifierBase {\r\n type: JwtType;\r\n method: JwtProtectionMethod;\r\n}\r\n\r\nexport interface DidJwtVerifier extends JwtVerifierBase {\r\n method: 'did';\r\n\r\n alg: SigningAlgo | string;\r\n didUrl: string;\r\n}\r\n\r\nexport interface X5cJwtVerifier extends JwtVerifierBase {\r\n method: 'x5c';\r\n\r\n alg: SigningAlgo | string;\r\n\r\n /**\r\n *\r\n * Array of base64-encoded certificate strings in the DER-format.\r\n *\r\n * The certificate containing the public key corresponding to the key used to digitally sign the JWS MUST be the first certificate.\r\n */\r\n x5c: Array<string>;\r\n\r\n /**\r\n * The jwt issuer\r\n */\r\n issuer: string;\r\n}\r\n\r\nexport interface OpenIdFederationJwtVerifier extends JwtVerifierBase {\r\n method: 'openid-federation';\r\n\r\n /**\r\n * The OpenId federation Entity\r\n */\r\n entityId: string;\r\n}\r\n\r\nexport interface JwkJwtVerifier extends JwtVerifierBase {\r\n method: 'jwk';\r\n alg: SigningAlgo | string;\r\n\r\n jwk: JWK;\r\n}\r\n\r\nexport interface CustomJwtVerifier extends JwtVerifierBase {\r\n method: 'custom';\r\n}\r\n\r\nexport type JwtVerifier = DidJwtVerifier | X5cJwtVerifier | CustomJwtVerifier | JwkJwtVerifier | OpenIdFederationJwtVerifier;\r\n\r\nexport const getDidJwtVerifier = (jwt: { header: JwtHeader; payload: JwtPayload }, options: { type: JwtType }): DidJwtVerifier => {\r\n const { type } = options;\r\n if (!jwt.header.kid) throw new Error(`Received an invalid JWT. Missing kid header.`);\r\n if (!jwt.header.alg) throw new Error(`Received an invalid JWT. Missing alg header.`);\r\n\r\n if (!jwt.header.kid.includes('#')) {\r\n throw new Error(`Received an invalid JWT.. '${type}' contains an invalid kid header.`);\r\n }\r\n return { method: 'did', didUrl: jwt.header.kid, type: type, alg: jwt.header.alg };\r\n};\r\n\r\nconst getIssuer = (type: JwtType, payload: JwtPayload): string => {\r\n // For 'request-object' the `iss` value is not required so we map the issuer to client_id\r\n if (type === 'request-object') {\r\n if (!payload.client_id) {\r\n throw new Error('Missing required field client_id in request object JWT');\r\n }\r\n return payload.client_id as string;\r\n }\r\n\r\n if (typeof payload.iss !== 'string') {\r\n throw new Error(`Received an invalid JWT. '${type}' contains an invalid iss claim or it is missing.`);\r\n }\r\n return payload.iss;\r\n};\r\n\r\nexport const getX5cVerifier = (jwt: { header: JwtHeader; payload: JwtPayload }, options: { type: JwtType }): X5cJwtVerifier => {\r\n const { type } = options;\r\n if (!jwt.header.x5c) throw new Error(`Received an invalid JWT. Missing x5c header.`);\r\n if (!jwt.header.alg) throw new Error(`Received an invalid JWT. Missing alg header.`);\r\n\r\n if (!Array.isArray(jwt.header.x5c) || jwt.header.x5c.length === 0 || !jwt.header.x5c.every((cert) => typeof cert === 'string')) {\r\n throw new Error(`Received an invalid JWT.. '${type}' contains an invalid x5c header.`);\r\n }\r\n\r\n return {\r\n method: 'x5c',\r\n x5c: jwt.header.x5c,\r\n issuer: getIssuer(type, jwt.payload),\r\n type: type,\r\n alg: jwt.header.alg,\r\n };\r\n};\r\n\r\nexport const getJwkVerifier = async (jwt: { header: JwtHeader; payload: JwtPayload }, options: { type: JwtType }): Promise<JwkJwtVerifier> => {\r\n const { type } = options;\r\n if (!jwt.header.jwk) throw new Error(`Received an invalid JWT. Missing jwk header.`);\r\n if (!jwt.header.alg) throw new Error(`Received an invalid JWT. Missing alg header.`);\r\n\r\n if (typeof jwt.header.jwk !== 'object') {\r\n throw new Error(`Received an invalid JWT. '${type}' contains an invalid jwk header.`);\r\n }\r\n\r\n return { method: 'jwk', type, jwk: jwt.header.jwk, alg: jwt.header.alg };\r\n};\r\n\r\nexport const getJwtVerifierWithContext = async (\r\n jwt: { header: JwtHeader; payload: JwtPayload },\r\n options: { type: JwtType },\r\n): Promise<JwtVerifier> => {\r\n const { header, payload } = jwt;\r\n\r\n if (header.kid?.startsWith('did:')) return getDidJwtVerifier({ header, payload }, options);\r\n else if (jwt.header.x5c) return getX5cVerifier({ header, payload }, options);\r\n else if (jwt.header.jwk) return getJwkVerifier({ header, payload }, options);\r\n\r\n return { method: 'custom', type: options.type };\r\n};\r\n\r\nexport type VerifyJwtCallbackBase<T extends JwtVerifier> = (\r\n jwtVerifier: T,\r\n jwt: { header: JwtHeader; payload: JwtPayload; raw: string },\r\n) => Promise<boolean>;\r\n","import { jwtDecode } from 'jwt-decode';\r\n\r\nimport { JwtHeader, JwtPayload } from './Jwt.types';\r\n\r\nexport type JwtType = 'id-token' | 'request-object' | 'verifier-attestation' | 'dpop';\r\n\r\nexport type JwtProtectionMethod = 'did' | 'x5c' | 'jwk' | 'openid-federation' | 'custom';\r\n\r\nexport function parseJWT<Header = JwtHeader, Payload = JwtPayload>(jwt: string) {\r\n const header = jwtDecode<Header>(jwt, { header: true });\r\n const payload = jwtDecode<Payload>(jwt, { header: false });\r\n\r\n if (!payload || !header) {\r\n throw new Error('Jwt Payload and/or Header could not be parsed');\r\n }\r\n return { header, payload };\r\n}\r\n\r\n/**\r\n * The maximum allowed clock skew time in seconds. If an time based validation\r\n * is performed against current time (`now`), the validation can be of by the skew\r\n * time.\r\n *\r\n * See https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.5\r\n */\r\nconst DEFAULT_SKEW_TIME = 60;\r\n\r\nexport function getNowSkewed(now?: number, skewTime?: number) {\r\n const _now = now ? now : epochTime();\r\n const _skewTime = skewTime ? skewTime : DEFAULT_SKEW_TIME;\r\n\r\n return {\r\n nowSkewedPast: _now - _skewTime,\r\n nowSkewedFuture: _now + _skewTime,\r\n };\r\n}\r\n\r\n/**\r\n * Returns the current unix timestamp in seconds.\r\n */\r\nexport function epochTime() {\r\n return Math.floor(Date.now() / 1000);\r\n}\r\n\r\nexport const BASE64_URL_REGEX = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;\r\n\r\nexport const isJws = (jws: string) => {\r\n const jwsParts = jws.split('.');\r\n return jwsParts.length === 3 && jwsParts.every((part) => BASE64_URL_REGEX.test(part));\r\n};\r\nexport const isJwe = (jwe: string) => {\r\n const jweParts = jwe.split('.');\r\n return jweParts.length === 5 && jweParts.every((part) => BASE64_URL_REGEX.test(part));\r\n};\r\n\r\nexport const decodeProtectedHeader = (jwt: string) => {\r\n return jwtDecode(jwt, { header: true });\r\n};\r\n\r\nexport const decodeJwt = (jwt: string): JwtPayload => {\r\n return jwtDecode(jwt, { header: false });\r\n};\r\n\r\nexport const checkExp = (input: {\r\n exp: number;\r\n now?: number; // The number of milliseconds elapsed since midnight, January 1, 1970 Universal Coordinated Time (UTC).\r\n clockSkew?: number;\r\n}) => {\r\n const { exp, now, clockSkew } = input;\r\n return exp < (now ?? Date.now() / 1000) - (clockSkew ?? 120);\r\n};\r\n","import { jwtDecode } from 'jwt-decode';\r\n// eslint-disable-next-line @typescript-eslint/ban-ts-comment\r\n// @ts-ignore\r\nimport * as u8a from 'uint8arrays';\r\nimport { v4 as uuidv4 } from 'uuid';\r\n\r\nimport { defaultHasher } from '../hasher';\r\nimport {\r\n calculateJwkThumbprint,\r\n CreateJwtCallback,\r\n epochTime,\r\n getNowSkewed,\r\n JWK,\r\n JwtHeader,\r\n JwtIssuerJwk,\r\n JwtPayload,\r\n parseJWT,\r\n SigningAlgo,\r\n VerifyJwtCallbackBase,\r\n} from '../jwt';\r\n\r\nexport const dpopTokenRequestNonceError = 'use_dpop_nonce';\r\n\r\nexport interface DPoPJwtIssuerWithContext extends JwtIssuerJwk {\r\n type: 'dpop';\r\n dPoPSigningAlgValuesSupported?: string[];\r\n}\r\n\r\nexport type DPoPJwtPayloadProps = {\r\n htu: string;\r\n iat: number;\r\n htm: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'TRACE' | 'CONNECT' | 'PATCH';\r\n ath?: string;\r\n nonce?: string;\r\n jti: string;\r\n};\r\nexport type DPoPJwtHeaderProps = { typ: 'dpop+jwt'; alg: SigningAlgo; jwk: JWK };\r\nexport type CreateDPoPJwtPayloadProps = Omit<DPoPJwtPayloadProps, 'iat' | 'jti' | 'ath'> & { accessToken?: string };\r\n\r\nexport interface CreateDPoPOpts<JwtPayloadProps = CreateDPoPJwtPayloadProps> {\r\n createJwtCallback: CreateJwtCallback<DPoPJwtIssuerWithContext>;\r\n jwtIssuer: Omit<JwtIssuerJwk, 'method' | 'type'>;\r\n jwtPayloadProps: Record<string, unknown> & JwtPayloadProps;\r\n dPoPSigningAlgValuesSupported?: (string | SigningAlgo)[];\r\n}\r\n\r\nexport type CreateDPoPClientOpts = CreateDPoPOpts<Omit<CreateDPoPJwtPayloadProps, 'htm' | 'htu'>>;\r\n\r\nexport function getCreateDPoPOptions(\r\n createDPoPClientOpts: CreateDPoPClientOpts,\r\n endPointUrl: string,\r\n resourceRequestOpts?: { accessToken: string },\r\n): CreateDPoPOpts {\r\n const htu = endPointUrl.split('?')[0].split('#')[0];\r\n return {\r\n ...createDPoPClientOpts,\r\n jwtPayloadProps: {\r\n ...createDPoPClientOpts.jwtPayloadProps,\r\n htu,\r\n htm: 'POST',\r\n ...(resourceRequestOpts && { accessToken: resourceRequestOpts.accessToken }),\r\n },\r\n };\r\n}\r\n\r\nexport async function createDPoP(options: CreateDPoPOpts): Promise<string> {\r\n const { createJwtCallback, jwtIssuer, jwtPayloadProps, dPoPSigningAlgValuesSupported } = options;\r\n\r\n if (jwtPayloadProps.accessToken && (jwtPayloadProps.accessToken?.startsWith('DPoP ') || jwtPayloadProps.accessToken?.startsWith('Bearer '))) {\r\n throw new Error('expected access token without scheme');\r\n }\r\n\r\n const ath = jwtPayloadProps.accessToken ? u8a.toString(defaultHasher(jwtPayloadProps.accessToken, 'sha256'), 'base64url') : undefined;\r\n return createJwtCallback(\r\n { method: 'jwk', type: 'dpop', alg: jwtIssuer.alg, jwk: jwtIssuer.jwk, dPoPSigningAlgValuesSupported },\r\n {\r\n header: { ...jwtIssuer, typ: 'dpop+jwt', alg: jwtIssuer.alg, jwk: jwtIssuer.jwk },\r\n payload: {\r\n ...jwtPayloadProps,\r\n iat: epochTime(),\r\n jti: uuidv4(),\r\n ...(ath && { ath }),\r\n },\r\n },\r\n );\r\n}\r\n\r\nexport type DPoPVerifyJwtCallback = VerifyJwtCallbackBase<JwtIssuerJwk & { type: 'dpop' }>;\r\nexport interface DPoPVerifyOptions {\r\n expectedNonce?: string;\r\n acceptedAlgorithms?: (string | SigningAlgo)[];\r\n // defaults to 300 seconds (5 minutes)\r\n maxIatAgeInSeconds?: number;\r\n expectAccessToken?: boolean;\r\n jwtVerifyCallback: DPoPVerifyJwtCallback;\r\n now?: number;\r\n}\r\n\r\nexport async function verifyDPoP(\r\n request: { headers: Record<string, string | string[] | undefined>; fullUrl: string } & Pick<Request, 'method'>,\r\n options: DPoPVerifyOptions,\r\n) {\r\n // There is not more than one DPoP HTTP request header field.\r\n const dpop = request.headers['dpop'];\r\n if (!dpop || typeof dpop !== 'string') {\r\n throw new Error('missing or invalid dpop header. Expected compact JWT');\r\n }\r\n\r\n // The DPoP HTTP request header field value is a single and well-formed JWT.\r\n const { header: dPoPHeader, payload: dPoPPayload } = parseJWT<JwtHeader, JwtPayload & Partial<DPoPJwtPayloadProps>>(dpop);\r\n\r\n // Ensure all required header claims are present\r\n if (dPoPHeader.typ !== 'dpop+jwt' || !dPoPHeader.alg || !dPoPHeader.jwk || typeof dPoPHeader.jwk !== 'object' || dPoPHeader.jwk.d) {\r\n throw new Error('invalid_dpop_proof. Invalid header claims');\r\n }\r\n\r\n // Ensure all required payload claims are present\r\n if (!dPoPPayload.htm || !dPoPPayload.htu || !dPoPPayload.iat || !dPoPPayload.jti) {\r\n throw new Error('invalid_dpop_proof. Missing required claims');\r\n }\r\n\r\n // Validate alg is supported\r\n if (options?.acceptedAlgorithms && !options.acceptedAlgorithms.includes(dPoPHeader.alg)) {\r\n throw new Error(`invalid_dpop_proof. Invalid 'alg' claim '${dPoPHeader.alg}'. Only ${options.acceptedAlgorithms.join(', ')} are supported.`);\r\n }\r\n\r\n // Validate nonce if provided\r\n if ((options?.expectedNonce && !dPoPPayload.nonce) || dPoPPayload.nonce !== options.expectedNonce) {\r\n throw new Error('invalid_dpop_proof. Nonce mismatch');\r\n }\r\n\r\n // Verify JWT signature\r\n try {\r\n const verificationResult = await options.jwtVerifyCallback(\r\n {\r\n method: 'jwk',\r\n type: 'dpop',\r\n jwk: dPoPHeader.jwk,\r\n alg: dPoPHeader.alg,\r\n },\r\n {\r\n header: dPoPHeader,\r\n payload: dPoPPayload,\r\n raw: dpop,\r\n },\r\n );\r\n\r\n if (!verificationResult) {\r\n throw new Error('invalid_dpop_proof. Invalid JWT signature');\r\n }\r\n } catch (error: unknown) {\r\n throw new Error('invalid_dpop_proof. Invalid JWT signature. ' + (error instanceof Error ? error.message : 'Unknown error'));\r\n }\r\n\r\n // Validate htm claim\r\n if (dPoPPayload.htm !== request.method) {\r\n throw new Error(`invalid_dpop_proof. Invalid htm claim. Must match request method '${request.method}'`);\r\n }\r\n\r\n // The htu claim matches the HTTP URI value for the HTTP request in which the JWT was received, ignoring any query and fragment parts.\r\n const currentUri = request.fullUrl.split('?')[0].split('#')[0];\r\n if (dPoPPayload.htu !== currentUri) {\r\n throw new Error('invalid_dpop_proof. Invalid htu claim');\r\n }\r\n\r\n // Validate nonce if provided\r\n if ((options.expectedNonce && dPoPPayload.nonce !== options.expectedNonce) || (!options.expectedNonce && dPoPPayload.nonce)) {\r\n throw new Error('invalid_dpop_proof. Nonce mismatch');\r\n }\r\n\r\n // Validate iat claim\r\n const { nowSkewedPast, nowSkewedFuture } = getNowSkewed(options.now);\r\n if (\r\n // iat claim is too far in the future\r\n nowSkewedPast - (options.maxIatAgeInSeconds ?? 60) > dPoPPayload.iat ||\r\n // iat claim is too old\r\n nowSkewedFuture + (options.maxIatAgeInSeconds ?? 60) < dPoPPayload.iat\r\n ) {\r\n // 5 minute window\r\n throw new Error('invalid_dpop_proof. Invalid iat claim');\r\n }\r\n\r\n // If access token is present, validate ath claim\r\n const authorizationHeader = request.headers.authorization;\r\n if (!options.expectAccessToken && authorizationHeader) {\r\n throw new Error('invalid_dpop_proof. Received an unexpected authorization header.');\r\n }\r\n\r\n if (options.expectAccessToken) {\r\n if (!dPoPPayload.ath) {\r\n throw new Error('invalid_dpop_proof. Missing expected ath claim.');\r\n }\r\n\r\n // validate that the DPOP proof is made for the provided access token\r\n if (!authorizationHeader || typeof authorizationHeader !== 'string' || !authorizationHeader.startsWith('DPoP ')) {\r\n throw new Error('invalid_dpop_proof. Invalid authorization header.');\r\n }\r\n\r\n const accessToken = authorizationHeader.replace('DPoP ', '');\r\n const expectedAth = u8a.toString(defaultHasher(accessToken, 'sha256'), 'base64url');\r\n if (dPoPPayload.ath !== expectedAth) {\r\n throw new Error('invalid_dpop_proof. Invalid ath claim');\r\n }\r\n\r\n // validate that the access token is signed with the same key as the DPOP proof\r\n const accessTokenPayload = jwtDecode<JwtPayload & { cnf?: { jkt?: string } }>(accessToken, { header: false });\r\n if (!accessTokenPayload.cnf?.jkt) {\r\n throw new Error('invalid_dpop_proof. Access token is missing the jkt claim');\r\n }\r\n\r\n const thumprint = await calculateJwkThumbprint(dPoPHeader.jwk, 'sha256');\r\n if (accessTokenPayload.cnf?.jkt !== thumprint) {\r\n throw new Error('invalid_dpop_proof. JwkThumbprint mismatch');\r\n }\r\n }\r\n\r\n // If all validations pass, return the dpop jwk\r\n return dPoPHeader.jwk;\r\n}\r\n\r\n/**\r\n * DPoP verifications for resource requests\r\n * For Bearer token compatibility jwt's must have a token_type claim\r\n * The access token itself must be validated before using this method\r\n * If the token_type is not DPoP, then the request is not a DPoP request\r\n * and we don't need to verify the DPoP proof\r\n */\r\nexport async function verifyResourceDPoP(\r\n request: { headers: Record<string, string | string[] | undefined>; fullUrl: string } & Pick<Request, 'method'>,\r\n options: Omit<DPoPVerifyOptions, 'expectAccessToken'>,\r\n) {\r\n if (!request.headers.authorization || typeof request.headers.authorization !== 'string') {\r\n throw new Error('Received an invalid resource request. Missing authorization header.');\r\n }\r\n const tokenPayload = jwtDecode<JwtPayload & { token_type?: string }>(request.headers.authorization, { header: false });\r\n const tokenType = tokenPayload.token_type;\r\n\r\n if (tokenType !== 'DPoP') {\r\n return;\r\n }\r\n\r\n return verifyDPoP(request, { ...options, expectAccessToken: true });\r\n}\r\n"],"mappings":"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","names":["SigningAlgo","u8a","supportedAlgorithms","defaultHasher","data","algorithm","sanitizedAlgorithm","toLowerCase","replace","includes","Error","Uint8Array","sha","update","fromString","digest","check","value","description","Error","calculateJwkThumbprint","jwk","digestAlgorithm","TypeError","algorithm","components","kty","crv","x","y","e","n","k","toString","defaultHasher","JSON","stringify","getDigestAlgorithmFromJwkThumbprintUri","uri","match","calculateJwkThumbprintUri","thumbprint","slice","getDidJwtVerifier","jwt","options","type","header","kid","Error","alg","includes","method","didUrl","getIssuer","payload","client_id","iss","getX5cVerifier","x5c","Array","isArray","length","every","cert","issuer","getJwkVerifier","jwk","getJwtVerifierWithContext","startsWith","parseJWT","jwt","header","jwtDecode","payload","Error","DEFAULT_SKEW_TIME","getNowSkewed","now","skewTime","_now","epochTime","_skewTime","nowSkewedPast","nowSkewedFuture","Math","floor","Date","BASE64_URL_REGEX","isJws","jws","jwsParts","split","length","every","part","test","isJwe","jwe","jweParts","decodeProtectedHeader","decodeJwt","checkExp","input","exp","clockSkew","import_jwt_decode","u8a","dpopTokenRequestNonceError","getCreateDPoPOptions","createDPoPClientOpts","endPointUrl","resourceRequestOpts","htu","split","jwtPayloadProps","htm","accessToken","createDPoP","options","createJwtCallback","jwtIssuer","dPoPSigningAlgValuesSupported","startsWith","Error","ath","toString","defaultHasher","undefined","method","type","alg","jwk","header","typ","payload","iat","epochTime","jti","uuidv4","verifyDPoP","request","dpop","headers","dPoPHeader","dPoPPayload","parseJWT","d","acceptedAlgorithms","includes","join","expectedNonce","nonce","verificationResult","jwtVerifyCallback","raw","error","message","currentUri","fullUrl","nowSkewedPast","nowSkewedFuture","getNowSkewed","now","maxIatAgeInSeconds","authorizationHeader","authorization","expectAccessToken","replace","expectedAth","accessTokenPayload","jwtDecode","cnf","jkt","thumprint","calculateJwkThumbprint","verifyResourceDPoP","tokenPayload","tokenType","token_type","import_uuid","VCI_LOGGERS","Loggers","DEFAULT","VCI_LOG_COMMON","get"]}