{"version":3,"file":"X509ModuleConfig.mjs","names":[],"sources":["../../../src/modules/x509/X509ModuleConfig.ts"],"sourcesContent":["import type { AgentContext } from '../../agent/context/AgentContext'\nimport type { VerificationTypeMdocReaderAuth } from '../../agent/TrustedIssuersForVerification'\nimport type { JwtPayload } from '../../crypto/jose/jwt/JwtPayload'\nimport type { Mdoc } from '../mdoc/Mdoc'\nimport type { SdJwtVc } from '../sd-jwt-vc/SdJwtVcService'\nimport type { W3cJwtVerifiableCredential } from '../vc/jwt-vc/W3cJwtVerifiableCredential'\nimport type { W3cJwtVerifiablePresentation } from '../vc/jwt-vc/W3cJwtVerifiablePresentation'\nimport { X509Certificate } from './X509Certificate'\nimport { type X509RevocationCheckOptions } from './X509ValidationOptions'\n\nexport type X509VerificationTrustedCertificates = {\n  issuance: string[]\n  status?: string[]\n}\n\nexport type X509VerificationTypeCredential = {\n  type: 'credential'\n  credential: SdJwtVc | Mdoc | W3cJwtVerifiableCredential | W3cJwtVerifiablePresentation\n\n  /**\n   * The `id` of the `DidCommProofRecord` that this verification is bound to.\n   */\n  didcommProofRecordId?: string\n\n  /**\n   * The `id` of the `OpenId4VcVerificationSessionRecord` that this verification is bound to.\n   */\n  openId4VcVerificationSessionId?: string\n}\n\n/**\n * Reader authentication on an incoming mdoc request.\n *\n * There is no separate legacy shape for this verification type: reader authentication is only\n * resolved on the DC API paths that were added after this callback was deprecated, so the type of\n * the `getTrustedIssuersForVerification` callback is reused as-is.\n */\nexport type X509VerificationTypeMdocReaderAuth = VerificationTypeMdocReaderAuth\n\n// NOTE: we should probably move these to the OpenID4VC module\n// but have to think about the typing. Probably the base interface should just contain\n// the `verification` with a `type`. And extension modules can extend the verification\nexport type X509VerificationTypeOauth2SecuredAuthorizationRequest = {\n  type: 'oauth2SecuredAuthorizationRequest'\n  authorizationRequest: {\n    jwt: string\n    payload: JwtPayload\n  }\n}\n\nexport type X509VerificationTypeOpenId4VciKeyAttestation = {\n  type: 'openId4VciKeyAttestation'\n\n  /**\n   * The `id` of the `OpenId4VcIssuanceSessionRecord` that this key\n   * attestation verification is bound to.\n   */\n  // TODO: should be the record, but we don't have access to the record type here.\n  openId4VcIssuanceSessionId: string\n\n  // NOTE: it would be more helpful to have the typed JWT payload from openid4vc here?\n  keyAttestation: {\n    jwt: string\n    payload: JwtPayload\n  }\n}\n\nexport type X509VerificationTypeOpenId4VciCredentialIssuerMetadata = {\n  type: 'openId4VciCredentialIssuerMetadata'\n\n  // NOTE: it would be more helpful to have the typed JWT payload from openid4vc here?\n  credentialIssuerMetadata: {\n    jwt: string\n    payload: JwtPayload\n  }\n}\n\nexport type X509VerificationTypeOauth2ClientAttestation = {\n  type: 'oauth2ClientAttestation'\n\n  /**\n   * The `id` of the `OpenId4VcIssuanceSessionRecord` that this client\n   * attestation verification is bound to.\n   */\n  // TODO: should be the record, but we don't have access to the record type here.\n  openId4VcIssuanceSessionId: string\n\n  // NOTE: it would be more helpful to have the typed JWT payload from openid4vc here?\n  clientAttestation: {\n    jwt: string\n    payload: JwtPayload\n  }\n}\n\nexport interface X509VerificationContext {\n  /**\n   * The certificate chain provided with the data to be verified. The trusted certificates\n   * are determined before verification and thus it is not verified that the data was actually\n   * signed by the private key associated with the leaf certificate in the certificate chain, or\n   * whether the certificate chain is valid. However if the certificate\n   * does not match, or is not valid, verification will always fail at a later stage\n   */\n  certificateChain: X509Certificate[]\n\n  verification:\n    | X509VerificationTypeCredential\n    | X509VerificationTypeMdocReaderAuth\n    | X509VerificationTypeOauth2SecuredAuthorizationRequest\n    | X509VerificationTypeOauth2ClientAttestation\n    | X509VerificationTypeOpenId4VciKeyAttestation\n    | X509VerificationTypeOpenId4VciCredentialIssuerMetadata\n}\n\nexport interface X509ModuleConfigOptions {\n  /**\n   *\n   * Array of trusted base64-encoded certificate strings in the DER-format.\n   */\n  trustedCertificates?: Array<string | X509Certificate>\n\n  /**\n   * Optional callback method that will be called to dynamically get trusted certificates for a verification.\n   * It will provide the `agentContext` and `verificationContext` allowing to dynamically set the trusted certificates\n   * for a tenant or verification context.\n   *\n   * If no certificates should be trusted an empty array should be returned. If `undefined` is returned\n   * it will fallback to the globally registered trusted certificates\n   *\n   * @deprecated use the global `getTrustedIssuersForVerification` instead\n   * @returns An array of base64-encoded certificate strings or PEM certificate strings.\n   */\n  getTrustedCertificatesForVerification?(\n    agentContext: AgentContext,\n    verificationContext: X509VerificationContext\n  ):\n    | Promise<string[] | undefined | X509VerificationTrustedCertificates[]>\n    | string[]\n    | X509VerificationTrustedCertificates[]\n    | undefined\n\n  /**\n   * Configuration for certificate revocation checking\n   * @default\n   * ```\n   * {\n   *  mode: X509RevocationCheckMode.SoftFail, // do not fail on network error\n   *  checkFullChain: true, // check the leaf and all intermediate CAs\n   *  timeoutMs: 5000, // 5 seconds\n   *  maxCrlSizeBytes: 10485760, // 10MB\n   *  crlCacheExpirySeconds: 3600 // 1 hour\n   * }\n   * ```\n   */\n  revocationCheck?: X509RevocationCheckOptions\n}\n\nexport class X509ModuleConfig {\n  #trustedCertificates?: X509Certificate[]\n  #getTrustedCertificatesForVerification?: X509ModuleConfigOptions['getTrustedCertificatesForVerification']\n  #revocationCheck?: X509RevocationCheckOptions\n\n  public constructor(options?: X509ModuleConfigOptions) {\n    this.setTrustedCertificates(options?.trustedCertificates)\n    if (options?.getTrustedCertificatesForVerification) {\n      this.setTrustedCertificatesForVerification(options.getTrustedCertificatesForVerification)\n    }\n    if (options?.revocationCheck) {\n      this.#revocationCheck = options.revocationCheck\n    }\n  }\n\n  public get trustedCertificates() {\n    // TODO: we should probably update this API to return the instances, but don't want to\n    // break too much now\n    return this.#trustedCertificates?.map((cert) => cert.toString('pem'))\n  }\n\n  /**\n   * @deprecated use the global `getTrustedIssuersForVerification` instead\n   */\n  public get getTrustedCertificatesForVerification() {\n    return this.#getTrustedCertificatesForVerification\n  }\n\n  /**\n   * @deprecated use the global `getTrustedIssuersForVerification` instead\n   */\n  public setTrustedCertificatesForVerification(fn: X509ModuleConfigOptions['getTrustedCertificatesForVerification']) {\n    this.#getTrustedCertificatesForVerification = fn\n  }\n\n  public get revocationCheck(): X509RevocationCheckOptions | undefined {\n    return this.#revocationCheck\n  }\n\n  public setRevocationCheck(options?: X509RevocationCheckOptions) {\n    this.#revocationCheck = options\n  }\n\n  public setTrustedCertificates(trustedCertificates?: Array<string | X509Certificate>) {\n    const certificateInstances = trustedCertificates?.map((trustedCertificate) =>\n      typeof trustedCertificate === 'string'\n        ? X509Certificate.fromEncodedCertificate(trustedCertificate)\n        : trustedCertificate\n    )\n    this.#trustedCertificates = trustedCertificates?.length ? certificateInstances : undefined\n  }\n\n  public addTrustedCertificate(trustedCertificate: string | X509Certificate) {\n    const certificateInstance =\n      typeof trustedCertificate === 'string'\n        ? X509Certificate.fromEncodedCertificate(trustedCertificate)\n        : trustedCertificate\n\n    if (!this.#trustedCertificates) {\n      this.#trustedCertificates = []\n    }\n\n    this.#trustedCertificates.push(certificateInstance)\n  }\n}\n"],"mappings":";;;;;;;;AA4JA,IAAa,mBAAb,MAA8B;CAK5B,YAAmB,SAAmC;;;;EACpD,KAAK,uBAAuB,SAAS,mBAAmB;EACxD,IAAI,SAAS,uCACX,KAAK,sCAAsC,QAAQ,qCAAqC;EAE1F,IAAI,SAAS,iBACX,uBAAA,kBAAA,MAAwB,QAAQ,eAAA;CAEpC;CAEA,IAAW,sBAAsB;EAG/B,OAAA,uBAAA,sBAAO,IAAA,CAAA,EAA2B,KAAK,SAAS,KAAK,SAAS,KAAK,CAAC;CACtE;;;;CAKA,IAAW,wCAAwC;EACjD,OAAA,uBAAA,wCAAO,IAAA;CACT;;;;CAKA,sCAA6C,IAAsE;EACjH,uBAAA,wCAAA,MAA8C,EAAA;CAChD;CAEA,IAAW,kBAA0D;EACnE,OAAA,uBAAA,kBAAO,IAAA;CACT;CAEA,mBAA0B,SAAsC;EAC9D,uBAAA,kBAAA,MAAwB,OAAA;CAC1B;CAEA,uBAA8B,qBAAuD;EACnF,MAAM,uBAAuB,qBAAqB,KAAK,uBACrD,OAAO,uBAAuB,WAC1B,gBAAgB,uBAAuB,kBAAkB,IACzD,kBACN;EACA,uBAAA,sBAAA,MAA4B,qBAAqB,SAAS,uBAAuB,KAAA,CAAA;CACnF;CAEA,sBAA6B,oBAA8C;EACzE,MAAM,sBACJ,OAAO,uBAAuB,WAC1B,gBAAgB,uBAAuB,kBAAkB,IACzD;EAEN,IAAI,CAAA,uBAAA,sBAAC,IAAA,GACH,uBAAA,sBAAA,MAA4B,CAAC,CAAA;EAG/B,uBAAA,sBAAA,IAAA,CAAA,CAA0B,KAAK,mBAAmB;CACpD;AACF"}