@credo-ts/openid4vc 0.6.0-pr-2539-20251127090105 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/build/OpenId4VcApi.mjs +2 -2
  2. package/build/_virtual/{_@oxc-project_runtime@0.97.0 → _@oxc-project_runtime@0.99.0}/helpers/decorate.mjs +1 -1
  3. package/build/_virtual/{_@oxc-project_runtime@0.97.0 → _@oxc-project_runtime@0.99.0}/helpers/decorateMetadata.mjs +1 -1
  4. package/build/_virtual/{_@oxc-project_runtime@0.97.0 → _@oxc-project_runtime@0.99.0}/helpers/decorateParam.mjs +1 -1
  5. package/build/openid4vc-holder/OpenId4VcHolderApi.mjs +2 -2
  6. package/build/openid4vc-holder/OpenId4VciHolderService.mjs +7 -7
  7. package/build/openid4vc-holder/OpenId4VciHolderService.mjs.map +1 -1
  8. package/build/openid4vc-holder/OpenId4vpHolderService.mjs +2 -2
  9. package/build/openid4vc-issuer/OpenId4VcIssuerApi.d.mts +1 -0
  10. package/build/openid4vc-issuer/OpenId4VcIssuerApi.d.mts.map +1 -1
  11. package/build/openid4vc-issuer/OpenId4VcIssuerApi.mjs +2 -2
  12. package/build/openid4vc-issuer/OpenId4VcIssuerService.d.mts +1 -0
  13. package/build/openid4vc-issuer/OpenId4VcIssuerService.d.mts.map +1 -1
  14. package/build/openid4vc-issuer/OpenId4VcIssuerService.mjs +4 -3
  15. package/build/openid4vc-issuer/OpenId4VcIssuerService.mjs.map +1 -1
  16. package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRecord.mjs +2 -2
  17. package/build/openid4vc-issuer/repository/OpenId4VcIssuanceSessionRepository.mjs +3 -3
  18. package/build/openid4vc-issuer/repository/OpenId4VcIssuerRecord.mjs +2 -2
  19. package/build/openid4vc-issuer/repository/OpenId4VcIssuerRepository.mjs +3 -3
  20. package/build/openid4vc-issuer/router/credentialEndpoint.mjs +1 -1
  21. package/build/openid4vc-issuer/router/credentialEndpoint.mjs.map +1 -1
  22. package/build/openid4vc-verifier/OpenId4VcVerifierApi.mjs +2 -2
  23. package/build/openid4vc-verifier/OpenId4VpVerifierService.d.mts.map +1 -1
  24. package/build/openid4vc-verifier/OpenId4VpVerifierService.mjs +16 -9
  25. package/build/openid4vc-verifier/OpenId4VpVerifierService.mjs.map +1 -1
  26. package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRecord.mjs +2 -2
  27. package/build/openid4vc-verifier/repository/OpenId4VcVerificationSessionRepository.mjs +3 -3
  28. package/build/openid4vc-verifier/repository/OpenId4VcVerifierRepository.mjs +3 -3
  29. package/build/shared/callbacks.mjs +1 -1
  30. package/build/shared/callbacks.mjs.map +1 -1
  31. package/build/shared/utils.mjs +1 -1
  32. package/build/shared/utils.mjs.map +1 -1
  33. package/package.json +10 -14
@@ -1 +1 @@
1
- {"version":3,"file":"OpenId4VpVerifierService.d.mts","names":[],"sources":["../../src/openid4vc-verifier/OpenId4VpVerifierService.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;cAgGa,wBAAA;;;EAAA,QAAA,sBAAwB;EAEgB,QAAA,2BAAA;EACnB,QAAA,MAAA;EACE,QAAA,sCAAA;EACK,WAAA,CAAA,MAAA,EAHY,MAGZ,EAAA,oBAAA,EAFP,oBAEO,EAAA,sBAAA,EADL,sBACK,EAAA,2BAAA,EAAA,2BAAA,EAAA,MAAA,EACrB,6BADqB,EAAA,sCAAA,EAEW,sCAFX;EACrB,QAAA,oBAAA;EACgC,0BAAA,CAAA,YAAA,EAWlC,YAXkC,EAAA,OAAA,EAYvC,0CAZuC,GAAA;IAWlC,QAAA,EACoD,uBADpD;EACL,CAAA,CAAA,EACR,OADQ,CACA,yCADA,CAAA;EAAyD,QAAA,uBAAA;EACzD,QAAA,0BAAA;EAAR,2BAAA,CAAA,YAAA,EAyUa,YAzUb,EAAA,OAAA,EA0UQ,2CA1UR,GAAA;IAyUa;;;IAOL,mBAAA,EAFc,kCAEd;EAAR,CAAA,CAAA,EAAA,OAAA,CAAQ,sCAAR,CAAA;EAwRa;;;;EA8I2B,QAAA,kCAAA;EAAY,gCAAA,CAAA,YAAA,EA9IvC,YA8IuC,EAAA,mBAAA,EA7IhC,kCA6IgC,CAAA,EA5IpD,OA4IoD,CA5I5C,sCA4I4C,CAAA;EAAA,QAAA,0BAAA;EAIJ,eAAA,CAAA,YAAA,EAJR,YAIQ,CAAA,EAJI,OAIJ,CAJI,uBAIJ,EAAA,CAAA;EAAgC,uBAAA,CAAA,YAAA,EAAhC,YAAgC,EAAA,UAAA,EAAA,MAAA,CAAA,EAAA,OAAA,CAAA,uBAAA,CAAA;EAAA,cAAA,CAAA,YAAA,EAIzC,YAJyC,EAAA,QAAA,EAIjB,uBAJiB,CAAA,EAIM,OAJN,CAAA,IAAA,CAAA;EAIzC,cAAA,CAAA,YAAA,EAIA,YAJA,EAAA,OAAA,CAAA,EAIwB,8BAJxB,CAAA,EAIsD,OAJtD,CAIsD,uBAJtD,CAAA;EAAwB,+BAAA,CAAA,YAAA,EAgBlD,YAhBkD,EAAA,KAAA,EAiBzD,KAjByD,CAiBnD,kCAjBmD,CAAA,EAAA,YAAA,CAAA,EAkBjD,YAlBiD,CAAA,EAkBrC,OAlBqC,CAkBrC,kCAlBqC,EAAA,CAAA;EAAuB,0BAAA,CAAA,YAAA,EAuBnC,YAvBmC,EAAA,qBAAA,EAAA,MAAA,CAAA,EAuBQ,OAvBR,CAuBQ,kCAvBR,CAAA;EAI/C,QAAA,iBAAA;EAAwB,QAAA,kBAAA;EAA8B,QAAA,kBAAA;EAAA;;;;EAc/E,WAAA,CAAA,YAAA,EA4ZD,YA5ZC,EAAA,mBAAA,EA6ZM,kCA7ZN,EAAA,QAAA,EA8ZL,iCA9ZK,CAAA,EA8Z4B,OA9Z5B,CAAA,IAAA,CAAA;EAAY,UAAA,qBAAA,CAAA,YAAA,EA4ab,YA5aa,EAAA,mBAAA,EA6aN,kCA7aM,EAAA,aAAA,EA8aZ,iCA9aY,GAAA,IAAA,CAAA,EAAA,IAAA"}
1
+ {"version":3,"file":"OpenId4VpVerifierService.d.mts","names":[],"sources":["../../src/openid4vc-verifier/OpenId4VpVerifierService.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;cAgGa,wBAAA;;;EAAA,QAAA,sBAAwB;EAEgB,QAAA,2BAAA;EACnB,QAAA,MAAA;EACE,QAAA,sCAAA;EACK,WAAA,CAAA,MAAA,EAHY,MAGZ,EAAA,oBAAA,EAFP,oBAEO,EAAA,sBAAA,EADL,sBACK,EAAA,2BAAA,EAAA,2BAAA,EAAA,MAAA,EACrB,6BADqB,EAAA,sCAAA,EAEW,sCAFX;EACrB,QAAA,oBAAA;EACgC,0BAAA,CAAA,YAAA,EAWlC,YAXkC,EAAA,OAAA,EAYvC,0CAZuC,GAAA;IAWlC,QAAA,EACoD,uBADpD;EACL,CAAA,CAAA,EACR,OADQ,CACA,yCADA,CAAA;EAAyD,QAAA,uBAAA;EACzD,QAAA,0BAAA;EAAR,2BAAA,CAAA,YAAA,EAyUa,YAzUb,EAAA,OAAA,EA0UQ,2CA1UR,GAAA;IAyUa;;;IAOL,mBAAA,EAFc,kCAEd;EAAR,CAAA,CAAA,EAAA,OAAA,CAAQ,sCAAR,CAAA;EAkSa;;;;EA8I2B,QAAA,kCAAA;EAAY,gCAAA,CAAA,YAAA,EA9IvC,YA8IuC,EAAA,mBAAA,EA7IhC,kCA6IgC,CAAA,EA5IpD,OA4IoD,CA5I5C,sCA4I4C,CAAA;EAAA,QAAA,0BAAA;EAIJ,eAAA,CAAA,YAAA,EAJR,YAIQ,CAAA,EAJI,OAIJ,CAJI,uBAIJ,EAAA,CAAA;EAAgC,uBAAA,CAAA,YAAA,EAAhC,YAAgC,EAAA,UAAA,EAAA,MAAA,CAAA,EAAA,OAAA,CAAA,uBAAA,CAAA;EAAA,cAAA,CAAA,YAAA,EAIzC,YAJyC,EAAA,QAAA,EAIjB,uBAJiB,CAAA,EAIM,OAJN,CAAA,IAAA,CAAA;EAIzC,cAAA,CAAA,YAAA,EAIA,YAJA,EAAA,OAAA,CAAA,EAIwB,8BAJxB,CAAA,EAIsD,OAJtD,CAIsD,uBAJtD,CAAA;EAAwB,+BAAA,CAAA,YAAA,EAgBlD,YAhBkD,EAAA,KAAA,EAiBzD,KAjByD,CAiBnD,kCAjBmD,CAAA,EAAA,YAAA,CAAA,EAkBjD,YAlBiD,CAAA,EAkBrC,OAlBqC,CAkBrC,kCAlBqC,EAAA,CAAA;EAAuB,0BAAA,CAAA,YAAA,EAuBnC,YAvBmC,EAAA,qBAAA,EAAA,MAAA,CAAA,EAuBQ,OAvBR,CAuBQ,kCAvBR,CAAA;EAI/C,QAAA,iBAAA;EAAwB,QAAA,kBAAA;EAA8B,QAAA,kBAAA;EAAA;;;;EAc/E,WAAA,CAAA,YAAA,EA4ZD,YA5ZC,EAAA,mBAAA,EA6ZM,kCA7ZN,EAAA,QAAA,EA8ZL,iCA9ZK,CAAA,EA8Z4B,OA9Z5B,CAAA,IAAA,CAAA;EAAY,UAAA,qBAAA,CAAA,YAAA,EA4ab,YA5aa,EAAA,mBAAA,EA6aN,kCA7aM,EAAA,aAAA,EA8aZ,iCA9aY,GAAA,IAAA,CAAA,EAAA,IAAA"}
@@ -3,9 +3,9 @@ import { storeActorIdForContextCorrelationId } from "../shared/router/tenants.mj
3
3
  import "../shared/router/index.mjs";
4
4
  import { credoJwtIssuerToOpenId4VcJwtIssuer, dcqlCredentialQueryToPresentationFormat, getSupportedJwaSignatureAlgorithms } from "../shared/utils.mjs";
5
5
  import { getOid4vcCallbacks } from "../shared/callbacks.mjs";
6
- import { __decorateMetadata } from "../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorateMetadata.mjs";
7
- import { __decorateParam } from "../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorateParam.mjs";
8
- import { __decorate } from "../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorate.mjs";
6
+ import { __decorateMetadata } from "../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
7
+ import { __decorateParam } from "../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateParam.mjs";
8
+ import { __decorate } from "../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
9
9
  import { OpenId4VcVerificationSessionState } from "./OpenId4VcVerificationSessionState.mjs";
10
10
  import { getSdJwtVcTransactionDataHashes } from "../shared/transactionData.mjs";
11
11
  import { OpenId4VcVerifierEvents } from "./OpenId4VcVerifierEvents.mjs";
@@ -267,11 +267,18 @@ let OpenId4VpVerifierService = class OpenId4VpVerifierService$1 {
267
267
  error_description: "One or more presentations failed verification."
268
268
  }, { internalMessage: errorMessages.join("\n") });
269
269
  const presentations = Object.fromEntries(presentationVerificationResults.map(([credentialId, presentations$1]) => [credentialId, presentations$1.map((p) => p.verified ? p.presentation : void 0).filter((p) => p !== void 0)]));
270
- dcqlResponse = {
271
- presentations,
272
- presentationResult: await dcql.assertValidDcqlPresentation(agentContext, presentations, dcqlQuery),
273
- query: dcqlQuery
274
- };
270
+ try {
271
+ dcqlResponse = {
272
+ presentations,
273
+ presentationResult: await dcql.assertValidDcqlPresentation(agentContext, presentations, dcqlQuery),
274
+ query: dcqlQuery
275
+ };
276
+ } catch (error) {
277
+ throw new Oauth2ServerErrorResponseError({
278
+ error: Oauth2ErrorCodes.InvalidRequest,
279
+ error_description: "Presentation submission does not satisfy presentation request."
280
+ }, { cause: error });
281
+ }
275
282
  }
276
283
  if (result.type === "pex") {
277
284
  const pex = agentContext.dependencyManager.resolve(DifPresentationExchangeService);
@@ -314,7 +321,7 @@ let OpenId4VpVerifierService = class OpenId4VpVerifierService$1 {
314
321
  } catch (error) {
315
322
  throw new Oauth2ServerErrorResponseError({
316
323
  error: Oauth2ErrorCodes.InvalidRequest,
317
- error_description: "Presentation submission does not satisy presentation request."
324
+ error_description: "Presentation submission does not satisfy presentation request."
318
325
  }, { cause: error });
319
326
  }
320
327
  pexResponse = {
@@ -1 +1 @@
1
- {"version":3,"file":"OpenId4VpVerifierService.mjs","names":["OpenId4VpVerifierService","logger: Logger","w3cCredentialService: W3cCredentialService","w3cV2CredentialService: W3cV2CredentialService","openId4VcVerifierRepository: OpenId4VcVerifierRepository","config: OpenId4VcVerifierModuleConfig","openId4VcVerificationSessionRepository: OpenId4VcVerificationSessionRepository","clientIdPrefix: ClientIdPrefix","clientId: string | undefined","presentations","parsedAuthorizationResponse: ParsedOpenid4vpAuthorizationResponse | undefined","dcqlResponse: OpenId4VpVerifiedAuthorizationResponseDcql | undefined","pexResponse: OpenId4VpVerifiedAuthorizationResponsePresentationExchange | undefined","transactionData: OpenId4VpVerifiedAuthorizationResponseTransactionData[] | undefined","result","presentationExchange: OpenId4VpVerifiedAuthorizationResponsePresentationExchange | undefined","transactionDataHashesCredentials: TransactionDataHashesCredentials","jarmEncryptionJwk: JarmEncryptionJwk | undefined","jarmClientMetadata:\n | Pick<\n ClientMetadata,\n | 'jwks'\n | 'encrypted_response_enc_values_supported'\n | 'authorization_encrypted_response_alg'\n | 'authorization_encrypted_response_enc'\n >\n | undefined","isValid: boolean","cause: Error | undefined","verifiablePresentation: VerifiablePresentation","trustedCertificates: string[] | undefined","mdocDeviceResponse","sessionTranscriptOptions: MdocSessionTranscriptOptions"],"sources":["../../src/openid4vc-verifier/OpenId4VpVerifierService.ts"],"sourcesContent":["import {\n AgentContext,\n ClaimFormat,\n CredoError,\n type DcqlEncodedPresentations,\n type DcqlQuery,\n DcqlService,\n type DifPresentationExchangeDefinition,\n DifPresentationExchangeService,\n type DifPresentationExchangeSubmission,\n EventEmitter,\n extractPresentationsWithDescriptorsFromSubmission,\n extractX509CertificatesFromJwt,\n getDomainFromUrl,\n Hasher,\n type HashName,\n InjectionSymbols,\n inject,\n injectable,\n isMdocSupportedSignatureAlgorithm,\n JsonEncoder,\n JsonTransformer,\n Jwt,\n joinUriParts,\n Kms,\n type Logger,\n MdocDeviceResponse,\n type MdocSessionTranscriptOptions,\n type MdocSupportedSignatureAlgorithm,\n mapNonEmptyArray,\n type NonEmptyArray,\n type Query,\n type QueryOptions,\n SdJwtVcApi,\n SignatureSuiteRegistry,\n TypedArrayEncoder,\n utils,\n type VerifiablePresentation,\n W3cCredentialService,\n W3cJsonLdVerifiablePresentation,\n W3cJwtVerifiablePresentation,\n W3cV2CredentialService,\n W3cV2SdJwtVerifiablePresentation,\n X509Certificate,\n X509ModuleConfig,\n X509Service,\n} from '@credo-ts/core'\nimport { type Jwk, Oauth2ErrorCodes, Oauth2ServerErrorResponseError } from '@openid4vc/oauth2'\nimport {\n type ClientIdPrefix,\n type ClientMetadata,\n calculateX509HashClientIdPrefixValue,\n getOpenid4vpClientId,\n isJarmResponseMode,\n isOpenid4vpAuthorizationRequestDcApi,\n JarmMode,\n Openid4vpVerifier,\n type ParsedOpenid4vpAuthorizationResponse,\n type TransactionDataHashesCredentials,\n zOpenid4vpAuthorizationResponse,\n} from '@openid4vc/openid4vp'\nimport { getOid4vcCallbacks } from '../shared/callbacks'\nimport type { OpenId4VpAuthorizationRequestPayload } from '../shared/index'\nimport { storeActorIdForContextCorrelationId } from '../shared/router'\nimport { getSdJwtVcTransactionDataHashes } from '../shared/transactionData'\nimport {\n credoJwtIssuerToOpenId4VcJwtIssuer,\n dcqlCredentialQueryToPresentationFormat,\n getSupportedJwaSignatureAlgorithms,\n} from '../shared/utils'\nimport { OpenId4VcVerificationSessionState } from './OpenId4VcVerificationSessionState'\nimport { type OpenId4VcVerificationSessionStateChangedEvent, OpenId4VcVerifierEvents } from './OpenId4VcVerifierEvents'\nimport { OpenId4VcVerifierModuleConfig } from './OpenId4VcVerifierModuleConfig'\nimport type {\n OpenId4VpCreateAuthorizationRequestOptions,\n OpenId4VpCreateAuthorizationRequestReturn,\n OpenId4VpCreateVerifierOptions,\n OpenId4VpVerifiedAuthorizationResponse,\n OpenId4VpVerifiedAuthorizationResponseDcql,\n OpenId4VpVerifiedAuthorizationResponsePresentationExchange,\n OpenId4VpVerifiedAuthorizationResponseTransactionData,\n OpenId4VpVerifyAuthorizationResponseOptions,\n OpenId4VpVersion,\n ResponseMode,\n} from './OpenId4VpVerifierServiceOptions'\nimport {\n OpenId4VcVerificationSessionRecord,\n OpenId4VcVerificationSessionRepository,\n OpenId4VcVerifierRecord,\n OpenId4VcVerifierRepository,\n} from './repository'\n\n/**\n * @internal\n */\n@injectable()\nexport class OpenId4VpVerifierService {\n public constructor(\n @inject(InjectionSymbols.Logger) private logger: Logger,\n private w3cCredentialService: W3cCredentialService,\n private w3cV2CredentialService: W3cV2CredentialService,\n private openId4VcVerifierRepository: OpenId4VcVerifierRepository,\n private config: OpenId4VcVerifierModuleConfig,\n private openId4VcVerificationSessionRepository: OpenId4VcVerificationSessionRepository\n ) {}\n\n private getOpenid4vpVerifier(agentContext: AgentContext) {\n const callbacks = getOid4vcCallbacks(agentContext)\n const openid4vpClient = new Openid4vpVerifier({ callbacks })\n\n return openid4vpClient\n }\n\n public async createAuthorizationRequest(\n agentContext: AgentContext,\n options: OpenId4VpCreateAuthorizationRequestOptions & { verifier: OpenId4VcVerifierRecord }\n ): Promise<OpenId4VpCreateAuthorizationRequestReturn> {\n const kms = agentContext.resolve(Kms.KeyManagementApi)\n const nonce = TypedArrayEncoder.toBase64URL(kms.randomBytes({ length: 32 }))\n const state = TypedArrayEncoder.toBase64URL(kms.randomBytes({ length: 32 }))\n\n const responseMode = options.responseMode ?? 'direct_post.jwt'\n const isDcApiRequest = responseMode === 'dc_api' || responseMode === 'dc_api.jwt'\n\n const version = options.version ?? 'v1'\n if (version === 'v1.draft21' && isDcApiRequest) {\n throw new CredoError(\n `OpenID4VP version '${version}' cannot be used with responseMode '${options.responseMode}'. Use version 'v1' or 'v1.draft24' instead.`\n )\n }\n if (version === 'v1.draft21' && options.transactionData) {\n throw new CredoError(\n `OpenID4VP version '${version}' cannot be used with transactionData. Use version 'v1' or 'v1.draft24' instead.`\n )\n }\n if (version === 'v1.draft21' && options.dcql) {\n throw new CredoError(\n `OpenID4VP version '${version}' cannot be used with dcql. Use version 'v1' or 'v1.draft24' instead.`\n )\n }\n if (version !== 'v1' && options.verifierInfo) {\n throw new CredoError(`OpenID4VP version '${version}' cannot be used with verifierInfo. Use version 'v1' instead.`)\n }\n if (version === 'v1' && options.presentationExchange) {\n throw new CredoError(\n `OpenID4VP version '${version}' cannot be used with presentationExchange. Use dcql instead (recommended), or use older versions 'v1.draft24' and 'v1.draft21'.`\n )\n }\n\n // For now we only support presentations with holder binding.\n if (options.dcql?.query.credentials.some((c) => c.require_cryptographic_holder_binding === false)) {\n throw new CredoError(\n `Setting 'require_cryptographic_holder_binding' to false in DCQL Query is not supported by Credo at the moment. Only presentations with cryptographic holder binding are supported.`\n )\n }\n\n if (isDcApiRequest && options.authorizationResponseRedirectUri) {\n throw new CredoError(\n \"'authorizationResponseRedirectUri' cannot be be used with response mode 'dc_api' and 'dc_api.jwt'.\"\n )\n }\n\n // Check to prevent direct_post from being used with mDOC\n const hasMdocRequest =\n options.presentationExchange?.definition.input_descriptors.some((i) => i.format?.mso_mdoc) ||\n options.dcql?.query.credentials.some((c) => c.format === 'mso_mdoc')\n // Up to draft 24 we use the 18013-7 mdoc session transcript which needs values from APU/APV\n if ((version === 'v1.draft21' || version === 'v1.draft24') && responseMode === 'direct_post' && hasMdocRequest) {\n throw new CredoError(\n \"Unable to create authorization request with response mode 'direct_post' containing mDOC credentials. ISO 18013-7 requires the usage of response mode 'direct_post.jwt', and needs parameters from the encrypted response header to verify the mDOC sigature. Either use version 'v1', or update the response mode to 'direct_post.jwt'\"\n )\n }\n\n if (options.verifierInfo) {\n const queryIds =\n options?.dcql?.query.credentials.map(({ id }) => id) ??\n options?.presentationExchange?.definition.input_descriptors.map(({ id }) => id) ??\n []\n\n const hasValidCredentialIds = options.verifierInfo.every(\n (vi) => !vi.credential_ids || vi.credential_ids.every((credentialId) => queryIds.includes(credentialId))\n )\n\n if (!hasValidCredentialIds) {\n throw new CredoError(\n 'Verifier info (attestations) were provided, but the verifier info used credential ids that are not present in the query'\n )\n }\n }\n\n const authorizationRequestId = utils.uuid()\n // We include the `session=` in the url so we can still easily\n // find the session an encrypted response\n const authorizationResponseUrl = `${joinUriParts(this.config.baseUrl, [options.verifier.verifierId, this.config.authorizationEndpoint])}?session=${authorizationRequestId}`\n\n const jwtIssuer =\n options.requestSigner.method !== 'none'\n ? await credoJwtIssuerToOpenId4VcJwtIssuer(agentContext, options.requestSigner)\n : undefined\n\n let clientIdPrefix: ClientIdPrefix\n let clientId: string | undefined\n\n if (!jwtIssuer) {\n if (isDcApiRequest) {\n clientIdPrefix = version === 'v1' ? 'origin' : 'web-origin'\n clientId = undefined\n } else {\n clientIdPrefix = 'redirect_uri'\n clientId = authorizationResponseUrl\n }\n } else if (jwtIssuer?.method === 'x5c') {\n const leafCertificate = X509Service.getLeafCertificate(agentContext, { certificateChain: jwtIssuer.x5c })\n\n if (\n !authorizationResponseUrl.startsWith('https://') &&\n !(authorizationResponseUrl.startsWith('http://') && agentContext.config.allowInsecureHttpUrls)\n ) {\n throw new CredoError('The X509 certificate issuer must be a HTTPS URI.')\n }\n\n if (options.requestSigner.method === 'x5c' && options.requestSigner.clientIdPrefix === 'x509_hash') {\n clientIdPrefix = 'x509_hash'\n clientId = await calculateX509HashClientIdPrefixValue({\n x509Certificate: leafCertificate.rawCertificate,\n hash: Hasher.hash,\n })\n } else {\n if (!leafCertificate.sanDnsNames.includes(getDomainFromUrl(authorizationResponseUrl))) {\n const sanDnsMessage =\n leafCertificate.sanDnsNames.length > 0\n ? `SAN-DNS names are ${leafCertificate.sanDnsNames.join(', ')}`\n : 'there are no SAN-DNS names'\n\n throw new CredoError(\n `The domain of the OpenID4VCI issuer does not match a SAN DNS name in the x5c certificate. The OpenID4VCI domain is '${getDomainFromUrl(authorizationResponseUrl)}', $${sanDnsMessage}`\n )\n }\n\n clientIdPrefix = 'x509_san_dns'\n clientId = getDomainFromUrl(authorizationResponseUrl)\n }\n } else if (jwtIssuer?.method === 'did') {\n clientId = jwtIssuer.didUrl.split('#')[0]\n clientIdPrefix = version === 'v1' ? 'decentralized_identifier' : 'did'\n } else {\n throw new CredoError(\n `Unsupported jwt issuer method '${options.requestSigner.method}'. Only 'did' and 'x5c' are supported.`\n )\n }\n\n // We always use shortened URIs currently\n const hostedAuthorizationRequestUri =\n !isDcApiRequest && jwtIssuer\n ? joinUriParts(this.config.baseUrl, [\n options.verifier.verifierId,\n this.config.authorizationRequestEndpoint,\n authorizationRequestId,\n ])\n : // No hosted request needed when using DC API or using unsigned request\n undefined\n\n const client_id =\n // For did/https and draft 21 the client id has no special prefix\n clientIdPrefix === 'did' || (clientIdPrefix as string) === 'https' || version === 'v1.draft21'\n ? clientId\n : `${clientIdPrefix}:${clientId}`\n\n // for did the client_id is same in draft 21 and 24 so we could support both at the same time\n const legacyClientIdScheme =\n version === 'v1.draft21' &&\n clientIdPrefix !== 'web-origin' &&\n clientIdPrefix !== 'origin' &&\n clientIdPrefix !== 'decentralized_identifier'\n ? clientIdPrefix\n : undefined\n\n const client_metadata = await this.getClientMetadata(agentContext, {\n responseMode,\n verifier: options.verifier,\n authorizationResponseUrl,\n version,\n\n // TODO: we don't validate the DCQL query when creating a request i think?\n dcqlQuery: options.dcql?.query,\n })\n\n const requestParamsBase = {\n nonce,\n presentation_definition: options.presentationExchange?.definition,\n dcql_query: options.dcql?.query,\n transaction_data: options.transactionData?.map((entry) => JsonEncoder.toBase64URL(entry)),\n response_mode: responseMode,\n response_type: 'vp_token',\n client_metadata,\n verifier_info: options.verifierInfo,\n } as const\n\n const openid4vpVerifier = this.getOpenid4vpVerifier(agentContext)\n const authorizationRequest = await openid4vpVerifier.createOpenId4vpAuthorizationRequest({\n jar: jwtIssuer\n ? {\n jwtSigner: jwtIssuer,\n requestUri: hostedAuthorizationRequestUri,\n expiresInSeconds: this.config.authorizationRequestExpiresInSeconds,\n }\n : undefined,\n authorizationRequestPayload:\n requestParamsBase.response_mode === 'dc_api.jwt' || requestParamsBase.response_mode === 'dc_api'\n ? {\n ...requestParamsBase,\n // No client_id for unsigned DC API requests\n client_id: jwtIssuer ? client_id : undefined,\n response_mode: requestParamsBase.response_mode,\n expected_origins: options.expectedOrigins,\n }\n : {\n ...requestParamsBase,\n response_mode: requestParamsBase.response_mode,\n client_id: client_id as string,\n state,\n response_uri: authorizationResponseUrl,\n client_id_scheme: legacyClientIdScheme,\n },\n })\n\n const verificationSession = new OpenId4VcVerificationSessionRecord({\n authorizationResponseRedirectUri: options.authorizationResponseRedirectUri,\n\n // Only store payload for unsiged requests\n authorizationRequestPayload: authorizationRequest.jar\n ? undefined\n : authorizationRequest.authorizationRequestPayload,\n authorizationRequestJwt: authorizationRequest.jar?.authorizationRequestJwt,\n authorizationRequestUri: hostedAuthorizationRequestUri,\n authorizationRequestId,\n state: OpenId4VcVerificationSessionState.RequestCreated,\n verifierId: options.verifier.verifierId,\n expiresAt: utils.addSecondsToDate(new Date(), this.config.authorizationRequestExpiresInSeconds),\n openId4VpVersion: version,\n })\n await this.openId4VcVerificationSessionRepository.save(agentContext, verificationSession)\n this.emitStateChangedEvent(agentContext, verificationSession, null)\n\n return {\n authorizationRequest: authorizationRequest.authorizationRequest,\n verificationSession,\n authorizationRequestObject: authorizationRequest.authorizationRequestObject,\n }\n }\n\n private async getDcqlVerifiedResponse(\n agentContext: AgentContext,\n _dcqlQuery: unknown,\n presentations: DcqlEncodedPresentations\n ) {\n const dcqlService = agentContext.dependencyManager.resolve(DcqlService)\n const dcqlQuery = dcqlService.validateDcqlQuery(_dcqlQuery)\n\n const dcqlPresentationEntries = Object.entries(presentations)\n const dcqlPresentation = Object.fromEntries(\n dcqlPresentationEntries.map(([credentialId, presentations]) => {\n const queryCredential = dcqlQuery.credentials.find((c) => c.id === credentialId)\n if (!queryCredential) {\n throw new CredoError(\n `vp_token contains presentation for credential query id '${credentialId}', but this credential is not present in the dcql query.`\n )\n }\n\n return [\n credentialId,\n mapNonEmptyArray(presentations, (presentation) =>\n this.decodePresentation(agentContext, {\n presentation,\n format: dcqlCredentialQueryToPresentationFormat(queryCredential),\n })\n ),\n ]\n })\n )\n\n const dcqlPresentationResult = await dcqlService.assertValidDcqlPresentation(\n agentContext,\n dcqlPresentation,\n dcqlQuery\n )\n\n return {\n query: dcqlQuery,\n presentations: dcqlPresentation,\n presentationResult: dcqlPresentationResult,\n } satisfies OpenId4VpVerifiedAuthorizationResponseDcql\n }\n\n private async parseAuthorizationResponse(\n agentContext: AgentContext,\n options: {\n authorizationResponse: Record<string, unknown>\n origin?: string\n verificationSession: OpenId4VcVerificationSessionRecord\n }\n ): Promise<ParsedOpenid4vpAuthorizationResponse & { verificationSession: OpenId4VcVerificationSessionRecord }> {\n const openid4vpVerifier = this.getOpenid4vpVerifier(agentContext)\n\n const { authorizationResponse, verificationSession, origin } = options\n let parsedAuthorizationResponse: ParsedOpenid4vpAuthorizationResponse | undefined\n\n try {\n parsedAuthorizationResponse = await openid4vpVerifier.parseOpenid4vpAuthorizationResponse({\n authorizationResponse,\n origin,\n authorizationRequestPayload: verificationSession.requestPayload,\n callbacks: getOid4vcCallbacks(agentContext),\n })\n\n if (parsedAuthorizationResponse.jarm && parsedAuthorizationResponse.jarm.type !== JarmMode.Encrypted) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: `Only encrypted JARM responses are supported, received '${parsedAuthorizationResponse.jarm.type}'.`,\n })\n }\n\n return {\n ...parsedAuthorizationResponse,\n verificationSession,\n }\n } catch (error) {\n if (\n verificationSession?.state === OpenId4VcVerificationSessionState.RequestUriRetrieved ||\n verificationSession?.state === OpenId4VcVerificationSessionState.RequestCreated\n ) {\n const parsed = zOpenid4vpAuthorizationResponse.safeParse(\n parsedAuthorizationResponse?.authorizationResponsePayload\n )\n\n verificationSession.authorizationResponsePayload = parsed.success ? parsed.data : undefined\n verificationSession.errorMessage = error.message\n await this.updateState(agentContext, verificationSession, OpenId4VcVerificationSessionState.Error)\n }\n\n throw error\n }\n }\n\n public async verifyAuthorizationResponse(\n agentContext: AgentContext,\n options: OpenId4VpVerifyAuthorizationResponseOptions & {\n /**\n * The verification session associated with the response\n */\n verificationSession: OpenId4VcVerificationSessionRecord\n }\n ): Promise<OpenId4VpVerifiedAuthorizationResponse> {\n const { verificationSession, authorizationResponse, origin } = options\n const authorizationRequest = verificationSession.requestPayload\n const openid4vpVersion =\n verificationSession.openId4VpVersion ??\n (authorizationRequest.client_id_scheme !== undefined ? 'v1.draft21' : 'v1.draft24')\n\n if (\n verificationSession.state !== OpenId4VcVerificationSessionState.RequestUriRetrieved &&\n verificationSession.state !== OpenId4VcVerificationSessionState.RequestCreated\n ) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'Invalid session',\n })\n }\n\n if (verificationSession.expiresAt && Date.now() > verificationSession.expiresAt.getTime()) {\n verificationSession.errorMessage = 'session expired'\n await this.updateState(agentContext, verificationSession, OpenId4VcVerificationSessionState.Error)\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'session expired',\n })\n }\n\n const result = await this.parseAuthorizationResponse(agentContext, {\n verificationSession,\n authorizationResponse,\n origin,\n })\n\n // NOTE: we always currently include only one key, and also use 'use=enc'. If we change\n // that, we should change this. I think we should return the jarm key in the openid4vp lib\n // and match against that (and also ensure then it's present in client_metadata -> should not conflict with federation)\n const encryptionJwk = authorizationRequest.client_metadata?.jwks?.keys.find((key) => key.use === 'enc')\n const encryptionPublicJwk = encryptionJwk ? Kms.PublicJwk.fromUnknown(encryptionJwk) : undefined\n\n let dcqlResponse: OpenId4VpVerifiedAuthorizationResponseDcql | undefined\n let pexResponse: OpenId4VpVerifiedAuthorizationResponsePresentationExchange | undefined\n let transactionData: OpenId4VpVerifiedAuthorizationResponseTransactionData[] | undefined\n\n try {\n const parsedClientId = getOpenid4vpClientId({\n responseMode: authorizationRequest.response_mode,\n clientId: authorizationRequest.client_id,\n legacyClientIdScheme: authorizationRequest.client_id_scheme,\n origin: options.origin,\n version: openid4vpVersion === 'v1' ? 100 : openid4vpVersion === 'v1.draft24' ? 24 : 21,\n })\n\n const clientId = parsedClientId.effectiveClientId\n const isDcApiRequest = isOpenid4vpAuthorizationRequestDcApi(authorizationRequest)\n\n // TODO: we should return the effectiveAudience in the returned value of openid4vp lib\n // Since it differs based on the version of openid4vp used\n // NOTE: in v1 DC API request the audience is always origin: (not the client id)\n const audience = openid4vpVersion === 'v1' && isDcApiRequest ? `origin:${options.origin}` : clientId\n\n const responseUri = isOpenid4vpAuthorizationRequestDcApi(authorizationRequest)\n ? undefined\n : authorizationRequest.response_uri\n\n // NOTE: apu is needed for mDOC over OID4VP without DC API up to draft 24\n const mdocGeneratedNonce = result.jarm?.jarmHeader.apu\n ? TypedArrayEncoder.toUtf8String(TypedArrayEncoder.fromBase64(result.jarm?.jarmHeader.apu))\n : undefined\n\n if (result.type === 'dcql') {\n const dcqlPresentationEntries = Object.entries(result.dcql.presentations)\n if (!authorizationRequest.dcql_query) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'DCQL response provided but no dcql_query found in the authorization request.',\n })\n }\n\n const dcql = agentContext.dependencyManager.resolve(DcqlService)\n const dcqlQuery = dcql.validateDcqlQuery(authorizationRequest.dcql_query)\n\n const presentationVerificationResults = await Promise.all(\n dcqlPresentationEntries.map(async ([credentialId, presentations]) => {\n const queryCredential = dcqlQuery.credentials.find((c) => c.id === credentialId)\n if (!queryCredential) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: `vp_token contains presentation for credential query id '${credentialId}', but this credential is not present in the dcql query.`,\n })\n }\n\n const verifiedPresentations = await Promise.all(\n mapNonEmptyArray(presentations, (presentation) =>\n this.verifyPresentation(agentContext, {\n format: dcqlCredentialQueryToPresentationFormat(queryCredential),\n nonce: authorizationRequest.nonce,\n audience,\n version: openid4vpVersion,\n clientId,\n encryptionJwk: encryptionPublicJwk,\n origin: options.origin,\n responseUri,\n mdocGeneratedNonce,\n verificationSessionId: result.verificationSession.id,\n presentation,\n })\n )\n )\n return [credentialId, verifiedPresentations] as const\n })\n )\n\n const errorMessages = presentationVerificationResults\n .flatMap(([credentialId, presentations], index) =>\n presentations.map((result) =>\n !result.verified ? `\\t- ${credentialId}[${index}]: ${result.reason}` : undefined\n )\n )\n .filter((i) => i !== undefined)\n if (errorMessages.length > 0) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'One or more presentations failed verification.',\n },\n { internalMessage: errorMessages.join('\\n') }\n )\n }\n\n // We can be certain here that all presentations passed verification\n const presentations = Object.fromEntries(\n presentationVerificationResults.map(\n ([credentialId, presentations]) =>\n [\n credentialId,\n presentations\n .map((p) => (p.verified ? p.presentation : undefined))\n // NOTE: we add NonEmpty cast here since it's needed for DCQL, and because we\n // previously ensured all items are valid, we can be sure this arary is non empty\n // even after the filter.\n .filter((p) => p !== undefined) as NonEmptyArray<VerifiablePresentation>,\n ] as const\n )\n )\n\n const presentationResult = await dcql.assertValidDcqlPresentation(agentContext, presentations, dcqlQuery)\n\n dcqlResponse = {\n presentations,\n presentationResult,\n query: dcqlQuery,\n }\n }\n\n if (result.type === 'pex') {\n const pex = agentContext.dependencyManager.resolve(DifPresentationExchangeService)\n\n const encodedPresentations = result.pex.presentations\n const submission = result.pex.presentationSubmission as DifPresentationExchangeSubmission\n const definition = result.pex.presentationDefinition as unknown as DifPresentationExchangeDefinition\n\n pex.validatePresentationDefinition(definition)\n\n try {\n pex.validatePresentationSubmission(submission)\n } catch (error) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'Invalid presentation submission.',\n },\n { cause: error }\n )\n }\n\n const presentationsArray = Array.isArray(encodedPresentations) ? encodedPresentations : [encodedPresentations]\n const presentationVerificationResults = await Promise.all(\n presentationsArray.map((presentation) => {\n return this.verifyPresentation(agentContext, {\n nonce: authorizationRequest.nonce,\n audience,\n clientId,\n version: openid4vpVersion,\n encryptionJwk: encryptionPublicJwk,\n responseUri,\n mdocGeneratedNonce,\n verificationSessionId: result.verificationSession.id,\n presentation,\n format: this.claimFormatFromEncodedPresentation(presentation),\n origin: options.origin,\n })\n })\n )\n\n const errorMessages = presentationVerificationResults\n .map((result, index) => (!result.verified ? `\\t- [${index}]: ${result.reason}` : undefined))\n .filter((i) => i !== undefined)\n if (errorMessages.length > 0) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'One or more presentations failed verification.',\n },\n { internalMessage: errorMessages.join('\\n') }\n )\n }\n\n const verifiablePresentations = presentationVerificationResults\n .map((p) => (p.verified ? p.presentation : undefined))\n .filter((p) => p !== undefined)\n\n try {\n pex.validatePresentation(\n definition,\n // vp_token MUST not be an array if only one entry\n verifiablePresentations.length === 1 ? verifiablePresentations[0] : verifiablePresentations,\n submission\n )\n } catch (error) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'Presentation submission does not satisy presentation request.',\n },\n { cause: error }\n )\n }\n\n const descriptors = extractPresentationsWithDescriptorsFromSubmission(\n // vp_token MUST not be an array if only one entry\n verifiablePresentations.length === 1 ? verifiablePresentations[0] : verifiablePresentations,\n submission,\n definition\n )\n\n pexResponse = {\n definition,\n descriptors,\n presentations: verifiablePresentations,\n submission,\n }\n }\n\n transactionData = await this.getVerifiedTransactionData(agentContext, {\n authorizationRequest,\n dcql: dcqlResponse,\n presentationExchange: pexResponse,\n })\n } catch (error) {\n result.verificationSession.errorMessage = error.message\n await this.updateState(agentContext, result.verificationSession, OpenId4VcVerificationSessionState.Error)\n throw error\n }\n\n result.verificationSession.authorizationResponsePayload = result.authorizationResponsePayload\n await this.updateState(agentContext, result.verificationSession, OpenId4VcVerificationSessionState.ResponseVerified)\n\n return {\n presentationExchange: pexResponse,\n dcql: dcqlResponse,\n transactionData,\n verificationSession: result.verificationSession,\n }\n }\n\n /**\n * Get the format based on an encoded presentation. This is mostly leveraged for\n * PEX where it's not known based on the request which format to expect\n */\n private claimFormatFromEncodedPresentation(\n presentation: string | Record<string, unknown>\n ): ClaimFormat.JwtVp | ClaimFormat.LdpVp | ClaimFormat.SdJwtDc | ClaimFormat.MsoMdoc {\n if (typeof presentation === 'object') return ClaimFormat.LdpVp\n if (presentation.includes('~')) return ClaimFormat.SdJwtDc\n if (Jwt.format.test(presentation)) return ClaimFormat.JwtVp\n\n // Fallback, we tried all other formats\n return ClaimFormat.MsoMdoc\n }\n\n public async getVerifiedAuthorizationResponse(\n agentContext: AgentContext,\n verificationSession: OpenId4VcVerificationSessionRecord\n ): Promise<OpenId4VpVerifiedAuthorizationResponse> {\n verificationSession.assertState(OpenId4VcVerificationSessionState.ResponseVerified)\n\n if (!verificationSession.authorizationResponsePayload) {\n throw new CredoError('No authorization response payload found in the verification session.')\n }\n\n const authorizationRequestPayload = verificationSession.requestPayload\n const openid4vpAuthorizationResponsePayload = verificationSession.authorizationResponsePayload\n const openid4vpVerifier = this.getOpenid4vpVerifier(agentContext)\n\n const result = openid4vpVerifier.validateOpenid4vpAuthorizationResponsePayload({\n authorizationRequestPayload: verificationSession.requestPayload,\n authorizationResponsePayload: openid4vpAuthorizationResponsePayload,\n })\n\n let presentationExchange: OpenId4VpVerifiedAuthorizationResponsePresentationExchange | undefined\n const dcql =\n result.type === 'dcql'\n ? await this.getDcqlVerifiedResponse(\n agentContext,\n authorizationRequestPayload.dcql_query,\n result.dcql.presentations\n )\n : undefined\n\n if (result.type === 'pex') {\n const presentationDefinition =\n authorizationRequestPayload.presentation_definition as unknown as DifPresentationExchangeDefinition\n const submission = openid4vpAuthorizationResponsePayload.presentation_submission as\n | DifPresentationExchangeSubmission\n | undefined\n\n if (!submission) {\n throw new CredoError('Unable to extract submission from the response.')\n }\n\n const verifiablePresentations = result.pex.presentations.map((presentation) =>\n this.decodePresentation(agentContext, {\n presentation,\n format: this.claimFormatFromEncodedPresentation(presentation),\n })\n )\n\n presentationExchange = {\n definition: presentationDefinition,\n submission,\n presentations: verifiablePresentations,\n descriptors: extractPresentationsWithDescriptorsFromSubmission(\n // vp_token MUST not be an array if only one entry\n verifiablePresentations.length === 1 ? verifiablePresentations[0] : verifiablePresentations,\n submission,\n presentationDefinition\n ),\n }\n }\n\n if (!presentationExchange && !dcql) {\n throw new CredoError('No presentationExchange or dcql found in the response.')\n }\n\n const transactionData = await this.getVerifiedTransactionData(agentContext, {\n authorizationRequest: authorizationRequestPayload,\n dcql,\n presentationExchange,\n })\n\n return {\n presentationExchange,\n dcql,\n transactionData,\n verificationSession,\n }\n }\n\n private async getVerifiedTransactionData(\n agentContext: AgentContext,\n {\n authorizationRequest,\n presentationExchange,\n dcql,\n }: {\n dcql?: OpenId4VpVerifiedAuthorizationResponseDcql\n presentationExchange?: OpenId4VpVerifiedAuthorizationResponsePresentationExchange\n authorizationRequest: OpenId4VpAuthorizationRequestPayload\n }\n ): Promise<OpenId4VpVerifiedAuthorizationResponseTransactionData[] | undefined> {\n if (!authorizationRequest.transaction_data) return undefined\n\n const openid4vpVerifier = this.getOpenid4vpVerifier(agentContext)\n const transactionDataHashesCredentials: TransactionDataHashesCredentials = {}\n\n // Extract presentations with credentialId\n const idToCredential = dcql\n ? Object.entries(dcql.presentations)\n : (presentationExchange?.descriptors.map(\n (descriptor) => [descriptor.descriptor.id, [descriptor.presentation]] as const\n ) ?? [])\n\n for (const [credentialId, presentations] of idToCredential) {\n // Only SD-JWT VC supported for now\n const transactionDataHashes = presentations.map((presentation) =>\n presentation.claimFormat === ClaimFormat.SdJwtDc ? getSdJwtVcTransactionDataHashes(presentation) : undefined\n )\n\n const firstHasHash = transactionDataHashes[0] !== undefined\n if (!transactionDataHashes.every((hash) => (firstHasHash ? hash !== undefined : hash === undefined))) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidTransactionData,\n error_description: `Multipe presentations were submitted for credential query ${credentialId} but not all presentations includes a transaction data hash. Either all or none of the presentations for a credential query id should include a transaction data hash.`,\n })\n }\n\n if (!firstHasHash) continue\n\n transactionDataHashesCredentials[credentialId] = transactionDataHashes as [\n Exclude<(typeof transactionDataHashes)[number], undefined>,\n ]\n }\n\n // Verify the transaction data\n const transactionData = await openid4vpVerifier.verifyTransactionData({\n credentials: transactionDataHashesCredentials,\n transactionData: authorizationRequest.transaction_data,\n })\n\n return transactionData.map(({ credentialId, transactionDataEntry, presentations }) => ({\n credentialId,\n encoded: transactionDataEntry.encoded,\n decoded: transactionDataEntry.transactionData,\n transactionDataIndex: transactionDataEntry.transactionDataIndex,\n presentations: presentations.map((presentation) => ({\n presentationHashIndex: presentation.credentialHashIndex,\n hash: presentation.hash,\n // We only support the values supported by Credo hasher, so it can't be any other value than those.\n hashAlg: presentation.hashAlg as HashName,\n })) as OpenId4VpVerifiedAuthorizationResponseTransactionData['presentations'],\n }))\n }\n\n public async getAllVerifiers(agentContext: AgentContext) {\n return this.openId4VcVerifierRepository.getAll(agentContext)\n }\n\n public async getVerifierByVerifierId(agentContext: AgentContext, verifierId: string) {\n return this.openId4VcVerifierRepository.getByVerifierId(agentContext, verifierId)\n }\n\n public async updateVerifier(agentContext: AgentContext, verifier: OpenId4VcVerifierRecord) {\n return this.openId4VcVerifierRepository.update(agentContext, verifier)\n }\n\n public async createVerifier(agentContext: AgentContext, options?: OpenId4VpCreateVerifierOptions) {\n const openId4VcVerifier = new OpenId4VcVerifierRecord({\n verifierId: options?.verifierId ?? utils.uuid(),\n clientMetadata: options?.clientMetadata,\n })\n\n await this.openId4VcVerifierRepository.save(agentContext, openId4VcVerifier)\n await storeActorIdForContextCorrelationId(agentContext, openId4VcVerifier.verifierId)\n return openId4VcVerifier\n }\n\n public async findVerificationSessionsByQuery(\n agentContext: AgentContext,\n query: Query<OpenId4VcVerificationSessionRecord>,\n queryOptions?: QueryOptions\n ) {\n return this.openId4VcVerificationSessionRepository.findByQuery(agentContext, query, queryOptions)\n }\n\n public async getVerificationSessionById(agentContext: AgentContext, verificationSessionId: string) {\n return this.openId4VcVerificationSessionRepository.getById(agentContext, verificationSessionId)\n }\n\n private async getClientMetadata(\n agentContext: AgentContext,\n options: {\n responseMode: ResponseMode\n verifier: OpenId4VcVerifierRecord\n authorizationResponseUrl: string\n dcqlQuery?: DcqlQuery\n version: NonNullable<OpenId4VpCreateAuthorizationRequestOptions['version']>\n }\n ): Promise<ClientMetadata> {\n const { responseMode, verifier } = options\n\n const signatureSuiteRegistry = agentContext.resolve(SignatureSuiteRegistry)\n const kms = agentContext.resolve(Kms.KeyManagementApi)\n const supportedAlgs = getSupportedJwaSignatureAlgorithms(agentContext) as [\n Kms.KnownJwaSignatureAlgorithm,\n ...Kms.KnownJwaSignatureAlgorithm[],\n ]\n const supportedMdocAlgs = supportedAlgs.filter(isMdocSupportedSignatureAlgorithm) as [\n MdocSupportedSignatureAlgorithm,\n ...MdocSupportedSignatureAlgorithm[],\n ]\n const supportedProofTypes = signatureSuiteRegistry.supportedProofTypes\n\n type JarmEncryptionJwk = Kms.Jwk & { kid: string; use: 'enc' }\n let jarmEncryptionJwk: JarmEncryptionJwk | undefined\n\n if (isJarmResponseMode(responseMode)) {\n const key = await kms.createKey({ type: { crv: 'P-256', kty: 'EC' } })\n jarmEncryptionJwk = { ...key.publicJwk, use: 'enc' }\n }\n\n const jarmClientMetadata:\n | Pick<\n ClientMetadata,\n | 'jwks'\n | 'encrypted_response_enc_values_supported'\n | 'authorization_encrypted_response_alg'\n | 'authorization_encrypted_response_enc'\n >\n | undefined = jarmEncryptionJwk\n ? {\n jwks: { keys: [jarmEncryptionJwk as Jwk] },\n\n ...(options.version === 'v1'\n ? {\n encrypted_response_enc_values_supported: ['A128GCM', 'A256GCM', 'A128CBC-HS256'],\n }\n : {\n authorization_encrypted_response_alg: 'ECDH-ES',\n\n // NOTE: pre draft 24 we could only include one version. To maximize compatiblity we use\n // - A128GCM for draft 24 (HAIP)\n // - A256GCM for draft 21 (18013-7)\n authorization_encrypted_response_enc: options.version === 'v1.draft24' ? 'A128GCM' : 'A256GCM',\n }),\n }\n : undefined\n\n const dclqQueryFormats = new Set(options.dcqlQuery?.credentials.map((c) => c.format))\n\n return {\n ...jarmClientMetadata,\n ...verifier.clientMetadata,\n response_types_supported: ['vp_token'],\n\n // for v1 version we only include the vp_formats_supported for formats we're\n // requesting.\n ...(options.version === 'v1'\n ? {\n vp_formats_supported: {\n ...(dclqQueryFormats.has('dc+sd-jwt')\n ? {\n 'dc+sd-jwt': {\n 'kb-jwt_alg_values': supportedAlgs,\n 'sd-jwt_alg_values': supportedAlgs,\n },\n }\n : {}),\n\n ...(dclqQueryFormats.has('mso_mdoc')\n ? {\n mso_mdoc: {\n // TODO: we need to add some generic utils for fully specified COSE algorithms\n deviceauth_alg_values: [/* P-256 */ -9, /* P-384 */ -51, /* Ed25519 */ -19],\n issuerauth_alg_values: [/* P-256 */ -9, /* P-384 */ -51, /* Ed25519 */ -19],\n },\n }\n : {}),\n\n ...(dclqQueryFormats.has('jwt_vc_json')\n ? {\n jwt_vc_json: {\n alg_values: supportedAlgs,\n },\n }\n : {}),\n\n ...(dclqQueryFormats.has('ldp_vc')\n ? {\n ldp_vc: {\n proof_type_values: supportedProofTypes as [string, ...string[]],\n },\n }\n : {}),\n },\n }\n : {\n vp_formats: {\n mso_mdoc: {\n alg: supportedMdocAlgs,\n },\n jwt_vc: {\n alg: supportedAlgs,\n },\n jwt_vc_json: {\n alg: supportedAlgs,\n },\n jwt_vp_json: {\n alg: supportedAlgs,\n },\n jwt_vp: {\n alg: supportedAlgs,\n },\n ldp_vc: {\n proof_type: supportedProofTypes,\n },\n ldp_vp: {\n proof_type: supportedProofTypes,\n },\n 'vc+sd-jwt': {\n 'kb-jwt_alg_values': supportedAlgs,\n 'sd-jwt_alg_values': supportedAlgs,\n },\n 'dc+sd-jwt': {\n 'kb-jwt_alg_values': supportedAlgs,\n 'sd-jwt_alg_values': supportedAlgs,\n },\n },\n }),\n }\n }\n\n private decodePresentation(\n agentContext: AgentContext,\n options: {\n presentation: string | Record<string, unknown>\n format: ClaimFormat.JwtVp | ClaimFormat.LdpVp | ClaimFormat.SdJwtDc | ClaimFormat.MsoMdoc | ClaimFormat.SdJwtW3cVp\n }\n ): VerifiablePresentation {\n const { presentation, format } = options\n\n if (format === ClaimFormat.SdJwtDc) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n const sdJwtVcApi = agentContext.dependencyManager.resolve(SdJwtVcApi)\n\n const sdJwtVc = sdJwtVcApi.fromCompact(presentation)\n return sdJwtVc\n }\n if (format === ClaimFormat.MsoMdoc) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n const mdocDeviceResponse = MdocDeviceResponse.fromBase64Url(presentation)\n return mdocDeviceResponse\n }\n if (format === ClaimFormat.JwtVp) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n return W3cJwtVerifiablePresentation.fromSerializedJwt(presentation)\n }\n if (format === ClaimFormat.SdJwtW3cVp) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n return W3cV2SdJwtVerifiablePresentation.fromCompact(presentation)\n }\n\n return JsonTransformer.fromJSON(presentation, W3cJsonLdVerifiablePresentation)\n }\n\n private async verifyPresentation(\n agentContext: AgentContext,\n options: {\n nonce: string\n audience: string\n clientId: string\n responseUri?: string\n mdocGeneratedNonce?: string\n origin?: string\n verificationSessionId: string\n presentation: string | Record<string, unknown>\n format: ClaimFormat.LdpVp | ClaimFormat.JwtVp | ClaimFormat.SdJwtW3cVp | ClaimFormat.SdJwtDc | ClaimFormat.MsoMdoc\n version: OpenId4VpVersion\n encryptionJwk?: Kms.PublicJwk\n }\n ): Promise<\n | {\n verified: true\n presentation: VerifiablePresentation\n transactionData?: TransactionDataHashesCredentials[string]\n }\n | { verified: false; reason: string }\n > {\n const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig)\n const sdJwtVcApi = agentContext.dependencyManager.resolve(SdJwtVcApi)\n\n const { presentation, format } = options\n\n try {\n this.logger.trace('Presentation response', JsonTransformer.toJSON(presentation))\n\n let isValid: boolean\n let cause: Error | undefined\n let verifiablePresentation: VerifiablePresentation\n\n if (format === ClaimFormat.SdJwtDc) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n\n const sdJwtVc = sdJwtVcApi.fromCompact(presentation)\n const jwt = Jwt.fromSerializedJwt(presentation.split('~')[0])\n const certificateChain = extractX509CertificatesFromJwt(jwt)\n\n let trustedCertificates: string[] | undefined\n if (certificateChain && x509Config.getTrustedCertificatesForVerification) {\n trustedCertificates = await x509Config.getTrustedCertificatesForVerification(agentContext, {\n certificateChain,\n verification: {\n type: 'credential',\n credential: sdJwtVc,\n openId4VcVerificationSessionId: options.verificationSessionId,\n },\n })\n }\n\n if (!trustedCertificates) {\n // We also take from the config here to avoid the callback being called again\n trustedCertificates = x509Config.trustedCertificates ?? []\n }\n\n const verificationResult = await sdJwtVcApi.verify({\n compactSdJwtVc: presentation,\n keyBinding: {\n audience: options.audience,\n nonce: options.nonce,\n },\n trustedCertificates,\n })\n\n isValid = verificationResult.isValid\n cause = verificationResult.isValid ? undefined : verificationResult.error\n verifiablePresentation = sdJwtVc\n } else if (format === ClaimFormat.MsoMdoc) {\n if (typeof presentation !== 'string') {\n throw new CredoError('Expected vp_token entry for format mso_mdoc to be of type string')\n }\n const mdocDeviceResponse = MdocDeviceResponse.fromBase64Url(presentation)\n if (mdocDeviceResponse.documents.length === 0) {\n throw new CredoError('mdoc device response does not contain any mdocs')\n }\n\n const deviceResponses = mdocDeviceResponse.splitIntoSingleDocumentResponses()\n\n for (const deviceResponseIndex of deviceResponses.keys()) {\n const mdocDeviceResponse = deviceResponses[deviceResponseIndex]\n\n const document = mdocDeviceResponse.documents[0]\n const certificateChain = document.issuerSignedCertificateChain.map((cert) =>\n X509Certificate.fromRawCertificate(cert)\n )\n\n const trustedCertificates = await x509Config.getTrustedCertificatesForVerification?.(agentContext, {\n certificateChain,\n verification: {\n type: 'credential',\n credential: document,\n openId4VcVerificationSessionId: options.verificationSessionId,\n },\n })\n\n let sessionTranscriptOptions: MdocSessionTranscriptOptions\n if (options.origin && options.version === 'v1') {\n sessionTranscriptOptions = {\n type: 'openId4VpDcApi',\n verifierGeneratedNonce: options.nonce,\n origin: options.origin,\n encryptionJwk: options.encryptionJwk,\n }\n } else if (options.origin) {\n sessionTranscriptOptions = {\n type: 'openId4VpDcApiDraft24',\n clientId: options.clientId,\n verifierGeneratedNonce: options.nonce,\n origin: options.origin,\n }\n } else if (options.version === 'v1') {\n if (!options.responseUri) {\n throw new CredoError('responseUri is required for mdoc openid4vp session transcript calculation')\n }\n\n sessionTranscriptOptions = {\n type: 'openId4Vp',\n clientId: options.clientId,\n responseUri: options.responseUri,\n verifierGeneratedNonce: options.nonce,\n encryptionJwk: options.encryptionJwk,\n }\n } else {\n if (!options.mdocGeneratedNonce || !options.responseUri) {\n throw new CredoError(\n 'mdocGeneratedNonce and responseUri are required for mdoc openid4vp session transcript calculation'\n )\n }\n\n sessionTranscriptOptions = {\n type: 'openId4VpDraft18',\n clientId: options.clientId,\n mdocGeneratedNonce: options.mdocGeneratedNonce,\n responseUri: options.responseUri,\n verifierGeneratedNonce: options.nonce,\n }\n }\n\n await mdocDeviceResponse.verify(agentContext, {\n sessionTranscriptOptions,\n trustedCertificates,\n })\n }\n // TODO: extract transaction data hashes once https://github.com/openid/OpenID4VP/pull/330 is resolved\n\n isValid = true\n verifiablePresentation = mdocDeviceResponse\n } else if (format === ClaimFormat.JwtVp) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n\n verifiablePresentation = W3cJwtVerifiablePresentation.fromSerializedJwt(presentation)\n const verificationResult = await this.w3cCredentialService.verifyPresentation(agentContext, {\n presentation,\n challenge: options.nonce,\n domain: options.audience,\n })\n\n isValid = verificationResult.isValid\n cause = verificationResult.error\n } else if (format === ClaimFormat.SdJwtW3cVp) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n\n verifiablePresentation = W3cV2SdJwtVerifiablePresentation.fromCompact(presentation)\n const verificationResult = await this.w3cV2CredentialService.verifyPresentation(agentContext, {\n presentation: verifiablePresentation,\n challenge: options.nonce,\n domain: options.audience,\n })\n\n isValid = verificationResult.isValid\n cause = verificationResult.error\n } else {\n verifiablePresentation = JsonTransformer.fromJSON(presentation, W3cJsonLdVerifiablePresentation)\n const verificationResult = await this.w3cCredentialService.verifyPresentation(agentContext, {\n presentation: verifiablePresentation,\n challenge: options.nonce,\n domain: options.audience,\n })\n\n isValid = verificationResult.isValid\n cause = verificationResult.error\n }\n\n if (!isValid) {\n throw new CredoError(`Error occured during verification of presentation.${cause ? ` ${cause.message}` : ''}`, {\n cause,\n })\n }\n\n return {\n verified: true,\n presentation: verifiablePresentation,\n }\n } catch (error) {\n agentContext.config.logger.warn('Error occurred during verification of presentation', {\n error,\n })\n return {\n verified: false,\n reason: error.message,\n }\n }\n }\n\n /**\n * Update the record to a new state and emit an state changed event. Also updates the record\n * in storage.\n */\n public async updateState(\n agentContext: AgentContext,\n verificationSession: OpenId4VcVerificationSessionRecord,\n newState: OpenId4VcVerificationSessionState\n ) {\n agentContext.config.logger.debug(\n `Updating openid4vc verification session record ${verificationSession.id} to state ${newState} (previous=${verificationSession.state})`\n )\n\n const previousState = verificationSession.state\n verificationSession.state = newState\n await this.openId4VcVerificationSessionRepository.update(agentContext, verificationSession)\n\n this.emitStateChangedEvent(agentContext, verificationSession, previousState)\n }\n\n protected emitStateChangedEvent(\n agentContext: AgentContext,\n verificationSession: OpenId4VcVerificationSessionRecord,\n previousState: OpenId4VcVerificationSessionState | null\n ) {\n const eventEmitter = agentContext.dependencyManager.resolve(EventEmitter)\n\n eventEmitter.emit<OpenId4VcVerificationSessionStateChangedEvent>(agentContext, {\n type: OpenId4VcVerifierEvents.VerificationSessionStateChanged,\n payload: {\n verificationSession: verificationSession.clone(),\n previousState,\n },\n })\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"OpenId4VpVerifierService.mjs","names":["OpenId4VpVerifierService","logger: Logger","w3cCredentialService: W3cCredentialService","w3cV2CredentialService: W3cV2CredentialService","openId4VcVerifierRepository: OpenId4VcVerifierRepository","config: OpenId4VcVerifierModuleConfig","openId4VcVerificationSessionRepository: OpenId4VcVerificationSessionRepository","clientIdPrefix: ClientIdPrefix","clientId: string | undefined","presentations","parsedAuthorizationResponse: ParsedOpenid4vpAuthorizationResponse | undefined","dcqlResponse: OpenId4VpVerifiedAuthorizationResponseDcql | undefined","pexResponse: OpenId4VpVerifiedAuthorizationResponsePresentationExchange | undefined","transactionData: OpenId4VpVerifiedAuthorizationResponseTransactionData[] | undefined","result","presentationExchange: OpenId4VpVerifiedAuthorizationResponsePresentationExchange | undefined","transactionDataHashesCredentials: TransactionDataHashesCredentials","jarmEncryptionJwk: JarmEncryptionJwk | undefined","jarmClientMetadata:\n | Pick<\n ClientMetadata,\n | 'jwks'\n | 'encrypted_response_enc_values_supported'\n | 'authorization_encrypted_response_alg'\n | 'authorization_encrypted_response_enc'\n >\n | undefined","isValid: boolean","cause: Error | undefined","verifiablePresentation: VerifiablePresentation","trustedCertificates: string[] | undefined","mdocDeviceResponse","sessionTranscriptOptions: MdocSessionTranscriptOptions"],"sources":["../../src/openid4vc-verifier/OpenId4VpVerifierService.ts"],"sourcesContent":["import {\n AgentContext,\n ClaimFormat,\n CredoError,\n type DcqlEncodedPresentations,\n type DcqlQuery,\n DcqlService,\n type DifPresentationExchangeDefinition,\n DifPresentationExchangeService,\n type DifPresentationExchangeSubmission,\n EventEmitter,\n extractPresentationsWithDescriptorsFromSubmission,\n extractX509CertificatesFromJwt,\n getDomainFromUrl,\n Hasher,\n type HashName,\n InjectionSymbols,\n inject,\n injectable,\n isMdocSupportedSignatureAlgorithm,\n JsonEncoder,\n JsonTransformer,\n Jwt,\n joinUriParts,\n Kms,\n type Logger,\n MdocDeviceResponse,\n type MdocSessionTranscriptOptions,\n type MdocSupportedSignatureAlgorithm,\n mapNonEmptyArray,\n type NonEmptyArray,\n type Query,\n type QueryOptions,\n SdJwtVcApi,\n SignatureSuiteRegistry,\n TypedArrayEncoder,\n utils,\n type VerifiablePresentation,\n W3cCredentialService,\n W3cJsonLdVerifiablePresentation,\n W3cJwtVerifiablePresentation,\n W3cV2CredentialService,\n W3cV2SdJwtVerifiablePresentation,\n X509Certificate,\n X509ModuleConfig,\n X509Service,\n} from '@credo-ts/core'\nimport { type Jwk, Oauth2ErrorCodes, Oauth2ServerErrorResponseError } from '@openid4vc/oauth2'\nimport {\n type ClientIdPrefix,\n type ClientMetadata,\n calculateX509HashClientIdPrefixValue,\n getOpenid4vpClientId,\n isJarmResponseMode,\n isOpenid4vpAuthorizationRequestDcApi,\n JarmMode,\n Openid4vpVerifier,\n type ParsedOpenid4vpAuthorizationResponse,\n type TransactionDataHashesCredentials,\n zOpenid4vpAuthorizationResponse,\n} from '@openid4vc/openid4vp'\nimport { getOid4vcCallbacks } from '../shared/callbacks'\nimport type { OpenId4VpAuthorizationRequestPayload } from '../shared/index'\nimport { storeActorIdForContextCorrelationId } from '../shared/router'\nimport { getSdJwtVcTransactionDataHashes } from '../shared/transactionData'\nimport {\n credoJwtIssuerToOpenId4VcJwtIssuer,\n dcqlCredentialQueryToPresentationFormat,\n getSupportedJwaSignatureAlgorithms,\n} from '../shared/utils'\nimport { OpenId4VcVerificationSessionState } from './OpenId4VcVerificationSessionState'\nimport { type OpenId4VcVerificationSessionStateChangedEvent, OpenId4VcVerifierEvents } from './OpenId4VcVerifierEvents'\nimport { OpenId4VcVerifierModuleConfig } from './OpenId4VcVerifierModuleConfig'\nimport type {\n OpenId4VpCreateAuthorizationRequestOptions,\n OpenId4VpCreateAuthorizationRequestReturn,\n OpenId4VpCreateVerifierOptions,\n OpenId4VpVerifiedAuthorizationResponse,\n OpenId4VpVerifiedAuthorizationResponseDcql,\n OpenId4VpVerifiedAuthorizationResponsePresentationExchange,\n OpenId4VpVerifiedAuthorizationResponseTransactionData,\n OpenId4VpVerifyAuthorizationResponseOptions,\n OpenId4VpVersion,\n ResponseMode,\n} from './OpenId4VpVerifierServiceOptions'\nimport {\n OpenId4VcVerificationSessionRecord,\n OpenId4VcVerificationSessionRepository,\n OpenId4VcVerifierRecord,\n OpenId4VcVerifierRepository,\n} from './repository'\n\n/**\n * @internal\n */\n@injectable()\nexport class OpenId4VpVerifierService {\n public constructor(\n @inject(InjectionSymbols.Logger) private logger: Logger,\n private w3cCredentialService: W3cCredentialService,\n private w3cV2CredentialService: W3cV2CredentialService,\n private openId4VcVerifierRepository: OpenId4VcVerifierRepository,\n private config: OpenId4VcVerifierModuleConfig,\n private openId4VcVerificationSessionRepository: OpenId4VcVerificationSessionRepository\n ) {}\n\n private getOpenid4vpVerifier(agentContext: AgentContext) {\n const callbacks = getOid4vcCallbacks(agentContext)\n const openid4vpClient = new Openid4vpVerifier({ callbacks })\n\n return openid4vpClient\n }\n\n public async createAuthorizationRequest(\n agentContext: AgentContext,\n options: OpenId4VpCreateAuthorizationRequestOptions & { verifier: OpenId4VcVerifierRecord }\n ): Promise<OpenId4VpCreateAuthorizationRequestReturn> {\n const kms = agentContext.resolve(Kms.KeyManagementApi)\n const nonce = TypedArrayEncoder.toBase64URL(kms.randomBytes({ length: 32 }))\n const state = TypedArrayEncoder.toBase64URL(kms.randomBytes({ length: 32 }))\n\n const responseMode = options.responseMode ?? 'direct_post.jwt'\n const isDcApiRequest = responseMode === 'dc_api' || responseMode === 'dc_api.jwt'\n\n const version = options.version ?? 'v1'\n if (version === 'v1.draft21' && isDcApiRequest) {\n throw new CredoError(\n `OpenID4VP version '${version}' cannot be used with responseMode '${options.responseMode}'. Use version 'v1' or 'v1.draft24' instead.`\n )\n }\n if (version === 'v1.draft21' && options.transactionData) {\n throw new CredoError(\n `OpenID4VP version '${version}' cannot be used with transactionData. Use version 'v1' or 'v1.draft24' instead.`\n )\n }\n if (version === 'v1.draft21' && options.dcql) {\n throw new CredoError(\n `OpenID4VP version '${version}' cannot be used with dcql. Use version 'v1' or 'v1.draft24' instead.`\n )\n }\n if (version !== 'v1' && options.verifierInfo) {\n throw new CredoError(`OpenID4VP version '${version}' cannot be used with verifierInfo. Use version 'v1' instead.`)\n }\n if (version === 'v1' && options.presentationExchange) {\n throw new CredoError(\n `OpenID4VP version '${version}' cannot be used with presentationExchange. Use dcql instead (recommended), or use older versions 'v1.draft24' and 'v1.draft21'.`\n )\n }\n\n // For now we only support presentations with holder binding.\n if (options.dcql?.query.credentials.some((c) => c.require_cryptographic_holder_binding === false)) {\n throw new CredoError(\n `Setting 'require_cryptographic_holder_binding' to false in DCQL Query is not supported by Credo at the moment. Only presentations with cryptographic holder binding are supported.`\n )\n }\n\n if (isDcApiRequest && options.authorizationResponseRedirectUri) {\n throw new CredoError(\n \"'authorizationResponseRedirectUri' cannot be be used with response mode 'dc_api' and 'dc_api.jwt'.\"\n )\n }\n\n // Check to prevent direct_post from being used with mDOC\n const hasMdocRequest =\n options.presentationExchange?.definition.input_descriptors.some((i) => i.format?.mso_mdoc) ||\n options.dcql?.query.credentials.some((c) => c.format === 'mso_mdoc')\n // Up to draft 24 we use the 18013-7 mdoc session transcript which needs values from APU/APV\n if ((version === 'v1.draft21' || version === 'v1.draft24') && responseMode === 'direct_post' && hasMdocRequest) {\n throw new CredoError(\n \"Unable to create authorization request with response mode 'direct_post' containing mDOC credentials. ISO 18013-7 requires the usage of response mode 'direct_post.jwt', and needs parameters from the encrypted response header to verify the mDOC sigature. Either use version 'v1', or update the response mode to 'direct_post.jwt'\"\n )\n }\n\n if (options.verifierInfo) {\n const queryIds =\n options?.dcql?.query.credentials.map(({ id }) => id) ??\n options?.presentationExchange?.definition.input_descriptors.map(({ id }) => id) ??\n []\n\n const hasValidCredentialIds = options.verifierInfo.every(\n (vi) => !vi.credential_ids || vi.credential_ids.every((credentialId) => queryIds.includes(credentialId))\n )\n\n if (!hasValidCredentialIds) {\n throw new CredoError(\n 'Verifier info (attestations) were provided, but the verifier info used credential ids that are not present in the query'\n )\n }\n }\n\n const authorizationRequestId = utils.uuid()\n // We include the `session=` in the url so we can still easily\n // find the session an encrypted response\n const authorizationResponseUrl = `${joinUriParts(this.config.baseUrl, [options.verifier.verifierId, this.config.authorizationEndpoint])}?session=${authorizationRequestId}`\n\n const jwtIssuer =\n options.requestSigner.method !== 'none'\n ? await credoJwtIssuerToOpenId4VcJwtIssuer(agentContext, options.requestSigner)\n : undefined\n\n let clientIdPrefix: ClientIdPrefix\n let clientId: string | undefined\n\n if (!jwtIssuer) {\n if (isDcApiRequest) {\n clientIdPrefix = version === 'v1' ? 'origin' : 'web-origin'\n clientId = undefined\n } else {\n clientIdPrefix = 'redirect_uri'\n clientId = authorizationResponseUrl\n }\n } else if (jwtIssuer?.method === 'x5c') {\n const leafCertificate = X509Service.getLeafCertificate(agentContext, { certificateChain: jwtIssuer.x5c })\n\n if (\n !authorizationResponseUrl.startsWith('https://') &&\n !(authorizationResponseUrl.startsWith('http://') && agentContext.config.allowInsecureHttpUrls)\n ) {\n throw new CredoError('The X509 certificate issuer must be a HTTPS URI.')\n }\n\n if (options.requestSigner.method === 'x5c' && options.requestSigner.clientIdPrefix === 'x509_hash') {\n clientIdPrefix = 'x509_hash'\n clientId = await calculateX509HashClientIdPrefixValue({\n x509Certificate: leafCertificate.rawCertificate,\n hash: Hasher.hash,\n })\n } else {\n if (!leafCertificate.sanDnsNames.includes(getDomainFromUrl(authorizationResponseUrl))) {\n const sanDnsMessage =\n leafCertificate.sanDnsNames.length > 0\n ? `SAN-DNS names are ${leafCertificate.sanDnsNames.join(', ')}`\n : 'there are no SAN-DNS names'\n\n throw new CredoError(\n `The domain of the OpenID4VCI issuer does not match a SAN DNS name in the x5c certificate. The OpenID4VCI domain is '${getDomainFromUrl(authorizationResponseUrl)}', $${sanDnsMessage}`\n )\n }\n\n clientIdPrefix = 'x509_san_dns'\n clientId = getDomainFromUrl(authorizationResponseUrl)\n }\n } else if (jwtIssuer?.method === 'did') {\n clientId = jwtIssuer.didUrl.split('#')[0]\n clientIdPrefix = version === 'v1' ? 'decentralized_identifier' : 'did'\n } else {\n throw new CredoError(\n `Unsupported jwt issuer method '${options.requestSigner.method}'. Only 'did' and 'x5c' are supported.`\n )\n }\n\n // We always use shortened URIs currently\n const hostedAuthorizationRequestUri =\n !isDcApiRequest && jwtIssuer\n ? joinUriParts(this.config.baseUrl, [\n options.verifier.verifierId,\n this.config.authorizationRequestEndpoint,\n authorizationRequestId,\n ])\n : // No hosted request needed when using DC API or using unsigned request\n undefined\n\n const client_id =\n // For did/https and draft 21 the client id has no special prefix\n clientIdPrefix === 'did' || (clientIdPrefix as string) === 'https' || version === 'v1.draft21'\n ? clientId\n : `${clientIdPrefix}:${clientId}`\n\n // for did the client_id is same in draft 21 and 24 so we could support both at the same time\n const legacyClientIdScheme =\n version === 'v1.draft21' &&\n clientIdPrefix !== 'web-origin' &&\n clientIdPrefix !== 'origin' &&\n clientIdPrefix !== 'decentralized_identifier'\n ? clientIdPrefix\n : undefined\n\n const client_metadata = await this.getClientMetadata(agentContext, {\n responseMode,\n verifier: options.verifier,\n authorizationResponseUrl,\n version,\n\n // TODO: we don't validate the DCQL query when creating a request i think?\n dcqlQuery: options.dcql?.query,\n })\n\n const requestParamsBase = {\n nonce,\n presentation_definition: options.presentationExchange?.definition,\n dcql_query: options.dcql?.query,\n transaction_data: options.transactionData?.map((entry) => JsonEncoder.toBase64URL(entry)),\n response_mode: responseMode,\n response_type: 'vp_token',\n client_metadata,\n verifier_info: options.verifierInfo,\n } as const\n\n const openid4vpVerifier = this.getOpenid4vpVerifier(agentContext)\n const authorizationRequest = await openid4vpVerifier.createOpenId4vpAuthorizationRequest({\n jar: jwtIssuer\n ? {\n jwtSigner: jwtIssuer,\n requestUri: hostedAuthorizationRequestUri,\n expiresInSeconds: this.config.authorizationRequestExpiresInSeconds,\n }\n : undefined,\n authorizationRequestPayload:\n requestParamsBase.response_mode === 'dc_api.jwt' || requestParamsBase.response_mode === 'dc_api'\n ? {\n ...requestParamsBase,\n // No client_id for unsigned DC API requests\n client_id: jwtIssuer ? client_id : undefined,\n response_mode: requestParamsBase.response_mode,\n expected_origins: options.expectedOrigins,\n }\n : {\n ...requestParamsBase,\n response_mode: requestParamsBase.response_mode,\n client_id: client_id as string,\n state,\n response_uri: authorizationResponseUrl,\n client_id_scheme: legacyClientIdScheme,\n },\n })\n\n const verificationSession = new OpenId4VcVerificationSessionRecord({\n authorizationResponseRedirectUri: options.authorizationResponseRedirectUri,\n\n // Only store payload for unsiged requests\n authorizationRequestPayload: authorizationRequest.jar\n ? undefined\n : authorizationRequest.authorizationRequestPayload,\n authorizationRequestJwt: authorizationRequest.jar?.authorizationRequestJwt,\n authorizationRequestUri: hostedAuthorizationRequestUri,\n authorizationRequestId,\n state: OpenId4VcVerificationSessionState.RequestCreated,\n verifierId: options.verifier.verifierId,\n expiresAt: utils.addSecondsToDate(new Date(), this.config.authorizationRequestExpiresInSeconds),\n openId4VpVersion: version,\n })\n await this.openId4VcVerificationSessionRepository.save(agentContext, verificationSession)\n this.emitStateChangedEvent(agentContext, verificationSession, null)\n\n return {\n authorizationRequest: authorizationRequest.authorizationRequest,\n verificationSession,\n authorizationRequestObject: authorizationRequest.authorizationRequestObject,\n }\n }\n\n private async getDcqlVerifiedResponse(\n agentContext: AgentContext,\n _dcqlQuery: unknown,\n presentations: DcqlEncodedPresentations\n ) {\n const dcqlService = agentContext.dependencyManager.resolve(DcqlService)\n const dcqlQuery = dcqlService.validateDcqlQuery(_dcqlQuery)\n\n const dcqlPresentationEntries = Object.entries(presentations)\n const dcqlPresentation = Object.fromEntries(\n dcqlPresentationEntries.map(([credentialId, presentations]) => {\n const queryCredential = dcqlQuery.credentials.find((c) => c.id === credentialId)\n if (!queryCredential) {\n throw new CredoError(\n `vp_token contains presentation for credential query id '${credentialId}', but this credential is not present in the dcql query.`\n )\n }\n\n return [\n credentialId,\n mapNonEmptyArray(presentations, (presentation) =>\n this.decodePresentation(agentContext, {\n presentation,\n format: dcqlCredentialQueryToPresentationFormat(queryCredential),\n })\n ),\n ]\n })\n )\n\n const dcqlPresentationResult = await dcqlService.assertValidDcqlPresentation(\n agentContext,\n dcqlPresentation,\n dcqlQuery\n )\n\n return {\n query: dcqlQuery,\n presentations: dcqlPresentation,\n presentationResult: dcqlPresentationResult,\n } satisfies OpenId4VpVerifiedAuthorizationResponseDcql\n }\n\n private async parseAuthorizationResponse(\n agentContext: AgentContext,\n options: {\n authorizationResponse: Record<string, unknown>\n origin?: string\n verificationSession: OpenId4VcVerificationSessionRecord\n }\n ): Promise<ParsedOpenid4vpAuthorizationResponse & { verificationSession: OpenId4VcVerificationSessionRecord }> {\n const openid4vpVerifier = this.getOpenid4vpVerifier(agentContext)\n\n const { authorizationResponse, verificationSession, origin } = options\n let parsedAuthorizationResponse: ParsedOpenid4vpAuthorizationResponse | undefined\n\n try {\n parsedAuthorizationResponse = await openid4vpVerifier.parseOpenid4vpAuthorizationResponse({\n authorizationResponse,\n origin,\n authorizationRequestPayload: verificationSession.requestPayload,\n callbacks: getOid4vcCallbacks(agentContext),\n })\n\n if (parsedAuthorizationResponse.jarm && parsedAuthorizationResponse.jarm.type !== JarmMode.Encrypted) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: `Only encrypted JARM responses are supported, received '${parsedAuthorizationResponse.jarm.type}'.`,\n })\n }\n\n return {\n ...parsedAuthorizationResponse,\n verificationSession,\n }\n } catch (error) {\n if (\n verificationSession?.state === OpenId4VcVerificationSessionState.RequestUriRetrieved ||\n verificationSession?.state === OpenId4VcVerificationSessionState.RequestCreated\n ) {\n const parsed = zOpenid4vpAuthorizationResponse.safeParse(\n parsedAuthorizationResponse?.authorizationResponsePayload\n )\n\n verificationSession.authorizationResponsePayload = parsed.success ? parsed.data : undefined\n verificationSession.errorMessage = error.message\n await this.updateState(agentContext, verificationSession, OpenId4VcVerificationSessionState.Error)\n }\n\n throw error\n }\n }\n\n public async verifyAuthorizationResponse(\n agentContext: AgentContext,\n options: OpenId4VpVerifyAuthorizationResponseOptions & {\n /**\n * The verification session associated with the response\n */\n verificationSession: OpenId4VcVerificationSessionRecord\n }\n ): Promise<OpenId4VpVerifiedAuthorizationResponse> {\n const { verificationSession, authorizationResponse, origin } = options\n const authorizationRequest = verificationSession.requestPayload\n const openid4vpVersion =\n verificationSession.openId4VpVersion ??\n (authorizationRequest.client_id_scheme !== undefined ? 'v1.draft21' : 'v1.draft24')\n\n if (\n verificationSession.state !== OpenId4VcVerificationSessionState.RequestUriRetrieved &&\n verificationSession.state !== OpenId4VcVerificationSessionState.RequestCreated\n ) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'Invalid session',\n })\n }\n\n if (verificationSession.expiresAt && Date.now() > verificationSession.expiresAt.getTime()) {\n verificationSession.errorMessage = 'session expired'\n await this.updateState(agentContext, verificationSession, OpenId4VcVerificationSessionState.Error)\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'session expired',\n })\n }\n\n const result = await this.parseAuthorizationResponse(agentContext, {\n verificationSession,\n authorizationResponse,\n origin,\n })\n\n // NOTE: we always currently include only one key, and also use 'use=enc'. If we change\n // that, we should change this. I think we should return the jarm key in the openid4vp lib\n // and match against that (and also ensure then it's present in client_metadata -> should not conflict with federation)\n const encryptionJwk = authorizationRequest.client_metadata?.jwks?.keys.find((key) => key.use === 'enc')\n const encryptionPublicJwk = encryptionJwk ? Kms.PublicJwk.fromUnknown(encryptionJwk) : undefined\n\n let dcqlResponse: OpenId4VpVerifiedAuthorizationResponseDcql | undefined\n let pexResponse: OpenId4VpVerifiedAuthorizationResponsePresentationExchange | undefined\n let transactionData: OpenId4VpVerifiedAuthorizationResponseTransactionData[] | undefined\n\n try {\n const parsedClientId = getOpenid4vpClientId({\n responseMode: authorizationRequest.response_mode,\n clientId: authorizationRequest.client_id,\n legacyClientIdScheme: authorizationRequest.client_id_scheme,\n origin: options.origin,\n version: openid4vpVersion === 'v1' ? 100 : openid4vpVersion === 'v1.draft24' ? 24 : 21,\n })\n\n const clientId = parsedClientId.effectiveClientId\n const isDcApiRequest = isOpenid4vpAuthorizationRequestDcApi(authorizationRequest)\n\n // TODO: we should return the effectiveAudience in the returned value of openid4vp lib\n // Since it differs based on the version of openid4vp used\n // NOTE: in v1 DC API request the audience is always origin: (not the client id)\n const audience = openid4vpVersion === 'v1' && isDcApiRequest ? `origin:${options.origin}` : clientId\n\n const responseUri = isOpenid4vpAuthorizationRequestDcApi(authorizationRequest)\n ? undefined\n : authorizationRequest.response_uri\n\n // NOTE: apu is needed for mDOC over OID4VP without DC API up to draft 24\n const mdocGeneratedNonce = result.jarm?.jarmHeader.apu\n ? TypedArrayEncoder.toUtf8String(TypedArrayEncoder.fromBase64(result.jarm?.jarmHeader.apu))\n : undefined\n\n if (result.type === 'dcql') {\n const dcqlPresentationEntries = Object.entries(result.dcql.presentations)\n if (!authorizationRequest.dcql_query) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'DCQL response provided but no dcql_query found in the authorization request.',\n })\n }\n\n const dcql = agentContext.dependencyManager.resolve(DcqlService)\n const dcqlQuery = dcql.validateDcqlQuery(authorizationRequest.dcql_query)\n\n const presentationVerificationResults = await Promise.all(\n dcqlPresentationEntries.map(async ([credentialId, presentations]) => {\n const queryCredential = dcqlQuery.credentials.find((c) => c.id === credentialId)\n if (!queryCredential) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: `vp_token contains presentation for credential query id '${credentialId}', but this credential is not present in the dcql query.`,\n })\n }\n\n const verifiedPresentations = await Promise.all(\n mapNonEmptyArray(presentations, (presentation) =>\n this.verifyPresentation(agentContext, {\n format: dcqlCredentialQueryToPresentationFormat(queryCredential),\n nonce: authorizationRequest.nonce,\n audience,\n version: openid4vpVersion,\n clientId,\n encryptionJwk: encryptionPublicJwk,\n origin: options.origin,\n responseUri,\n mdocGeneratedNonce,\n verificationSessionId: result.verificationSession.id,\n presentation,\n })\n )\n )\n return [credentialId, verifiedPresentations] as const\n })\n )\n\n const errorMessages = presentationVerificationResults\n .flatMap(([credentialId, presentations], index) =>\n presentations.map((result) =>\n !result.verified ? `\\t- ${credentialId}[${index}]: ${result.reason}` : undefined\n )\n )\n .filter((i) => i !== undefined)\n if (errorMessages.length > 0) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'One or more presentations failed verification.',\n },\n { internalMessage: errorMessages.join('\\n') }\n )\n }\n\n // We can be certain here that all presentations passed verification\n const presentations = Object.fromEntries(\n presentationVerificationResults.map(\n ([credentialId, presentations]) =>\n [\n credentialId,\n presentations\n .map((p) => (p.verified ? p.presentation : undefined))\n // NOTE: we add NonEmpty cast here since it's needed for DCQL, and because we\n // previously ensured all items are valid, we can be sure this arary is non empty\n // even after the filter.\n .filter((p) => p !== undefined) as NonEmptyArray<VerifiablePresentation>,\n ] as const\n )\n )\n\n try {\n const presentationResult = await dcql.assertValidDcqlPresentation(agentContext, presentations, dcqlQuery)\n\n dcqlResponse = {\n presentations,\n presentationResult,\n query: dcqlQuery,\n }\n } catch (error) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'Presentation submission does not satisfy presentation request.',\n },\n { cause: error }\n )\n }\n }\n\n if (result.type === 'pex') {\n const pex = agentContext.dependencyManager.resolve(DifPresentationExchangeService)\n\n const encodedPresentations = result.pex.presentations\n const submission = result.pex.presentationSubmission as DifPresentationExchangeSubmission\n const definition = result.pex.presentationDefinition as unknown as DifPresentationExchangeDefinition\n\n pex.validatePresentationDefinition(definition)\n\n try {\n pex.validatePresentationSubmission(submission)\n } catch (error) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'Invalid presentation submission.',\n },\n { cause: error }\n )\n }\n\n const presentationsArray = Array.isArray(encodedPresentations) ? encodedPresentations : [encodedPresentations]\n const presentationVerificationResults = await Promise.all(\n presentationsArray.map((presentation) => {\n return this.verifyPresentation(agentContext, {\n nonce: authorizationRequest.nonce,\n audience,\n clientId,\n version: openid4vpVersion,\n encryptionJwk: encryptionPublicJwk,\n responseUri,\n mdocGeneratedNonce,\n verificationSessionId: result.verificationSession.id,\n presentation,\n format: this.claimFormatFromEncodedPresentation(presentation),\n origin: options.origin,\n })\n })\n )\n\n const errorMessages = presentationVerificationResults\n .map((result, index) => (!result.verified ? `\\t- [${index}]: ${result.reason}` : undefined))\n .filter((i) => i !== undefined)\n if (errorMessages.length > 0) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'One or more presentations failed verification.',\n },\n { internalMessage: errorMessages.join('\\n') }\n )\n }\n\n const verifiablePresentations = presentationVerificationResults\n .map((p) => (p.verified ? p.presentation : undefined))\n .filter((p) => p !== undefined)\n\n try {\n pex.validatePresentation(\n definition,\n // vp_token MUST not be an array if only one entry\n verifiablePresentations.length === 1 ? verifiablePresentations[0] : verifiablePresentations,\n submission\n )\n } catch (error) {\n throw new Oauth2ServerErrorResponseError(\n {\n error: Oauth2ErrorCodes.InvalidRequest,\n error_description: 'Presentation submission does not satisfy presentation request.',\n },\n { cause: error }\n )\n }\n\n const descriptors = extractPresentationsWithDescriptorsFromSubmission(\n // vp_token MUST not be an array if only one entry\n verifiablePresentations.length === 1 ? verifiablePresentations[0] : verifiablePresentations,\n submission,\n definition\n )\n\n pexResponse = {\n definition,\n descriptors,\n presentations: verifiablePresentations,\n submission,\n }\n }\n\n transactionData = await this.getVerifiedTransactionData(agentContext, {\n authorizationRequest,\n dcql: dcqlResponse,\n presentationExchange: pexResponse,\n })\n } catch (error) {\n result.verificationSession.errorMessage = error.message\n await this.updateState(agentContext, result.verificationSession, OpenId4VcVerificationSessionState.Error)\n throw error\n }\n\n result.verificationSession.authorizationResponsePayload = result.authorizationResponsePayload\n await this.updateState(agentContext, result.verificationSession, OpenId4VcVerificationSessionState.ResponseVerified)\n\n return {\n presentationExchange: pexResponse,\n dcql: dcqlResponse,\n transactionData,\n verificationSession: result.verificationSession,\n }\n }\n\n /**\n * Get the format based on an encoded presentation. This is mostly leveraged for\n * PEX where it's not known based on the request which format to expect\n */\n private claimFormatFromEncodedPresentation(\n presentation: string | Record<string, unknown>\n ): ClaimFormat.JwtVp | ClaimFormat.LdpVp | ClaimFormat.SdJwtDc | ClaimFormat.MsoMdoc {\n if (typeof presentation === 'object') return ClaimFormat.LdpVp\n if (presentation.includes('~')) return ClaimFormat.SdJwtDc\n if (Jwt.format.test(presentation)) return ClaimFormat.JwtVp\n\n // Fallback, we tried all other formats\n return ClaimFormat.MsoMdoc\n }\n\n public async getVerifiedAuthorizationResponse(\n agentContext: AgentContext,\n verificationSession: OpenId4VcVerificationSessionRecord\n ): Promise<OpenId4VpVerifiedAuthorizationResponse> {\n verificationSession.assertState(OpenId4VcVerificationSessionState.ResponseVerified)\n\n if (!verificationSession.authorizationResponsePayload) {\n throw new CredoError('No authorization response payload found in the verification session.')\n }\n\n const authorizationRequestPayload = verificationSession.requestPayload\n const openid4vpAuthorizationResponsePayload = verificationSession.authorizationResponsePayload\n const openid4vpVerifier = this.getOpenid4vpVerifier(agentContext)\n\n const result = openid4vpVerifier.validateOpenid4vpAuthorizationResponsePayload({\n authorizationRequestPayload: verificationSession.requestPayload,\n authorizationResponsePayload: openid4vpAuthorizationResponsePayload,\n })\n\n let presentationExchange: OpenId4VpVerifiedAuthorizationResponsePresentationExchange | undefined\n const dcql =\n result.type === 'dcql'\n ? await this.getDcqlVerifiedResponse(\n agentContext,\n authorizationRequestPayload.dcql_query,\n result.dcql.presentations\n )\n : undefined\n\n if (result.type === 'pex') {\n const presentationDefinition =\n authorizationRequestPayload.presentation_definition as unknown as DifPresentationExchangeDefinition\n const submission = openid4vpAuthorizationResponsePayload.presentation_submission as\n | DifPresentationExchangeSubmission\n | undefined\n\n if (!submission) {\n throw new CredoError('Unable to extract submission from the response.')\n }\n\n const verifiablePresentations = result.pex.presentations.map((presentation) =>\n this.decodePresentation(agentContext, {\n presentation,\n format: this.claimFormatFromEncodedPresentation(presentation),\n })\n )\n\n presentationExchange = {\n definition: presentationDefinition,\n submission,\n presentations: verifiablePresentations,\n descriptors: extractPresentationsWithDescriptorsFromSubmission(\n // vp_token MUST not be an array if only one entry\n verifiablePresentations.length === 1 ? verifiablePresentations[0] : verifiablePresentations,\n submission,\n presentationDefinition\n ),\n }\n }\n\n if (!presentationExchange && !dcql) {\n throw new CredoError('No presentationExchange or dcql found in the response.')\n }\n\n const transactionData = await this.getVerifiedTransactionData(agentContext, {\n authorizationRequest: authorizationRequestPayload,\n dcql,\n presentationExchange,\n })\n\n return {\n presentationExchange,\n dcql,\n transactionData,\n verificationSession,\n }\n }\n\n private async getVerifiedTransactionData(\n agentContext: AgentContext,\n {\n authorizationRequest,\n presentationExchange,\n dcql,\n }: {\n dcql?: OpenId4VpVerifiedAuthorizationResponseDcql\n presentationExchange?: OpenId4VpVerifiedAuthorizationResponsePresentationExchange\n authorizationRequest: OpenId4VpAuthorizationRequestPayload\n }\n ): Promise<OpenId4VpVerifiedAuthorizationResponseTransactionData[] | undefined> {\n if (!authorizationRequest.transaction_data) return undefined\n\n const openid4vpVerifier = this.getOpenid4vpVerifier(agentContext)\n const transactionDataHashesCredentials: TransactionDataHashesCredentials = {}\n\n // Extract presentations with credentialId\n const idToCredential = dcql\n ? Object.entries(dcql.presentations)\n : (presentationExchange?.descriptors.map(\n (descriptor) => [descriptor.descriptor.id, [descriptor.presentation]] as const\n ) ?? [])\n\n for (const [credentialId, presentations] of idToCredential) {\n // Only SD-JWT VC supported for now\n const transactionDataHashes = presentations.map((presentation) =>\n presentation.claimFormat === ClaimFormat.SdJwtDc ? getSdJwtVcTransactionDataHashes(presentation) : undefined\n )\n\n const firstHasHash = transactionDataHashes[0] !== undefined\n if (!transactionDataHashes.every((hash) => (firstHasHash ? hash !== undefined : hash === undefined))) {\n throw new Oauth2ServerErrorResponseError({\n error: Oauth2ErrorCodes.InvalidTransactionData,\n error_description: `Multipe presentations were submitted for credential query ${credentialId} but not all presentations includes a transaction data hash. Either all or none of the presentations for a credential query id should include a transaction data hash.`,\n })\n }\n\n if (!firstHasHash) continue\n\n transactionDataHashesCredentials[credentialId] = transactionDataHashes as [\n Exclude<(typeof transactionDataHashes)[number], undefined>,\n ]\n }\n\n // Verify the transaction data\n const transactionData = await openid4vpVerifier.verifyTransactionData({\n credentials: transactionDataHashesCredentials,\n transactionData: authorizationRequest.transaction_data,\n })\n\n return transactionData.map(({ credentialId, transactionDataEntry, presentations }) => ({\n credentialId,\n encoded: transactionDataEntry.encoded,\n decoded: transactionDataEntry.transactionData,\n transactionDataIndex: transactionDataEntry.transactionDataIndex,\n presentations: presentations.map((presentation) => ({\n presentationHashIndex: presentation.credentialHashIndex,\n hash: presentation.hash,\n // We only support the values supported by Credo hasher, so it can't be any other value than those.\n hashAlg: presentation.hashAlg as HashName,\n })) as OpenId4VpVerifiedAuthorizationResponseTransactionData['presentations'],\n }))\n }\n\n public async getAllVerifiers(agentContext: AgentContext) {\n return this.openId4VcVerifierRepository.getAll(agentContext)\n }\n\n public async getVerifierByVerifierId(agentContext: AgentContext, verifierId: string) {\n return this.openId4VcVerifierRepository.getByVerifierId(agentContext, verifierId)\n }\n\n public async updateVerifier(agentContext: AgentContext, verifier: OpenId4VcVerifierRecord) {\n return this.openId4VcVerifierRepository.update(agentContext, verifier)\n }\n\n public async createVerifier(agentContext: AgentContext, options?: OpenId4VpCreateVerifierOptions) {\n const openId4VcVerifier = new OpenId4VcVerifierRecord({\n verifierId: options?.verifierId ?? utils.uuid(),\n clientMetadata: options?.clientMetadata,\n })\n\n await this.openId4VcVerifierRepository.save(agentContext, openId4VcVerifier)\n await storeActorIdForContextCorrelationId(agentContext, openId4VcVerifier.verifierId)\n return openId4VcVerifier\n }\n\n public async findVerificationSessionsByQuery(\n agentContext: AgentContext,\n query: Query<OpenId4VcVerificationSessionRecord>,\n queryOptions?: QueryOptions\n ) {\n return this.openId4VcVerificationSessionRepository.findByQuery(agentContext, query, queryOptions)\n }\n\n public async getVerificationSessionById(agentContext: AgentContext, verificationSessionId: string) {\n return this.openId4VcVerificationSessionRepository.getById(agentContext, verificationSessionId)\n }\n\n private async getClientMetadata(\n agentContext: AgentContext,\n options: {\n responseMode: ResponseMode\n verifier: OpenId4VcVerifierRecord\n authorizationResponseUrl: string\n dcqlQuery?: DcqlQuery\n version: NonNullable<OpenId4VpCreateAuthorizationRequestOptions['version']>\n }\n ): Promise<ClientMetadata> {\n const { responseMode, verifier } = options\n\n const signatureSuiteRegistry = agentContext.resolve(SignatureSuiteRegistry)\n const kms = agentContext.resolve(Kms.KeyManagementApi)\n const supportedAlgs = getSupportedJwaSignatureAlgorithms(agentContext) as [\n Kms.KnownJwaSignatureAlgorithm,\n ...Kms.KnownJwaSignatureAlgorithm[],\n ]\n const supportedMdocAlgs = supportedAlgs.filter(isMdocSupportedSignatureAlgorithm) as [\n MdocSupportedSignatureAlgorithm,\n ...MdocSupportedSignatureAlgorithm[],\n ]\n const supportedProofTypes = signatureSuiteRegistry.supportedProofTypes\n\n type JarmEncryptionJwk = Kms.Jwk & { kid: string; use: 'enc' }\n let jarmEncryptionJwk: JarmEncryptionJwk | undefined\n\n if (isJarmResponseMode(responseMode)) {\n const key = await kms.createKey({ type: { crv: 'P-256', kty: 'EC' } })\n jarmEncryptionJwk = { ...key.publicJwk, use: 'enc' }\n }\n\n const jarmClientMetadata:\n | Pick<\n ClientMetadata,\n | 'jwks'\n | 'encrypted_response_enc_values_supported'\n | 'authorization_encrypted_response_alg'\n | 'authorization_encrypted_response_enc'\n >\n | undefined = jarmEncryptionJwk\n ? {\n jwks: { keys: [jarmEncryptionJwk as Jwk] },\n\n ...(options.version === 'v1'\n ? {\n encrypted_response_enc_values_supported: ['A128GCM', 'A256GCM', 'A128CBC-HS256'],\n }\n : {\n authorization_encrypted_response_alg: 'ECDH-ES',\n\n // NOTE: pre draft 24 we could only include one version. To maximize compatiblity we use\n // - A128GCM for draft 24 (HAIP)\n // - A256GCM for draft 21 (18013-7)\n authorization_encrypted_response_enc: options.version === 'v1.draft24' ? 'A128GCM' : 'A256GCM',\n }),\n }\n : undefined\n\n const dclqQueryFormats = new Set(options.dcqlQuery?.credentials.map((c) => c.format))\n\n return {\n ...jarmClientMetadata,\n ...verifier.clientMetadata,\n response_types_supported: ['vp_token'],\n\n // for v1 version we only include the vp_formats_supported for formats we're\n // requesting.\n ...(options.version === 'v1'\n ? {\n vp_formats_supported: {\n ...(dclqQueryFormats.has('dc+sd-jwt')\n ? {\n 'dc+sd-jwt': {\n 'kb-jwt_alg_values': supportedAlgs,\n 'sd-jwt_alg_values': supportedAlgs,\n },\n }\n : {}),\n\n ...(dclqQueryFormats.has('mso_mdoc')\n ? {\n mso_mdoc: {\n // TODO: we need to add some generic utils for fully specified COSE algorithms\n deviceauth_alg_values: [/* P-256 */ -9, /* P-384 */ -51, /* Ed25519 */ -19],\n issuerauth_alg_values: [/* P-256 */ -9, /* P-384 */ -51, /* Ed25519 */ -19],\n },\n }\n : {}),\n\n ...(dclqQueryFormats.has('jwt_vc_json')\n ? {\n jwt_vc_json: {\n alg_values: supportedAlgs,\n },\n }\n : {}),\n\n ...(dclqQueryFormats.has('ldp_vc')\n ? {\n ldp_vc: {\n proof_type_values: supportedProofTypes as [string, ...string[]],\n },\n }\n : {}),\n },\n }\n : {\n vp_formats: {\n mso_mdoc: {\n alg: supportedMdocAlgs,\n },\n jwt_vc: {\n alg: supportedAlgs,\n },\n jwt_vc_json: {\n alg: supportedAlgs,\n },\n jwt_vp_json: {\n alg: supportedAlgs,\n },\n jwt_vp: {\n alg: supportedAlgs,\n },\n ldp_vc: {\n proof_type: supportedProofTypes,\n },\n ldp_vp: {\n proof_type: supportedProofTypes,\n },\n 'vc+sd-jwt': {\n 'kb-jwt_alg_values': supportedAlgs,\n 'sd-jwt_alg_values': supportedAlgs,\n },\n 'dc+sd-jwt': {\n 'kb-jwt_alg_values': supportedAlgs,\n 'sd-jwt_alg_values': supportedAlgs,\n },\n },\n }),\n }\n }\n\n private decodePresentation(\n agentContext: AgentContext,\n options: {\n presentation: string | Record<string, unknown>\n format: ClaimFormat.JwtVp | ClaimFormat.LdpVp | ClaimFormat.SdJwtDc | ClaimFormat.MsoMdoc | ClaimFormat.SdJwtW3cVp\n }\n ): VerifiablePresentation {\n const { presentation, format } = options\n\n if (format === ClaimFormat.SdJwtDc) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n const sdJwtVcApi = agentContext.dependencyManager.resolve(SdJwtVcApi)\n\n const sdJwtVc = sdJwtVcApi.fromCompact(presentation)\n return sdJwtVc\n }\n if (format === ClaimFormat.MsoMdoc) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n const mdocDeviceResponse = MdocDeviceResponse.fromBase64Url(presentation)\n return mdocDeviceResponse\n }\n if (format === ClaimFormat.JwtVp) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n return W3cJwtVerifiablePresentation.fromSerializedJwt(presentation)\n }\n if (format === ClaimFormat.SdJwtW3cVp) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n return W3cV2SdJwtVerifiablePresentation.fromCompact(presentation)\n }\n\n return JsonTransformer.fromJSON(presentation, W3cJsonLdVerifiablePresentation)\n }\n\n private async verifyPresentation(\n agentContext: AgentContext,\n options: {\n nonce: string\n audience: string\n clientId: string\n responseUri?: string\n mdocGeneratedNonce?: string\n origin?: string\n verificationSessionId: string\n presentation: string | Record<string, unknown>\n format: ClaimFormat.LdpVp | ClaimFormat.JwtVp | ClaimFormat.SdJwtW3cVp | ClaimFormat.SdJwtDc | ClaimFormat.MsoMdoc\n version: OpenId4VpVersion\n encryptionJwk?: Kms.PublicJwk\n }\n ): Promise<\n | {\n verified: true\n presentation: VerifiablePresentation\n transactionData?: TransactionDataHashesCredentials[string]\n }\n | { verified: false; reason: string }\n > {\n const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig)\n const sdJwtVcApi = agentContext.dependencyManager.resolve(SdJwtVcApi)\n\n const { presentation, format } = options\n\n try {\n this.logger.trace('Presentation response', JsonTransformer.toJSON(presentation))\n\n let isValid: boolean\n let cause: Error | undefined\n let verifiablePresentation: VerifiablePresentation\n\n if (format === ClaimFormat.SdJwtDc) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n\n const sdJwtVc = sdJwtVcApi.fromCompact(presentation)\n const jwt = Jwt.fromSerializedJwt(presentation.split('~')[0])\n const certificateChain = extractX509CertificatesFromJwt(jwt)\n\n let trustedCertificates: string[] | undefined\n if (certificateChain && x509Config.getTrustedCertificatesForVerification) {\n trustedCertificates = await x509Config.getTrustedCertificatesForVerification(agentContext, {\n certificateChain,\n verification: {\n type: 'credential',\n credential: sdJwtVc,\n openId4VcVerificationSessionId: options.verificationSessionId,\n },\n })\n }\n\n if (!trustedCertificates) {\n // We also take from the config here to avoid the callback being called again\n trustedCertificates = x509Config.trustedCertificates ?? []\n }\n\n const verificationResult = await sdJwtVcApi.verify({\n compactSdJwtVc: presentation,\n keyBinding: {\n audience: options.audience,\n nonce: options.nonce,\n },\n trustedCertificates,\n })\n\n isValid = verificationResult.isValid\n cause = verificationResult.isValid ? undefined : verificationResult.error\n verifiablePresentation = sdJwtVc\n } else if (format === ClaimFormat.MsoMdoc) {\n if (typeof presentation !== 'string') {\n throw new CredoError('Expected vp_token entry for format mso_mdoc to be of type string')\n }\n const mdocDeviceResponse = MdocDeviceResponse.fromBase64Url(presentation)\n if (mdocDeviceResponse.documents.length === 0) {\n throw new CredoError('mdoc device response does not contain any mdocs')\n }\n\n const deviceResponses = mdocDeviceResponse.splitIntoSingleDocumentResponses()\n\n for (const deviceResponseIndex of deviceResponses.keys()) {\n const mdocDeviceResponse = deviceResponses[deviceResponseIndex]\n\n const document = mdocDeviceResponse.documents[0]\n const certificateChain = document.issuerSignedCertificateChain.map((cert) =>\n X509Certificate.fromRawCertificate(cert)\n )\n\n const trustedCertificates = await x509Config.getTrustedCertificatesForVerification?.(agentContext, {\n certificateChain,\n verification: {\n type: 'credential',\n credential: document,\n openId4VcVerificationSessionId: options.verificationSessionId,\n },\n })\n\n let sessionTranscriptOptions: MdocSessionTranscriptOptions\n if (options.origin && options.version === 'v1') {\n sessionTranscriptOptions = {\n type: 'openId4VpDcApi',\n verifierGeneratedNonce: options.nonce,\n origin: options.origin,\n encryptionJwk: options.encryptionJwk,\n }\n } else if (options.origin) {\n sessionTranscriptOptions = {\n type: 'openId4VpDcApiDraft24',\n clientId: options.clientId,\n verifierGeneratedNonce: options.nonce,\n origin: options.origin,\n }\n } else if (options.version === 'v1') {\n if (!options.responseUri) {\n throw new CredoError('responseUri is required for mdoc openid4vp session transcript calculation')\n }\n\n sessionTranscriptOptions = {\n type: 'openId4Vp',\n clientId: options.clientId,\n responseUri: options.responseUri,\n verifierGeneratedNonce: options.nonce,\n encryptionJwk: options.encryptionJwk,\n }\n } else {\n if (!options.mdocGeneratedNonce || !options.responseUri) {\n throw new CredoError(\n 'mdocGeneratedNonce and responseUri are required for mdoc openid4vp session transcript calculation'\n )\n }\n\n sessionTranscriptOptions = {\n type: 'openId4VpDraft18',\n clientId: options.clientId,\n mdocGeneratedNonce: options.mdocGeneratedNonce,\n responseUri: options.responseUri,\n verifierGeneratedNonce: options.nonce,\n }\n }\n\n await mdocDeviceResponse.verify(agentContext, {\n sessionTranscriptOptions,\n trustedCertificates,\n })\n }\n // TODO: extract transaction data hashes once https://github.com/openid/OpenID4VP/pull/330 is resolved\n\n isValid = true\n verifiablePresentation = mdocDeviceResponse\n } else if (format === ClaimFormat.JwtVp) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n\n verifiablePresentation = W3cJwtVerifiablePresentation.fromSerializedJwt(presentation)\n const verificationResult = await this.w3cCredentialService.verifyPresentation(agentContext, {\n presentation,\n challenge: options.nonce,\n domain: options.audience,\n })\n\n isValid = verificationResult.isValid\n cause = verificationResult.error\n } else if (format === ClaimFormat.SdJwtW3cVp) {\n if (typeof presentation !== 'string') {\n throw new CredoError(`Expected vp_token entry for format ${format} to be of type string`)\n }\n\n verifiablePresentation = W3cV2SdJwtVerifiablePresentation.fromCompact(presentation)\n const verificationResult = await this.w3cV2CredentialService.verifyPresentation(agentContext, {\n presentation: verifiablePresentation,\n challenge: options.nonce,\n domain: options.audience,\n })\n\n isValid = verificationResult.isValid\n cause = verificationResult.error\n } else {\n verifiablePresentation = JsonTransformer.fromJSON(presentation, W3cJsonLdVerifiablePresentation)\n const verificationResult = await this.w3cCredentialService.verifyPresentation(agentContext, {\n presentation: verifiablePresentation,\n challenge: options.nonce,\n domain: options.audience,\n })\n\n isValid = verificationResult.isValid\n cause = verificationResult.error\n }\n\n if (!isValid) {\n throw new CredoError(`Error occured during verification of presentation.${cause ? ` ${cause.message}` : ''}`, {\n cause,\n })\n }\n\n return {\n verified: true,\n presentation: verifiablePresentation,\n }\n } catch (error) {\n agentContext.config.logger.warn('Error occurred during verification of presentation', {\n error,\n })\n return {\n verified: false,\n reason: error.message,\n }\n }\n }\n\n /**\n * Update the record to a new state and emit an state changed event. Also updates the record\n * in storage.\n */\n public async updateState(\n agentContext: AgentContext,\n verificationSession: OpenId4VcVerificationSessionRecord,\n newState: OpenId4VcVerificationSessionState\n ) {\n agentContext.config.logger.debug(\n `Updating openid4vc verification session record ${verificationSession.id} to state ${newState} (previous=${verificationSession.state})`\n )\n\n const previousState = verificationSession.state\n verificationSession.state = newState\n await this.openId4VcVerificationSessionRepository.update(agentContext, verificationSession)\n\n this.emitStateChangedEvent(agentContext, verificationSession, previousState)\n }\n\n protected emitStateChangedEvent(\n agentContext: AgentContext,\n verificationSession: OpenId4VcVerificationSessionRecord,\n previousState: OpenId4VcVerificationSessionState | null\n ) {\n const eventEmitter = agentContext.dependencyManager.resolve(EventEmitter)\n\n eventEmitter.emit<OpenId4VcVerificationSessionStateChangedEvent>(agentContext, {\n type: OpenId4VcVerifierEvents.VerificationSessionStateChanged,\n payload: {\n verificationSession: verificationSession.clone(),\n previousState,\n },\n })\n }\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorateMetadata.mjs";
2
- import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorate.mjs";
1
+ import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
2
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
3
3
  import { BaseRecord, CredoError, DateTransformer, Jwt, utils } from "@credo-ts/core";
4
4
 
5
5
  //#region src/openid4vc-verifier/repository/OpenId4VcVerificationSessionRecord.ts
@@ -1,6 +1,6 @@
1
- import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorateMetadata.mjs";
2
- import { __decorateParam } from "../../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorateParam.mjs";
3
- import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorate.mjs";
1
+ import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
2
+ import { __decorateParam } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateParam.mjs";
3
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
4
4
  import { OpenId4VcVerificationSessionRecord } from "./OpenId4VcVerificationSessionRecord.mjs";
5
5
  import { EventEmitter, InjectionSymbols, Repository, inject, injectable } from "@credo-ts/core";
6
6
 
@@ -1,6 +1,6 @@
1
- import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorateMetadata.mjs";
2
- import { __decorateParam } from "../../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorateParam.mjs";
3
- import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.97.0/helpers/decorate.mjs";
1
+ import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
2
+ import { __decorateParam } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateParam.mjs";
3
+ import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
4
4
  import { OpenId4VcVerifierRecord } from "./OpenId4VcVerifierRecord.mjs";
5
5
  import { EventEmitter, InjectionSymbols, Repository, inject, injectable } from "@credo-ts/core";
6
6
 
@@ -214,7 +214,7 @@ function getOid4vcJwtSignCallback(agentContext) {
214
214
  };
215
215
  }
216
216
  const publicJwk = signer.method === "did" ? await getPublicJwkFromDid(agentContext, signer.didUrl) : Kms.PublicJwk.fromUnknown(signer.publicJwk);
217
- if (!publicJwk.supportedSignatureAlgorithms.includes(signer.alg)) throw new CredoError(`jwk ${publicJwk.jwkTypehumanDescription} does not support JWS signature alg '${signer.alg}'`);
217
+ if (!publicJwk.supportedSignatureAlgorithms.includes(signer.alg)) throw new CredoError(`jwk ${publicJwk.jwkTypeHumanDescription} does not support JWS signature alg '${signer.alg}'`);
218
218
  return {
219
219
  jwt: await jwsService.createJwsCompact(agentContext, {
220
220
  protectedHeaderOptions: {
@@ -1 +1 @@
1
- {"version":3,"file":"callbacks.mjs","names":["jwsSigner: JwsSignerWithJwk | undefined","publicJwk","decryptedPayload: string","publicJwk: Kms.PublicJwk"],"sources":["../../src/shared/callbacks.ts"],"sourcesContent":["import {\n AgentContext,\n Buffer,\n CredoError,\n Hasher,\n JsonEncoder,\n JwsService,\n type JwsSignerWithJwk,\n JwtPayload,\n Kms,\n TypedArrayEncoder,\n X509Certificate,\n X509ModuleConfig,\n X509Service,\n} from '@credo-ts/core'\nimport type {\n CallbackContext,\n ClientAuthenticationCallback,\n DecryptJweCallback,\n EncryptJweCallback,\n Jwk,\n SignJwtCallback,\n VerifyJwtCallback,\n} from '@openid4vc/oauth2'\nimport { clientAuthenticationDynamic, decodeJwtHeader } from '@openid4vc/oauth2'\nimport type { OpenId4VcIssuerRecord } from '../openid4vc-issuer/repository'\n\nimport { getPublicJwkFromDid } from './utils'\n\nexport function getOid4vcJwtVerifyCallback(\n agentContext: AgentContext,\n options?: {\n trustedCertificates?: string[]\n\n issuanceSessionId?: string\n\n /**\n * Whether this verification callback should assume a JAR authorization is verified\n * Starting from OID4VP draft 24 the JAR must use oauth-authz-req+jwt header typ\n * but for backwards compatiblity we need to also handle the case where the header typ is different\n * @default false\n */\n isAuthorizationRequestJwt?: boolean\n }\n): VerifyJwtCallback {\n const jwsService = agentContext.dependencyManager.resolve(JwsService)\n\n return async (signer, { compact, header, payload }) => {\n let trustedCertificates = options?.trustedCertificates\n if (\n signer.method === 'x5c' &&\n (header.typ === 'oauth-authz-req+jwt' || options?.isAuthorizationRequestJwt) &&\n !trustedCertificates\n ) {\n const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig)\n const certificateChain = signer.x5c?.map((cert) => X509Certificate.fromEncodedCertificate(cert))\n\n trustedCertificates = await x509Config.getTrustedCertificatesForVerification?.(agentContext, {\n certificateChain,\n verification: {\n type: 'oauth2SecuredAuthorizationRequest',\n authorizationRequest: {\n jwt: compact,\n payload: JwtPayload.fromJson(payload),\n },\n },\n })\n }\n\n if (\n signer.method === 'x5c' &&\n (header.typ === 'keyattestation+jwt' || header.typ === 'key-attestation+jwt') &&\n options?.issuanceSessionId &&\n !trustedCertificates\n ) {\n const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig)\n const certificateChain = signer.x5c?.map((cert) => X509Certificate.fromEncodedCertificate(cert))\n\n trustedCertificates = await x509Config.getTrustedCertificatesForVerification?.(agentContext, {\n certificateChain,\n verification: {\n type: 'openId4VciKeyAttestation',\n openId4VcIssuanceSessionId: options.issuanceSessionId,\n keyAttestation: {\n jwt: compact,\n payload: JwtPayload.fromJson(payload),\n },\n },\n })\n }\n\n if (signer.method === 'x5c' && header.typ === 'openidvci-issuer-metadata+jwt' && !trustedCertificates) {\n const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig)\n const certificateChain = signer.x5c?.map((cert) => X509Certificate.fromEncodedCertificate(cert))\n\n trustedCertificates = await x509Config.getTrustedCertificatesForVerification?.(agentContext, {\n certificateChain,\n verification: {\n type: 'openId4VciCredentialIssuerMetadata',\n credentialIssuerMetadata: {\n jwt: compact,\n payload: JwtPayload.fromJson(payload),\n },\n },\n })\n }\n\n if (\n signer.method === 'x5c' &&\n header.typ === 'oauth-client-attestation+jwt' &&\n options?.issuanceSessionId &&\n !trustedCertificates\n ) {\n const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig)\n const certificateChain = signer.x5c?.map((cert) => X509Certificate.fromEncodedCertificate(cert))\n\n trustedCertificates = await x509Config.getTrustedCertificatesForVerification?.(agentContext, {\n certificateChain,\n verification: {\n type: 'oauth2ClientAttestation',\n openId4VcIssuanceSessionId: options.issuanceSessionId,\n clientAttestation: {\n jwt: compact,\n payload: JwtPayload.fromJson(payload),\n },\n },\n })\n }\n\n const alg = signer.alg as Kms.KnownJwaSignatureAlgorithm\n if (!Object.values(Kms.KnownJwaSignatureAlgorithms).includes(alg)) {\n throw new CredoError(`Unsupported jwa signatre algorithm '${alg}'`)\n }\n\n const jwsSigner: JwsSignerWithJwk | undefined =\n signer.method === 'did'\n ? {\n method: 'did',\n didUrl: signer.didUrl,\n jwk: await getPublicJwkFromDid(agentContext, signer.didUrl),\n }\n : signer.method === 'jwk'\n ? {\n method: 'jwk',\n jwk: Kms.PublicJwk.fromUnknown(signer.publicJwk),\n }\n : signer.method === 'x5c'\n ? {\n method: 'x5c',\n x5c: signer.x5c,\n jwk: X509Certificate.fromEncodedCertificate(signer.x5c[0]).publicJwk,\n }\n : undefined\n\n if (!jwsSigner) {\n throw new CredoError(`Unable to verify jws with unsupported jws signer method '${signer.method}'`)\n }\n\n const { isValid, jwsSigners } = await jwsService.verifyJws(agentContext, {\n jws: compact,\n trustedCertificates,\n jwsSigner,\n })\n\n if (!isValid) {\n return { verified: false, signerJwk: undefined }\n }\n\n const signerJwk = jwsSigners[0].jwk.toJson() as Jwk\n return { verified: true, signerJwk }\n }\n}\n\nexport function getOid4vcEncryptJweCallback(agentContext: AgentContext): EncryptJweCallback {\n const kms = agentContext.dependencyManager.resolve(Kms.KeyManagementApi)\n\n return async (jweEncryptor, compact) => {\n if (jweEncryptor.method !== 'jwk') {\n throw new CredoError(\n `Jwt encryption method '${jweEncryptor.method}' is not supported for jwt signer. Only 'jwk' is supported.`\n )\n }\n\n // TODO: we should probably add a key id or ference to the jweEncryptor/jwsSigner in\n // oid4vc-ts so we can keep a reference to the key\n const jwk = Kms.PublicJwk.fromUnknown(jweEncryptor.publicJwk)\n if (!jwk.hasKeyId) {\n throw new CredoError('Expected kid to be defined on the JWK')\n }\n\n if (jweEncryptor.alg !== 'ECDH-ES') {\n throw new CredoError(\"Only 'ECDH-ES' is supported as 'alg' value for JARM response encryption\")\n }\n\n if (jweEncryptor.enc !== 'A256GCM' && jweEncryptor.enc !== 'A128GCM' && jweEncryptor.enc !== 'A128CBC-HS256') {\n throw new CredoError(\n \"Only 'A256GCM', 'A128GCM', and 'A128CBC-HS256' is supported as 'enc' value for JARM response encryption\"\n )\n }\n\n const jwkJson = jwk.toJson()\n if (jwkJson.kty !== 'EC' && jwkJson.kty !== 'OKP') {\n throw new CredoError(`Expected EC or OKP jwk for encryption, found ${Kms.getJwkHumanDescription(jwkJson)}`)\n }\n\n if (jwkJson.crv === 'Ed25519') {\n throw new CredoError(`Expected ${jwkJson.kty} with crv X25519, found ${Kms.getJwkHumanDescription(jwkJson)}`)\n }\n\n // TODO: create a JWE service that handles this\n const ephmeralKey = await kms.createKey({\n type: jwkJson,\n })\n\n try {\n const header = {\n kid: jweEncryptor.publicJwk.kid,\n apu: jweEncryptor.apu,\n apv: jweEncryptor.apv,\n enc: jweEncryptor.enc,\n alg: 'ECDH-ES',\n epk: ephmeralKey.publicJwk,\n }\n const encodedHeader = JsonEncoder.toBase64URL(header)\n\n const encrypted = await kms.encrypt({\n key: {\n keyAgreement: {\n // FIXME: We can make the keyId optional for ECDH-ES\n // That way we don't have to store the key\n keyId: ephmeralKey.keyId,\n algorithm: 'ECDH-ES',\n apu: jweEncryptor.apu ? TypedArrayEncoder.fromBase64(jweEncryptor.apu) : undefined,\n apv: jweEncryptor.apv ? TypedArrayEncoder.fromBase64(jweEncryptor.apv) : undefined,\n externalPublicJwk: jwkJson,\n },\n },\n data: Buffer.from(compact),\n encryption: {\n algorithm: jweEncryptor.enc,\n aad: Buffer.from(encodedHeader),\n },\n })\n\n if (!encrypted.iv || !encrypted.tag) {\n throw new CredoError(\"Expected 'iv' and 'tag' to be defined\")\n }\n\n const compactJwe = `${encodedHeader}..${TypedArrayEncoder.toBase64URL(encrypted.iv)}.${TypedArrayEncoder.toBase64URL(\n encrypted.encrypted\n )}.${TypedArrayEncoder.toBase64URL(encrypted.tag)}`\n\n return { encryptionJwk: jweEncryptor.publicJwk, jwe: compactJwe }\n } finally {\n // Delete the key\n await kms.deleteKey({\n keyId: ephmeralKey.keyId,\n })\n }\n }\n}\n\nexport function getOid4vcDecryptJweCallback(agentContext: AgentContext): DecryptJweCallback {\n const kms = agentContext.resolve(Kms.KeyManagementApi)\n return async (jwe, options) => {\n // TODO: use custom header zod schema to limit which algorithms can be used\n const { header } = decodeJwtHeader({ jwt: jwe })\n\n let kid = options?.jwk?.kid ?? header.kid\n if (!kid) {\n throw new CredoError('Uanbel to decrypt jwe. No kid or jwk found')\n }\n\n // Previously we used the fingerprint as the kid for JARM\n // We try to parse it as fingerprint if it starts with z (base58 encoding)\n // It's not 100%\n if (kid.startsWith('z')) {\n try {\n const publicJwk = Kms.PublicJwk.fromFingerprint(kid)\n if (publicJwk) kid = publicJwk.legacyKeyId\n } catch {\n // no-op\n }\n }\n\n // TODO: decodeJwe method in oid4vc-ts\n // encryption key is not used (we don't use key wrapping)\n const [encodedHeader /* encryptionKey */, , encodedIv, encodedCiphertext, encodedTag] = jwe.split('.')\n\n if (header.alg !== 'ECDH-ES') {\n throw new CredoError(\"Only 'ECDH-ES' is supported as 'alg' value for JARM response decryption\")\n }\n\n if (header.enc !== 'A256GCM' && header.enc !== 'A128GCM' && header.enc !== 'A128CBC-HS256') {\n throw new CredoError(\n \"Only 'A256GCM', 'A128GCM', and 'A128CBC-HS256' is supported as 'enc' value for JARM response decryption\"\n )\n }\n\n let decryptedPayload: string\n let publicJwk: Kms.PublicJwk\n\n const epk = Kms.PublicJwk.fromUnknown(header.epk)\n\n try {\n const decrypted = await kms.decrypt({\n encrypted: TypedArrayEncoder.fromBase64(encodedCiphertext),\n decryption: {\n algorithm: header.enc,\n // aad is the base64 encoded bytes (not just the bytes)\n aad: TypedArrayEncoder.fromString(encodedHeader),\n iv: TypedArrayEncoder.fromBase64(encodedIv),\n tag: TypedArrayEncoder.fromBase64(encodedTag),\n },\n key: {\n keyAgreement: {\n algorithm: header.alg,\n externalPublicJwk: epk.toJson() as Kms.KmsJwkPublicEcdh,\n keyId: kid,\n apu: typeof header.apu === 'string' ? TypedArrayEncoder.fromBase64(header.apu) : undefined,\n apv: typeof header.apv === 'string' ? TypedArrayEncoder.fromBase64(header.apv) : undefined,\n },\n },\n })\n\n // TODO: decrypt should return the public jwk instance\n publicJwk = Kms.PublicJwk.fromUnknown(\n await kms.getPublicKey({\n keyId: kid,\n })\n )\n\n decryptedPayload = TypedArrayEncoder.toUtf8String(decrypted.data)\n } catch (error) {\n agentContext.config.logger.error('Error decrypting JWE', {\n error,\n })\n return {\n decrypted: false,\n encryptionJwk: options?.jwk,\n payload: undefined,\n header,\n }\n }\n\n return {\n decrypted: true,\n decryptionJwk: publicJwk.toJson() as Jwk,\n payload: decryptedPayload,\n header,\n }\n }\n}\n\nexport function getOid4vcJwtSignCallback(agentContext: AgentContext): SignJwtCallback {\n const jwsService = agentContext.dependencyManager.resolve(JwsService)\n\n return async (signer, { payload, header }) => {\n if (signer.method === 'custom' || signer.method === 'federation') {\n throw new CredoError(`Jwt signer method 'custom' and 'federation' are not supported for jwt signer.`)\n }\n\n if (signer.method === 'x5c') {\n const leafCertificate = X509Service.getLeafCertificate(agentContext, { certificateChain: signer.x5c })\n\n const jws = await jwsService.createJwsCompact(agentContext, {\n protectedHeaderOptions: { ...header, alg: signer.alg as Kms.KnownJwaSignatureAlgorithm, jwk: undefined },\n payload: JwtPayload.fromJson(payload),\n keyId: signer.kid ?? leafCertificate.publicJwk.keyId,\n })\n\n return { jwt: jws, signerJwk: leafCertificate.publicJwk.toJson() as Jwk }\n }\n\n // TOOD: createJwsCompact should return the Jwk, so we don't have to reoslve it here\n const publicJwk =\n signer.method === 'did'\n ? await getPublicJwkFromDid(agentContext, signer.didUrl)\n : Kms.PublicJwk.fromUnknown(signer.publicJwk)\n\n if (!publicJwk.supportedSignatureAlgorithms.includes(signer.alg as Kms.KnownJwaSignatureAlgorithm)) {\n throw new CredoError(\n `jwk ${publicJwk.jwkTypehumanDescription} does not support JWS signature alg '${signer.alg}'`\n )\n }\n\n const jwt = await jwsService.createJwsCompact(agentContext, {\n protectedHeaderOptions: {\n ...header,\n jwk: header.jwk ? publicJwk : undefined,\n alg: signer.alg as Kms.KnownJwaSignatureAlgorithm,\n },\n payload: JsonEncoder.toBuffer(payload),\n keyId: signer.kid ?? publicJwk.keyId,\n })\n\n return { jwt, signerJwk: publicJwk.toJson() as Jwk }\n }\n}\n\nexport function getOid4vcCallbacks(\n agentContext: AgentContext,\n options?: {\n trustedCertificates?: string[]\n isVerifyOpenId4VpAuthorizationRequest?: boolean\n issuanceSessionId?: string\n }\n) {\n const kms = agentContext.resolve(Kms.KeyManagementApi)\n\n return {\n hash: (data, alg) => Hasher.hash(data, alg.toLowerCase()),\n generateRandom: (length) => kms.randomBytes({ length }),\n signJwt: getOid4vcJwtSignCallback(agentContext),\n clientAuthentication: () => {\n throw new CredoError('Did not expect client authentication to be called.')\n },\n verifyJwt: getOid4vcJwtVerifyCallback(agentContext, {\n trustedCertificates: options?.trustedCertificates,\n isAuthorizationRequestJwt: options?.isVerifyOpenId4VpAuthorizationRequest,\n issuanceSessionId: options?.issuanceSessionId,\n }),\n fetch: agentContext.config.agentDependencies.fetch,\n encryptJwe: getOid4vcEncryptJweCallback(agentContext),\n decryptJwe: getOid4vcDecryptJweCallback(agentContext),\n getX509CertificateMetadata: (certificate: string) => {\n const leafCertificate = X509Service.getLeafCertificate(agentContext, { certificateChain: [certificate] })\n return {\n sanDnsNames: leafCertificate.sanDnsNames,\n sanUriNames: leafCertificate.sanUriNames,\n }\n },\n } satisfies Partial<CallbackContext>\n}\n\n/**\n * Allows us to authenticate when making requests to an external\n * authorization server\n */\nexport function dynamicOid4vciClientAuthentication(\n agentContext: AgentContext,\n issuerRecord: OpenId4VcIssuerRecord\n): ClientAuthenticationCallback {\n return (callbackOptions) => {\n const authorizationServer = issuerRecord.authorizationServerConfigs?.find(\n (a) => a.issuer === callbackOptions.authorizationServerMetadata.issuer\n )\n\n if (!authorizationServer) {\n // No client authentication if authorization server is not configured\n agentContext.config.logger.debug(\n `Unknown authorization server '${callbackOptions.authorizationServerMetadata.issuer}' for issuer '${issuerRecord.issuerId}' for request to '${callbackOptions.url}'`\n )\n return\n }\n\n if (!authorizationServer.clientAuthentication) {\n throw new CredoError(\n `Unable to authenticate to authorization server '${authorizationServer.issuer}' for issuer '${issuerRecord.issuerId}' for request to '${callbackOptions.url}'. Make sure to configure a 'clientId' and 'clientSecret' for the authorization server on the issuer record.`\n )\n }\n\n return clientAuthenticationDynamic({\n clientId: authorizationServer.clientAuthentication.clientId,\n clientSecret: authorizationServer.clientAuthentication.clientSecret,\n })(callbackOptions)\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"callbacks.mjs","names":["jwsSigner: JwsSignerWithJwk | undefined","publicJwk","decryptedPayload: string","publicJwk: Kms.PublicJwk"],"sources":["../../src/shared/callbacks.ts"],"sourcesContent":["import {\n AgentContext,\n Buffer,\n CredoError,\n Hasher,\n JsonEncoder,\n JwsService,\n type JwsSignerWithJwk,\n JwtPayload,\n Kms,\n TypedArrayEncoder,\n X509Certificate,\n X509ModuleConfig,\n X509Service,\n} from '@credo-ts/core'\nimport type {\n CallbackContext,\n ClientAuthenticationCallback,\n DecryptJweCallback,\n EncryptJweCallback,\n Jwk,\n SignJwtCallback,\n VerifyJwtCallback,\n} from '@openid4vc/oauth2'\nimport { clientAuthenticationDynamic, decodeJwtHeader } from '@openid4vc/oauth2'\nimport type { OpenId4VcIssuerRecord } from '../openid4vc-issuer/repository'\n\nimport { getPublicJwkFromDid } from './utils'\n\nexport function getOid4vcJwtVerifyCallback(\n agentContext: AgentContext,\n options?: {\n trustedCertificates?: string[]\n\n issuanceSessionId?: string\n\n /**\n * Whether this verification callback should assume a JAR authorization is verified\n * Starting from OID4VP draft 24 the JAR must use oauth-authz-req+jwt header typ\n * but for backwards compatiblity we need to also handle the case where the header typ is different\n * @default false\n */\n isAuthorizationRequestJwt?: boolean\n }\n): VerifyJwtCallback {\n const jwsService = agentContext.dependencyManager.resolve(JwsService)\n\n return async (signer, { compact, header, payload }) => {\n let trustedCertificates = options?.trustedCertificates\n if (\n signer.method === 'x5c' &&\n (header.typ === 'oauth-authz-req+jwt' || options?.isAuthorizationRequestJwt) &&\n !trustedCertificates\n ) {\n const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig)\n const certificateChain = signer.x5c?.map((cert) => X509Certificate.fromEncodedCertificate(cert))\n\n trustedCertificates = await x509Config.getTrustedCertificatesForVerification?.(agentContext, {\n certificateChain,\n verification: {\n type: 'oauth2SecuredAuthorizationRequest',\n authorizationRequest: {\n jwt: compact,\n payload: JwtPayload.fromJson(payload),\n },\n },\n })\n }\n\n if (\n signer.method === 'x5c' &&\n (header.typ === 'keyattestation+jwt' || header.typ === 'key-attestation+jwt') &&\n options?.issuanceSessionId &&\n !trustedCertificates\n ) {\n const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig)\n const certificateChain = signer.x5c?.map((cert) => X509Certificate.fromEncodedCertificate(cert))\n\n trustedCertificates = await x509Config.getTrustedCertificatesForVerification?.(agentContext, {\n certificateChain,\n verification: {\n type: 'openId4VciKeyAttestation',\n openId4VcIssuanceSessionId: options.issuanceSessionId,\n keyAttestation: {\n jwt: compact,\n payload: JwtPayload.fromJson(payload),\n },\n },\n })\n }\n\n if (signer.method === 'x5c' && header.typ === 'openidvci-issuer-metadata+jwt' && !trustedCertificates) {\n const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig)\n const certificateChain = signer.x5c?.map((cert) => X509Certificate.fromEncodedCertificate(cert))\n\n trustedCertificates = await x509Config.getTrustedCertificatesForVerification?.(agentContext, {\n certificateChain,\n verification: {\n type: 'openId4VciCredentialIssuerMetadata',\n credentialIssuerMetadata: {\n jwt: compact,\n payload: JwtPayload.fromJson(payload),\n },\n },\n })\n }\n\n if (\n signer.method === 'x5c' &&\n header.typ === 'oauth-client-attestation+jwt' &&\n options?.issuanceSessionId &&\n !trustedCertificates\n ) {\n const x509Config = agentContext.dependencyManager.resolve(X509ModuleConfig)\n const certificateChain = signer.x5c?.map((cert) => X509Certificate.fromEncodedCertificate(cert))\n\n trustedCertificates = await x509Config.getTrustedCertificatesForVerification?.(agentContext, {\n certificateChain,\n verification: {\n type: 'oauth2ClientAttestation',\n openId4VcIssuanceSessionId: options.issuanceSessionId,\n clientAttestation: {\n jwt: compact,\n payload: JwtPayload.fromJson(payload),\n },\n },\n })\n }\n\n const alg = signer.alg as Kms.KnownJwaSignatureAlgorithm\n if (!Object.values(Kms.KnownJwaSignatureAlgorithms).includes(alg)) {\n throw new CredoError(`Unsupported jwa signatre algorithm '${alg}'`)\n }\n\n const jwsSigner: JwsSignerWithJwk | undefined =\n signer.method === 'did'\n ? {\n method: 'did',\n didUrl: signer.didUrl,\n jwk: await getPublicJwkFromDid(agentContext, signer.didUrl),\n }\n : signer.method === 'jwk'\n ? {\n method: 'jwk',\n jwk: Kms.PublicJwk.fromUnknown(signer.publicJwk),\n }\n : signer.method === 'x5c'\n ? {\n method: 'x5c',\n x5c: signer.x5c,\n jwk: X509Certificate.fromEncodedCertificate(signer.x5c[0]).publicJwk,\n }\n : undefined\n\n if (!jwsSigner) {\n throw new CredoError(`Unable to verify jws with unsupported jws signer method '${signer.method}'`)\n }\n\n const { isValid, jwsSigners } = await jwsService.verifyJws(agentContext, {\n jws: compact,\n trustedCertificates,\n jwsSigner,\n })\n\n if (!isValid) {\n return { verified: false, signerJwk: undefined }\n }\n\n const signerJwk = jwsSigners[0].jwk.toJson() as Jwk\n return { verified: true, signerJwk }\n }\n}\n\nexport function getOid4vcEncryptJweCallback(agentContext: AgentContext): EncryptJweCallback {\n const kms = agentContext.dependencyManager.resolve(Kms.KeyManagementApi)\n\n return async (jweEncryptor, compact) => {\n if (jweEncryptor.method !== 'jwk') {\n throw new CredoError(\n `Jwt encryption method '${jweEncryptor.method}' is not supported for jwt signer. Only 'jwk' is supported.`\n )\n }\n\n // TODO: we should probably add a key id or ference to the jweEncryptor/jwsSigner in\n // oid4vc-ts so we can keep a reference to the key\n const jwk = Kms.PublicJwk.fromUnknown(jweEncryptor.publicJwk)\n if (!jwk.hasKeyId) {\n throw new CredoError('Expected kid to be defined on the JWK')\n }\n\n if (jweEncryptor.alg !== 'ECDH-ES') {\n throw new CredoError(\"Only 'ECDH-ES' is supported as 'alg' value for JARM response encryption\")\n }\n\n if (jweEncryptor.enc !== 'A256GCM' && jweEncryptor.enc !== 'A128GCM' && jweEncryptor.enc !== 'A128CBC-HS256') {\n throw new CredoError(\n \"Only 'A256GCM', 'A128GCM', and 'A128CBC-HS256' is supported as 'enc' value for JARM response encryption\"\n )\n }\n\n const jwkJson = jwk.toJson()\n if (jwkJson.kty !== 'EC' && jwkJson.kty !== 'OKP') {\n throw new CredoError(`Expected EC or OKP jwk for encryption, found ${Kms.getJwkHumanDescription(jwkJson)}`)\n }\n\n if (jwkJson.crv === 'Ed25519') {\n throw new CredoError(`Expected ${jwkJson.kty} with crv X25519, found ${Kms.getJwkHumanDescription(jwkJson)}`)\n }\n\n // TODO: create a JWE service that handles this\n const ephmeralKey = await kms.createKey({\n type: jwkJson,\n })\n\n try {\n const header = {\n kid: jweEncryptor.publicJwk.kid,\n apu: jweEncryptor.apu,\n apv: jweEncryptor.apv,\n enc: jweEncryptor.enc,\n alg: 'ECDH-ES',\n epk: ephmeralKey.publicJwk,\n }\n const encodedHeader = JsonEncoder.toBase64URL(header)\n\n const encrypted = await kms.encrypt({\n key: {\n keyAgreement: {\n // FIXME: We can make the keyId optional for ECDH-ES\n // That way we don't have to store the key\n keyId: ephmeralKey.keyId,\n algorithm: 'ECDH-ES',\n apu: jweEncryptor.apu ? TypedArrayEncoder.fromBase64(jweEncryptor.apu) : undefined,\n apv: jweEncryptor.apv ? TypedArrayEncoder.fromBase64(jweEncryptor.apv) : undefined,\n externalPublicJwk: jwkJson,\n },\n },\n data: Buffer.from(compact),\n encryption: {\n algorithm: jweEncryptor.enc,\n aad: Buffer.from(encodedHeader),\n },\n })\n\n if (!encrypted.iv || !encrypted.tag) {\n throw new CredoError(\"Expected 'iv' and 'tag' to be defined\")\n }\n\n const compactJwe = `${encodedHeader}..${TypedArrayEncoder.toBase64URL(encrypted.iv)}.${TypedArrayEncoder.toBase64URL(\n encrypted.encrypted\n )}.${TypedArrayEncoder.toBase64URL(encrypted.tag)}`\n\n return { encryptionJwk: jweEncryptor.publicJwk, jwe: compactJwe }\n } finally {\n // Delete the key\n await kms.deleteKey({\n keyId: ephmeralKey.keyId,\n })\n }\n }\n}\n\nexport function getOid4vcDecryptJweCallback(agentContext: AgentContext): DecryptJweCallback {\n const kms = agentContext.resolve(Kms.KeyManagementApi)\n return async (jwe, options) => {\n // TODO: use custom header zod schema to limit which algorithms can be used\n const { header } = decodeJwtHeader({ jwt: jwe })\n\n let kid = options?.jwk?.kid ?? header.kid\n if (!kid) {\n throw new CredoError('Uanbel to decrypt jwe. No kid or jwk found')\n }\n\n // Previously we used the fingerprint as the kid for JARM\n // We try to parse it as fingerprint if it starts with z (base58 encoding)\n // It's not 100%\n if (kid.startsWith('z')) {\n try {\n const publicJwk = Kms.PublicJwk.fromFingerprint(kid)\n if (publicJwk) kid = publicJwk.legacyKeyId\n } catch {\n // no-op\n }\n }\n\n // TODO: decodeJwe method in oid4vc-ts\n // encryption key is not used (we don't use key wrapping)\n const [encodedHeader /* encryptionKey */, , encodedIv, encodedCiphertext, encodedTag] = jwe.split('.')\n\n if (header.alg !== 'ECDH-ES') {\n throw new CredoError(\"Only 'ECDH-ES' is supported as 'alg' value for JARM response decryption\")\n }\n\n if (header.enc !== 'A256GCM' && header.enc !== 'A128GCM' && header.enc !== 'A128CBC-HS256') {\n throw new CredoError(\n \"Only 'A256GCM', 'A128GCM', and 'A128CBC-HS256' is supported as 'enc' value for JARM response decryption\"\n )\n }\n\n let decryptedPayload: string\n let publicJwk: Kms.PublicJwk\n\n const epk = Kms.PublicJwk.fromUnknown(header.epk)\n\n try {\n const decrypted = await kms.decrypt({\n encrypted: TypedArrayEncoder.fromBase64(encodedCiphertext),\n decryption: {\n algorithm: header.enc,\n // aad is the base64 encoded bytes (not just the bytes)\n aad: TypedArrayEncoder.fromString(encodedHeader),\n iv: TypedArrayEncoder.fromBase64(encodedIv),\n tag: TypedArrayEncoder.fromBase64(encodedTag),\n },\n key: {\n keyAgreement: {\n algorithm: header.alg,\n externalPublicJwk: epk.toJson() as Kms.KmsJwkPublicEcdh,\n keyId: kid,\n apu: typeof header.apu === 'string' ? TypedArrayEncoder.fromBase64(header.apu) : undefined,\n apv: typeof header.apv === 'string' ? TypedArrayEncoder.fromBase64(header.apv) : undefined,\n },\n },\n })\n\n // TODO: decrypt should return the public jwk instance\n publicJwk = Kms.PublicJwk.fromUnknown(\n await kms.getPublicKey({\n keyId: kid,\n })\n )\n\n decryptedPayload = TypedArrayEncoder.toUtf8String(decrypted.data)\n } catch (error) {\n agentContext.config.logger.error('Error decrypting JWE', {\n error,\n })\n return {\n decrypted: false,\n encryptionJwk: options?.jwk,\n payload: undefined,\n header,\n }\n }\n\n return {\n decrypted: true,\n decryptionJwk: publicJwk.toJson() as Jwk,\n payload: decryptedPayload,\n header,\n }\n }\n}\n\nexport function getOid4vcJwtSignCallback(agentContext: AgentContext): SignJwtCallback {\n const jwsService = agentContext.dependencyManager.resolve(JwsService)\n\n return async (signer, { payload, header }) => {\n if (signer.method === 'custom' || signer.method === 'federation') {\n throw new CredoError(`Jwt signer method 'custom' and 'federation' are not supported for jwt signer.`)\n }\n\n if (signer.method === 'x5c') {\n const leafCertificate = X509Service.getLeafCertificate(agentContext, { certificateChain: signer.x5c })\n\n const jws = await jwsService.createJwsCompact(agentContext, {\n protectedHeaderOptions: { ...header, alg: signer.alg as Kms.KnownJwaSignatureAlgorithm, jwk: undefined },\n payload: JwtPayload.fromJson(payload),\n keyId: signer.kid ?? leafCertificate.publicJwk.keyId,\n })\n\n return { jwt: jws, signerJwk: leafCertificate.publicJwk.toJson() as Jwk }\n }\n\n // TOOD: createJwsCompact should return the Jwk, so we don't have to reoslve it here\n const publicJwk =\n signer.method === 'did'\n ? await getPublicJwkFromDid(agentContext, signer.didUrl)\n : Kms.PublicJwk.fromUnknown(signer.publicJwk)\n\n if (!publicJwk.supportedSignatureAlgorithms.includes(signer.alg as Kms.KnownJwaSignatureAlgorithm)) {\n throw new CredoError(\n `jwk ${publicJwk.jwkTypeHumanDescription} does not support JWS signature alg '${signer.alg}'`\n )\n }\n\n const jwt = await jwsService.createJwsCompact(agentContext, {\n protectedHeaderOptions: {\n ...header,\n jwk: header.jwk ? publicJwk : undefined,\n alg: signer.alg as Kms.KnownJwaSignatureAlgorithm,\n },\n payload: JsonEncoder.toBuffer(payload),\n keyId: signer.kid ?? publicJwk.keyId,\n })\n\n return { jwt, signerJwk: publicJwk.toJson() as Jwk }\n }\n}\n\nexport function getOid4vcCallbacks(\n agentContext: AgentContext,\n options?: {\n trustedCertificates?: string[]\n isVerifyOpenId4VpAuthorizationRequest?: boolean\n issuanceSessionId?: string\n }\n) {\n const kms = agentContext.resolve(Kms.KeyManagementApi)\n\n return {\n hash: (data, alg) => Hasher.hash(data, alg.toLowerCase()),\n generateRandom: (length) => kms.randomBytes({ length }),\n signJwt: getOid4vcJwtSignCallback(agentContext),\n clientAuthentication: () => {\n throw new CredoError('Did not expect client authentication to be called.')\n },\n verifyJwt: getOid4vcJwtVerifyCallback(agentContext, {\n trustedCertificates: options?.trustedCertificates,\n isAuthorizationRequestJwt: options?.isVerifyOpenId4VpAuthorizationRequest,\n issuanceSessionId: options?.issuanceSessionId,\n }),\n fetch: agentContext.config.agentDependencies.fetch,\n encryptJwe: getOid4vcEncryptJweCallback(agentContext),\n decryptJwe: getOid4vcDecryptJweCallback(agentContext),\n getX509CertificateMetadata: (certificate: string) => {\n const leafCertificate = X509Service.getLeafCertificate(agentContext, { certificateChain: [certificate] })\n return {\n sanDnsNames: leafCertificate.sanDnsNames,\n sanUriNames: leafCertificate.sanUriNames,\n }\n },\n } satisfies Partial<CallbackContext>\n}\n\n/**\n * Allows us to authenticate when making requests to an external\n * authorization server\n */\nexport function dynamicOid4vciClientAuthentication(\n agentContext: AgentContext,\n issuerRecord: OpenId4VcIssuerRecord\n): ClientAuthenticationCallback {\n return (callbackOptions) => {\n const authorizationServer = issuerRecord.authorizationServerConfigs?.find(\n (a) => a.issuer === callbackOptions.authorizationServerMetadata.issuer\n )\n\n if (!authorizationServer) {\n // No client authentication if authorization server is not configured\n agentContext.config.logger.debug(\n `Unknown authorization server '${callbackOptions.authorizationServerMetadata.issuer}' for issuer '${issuerRecord.issuerId}' for request to '${callbackOptions.url}'`\n )\n return\n }\n\n if (!authorizationServer.clientAuthentication) {\n throw new CredoError(\n `Unable to authenticate to authorization server '${authorizationServer.issuer}' for issuer '${issuerRecord.issuerId}' for request to '${callbackOptions.url}'. Make sure to configure a 'clientId' and 'clientSecret' for the authorization server on the issuer record.`\n )\n }\n\n return clientAuthenticationDynamic({\n clientId: authorizationServer.clientAuthentication.clientId,\n clientSecret: authorizationServer.clientAuthentication.clientSecret,\n })(callbackOptions)\n }\n}\n"],"mappings":"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"}
@@ -70,7 +70,7 @@ async function credoJwtIssuerToOpenId4VcJwtIssuer(agentContext, createJwtIssuer)
70
70
  }
71
71
  function getProofTypeFromPublicJwk(agentContext, key) {
72
72
  const supportedSignatureSuites = agentContext.dependencyManager.resolve(SignatureSuiteRegistry).getAllByPublicJwkType(key);
73
- if (supportedSignatureSuites.length === 0) throw new CredoError(`Couldn't find a supported signature suite for the given key ${key.jwkTypehumanDescription}.`);
73
+ if (supportedSignatureSuites.length === 0) throw new CredoError(`Couldn't find a supported signature suite for the given key ${key.jwkTypeHumanDescription}.`);
74
74
  return supportedSignatureSuites[0].proofType;
75
75
  }
76
76
  function dcqlCredentialQueryToPresentationFormat(credential) {