{"version":3,"file":"W3cV2JwtCredentialService.mjs","names":[],"sources":["../../../../src/modules/vc/jwt-vc/W3cV2JwtCredentialService.ts"],"sourcesContent":["import type { AgentContext } from '../../../agent/context'\nimport { TrustedIssuerContext } from '../../../agent/TrustedIssuerContext'\nimport { JwsService, JwtPayload } from '../../../crypto'\nimport type { VerifyJwsResult } from '../../../crypto/JwsService'\nimport { CredoError } from '../../../error'\nimport { injectable } from '../../../plugins'\nimport { asArray, JsonTransformer, MessageValidator, nowInSeconds } from '../../../utils'\nimport { getPublicJwkFromVerificationMethod } from '../../dids/domain/key-type/keyDidMapping'\nimport { extractKeyFromHolderBinding } from '../../sd-jwt-vc/utils'\nimport type { W3cV2VerifyCredentialResult, W3cV2VerifyPresentationResult } from '../models'\nimport {\n  extractHolderFromPresentationCredentials,\n  getVerificationMethodForJwt,\n  validateAndResolveVerificationMethod,\n} from '../v2-jwt-utils'\nimport {\n  validateVc2ContextBaseline,\n  validateVc2CredentialStatus,\n  validateVc2CredentialValidityPeriod,\n} from '../validators'\nimport type {\n  W3cV2JwtSignCredentialOptions,\n  W3cV2JwtSignPresentationOptions,\n  W3cV2JwtVerifyCredentialOptions,\n  W3cV2JwtVerifyPresentationOptions,\n} from '../W3cV2CredentialServiceOptions'\nimport { W3cV2JwtVerifiableCredential } from './W3cV2JwtVerifiableCredential'\nimport { W3cV2JwtVerifiablePresentation } from './W3cV2JwtVerifiablePresentation'\n\n/**\n * Supports signing and verifying W3C Verifiable Credentials and Presentations\n * secured with JSON Web Tokens (JWT).\n *\n * @see https://www.w3.org/TR/vc-data-model/\n * @see https://www.w3.org/TR/vc-jose-cose/#with-jose\n */\n@injectable()\nexport class W3cV2JwtCredentialService {\n  private jwsService: JwsService\n\n  public constructor(jwsService: JwsService) {\n    this.jwsService = jwsService\n  }\n\n  /**\n   * Signs a credential\n   */\n  public async signCredential(\n    agentContext: AgentContext,\n    options: W3cV2JwtSignCredentialOptions\n  ): Promise<W3cV2JwtVerifiableCredential> {\n    // Validate the instance\n    MessageValidator.validateSync(options.credential)\n\n    // The JWT payload is simply the credential\n    const jwtPayload = new JwtPayload({\n      additionalClaims: JsonTransformer.toJSON(options.credential),\n    })\n\n    // Add iat and cnf to the payload\n    jwtPayload.iat = nowInSeconds()\n    jwtPayload.additionalClaims.cnf = options.holder\n      ? (await extractKeyFromHolderBinding(agentContext, options.holder)).cnf\n      : undefined\n\n    // Validate and resolve the verification method\n    const publicJwk = await validateAndResolveVerificationMethod(agentContext, options.verificationMethod, [\n      'assertionMethod',\n    ])\n\n    // Sign the JWT\n    const jwt = await this.jwsService.createJwsCompact(agentContext, {\n      payload: jwtPayload,\n      keyId: publicJwk.keyId,\n      protectedHeaderOptions: {\n        typ: 'vc+jwt',\n        alg: options.alg,\n        kid: options.verificationMethod,\n      },\n    })\n\n    return W3cV2JwtVerifiableCredential.fromCompact(jwt)\n  }\n\n  /**\n   * Verifies the signature(s) of a credential\n   *\n   * @param credential the credential to be verified\n   * @returns the verification result\n   */\n  public async verifyCredential(\n    agentContext: AgentContext,\n    options: W3cV2JwtVerifyCredentialOptions\n  ): Promise<W3cV2VerifyCredentialResult> {\n    const validationResults: W3cV2VerifyCredentialResult = {\n      isValid: false,\n      validations: {},\n    }\n\n    try {\n      let credential: W3cV2JwtVerifiableCredential\n      try {\n        // If instance is provided as input, we want to validate the credential.\n        // Otherwise, it is done by the fromCompact method below\n        if (options.credential instanceof W3cV2JwtVerifiableCredential) {\n          options.credential.validate()\n        }\n\n        credential =\n          options.credential instanceof W3cV2JwtVerifiableCredential\n            ? options.credential\n            : W3cV2JwtVerifiableCredential.fromCompact(options.credential)\n\n        // Verify the JWT payload (verifies whether it's not expired, etc...)\n        credential.jwt.payload.validate({\n          skewSeconds: agentContext.config.validitySkewSeconds,\n        })\n\n        this.logCredentialShouldWarnings(agentContext, credential)\n\n        validationResults.validations.dataModel = validateVc2ContextBaseline(credential.resolvedCredential.context)\n        if (!validationResults.validations.dataModel.isValid) {\n          return validationResults\n        }\n\n        validationResults.validations.dataModel = {\n          isValid: true,\n        }\n\n        validationResults.validations.validityPeriod = validateVc2CredentialValidityPeriod({\n          validFrom: credential.resolvedCredential.validFrom,\n          validUntil: credential.resolvedCredential.validUntil,\n          skewSeconds: agentContext.config.validitySkewSeconds,\n        })\n\n        validationResults.validations.credentialStatus = validateVc2CredentialStatus({\n          credentialStatus: credential.resolvedCredential.credentialStatus,\n          credentialFormat: 'JWT',\n          verifyCredentialStatus: options.verifyCredentialStatus,\n        })\n      } catch (error) {\n        validationResults.validations.dataModel = {\n          isValid: false,\n          error,\n        }\n\n        return validationResults\n      }\n\n      const issuerVerificationMethod = await getVerificationMethodForJwt(agentContext, credential, ['assertionMethod'])\n      const issuerPublicKey = getPublicJwkFromVerificationMethod(issuerVerificationMethod)\n\n      // Ensure the issuer is trusted according to the (optional) `getTrustedIssuersForVerification`\n      // callback. For did-based issuers this is a no-op when no trusted issuers are configured,\n      // preserving the previous \"trust any valid signature\" behavior. Throws when the issuer is not trusted.\n      await TrustedIssuerContext.ensureTrustedSigner(\n        agentContext,\n        {\n          signer: { method: 'did', didUrl: issuerVerificationMethod.id },\n          verification: { type: 'credential', credential },\n        },\n        options.trustedIssuers\n      )\n\n      let signatureResult: VerifyJwsResult | undefined\n      try {\n        // Verify the JWS signature\n        signatureResult = await this.jwsService.verifyJws(agentContext, {\n          jws: credential.jwt.serializedJwt,\n          // We have pre-fetched the key based on the issuer/signer of the credential\n          jwsSigner: {\n            method: 'did',\n            jwk: issuerPublicKey,\n            didUrl: issuerVerificationMethod.id,\n          },\n        })\n\n        if (!signatureResult.isValid) {\n          validationResults.validations.signature = {\n            isValid: false,\n            error: new CredoError('Invalid JWS signature'),\n          }\n        } else {\n          validationResults.validations.signature = {\n            isValid: true,\n          }\n        }\n      } catch (error) {\n        validationResults.validations.signature = {\n          isValid: false,\n          error,\n        }\n      }\n\n      // Validate whether the credential is signed with the 'issuer' id\n      // NOTE: this uses the verificationMethod.controller. We may want to use the verificationMethod.id?\n      if (credential.resolvedCredential.issuerId !== issuerVerificationMethod.controller) {\n        validationResults.validations.issuerIsSigner = {\n          isValid: false,\n          error: new CredoError(\n            `Credential is signed using verification method ${issuerVerificationMethod.id}, while the issuer of the credential is '${credential.resolvedCredential.issuerId}'`\n          ),\n        }\n      } else {\n        validationResults.validations.issuerIsSigner = {\n          isValid: true,\n        }\n      }\n\n      // Validate whether the `issuer` of the credential is also the signer\n      const issuerIsSigner = signatureResult?.jwsSigners.some(\n        (jwsSigner) => jwsSigner.jwk.fingerprint === issuerPublicKey.fingerprint\n      )\n      if (!issuerIsSigner) {\n        validationResults.validations.issuerIsSigner = {\n          isValid: false,\n          error: new CredoError('Credential is not signed by the issuer of the credential'),\n        }\n      } else {\n        validationResults.validations.issuerIsSigner = {\n          isValid: true,\n        }\n      }\n\n      validationResults.isValid = Object.values(validationResults.validations).every(\n        (validation) => validation?.isValid === true\n      )\n\n      return validationResults\n    } catch (error) {\n      validationResults.error = error\n      return validationResults\n    }\n  }\n\n  /**\n   * Signs a presentation including the credentials it includes\n   *\n   * @param presentation the presentation to be signed\n   * @returns the signed presentation\n   */\n  public async signPresentation(\n    agentContext: AgentContext,\n    options: W3cV2JwtSignPresentationOptions\n  ): Promise<W3cV2JwtVerifiablePresentation> {\n    // Validate the instance\n    MessageValidator.validateSync(options.presentation)\n\n    // The JWT payload is simply the presentation\n    const jwtPayload = new JwtPayload({\n      additionalClaims: JsonTransformer.toJSON(options.presentation),\n    })\n\n    // Add the nonce and aud to the payload\n    jwtPayload.additionalClaims.nonce = options.challenge\n    jwtPayload.aud = options.domain\n\n    const holder = await extractHolderFromPresentationCredentials(agentContext, options.presentation)\n\n    // Sign JWT\n    const jwt = await this.jwsService.createJwsCompact(agentContext, {\n      payload: jwtPayload,\n      keyId: holder.publicJwk.keyId,\n      protectedHeaderOptions: {\n        typ: 'vp+jwt',\n        alg: holder.alg,\n        kid: holder?.cnf?.kid,\n      },\n    })\n\n    return W3cV2JwtVerifiablePresentation.fromCompact(jwt)\n  }\n\n  /**\n   * Verifies a presentation including the credentials it includes\n   *\n   * @param presentation the presentation to be verified\n   * @returns the verification result\n   */\n  public async verifyPresentation(\n    agentContext: AgentContext,\n    options: W3cV2JwtVerifyPresentationOptions\n  ): Promise<W3cV2VerifyPresentationResult> {\n    const validationResults: W3cV2VerifyPresentationResult = {\n      isValid: false,\n      presentation: {\n        isValid: false,\n        validations: {},\n      },\n      credentialEntries: [],\n    }\n\n    try {\n      let presentation: W3cV2JwtVerifiablePresentation\n      try {\n        // If instance is provided as input, we want to validate the presentation\n        if (options.presentation instanceof W3cV2JwtVerifiablePresentation) {\n          options.presentation.validate()\n        }\n\n        presentation =\n          options.presentation instanceof W3cV2JwtVerifiablePresentation\n            ? options.presentation\n            : W3cV2JwtVerifiablePresentation.fromCompact(options.presentation)\n\n        // Verify the JWT payload (verifies whether it's not expired, etc...)\n        presentation.jwt.payload.validate({\n          skewSeconds: agentContext.config.validitySkewSeconds,\n        })\n\n        this.logPresentationShouldWarnings(agentContext, presentation)\n\n        // Make sure challenge matches nonce\n        if (options.challenge !== presentation.jwt.payload.additionalClaims.nonce) {\n          throw new CredoError(`JWT payload 'nonce' does not match challenge '${options.challenge}'`)\n        }\n\n        const audArray = asArray(presentation.jwt.payload.aud)\n        if (options.domain && !audArray.includes(options.domain)) {\n          throw new CredoError(`JWT payload 'aud' does not include domain '${options.domain}'`)\n        }\n\n        const contextValidationResult = validateVc2ContextBaseline(presentation.resolvedPresentation.context)\n        if (!contextValidationResult.isValid) {\n          throw contextValidationResult.error\n        }\n\n        validationResults.presentation.validations.dataModel = {\n          isValid: true,\n        }\n      } catch (error) {\n        validationResults.presentation.validations.dataModel = {\n          isValid: false,\n          error,\n        }\n\n        return validationResults\n      }\n\n      const proverVerificationMethod = await getVerificationMethodForJwt(agentContext, presentation, ['authentication'])\n      const proverPublicKey = getPublicJwkFromVerificationMethod(proverVerificationMethod)\n\n      try {\n        // Verify the JWS signature\n        const signatureResult = await this.jwsService.verifyJws(agentContext, {\n          jws: presentation.jwt.serializedJwt,\n          allowedJwsSignerMethods: ['did'],\n          jwsSigner: {\n            method: 'did',\n            didUrl: proverVerificationMethod.id,\n            jwk: proverPublicKey,\n          },\n          trustedCertificates: [],\n        })\n\n        if (!signatureResult.isValid) {\n          validationResults.presentation.validations.presentationSignature = {\n            isValid: false,\n            error: new CredoError('Invalid JWS signature on presentation'),\n          }\n        } else {\n          validationResults.presentation.validations.presentationSignature = {\n            isValid: true,\n          }\n        }\n      } catch (error) {\n        validationResults.presentation.validations.presentationSignature = {\n          isValid: false,\n          error,\n        }\n      }\n\n      // Validate whether the presentation is signed with the 'holder' id\n      // NOTE: this uses the verificationMethod.controller. We may want to use the verificationMethod.id?\n      if (\n        presentation.resolvedPresentation.holderId &&\n        proverVerificationMethod.controller !== presentation.resolvedPresentation.holderId\n      ) {\n        validationResults.presentation.validations.holderIsSigner = {\n          isValid: false,\n          error: new CredoError(\n            `Presentation is signed using verification method ${proverVerificationMethod.id}, while the holder of the presentation is '${presentation.resolvedPresentation.holderId}'`\n          ),\n        }\n      } else {\n        // If no holderId is present, this validation passes by default as there can't be\n        // a mismatch between the 'holder' property and the signer of the presentation.\n        validationResults.presentation.validations.holderIsSigner = {\n          isValid: true,\n        }\n      }\n\n      validationResults.presentation.isValid = Object.values(validationResults.presentation.validations).every(\n        (validation) => validation.isValid\n      )\n\n      // Credential-entry dispatch is orchestrated by W3cV2CredentialService.\n      // This service verifies VP container integrity only.\n      validationResults.isValid = validationResults.presentation.isValid\n\n      return validationResults\n    } catch (error) {\n      validationResults.error = error\n      return validationResults\n    }\n  }\n\n  private logCredentialShouldWarnings(agentContext: AgentContext, credential: W3cV2JwtVerifiableCredential) {\n    const payload = credential.jwt.payload\n    const headerIss = credential.jwt.header.iss\n\n    if (typeof headerIss === 'string' && typeof payload.iss === 'string' && headerIss !== payload.iss) {\n      agentContext.config.logger.warn('VC-JOSE-COSE SHOULD warning: JOSE header iss conflicts with payload iss', {\n        format: 'vc+jwt',\n        headerIss,\n        payloadIss: payload.iss,\n      })\n    }\n\n    if (\n      typeof payload.jti === 'string' &&\n      credential.resolvedCredential.id &&\n      credential.resolvedCredential.id !== payload.jti\n    ) {\n      agentContext.config.logger.warn('VC-JOSE-COSE SHOULD warning: jti claim conflicts with credential id', {\n        format: 'vc+jwt',\n        jti: payload.jti,\n        credentialId: credential.resolvedCredential.id,\n      })\n    }\n\n    if (typeof payload.sub === 'string' && !credential.resolvedCredential.credentialSubjectIds.includes(payload.sub)) {\n      agentContext.config.logger.warn(\n        'VC-JOSE-COSE SHOULD warning: sub claim does not match any credentialSubject.id',\n        {\n          format: 'vc+jwt',\n          sub: payload.sub,\n          credentialSubjectIds: credential.resolvedCredential.credentialSubjectIds,\n        }\n      )\n    }\n  }\n\n  private logPresentationShouldWarnings(agentContext: AgentContext, presentation: W3cV2JwtVerifiablePresentation) {\n    const payload = presentation.jwt.payload\n    const headerIss = presentation.jwt.header.iss\n\n    if (typeof headerIss === 'string' && typeof payload.iss === 'string' && headerIss !== payload.iss) {\n      agentContext.config.logger.warn('VC-JOSE-COSE SHOULD warning: JOSE header iss conflicts with payload iss', {\n        format: 'vp+jwt',\n        headerIss,\n        payloadIss: payload.iss,\n      })\n    }\n\n    if (\n      typeof payload.jti === 'string' &&\n      presentation.resolvedPresentation.id &&\n      presentation.resolvedPresentation.id !== payload.jti\n    ) {\n      agentContext.config.logger.warn('VC-JOSE-COSE SHOULD warning: jti claim conflicts with presentation id', {\n        format: 'vp+jwt',\n        jti: payload.jti,\n        presentationId: presentation.resolvedPresentation.id,\n      })\n    }\n  }\n}\n"],"mappings":"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"}