@credo-ts/core 0.6.2-alpha-20251211125338 → 0.6.2-alpha-20251222120740

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 (77) hide show
  1. package/build/agent/Agent.mjs +2 -2
  2. package/build/agent/AgentConfig.d.mts +2 -0
  3. package/build/agent/AgentConfig.d.mts.map +1 -1
  4. package/build/agent/AgentConfig.mjs +4 -0
  5. package/build/agent/AgentConfig.mjs.map +1 -1
  6. package/build/agent/context/DefaultAgentContextProvider.mjs +1 -1
  7. package/build/crypto/JwsService.mjs +4 -4
  8. package/build/crypto/KmsKeyPair.mjs +1 -1
  9. package/build/crypto/index.mjs +1 -1
  10. package/build/crypto/jose/jwt/Jwt.mjs +1 -1
  11. package/build/crypto/jose/jwt/JwtPayload.d.mts +5 -0
  12. package/build/crypto/jose/jwt/JwtPayload.d.mts.map +1 -1
  13. package/build/crypto/jose/jwt/JwtPayload.mjs +10 -8
  14. package/build/crypto/jose/jwt/JwtPayload.mjs.map +1 -1
  15. package/build/index.mjs +12 -12
  16. package/build/modules/cache/CachedStorageService.mjs +2 -2
  17. package/build/modules/dcql/DcqlService.mjs +1 -1
  18. package/build/modules/dids/DidsApi.mjs +1 -1
  19. package/build/modules/dids/domain/DidDocument.mjs +2 -2
  20. package/build/modules/dids/domain/service/DidCommV1Service.mjs +2 -2
  21. package/build/modules/dids/domain/service/DidCommV2Service.mjs +2 -2
  22. package/build/modules/dids/domain/service/IndyAgentService.mjs +2 -2
  23. package/build/modules/dids/domain/service/LegacyDidCommV2Service.mjs +2 -2
  24. package/build/modules/dids/services/DidResolverService.mjs +2 -2
  25. package/build/modules/dif-presentation-exchange/DifPresentationExchangeService.mjs +2 -2
  26. package/build/modules/kms/jwk/PublicJwk.mjs +1 -1
  27. package/build/modules/kms/jwk/alg/encryption.mjs +1 -1
  28. package/build/modules/kms/jwk/alg/signing.mjs +1 -1
  29. package/build/modules/kms/jwk/kty/ec/ecPublicKey.mjs +1 -1
  30. package/build/modules/kms/jwk/kty/rsa/RsaPublicJwk.mjs +1 -1
  31. package/build/modules/kms/legacy.mjs +1 -1
  32. package/build/modules/mdoc/Mdoc.mjs +2 -2
  33. package/build/modules/mdoc/Mdoc.mjs.map +1 -1
  34. package/build/modules/mdoc/MdocDeviceResponse.mjs +2 -2
  35. package/build/modules/mdoc/MdocDeviceResponse.mjs.map +1 -1
  36. package/build/modules/mdoc/mdocSupportedAlgs.d.mts +2 -2
  37. package/build/modules/mdoc/mdocSupportedAlgs.mjs +3 -3
  38. package/build/modules/mdoc/mdocSupportedAlgs.mjs.map +1 -1
  39. package/build/modules/sd-jwt-vc/SdJwtVcService.mjs +6 -6
  40. package/build/modules/sd-jwt-vc/SdJwtVcService.mjs.map +1 -1
  41. package/build/modules/sd-jwt-vc/utils.mjs +1 -1
  42. package/build/modules/vc/data-integrity/W3cJsonLdCredentialService.mjs +3 -3
  43. package/build/modules/vc/data-integrity/models/DataIntegrityProof.mjs +2 -2
  44. package/build/modules/vc/data-integrity/models/LinkedDataProof.mjs +2 -2
  45. package/build/modules/vc/data-integrity/models/W3cJsonLdVerifiableCredential.mjs +2 -2
  46. package/build/modules/vc/data-integrity/models/W3cJsonLdVerifiablePresentation.mjs +2 -2
  47. package/build/modules/vc/jwt-vc/W3cJwtCredentialService.d.mts.map +1 -1
  48. package/build/modules/vc/jwt-vc/W3cJwtCredentialService.mjs +5 -5
  49. package/build/modules/vc/jwt-vc/W3cJwtCredentialService.mjs.map +1 -1
  50. package/build/modules/vc/jwt-vc/W3cV2JwtCredentialService.d.mts.map +1 -1
  51. package/build/modules/vc/jwt-vc/W3cV2JwtCredentialService.mjs +5 -5
  52. package/build/modules/vc/jwt-vc/W3cV2JwtCredentialService.mjs.map +1 -1
  53. package/build/modules/vc/jwt-vc/credentialTransformer.mjs +1 -1
  54. package/build/modules/vc/jwt-vc/presentationTransformer.mjs +1 -1
  55. package/build/modules/vc/models/credential/W3cCredential.mjs +2 -2
  56. package/build/modules/vc/models/credential/W3cCredentialSchema.mjs +1 -1
  57. package/build/modules/vc/models/credential/W3cCredentialStatus.mjs +1 -1
  58. package/build/modules/vc/models/credential/W3cIssuer.mjs +1 -1
  59. package/build/modules/vc/models/credential/W3cV2Credential.mjs +2 -2
  60. package/build/modules/vc/models/credential/W3cV2CredentialSchema.mjs +2 -2
  61. package/build/modules/vc/models/credential/W3cV2CredentialStatus.mjs +2 -2
  62. package/build/modules/vc/models/credential/W3cV2CredentialSubject.mjs +2 -2
  63. package/build/modules/vc/models/credential/W3cV2Evidence.mjs +2 -2
  64. package/build/modules/vc/models/credential/W3cV2Issuer.mjs +2 -2
  65. package/build/modules/vc/models/presentation/W3cHolder.mjs +1 -1
  66. package/build/modules/vc/models/presentation/W3cPresentation.mjs +2 -2
  67. package/build/modules/vc/models/presentation/W3cV2Holder.mjs +2 -2
  68. package/build/modules/vc/models/presentation/W3cV2Presentation.mjs +2 -2
  69. package/build/modules/vc/sd-jwt-vc/W3cV2SdJwtCredentialService.d.mts.map +1 -1
  70. package/build/modules/vc/sd-jwt-vc/W3cV2SdJwtCredentialService.mjs +7 -7
  71. package/build/modules/vc/sd-jwt-vc/W3cV2SdJwtCredentialService.mjs.map +1 -1
  72. package/build/modules/vc/v2-jwt-utils.mjs +1 -1
  73. package/build/storage/BaseRecord.mjs +2 -2
  74. package/build/types.d.mts +17 -0
  75. package/build/types.d.mts.map +1 -1
  76. package/build/types.mjs.map +1 -1
  77. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"W3cJwtCredentialService.mjs","names":["W3cJwtCredentialService","validationResults: W3cVerifyCredentialResult","credential: W3cJwtVerifiableCredential","signatureResult: VerifyJwsResult | undefined","validationResults: W3cVerifyPresentationResult","presentation: W3cJwtVerifiablePresentation","credentialSubjectAuthentication: SingleValidationResult","verificationMethod: VerificationMethod"],"sources":["../../../../src/modules/vc/jwt-vc/W3cJwtCredentialService.ts"],"sourcesContent":["import type { AgentContext } from '../../../agent/context'\nimport type { VerifyJwsResult } from '../../../crypto/JwsService'\nimport { JwsService } from '../../../crypto/JwsService'\nimport { CredoError } from '../../../error'\nimport { injectable } from '../../../plugins'\nimport { asArray, isDid, MessageValidator } from '../../../utils'\nimport type { DidPurpose, VerificationMethod } from '../../dids'\nimport { DidResolverService, DidsApi, parseDid } from '../../dids'\nimport {\n getPublicJwkFromVerificationMethod,\n getSupportedVerificationMethodTypesForPublicJwk,\n} from '../../dids/domain/key-type/keyDidMapping'\nimport { type KnownJwaSignatureAlgorithm, PublicJwk } from '../../kms'\nimport { W3cJsonLdVerifiableCredential } from '../data-integrity'\nimport type { SingleValidationResult, W3cVerifyCredentialResult, W3cVerifyPresentationResult } from '../models'\nimport type {\n W3cJwtSignCredentialOptions,\n W3cJwtSignPresentationOptions,\n W3cJwtVerifyCredentialOptions,\n W3cJwtVerifyPresentationOptions,\n} from '../W3cCredentialServiceOptions'\nimport { getJwtPayloadFromCredential } from './credentialTransformer'\nimport { getJwtPayloadFromPresentation } from './presentationTransformer'\nimport { W3cJwtVerifiableCredential } from './W3cJwtVerifiableCredential'\nimport { W3cJwtVerifiablePresentation } from './W3cJwtVerifiablePresentation'\n\n/**\n * Supports signing and verification of credentials according to the [Verifiable Credential Data Model](https://www.w3.org/TR/vc-data-model)\n * using [Json Web Tokens](https://www.w3.org/TR/vc-data-model/#json-web-token).\n */\n@injectable()\nexport class W3cJwtCredentialService {\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: W3cJwtSignCredentialOptions\n ): Promise<W3cJwtVerifiableCredential> {\n // Validate the instance\n MessageValidator.validateSync(options.credential)\n\n // Get the JWT payload for the JWT based on the JWT Encoding rules form the VC-DATA-MODEL\n // https://www.w3.org/TR/vc-data-model/#jwt-encoding\n const jwtPayload = getJwtPayloadFromCredential(options.credential)\n\n if (!isDid(options.verificationMethod)) {\n throw new CredoError('Only did identifiers are supported as verification method')\n }\n\n const publicJwk = await this.resolveVerificationMethod(agentContext, options.verificationMethod, [\n 'assertionMethod',\n ])\n\n const jwt = await this.jwsService.createJwsCompact(agentContext, {\n payload: jwtPayload,\n keyId: publicJwk.keyId,\n protectedHeaderOptions: {\n typ: 'JWT',\n alg: options.alg,\n kid: options.verificationMethod,\n },\n })\n\n // TODO: this re-parses and validates the credential in the JWT, which is not necessary.\n // We should somehow create an instance of W3cJwtVerifiableCredential directly from the JWT\n const jwtVc = W3cJwtVerifiableCredential.fromSerializedJwt(jwt)\n\n return jwtVc\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: W3cJwtVerifyCredentialOptions\n ): Promise<W3cVerifyCredentialResult> {\n // NOTE: this is mostly from the JSON-LD service that adds this option. Once we support\n // the same granular validation results, we can remove this and the user could just check\n // which of the validations failed. Supporting for consistency with the JSON-LD service for now.\n const verifyCredentialStatus = options.verifyCredentialStatus ?? true\n\n const validationResults: W3cVerifyCredentialResult = {\n isValid: false,\n validations: {},\n }\n\n try {\n let credential: W3cJwtVerifiableCredential\n try {\n // If instance is provided as input, we want to validate the credential (otherwise it's done in the fromSerializedJwt method below)\n if (options.credential instanceof W3cJwtVerifiableCredential) {\n MessageValidator.validateSync(options.credential.credential)\n }\n\n credential =\n options.credential instanceof W3cJwtVerifiableCredential\n ? options.credential\n : W3cJwtVerifiableCredential.fromSerializedJwt(options.credential)\n\n // Verify the JWT payload (verifies whether it's not expired, etc...)\n credential.jwt.payload.validate()\n\n validationResults.validations.dataModel = {\n isValid: true,\n }\n } catch (error) {\n validationResults.validations.dataModel = {\n isValid: false,\n error,\n }\n\n return validationResults\n }\n\n const issuerVerificationMethod = await this.getVerificationMethodForJwtCredential(agentContext, {\n credential,\n purpose: ['assertionMethod'],\n })\n const issuerPublicKey = getPublicJwkFromVerificationMethod(issuerVerificationMethod)\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.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.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 // Validate credentialStatus\n if (verifyCredentialStatus && !credential.credentialStatus) {\n validationResults.validations.credentialStatus = {\n isValid: true,\n }\n } else if (verifyCredentialStatus && credential.credentialStatus) {\n validationResults.validations.credentialStatus = {\n isValid: false,\n error: new CredoError('Verifying credential status is not supported for JWT VCs'),\n }\n }\n\n validationResults.isValid = Object.values(validationResults.validations).every((v) => v.isValid)\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: W3cJwtSignPresentationOptions\n ): Promise<W3cJwtVerifiablePresentation> {\n // Validate the instance\n MessageValidator.validateSync(options.presentation)\n\n // Get the JWT payload for the JWT based on the JWT Encoding rules form the VC-DATA-MODEL\n // https://www.w3.org/TR/vc-data-model/#jwt-encoding\n const jwtPayload = getJwtPayloadFromPresentation(options.presentation)\n\n // Set the nonce so it's included in the signature\n jwtPayload.additionalClaims.nonce = options.challenge\n jwtPayload.aud = options.domain\n\n const publicJwk = await this.resolveVerificationMethod(agentContext, options.verificationMethod, ['authentication'])\n\n const jwt = await this.jwsService.createJwsCompact(agentContext, {\n payload: jwtPayload,\n keyId: publicJwk.keyId,\n protectedHeaderOptions: {\n typ: 'JWT',\n alg: options.alg,\n kid: options.verificationMethod,\n },\n })\n\n // TODO: this re-parses and validates the presentation in the JWT, which is not necessary.\n // We should somehow create an instance of W3cJwtVerifiablePresentation directly from the JWT\n const jwtVp = W3cJwtVerifiablePresentation.fromSerializedJwt(jwt)\n\n return jwtVp\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: W3cJwtVerifyPresentationOptions\n ): Promise<W3cVerifyPresentationResult> {\n const validationResults: W3cVerifyPresentationResult = {\n isValid: false,\n validations: {},\n }\n\n try {\n let presentation: W3cJwtVerifiablePresentation\n try {\n // If instance is provided as input, we want to validate the presentation\n if (options.presentation instanceof W3cJwtVerifiablePresentation) {\n MessageValidator.validateSync(options.presentation.presentation)\n }\n\n presentation =\n options.presentation instanceof W3cJwtVerifiablePresentation\n ? options.presentation\n : W3cJwtVerifiablePresentation.fromSerializedJwt(options.presentation)\n\n // Verify the JWT payload (verifies whether it's not expired, etc...)\n presentation.jwt.payload.validate()\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 validationResults.validations.dataModel = {\n isValid: true,\n }\n } catch (error) {\n validationResults.validations.dataModel = {\n isValid: false,\n error,\n }\n\n return validationResults\n }\n\n const proverVerificationMethod = await this.getVerificationMethodForJwtCredential(agentContext, {\n credential: presentation,\n purpose: ['authentication'],\n })\n const proverPublicKey = getPublicJwkFromVerificationMethod(proverVerificationMethod)\n\n let signatureResult: VerifyJwsResult | undefined\n try {\n // Verify the JWS signature\n 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.validations.presentationSignature = {\n isValid: false,\n error: new CredoError('Invalid JWS signature on presentation'),\n }\n } else {\n validationResults.validations.presentationSignature = {\n isValid: true,\n }\n }\n } catch (error) {\n validationResults.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 (presentation.holderId && proverVerificationMethod.controller !== presentation.holderId) {\n validationResults.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.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.validations.holderIsSigner = {\n isValid: true,\n }\n }\n\n // To keep things simple, we only support JWT VCs in JWT VPs for now\n const credentials = asArray(presentation.presentation.verifiableCredential)\n\n // Verify all credentials in parallel, and await the result\n validationResults.validations.credentials = await Promise.all(\n credentials.map(async (credential) => {\n if (credential instanceof W3cJsonLdVerifiableCredential) {\n return {\n isValid: false,\n error: new CredoError(\n 'Credential is of format ldp_vc. presentations in jwt_vp format can only contain credentials in jwt_vc format'\n ),\n validations: {},\n }\n }\n\n const credentialResult = await this.verifyCredential(agentContext, {\n credential,\n verifyCredentialStatus: options.verifyCredentialStatus,\n })\n\n let credentialSubjectAuthentication: SingleValidationResult\n\n // Check whether any of the credentialSubjectIds for each credential is the same as the controller of the verificationMethod\n // This authenticates the presentation creator controls one of the credentialSubject ids.\n // NOTE: this doesn't take into account the case where the credentialSubject is no the holder. In the\n // future we can add support for other flows, but for now this is the most common use case.\n // TODO: should this be handled on a higher level? I don't really see it being handled in the jsonld lib\n // or in the did-jwt-vc lib (it seems they don't even verify the credentials itself), but we probably need some\n // more experience on the use cases before we loosen the restrictions (as it means we need to handle it on a higher layer).\n const credentialSubjectIds = credential.credentialSubjectIds\n const presentationAuthenticatesCredentialSubject = credentialSubjectIds.some(\n (subjectId) => proverVerificationMethod.controller === subjectId\n )\n\n if (credentialSubjectIds.length > 0 && !presentationAuthenticatesCredentialSubject) {\n credentialSubjectAuthentication = {\n isValid: false,\n error: new CredoError(\n 'Credential has one or more credentialSubject ids, but presentation does not authenticate credential subject'\n ),\n }\n } else {\n credentialSubjectAuthentication = {\n isValid: true,\n }\n }\n\n return {\n ...credentialResult,\n isValid: credentialResult.isValid && credentialSubjectAuthentication.isValid,\n validations: {\n ...credentialResult.validations,\n credentialSubjectAuthentication,\n },\n }\n })\n )\n\n // Deeply nested check whether all validations have passed\n validationResults.isValid = Object.values(validationResults.validations).every((v) =>\n Array.isArray(v) ? v.every((vv) => vv.isValid) : v.isValid\n )\n\n return validationResults\n } catch (error) {\n validationResults.error = error\n return validationResults\n }\n }\n\n private async resolveVerificationMethod(\n agentContext: AgentContext,\n verificationMethod: string,\n allowsPurposes?: DidPurpose[]\n ): Promise<PublicJwk> {\n const dids = agentContext.resolve(DidsApi)\n\n const parsedDid = parseDid(verificationMethod)\n const { didDocument, keys } = await dids.resolveCreatedDidDocumentWithKeys(parsedDid.did)\n const verificationMethodObject = didDocument.dereferenceKey(verificationMethod, allowsPurposes)\n const publicJwk = getPublicJwkFromVerificationMethod(verificationMethodObject)\n\n publicJwk.keyId =\n keys?.find(({ didDocumentRelativeKeyId }) => verificationMethodObject.id.endsWith(didDocumentRelativeKeyId))\n ?.kmsKeyId ?? publicJwk.legacyKeyId\n\n return publicJwk\n }\n\n /**\n * This method tries to find the verification method associated with the JWT credential or presentation.\n * This verification method can then be used to verify the credential or presentation signature.\n *\n * The following methods are used to extract the verification method:\n * - verification method is resolved based on the `kid` in the protected header\n * - either as absolute reference (e.g. `did:example:123#key-1`)\n * - or as relative reference to the `iss` of the JWT (e.g. `iss` is `did:example:123` and `kid` is `#key-1`)\n * - the did document is resolved based on the `iss` field, after which the verification method is extracted based on the `alg`\n * used to sign the JWT and the specified `purpose`. Only a single verification method may be present, and in all other cases,\n * an error is thrown.\n *\n * The signer (`iss`) of the JWT is verified against the `controller` of the verificationMethod resolved in the did\n * document. This means if the `iss` of a credential is `did:example:123` and the controller of the verificationMethod\n * is `did:example:456`, an error is thrown to prevent the JWT from successfully being verified.\n *\n * In addition the JWT must conform to one of the following rules:\n * - MUST be a credential and have an `iss` field and MAY have an absolute or relative `kid`\n * - MUST not be a credential AND ONE of the following:\n * - have an `iss` field and MAY have an absolute or relative `kid`\n * - does not have an `iss` field and MUST have an absolute `kid`\n */\n private async getVerificationMethodForJwtCredential(\n agentContext: AgentContext,\n options: {\n credential: W3cJwtVerifiableCredential | W3cJwtVerifiablePresentation\n purpose?: DidPurpose[]\n }\n ) {\n const { credential, purpose } = options\n const kid = credential.jwt.header.kid\n\n const didResolver = agentContext.dependencyManager.resolve(DidResolverService)\n\n // The signerId is the `holder` of the presentation or the `issuer` of the credential\n // For a credential only the `iss` COULD be enough to resolve the signer key (see method comments)\n const signerId = credential.jwt.payload.iss\n\n let verificationMethod: VerificationMethod\n\n // If the kid starts with # we assume it is a relative did url, and we resolve it based on the `iss` and the `kid`\n if (kid?.startsWith('#')) {\n if (!signerId) {\n throw new CredoError(`JWT 'kid' MUST be absolute when when no 'iss' is present in JWT payload`)\n }\n\n const didDocument = await didResolver.resolveDidDocument(agentContext, signerId)\n verificationMethod = didDocument.dereferenceKey(`${signerId}${kid}`, purpose)\n }\n // this is a full did url (todo check if it contains a #)\n else if (kid && isDid(kid)) {\n const didDocument = await didResolver.resolveDidDocument(agentContext, kid)\n\n verificationMethod = didDocument.dereferenceKey(kid, purpose)\n\n if (signerId && didDocument.id !== signerId) {\n throw new CredoError(`kid '${kid}' does not match id of signer (holder/issuer) '${signerId}'`)\n }\n } else {\n if (!signerId) {\n throw new CredoError(`JWT 'iss' MUST be present in payload when no 'kid' is specified`)\n }\n\n // Find the verificationMethod in the did document based on the alg and proofPurpose\n const jwkClass = PublicJwk.supportedPublicJwkClassForSignatureAlgorithm(\n credential.jwt.header.alg as KnownJwaSignatureAlgorithm\n )\n const supportedVerificationMethodTypes = getSupportedVerificationMethodTypesForPublicJwk(jwkClass)\n\n const didDocument = await didResolver.resolveDidDocument(agentContext, signerId)\n const verificationMethods =\n didDocument.assertionMethod\n ?.map((v) => (typeof v === 'string' ? didDocument.dereferenceVerificationMethod(v) : v))\n .filter((v) => supportedVerificationMethodTypes.includes(v.type)) ?? []\n\n if (verificationMethods.length === 0) {\n throw new CredoError(\n `No verification methods found for signer '${signerId}' and key type '${jwkClass.name}' for alg '${credential.jwt.header.alg}'. Unable to determine which public key is associated with the credential.`\n )\n }\n if (verificationMethods.length > 1) {\n throw new CredoError(\n `Multiple verification methods found for signer '${signerId}' and key type '${jwkClass.name}' for alg '${credential.jwt.header.alg}'. Unable to determine which public key is associated with the credential.`\n )\n }\n\n verificationMethod = verificationMethods[0]\n }\n\n // Verify the controller of the verificationMethod matches the signer of the credential\n if (signerId && verificationMethod.controller !== signerId) {\n throw new CredoError(\n `Verification method controller '${verificationMethod.controller}' does not match the signer '${signerId}'`\n )\n }\n\n return verificationMethod\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"W3cJwtCredentialService.mjs","names":["W3cJwtCredentialService","validationResults: W3cVerifyCredentialResult","credential: W3cJwtVerifiableCredential","signatureResult: VerifyJwsResult | undefined","validationResults: W3cVerifyPresentationResult","presentation: W3cJwtVerifiablePresentation","credentialSubjectAuthentication: SingleValidationResult","verificationMethod: VerificationMethod"],"sources":["../../../../src/modules/vc/jwt-vc/W3cJwtCredentialService.ts"],"sourcesContent":["import type { AgentContext } from '../../../agent/context'\nimport type { VerifyJwsResult } from '../../../crypto/JwsService'\nimport { JwsService } from '../../../crypto/JwsService'\nimport { CredoError } from '../../../error'\nimport { injectable } from '../../../plugins'\nimport { asArray, isDid, MessageValidator } from '../../../utils'\nimport type { DidPurpose, VerificationMethod } from '../../dids'\nimport { DidResolverService, DidsApi, parseDid } from '../../dids'\nimport {\n getPublicJwkFromVerificationMethod,\n getSupportedVerificationMethodTypesForPublicJwk,\n} from '../../dids/domain/key-type/keyDidMapping'\nimport { type KnownJwaSignatureAlgorithm, PublicJwk } from '../../kms'\nimport { W3cJsonLdVerifiableCredential } from '../data-integrity'\nimport type { SingleValidationResult, W3cVerifyCredentialResult, W3cVerifyPresentationResult } from '../models'\nimport type {\n W3cJwtSignCredentialOptions,\n W3cJwtSignPresentationOptions,\n W3cJwtVerifyCredentialOptions,\n W3cJwtVerifyPresentationOptions,\n} from '../W3cCredentialServiceOptions'\nimport { getJwtPayloadFromCredential } from './credentialTransformer'\nimport { getJwtPayloadFromPresentation } from './presentationTransformer'\nimport { W3cJwtVerifiableCredential } from './W3cJwtVerifiableCredential'\nimport { W3cJwtVerifiablePresentation } from './W3cJwtVerifiablePresentation'\n\n/**\n * Supports signing and verification of credentials according to the [Verifiable Credential Data Model](https://www.w3.org/TR/vc-data-model)\n * using [Json Web Tokens](https://www.w3.org/TR/vc-data-model/#json-web-token).\n */\n@injectable()\nexport class W3cJwtCredentialService {\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: W3cJwtSignCredentialOptions\n ): Promise<W3cJwtVerifiableCredential> {\n // Validate the instance\n MessageValidator.validateSync(options.credential)\n\n // Get the JWT payload for the JWT based on the JWT Encoding rules form the VC-DATA-MODEL\n // https://www.w3.org/TR/vc-data-model/#jwt-encoding\n const jwtPayload = getJwtPayloadFromCredential(options.credential)\n\n if (!isDid(options.verificationMethod)) {\n throw new CredoError('Only did identifiers are supported as verification method')\n }\n\n const publicJwk = await this.resolveVerificationMethod(agentContext, options.verificationMethod, [\n 'assertionMethod',\n ])\n\n const jwt = await this.jwsService.createJwsCompact(agentContext, {\n payload: jwtPayload,\n keyId: publicJwk.keyId,\n protectedHeaderOptions: {\n typ: 'JWT',\n alg: options.alg,\n kid: options.verificationMethod,\n },\n })\n\n // TODO: this re-parses and validates the credential in the JWT, which is not necessary.\n // We should somehow create an instance of W3cJwtVerifiableCredential directly from the JWT\n const jwtVc = W3cJwtVerifiableCredential.fromSerializedJwt(jwt)\n\n return jwtVc\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: W3cJwtVerifyCredentialOptions\n ): Promise<W3cVerifyCredentialResult> {\n // NOTE: this is mostly from the JSON-LD service that adds this option. Once we support\n // the same granular validation results, we can remove this and the user could just check\n // which of the validations failed. Supporting for consistency with the JSON-LD service for now.\n const verifyCredentialStatus = options.verifyCredentialStatus ?? true\n\n const validationResults: W3cVerifyCredentialResult = {\n isValid: false,\n validations: {},\n }\n\n try {\n let credential: W3cJwtVerifiableCredential\n try {\n // If instance is provided as input, we want to validate the credential (otherwise it's done in the fromSerializedJwt method below)\n if (options.credential instanceof W3cJwtVerifiableCredential) {\n MessageValidator.validateSync(options.credential.credential)\n }\n\n credential =\n options.credential instanceof W3cJwtVerifiableCredential\n ? options.credential\n : W3cJwtVerifiableCredential.fromSerializedJwt(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 validationResults.validations.dataModel = {\n isValid: true,\n }\n } catch (error) {\n validationResults.validations.dataModel = {\n isValid: false,\n error,\n }\n\n return validationResults\n }\n\n const issuerVerificationMethod = await this.getVerificationMethodForJwtCredential(agentContext, {\n credential,\n purpose: ['assertionMethod'],\n })\n const issuerPublicKey = getPublicJwkFromVerificationMethod(issuerVerificationMethod)\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.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.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 // Validate credentialStatus\n if (verifyCredentialStatus && !credential.credentialStatus) {\n validationResults.validations.credentialStatus = {\n isValid: true,\n }\n } else if (verifyCredentialStatus && credential.credentialStatus) {\n validationResults.validations.credentialStatus = {\n isValid: false,\n error: new CredoError('Verifying credential status is not supported for JWT VCs'),\n }\n }\n\n validationResults.isValid = Object.values(validationResults.validations).every((v) => v.isValid)\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: W3cJwtSignPresentationOptions\n ): Promise<W3cJwtVerifiablePresentation> {\n // Validate the instance\n MessageValidator.validateSync(options.presentation)\n\n // Get the JWT payload for the JWT based on the JWT Encoding rules form the VC-DATA-MODEL\n // https://www.w3.org/TR/vc-data-model/#jwt-encoding\n const jwtPayload = getJwtPayloadFromPresentation(options.presentation)\n\n // Set the nonce so it's included in the signature\n jwtPayload.additionalClaims.nonce = options.challenge\n jwtPayload.aud = options.domain\n\n const publicJwk = await this.resolveVerificationMethod(agentContext, options.verificationMethod, ['authentication'])\n\n const jwt = await this.jwsService.createJwsCompact(agentContext, {\n payload: jwtPayload,\n keyId: publicJwk.keyId,\n protectedHeaderOptions: {\n typ: 'JWT',\n alg: options.alg,\n kid: options.verificationMethod,\n },\n })\n\n // TODO: this re-parses and validates the presentation in the JWT, which is not necessary.\n // We should somehow create an instance of W3cJwtVerifiablePresentation directly from the JWT\n const jwtVp = W3cJwtVerifiablePresentation.fromSerializedJwt(jwt)\n\n return jwtVp\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: W3cJwtVerifyPresentationOptions\n ): Promise<W3cVerifyPresentationResult> {\n const validationResults: W3cVerifyPresentationResult = {\n isValid: false,\n validations: {},\n }\n\n try {\n let presentation: W3cJwtVerifiablePresentation\n try {\n // If instance is provided as input, we want to validate the presentation\n if (options.presentation instanceof W3cJwtVerifiablePresentation) {\n MessageValidator.validateSync(options.presentation.presentation)\n }\n\n presentation =\n options.presentation instanceof W3cJwtVerifiablePresentation\n ? options.presentation\n : W3cJwtVerifiablePresentation.fromSerializedJwt(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 // 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 validationResults.validations.dataModel = {\n isValid: true,\n }\n } catch (error) {\n validationResults.validations.dataModel = {\n isValid: false,\n error,\n }\n\n return validationResults\n }\n\n const proverVerificationMethod = await this.getVerificationMethodForJwtCredential(agentContext, {\n credential: presentation,\n purpose: ['authentication'],\n })\n const proverPublicKey = getPublicJwkFromVerificationMethod(proverVerificationMethod)\n\n let signatureResult: VerifyJwsResult | undefined\n try {\n // Verify the JWS signature\n 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.validations.presentationSignature = {\n isValid: false,\n error: new CredoError('Invalid JWS signature on presentation'),\n }\n } else {\n validationResults.validations.presentationSignature = {\n isValid: true,\n }\n }\n } catch (error) {\n validationResults.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 (presentation.holderId && proverVerificationMethod.controller !== presentation.holderId) {\n validationResults.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.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.validations.holderIsSigner = {\n isValid: true,\n }\n }\n\n // To keep things simple, we only support JWT VCs in JWT VPs for now\n const credentials = asArray(presentation.presentation.verifiableCredential)\n\n // Verify all credentials in parallel, and await the result\n validationResults.validations.credentials = await Promise.all(\n credentials.map(async (credential) => {\n if (credential instanceof W3cJsonLdVerifiableCredential) {\n return {\n isValid: false,\n error: new CredoError(\n 'Credential is of format ldp_vc. presentations in jwt_vp format can only contain credentials in jwt_vc format'\n ),\n validations: {},\n }\n }\n\n const credentialResult = await this.verifyCredential(agentContext, {\n credential,\n verifyCredentialStatus: options.verifyCredentialStatus,\n })\n\n let credentialSubjectAuthentication: SingleValidationResult\n\n // Check whether any of the credentialSubjectIds for each credential is the same as the controller of the verificationMethod\n // This authenticates the presentation creator controls one of the credentialSubject ids.\n // NOTE: this doesn't take into account the case where the credentialSubject is no the holder. In the\n // future we can add support for other flows, but for now this is the most common use case.\n // TODO: should this be handled on a higher level? I don't really see it being handled in the jsonld lib\n // or in the did-jwt-vc lib (it seems they don't even verify the credentials itself), but we probably need some\n // more experience on the use cases before we loosen the restrictions (as it means we need to handle it on a higher layer).\n const credentialSubjectIds = credential.credentialSubjectIds\n const presentationAuthenticatesCredentialSubject = credentialSubjectIds.some(\n (subjectId) => proverVerificationMethod.controller === subjectId\n )\n\n if (credentialSubjectIds.length > 0 && !presentationAuthenticatesCredentialSubject) {\n credentialSubjectAuthentication = {\n isValid: false,\n error: new CredoError(\n 'Credential has one or more credentialSubject ids, but presentation does not authenticate credential subject'\n ),\n }\n } else {\n credentialSubjectAuthentication = {\n isValid: true,\n }\n }\n\n return {\n ...credentialResult,\n isValid: credentialResult.isValid && credentialSubjectAuthentication.isValid,\n validations: {\n ...credentialResult.validations,\n credentialSubjectAuthentication,\n },\n }\n })\n )\n\n // Deeply nested check whether all validations have passed\n validationResults.isValid = Object.values(validationResults.validations).every((v) =>\n Array.isArray(v) ? v.every((vv) => vv.isValid) : v.isValid\n )\n\n return validationResults\n } catch (error) {\n validationResults.error = error\n return validationResults\n }\n }\n\n private async resolveVerificationMethod(\n agentContext: AgentContext,\n verificationMethod: string,\n allowsPurposes?: DidPurpose[]\n ): Promise<PublicJwk> {\n const dids = agentContext.resolve(DidsApi)\n\n const parsedDid = parseDid(verificationMethod)\n const { didDocument, keys } = await dids.resolveCreatedDidDocumentWithKeys(parsedDid.did)\n const verificationMethodObject = didDocument.dereferenceKey(verificationMethod, allowsPurposes)\n const publicJwk = getPublicJwkFromVerificationMethod(verificationMethodObject)\n\n publicJwk.keyId =\n keys?.find(({ didDocumentRelativeKeyId }) => verificationMethodObject.id.endsWith(didDocumentRelativeKeyId))\n ?.kmsKeyId ?? publicJwk.legacyKeyId\n\n return publicJwk\n }\n\n /**\n * This method tries to find the verification method associated with the JWT credential or presentation.\n * This verification method can then be used to verify the credential or presentation signature.\n *\n * The following methods are used to extract the verification method:\n * - verification method is resolved based on the `kid` in the protected header\n * - either as absolute reference (e.g. `did:example:123#key-1`)\n * - or as relative reference to the `iss` of the JWT (e.g. `iss` is `did:example:123` and `kid` is `#key-1`)\n * - the did document is resolved based on the `iss` field, after which the verification method is extracted based on the `alg`\n * used to sign the JWT and the specified `purpose`. Only a single verification method may be present, and in all other cases,\n * an error is thrown.\n *\n * The signer (`iss`) of the JWT is verified against the `controller` of the verificationMethod resolved in the did\n * document. This means if the `iss` of a credential is `did:example:123` and the controller of the verificationMethod\n * is `did:example:456`, an error is thrown to prevent the JWT from successfully being verified.\n *\n * In addition the JWT must conform to one of the following rules:\n * - MUST be a credential and have an `iss` field and MAY have an absolute or relative `kid`\n * - MUST not be a credential AND ONE of the following:\n * - have an `iss` field and MAY have an absolute or relative `kid`\n * - does not have an `iss` field and MUST have an absolute `kid`\n */\n private async getVerificationMethodForJwtCredential(\n agentContext: AgentContext,\n options: {\n credential: W3cJwtVerifiableCredential | W3cJwtVerifiablePresentation\n purpose?: DidPurpose[]\n }\n ) {\n const { credential, purpose } = options\n const kid = credential.jwt.header.kid\n\n const didResolver = agentContext.dependencyManager.resolve(DidResolverService)\n\n // The signerId is the `holder` of the presentation or the `issuer` of the credential\n // For a credential only the `iss` COULD be enough to resolve the signer key (see method comments)\n const signerId = credential.jwt.payload.iss\n\n let verificationMethod: VerificationMethod\n\n // If the kid starts with # we assume it is a relative did url, and we resolve it based on the `iss` and the `kid`\n if (kid?.startsWith('#')) {\n if (!signerId) {\n throw new CredoError(`JWT 'kid' MUST be absolute when when no 'iss' is present in JWT payload`)\n }\n\n const didDocument = await didResolver.resolveDidDocument(agentContext, signerId)\n verificationMethod = didDocument.dereferenceKey(`${signerId}${kid}`, purpose)\n }\n // this is a full did url (todo check if it contains a #)\n else if (kid && isDid(kid)) {\n const didDocument = await didResolver.resolveDidDocument(agentContext, kid)\n\n verificationMethod = didDocument.dereferenceKey(kid, purpose)\n\n if (signerId && didDocument.id !== signerId) {\n throw new CredoError(`kid '${kid}' does not match id of signer (holder/issuer) '${signerId}'`)\n }\n } else {\n if (!signerId) {\n throw new CredoError(`JWT 'iss' MUST be present in payload when no 'kid' is specified`)\n }\n\n // Find the verificationMethod in the did document based on the alg and proofPurpose\n const jwkClass = PublicJwk.supportedPublicJwkClassForSignatureAlgorithm(\n credential.jwt.header.alg as KnownJwaSignatureAlgorithm\n )\n const supportedVerificationMethodTypes = getSupportedVerificationMethodTypesForPublicJwk(jwkClass)\n\n const didDocument = await didResolver.resolveDidDocument(agentContext, signerId)\n const verificationMethods =\n didDocument.assertionMethod\n ?.map((v) => (typeof v === 'string' ? didDocument.dereferenceVerificationMethod(v) : v))\n .filter((v) => supportedVerificationMethodTypes.includes(v.type)) ?? []\n\n if (verificationMethods.length === 0) {\n throw new CredoError(\n `No verification methods found for signer '${signerId}' and key type '${jwkClass.name}' for alg '${credential.jwt.header.alg}'. Unable to determine which public key is associated with the credential.`\n )\n }\n if (verificationMethods.length > 1) {\n throw new CredoError(\n `Multiple verification methods found for signer '${signerId}' and key type '${jwkClass.name}' for alg '${credential.jwt.header.alg}'. Unable to determine which public key is associated with the credential.`\n )\n }\n\n verificationMethod = verificationMethods[0]\n }\n\n // Verify the controller of the verificationMethod matches the signer of the credential\n if (signerId && verificationMethod.controller !== signerId) {\n throw new CredoError(\n `Verification method controller '${verificationMethod.controller}' does not match the signer '${signerId}'`\n )\n }\n\n return verificationMethod\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"W3cV2JwtCredentialService.d.mts","names":[],"sources":["../../../../src/modules/vc/jwt-vc/W3cV2JwtCredentialService.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;AA+Ba,cAAA,yBAAA,CAAyB;EAGL,QAAA,UAAA;EAQf,WAAA,CAAA,UAAA,EARe,UAQf;EACL;;;EA0CK,cAAA,CAAA,YAAA,EA3CA,YA2CA,EAAA,OAAA,EA1CL,6BA0CK,CAAA,EAzCb,OAyCa,CAzCL,4BAyCK,CAAA;EACL;;;;;;EAqHR,gBAAA,CAAA,YAAA,EAtHa,YAsHb,EAAA,OAAA,EArHQ,+BAqHR,CAAA,EApHA,OAoHA,CApHQ,2BAoHR,CAAA;EAoCa;;;;;;iCAtCA,uBACL,kCACR,QAAQ;;;;;;;mCAoCK,uBACL,oCACR,QAAQ"}
1
+ {"version":3,"file":"W3cV2JwtCredentialService.d.mts","names":[],"sources":["../../../../src/modules/vc/jwt-vc/W3cV2JwtCredentialService.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;AA+Ba,cAAA,yBAAA,CAAyB;EAGL,QAAA,UAAA;EAQf,WAAA,CAAA,UAAA,EARe,UAQf;EACL;;;EA0CK,cAAA,CAAA,YAAA,EA3CA,YA2CA,EAAA,OAAA,EA1CL,6BA0CK,CAAA,EAzCb,OAyCa,CAzCL,4BAyCK,CAAA;EACL;;;;;;EAuHR,gBAAA,CAAA,YAAA,EAxHa,YAwHb,EAAA,OAAA,EAvHQ,+BAuHR,CAAA,EAtHA,OAsHA,CAtHQ,2BAsHR,CAAA;EAoCa;;;;;;iCAtCA,uBACL,kCACR,QAAQ;;;;;;;mCAoCK,uBACL,oCACR,QAAQ"}
@@ -2,15 +2,15 @@
2
2
 
3
3
  import { CredoError } from "../../../error/CredoError.mjs";
4
4
  import "../../../error/index.mjs";
5
- import { injectable } from "../../../plugins/index.mjs";
6
- import { __decorateMetadata } from "../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
7
- import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
8
5
  import { asArray } from "../../../utils/array.mjs";
9
6
  import { MessageValidator } from "../../../utils/MessageValidator.mjs";
10
7
  import { JsonTransformer } from "../../../utils/JsonTransformer.mjs";
11
8
  import { nowInSeconds } from "../../../utils/timestamp.mjs";
12
9
  import "../../../utils/index.mjs";
13
10
  import { JwtPayload } from "../../../crypto/jose/jwt/JwtPayload.mjs";
11
+ import { injectable } from "../../../plugins/index.mjs";
12
+ import { __decorateMetadata } from "../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
13
+ import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
14
14
  import { JwsService } from "../../../crypto/JwsService.mjs";
15
15
  import { getPublicJwkFromVerificationMethod } from "../../dids/domain/key-type/keyDidMapping.mjs";
16
16
  import { W3cV2JwtVerifiableCredential } from "./W3cV2JwtVerifiableCredential.mjs";
@@ -61,7 +61,7 @@ let W3cV2JwtCredentialService = class W3cV2JwtCredentialService$1 {
61
61
  try {
62
62
  if (options.credential instanceof W3cV2JwtVerifiableCredential) options.credential.validate();
63
63
  credential = options.credential instanceof W3cV2JwtVerifiableCredential ? options.credential : W3cV2JwtVerifiableCredential.fromCompact(options.credential);
64
- credential.jwt.payload.validate();
64
+ credential.jwt.payload.validate({ skewSeconds: agentContext.config.validitySkewSeconds });
65
65
  validationResults.validations.dataModel = { isValid: true };
66
66
  } catch (error) {
67
67
  validationResults.validations.dataModel = {
@@ -149,7 +149,7 @@ let W3cV2JwtCredentialService = class W3cV2JwtCredentialService$1 {
149
149
  try {
150
150
  if (options.presentation instanceof W3cV2JwtVerifiablePresentation) options.presentation.validate();
151
151
  presentation = options.presentation instanceof W3cV2JwtVerifiablePresentation ? options.presentation : W3cV2JwtVerifiablePresentation.fromCompact(options.presentation);
152
- presentation.jwt.payload.validate();
152
+ presentation.jwt.payload.validate({ skewSeconds: agentContext.config.validitySkewSeconds });
153
153
  if (options.challenge !== presentation.jwt.payload.additionalClaims.nonce) throw new CredoError(`JWT payload 'nonce' does not match challenge '${options.challenge}'`);
154
154
  const audArray = asArray(presentation.jwt.payload.aud);
155
155
  if (options.domain && !audArray.includes(options.domain)) throw new CredoError(`JWT payload 'aud' does not include domain '${options.domain}'`);
@@ -1 +1 @@
1
- {"version":3,"file":"W3cV2JwtCredentialService.mjs","names":["W3cV2JwtCredentialService","validationResults: W3cV2VerifyCredentialResult","credential: W3cV2JwtVerifiableCredential","signatureResult: VerifyJwsResult | undefined","validationResults: W3cV2VerifyPresentationResult","presentation: W3cV2JwtVerifiablePresentation","credentialSubjectAuthentication: SingleValidationResult"],"sources":["../../../../src/modules/vc/jwt-vc/W3cV2JwtCredentialService.ts"],"sourcesContent":["import type { AgentContext } from '../../../agent/context'\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 { SingleValidationResult, W3cV2VerifyCredentialResult, W3cV2VerifyPresentationResult } from '../models'\nimport {\n extractHolderFromPresentationCredentials,\n getVerificationMethodForJwt,\n validateAndResolveVerificationMethod,\n} from '../v2-jwt-utils'\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\n validationResults.validations.dataModel = {\n isValid: true,\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 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((v) => v.isValid)\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 validations: {},\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\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 validationResults.validations.dataModel = {\n isValid: true,\n }\n } catch (error) {\n validationResults.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 let signatureResult: VerifyJwsResult | undefined\n try {\n // Verify the JWS signature\n 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.validations.presentationSignature = {\n isValid: false,\n error: new CredoError('Invalid JWS signature on presentation'),\n }\n } else {\n validationResults.validations.presentationSignature = {\n isValid: true,\n }\n }\n } catch (error) {\n validationResults.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.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.validations.holderIsSigner = {\n isValid: true,\n }\n }\n\n // To keep things simple, we only support JWT VCs in JWT VPs for now\n const credentials = asArray(presentation.resolvedPresentation.verifiableCredential)\n\n // Verify all credentials in parallel, and await the result\n validationResults.validations.credentials = await Promise.all(\n credentials.map(async (credential) => {\n if (!(credential.envelopedCredential instanceof W3cV2JwtVerifiableCredential)) {\n return {\n isValid: false,\n error: new CredoError(\n 'Credential is not of format JWT. Presentations in JWT format can only contain credentials in JWT format.'\n ),\n validations: {},\n }\n }\n\n const credentialResult = await this.verifyCredential(agentContext, {\n credential: credential.envelopedCredential,\n })\n\n let credentialSubjectAuthentication: SingleValidationResult\n\n // Check whether any of the credentialSubjectIds for each credential is the same as the controller of the verificationMethod\n // This authenticates the presentation creator controls one of the credentialSubject ids.\n // NOTE: this doesn't take into account the case where the credentialSubject is no the holder. In the\n // future we can add support for other flows, but for now this is the most common use case.\n // TODO: should this be handled on a higher level? I don't really see it being handled in the jsonld lib\n // or in the did-jwt-vc lib (it seems they don't even verify the credentials itself), but we probably need some\n // more experience on the use cases before we loosen the restrictions (as it means we need to handle it on a higher layer).\n const credentialSubjectIds = credential.resolvedCredential.credentialSubjectIds\n const presentationAuthenticatesCredentialSubject = credentialSubjectIds.some(\n (subjectId) => proverVerificationMethod.controller === subjectId\n )\n\n if (credentialSubjectIds.length > 0 && !presentationAuthenticatesCredentialSubject) {\n credentialSubjectAuthentication = {\n isValid: false,\n error: new CredoError(\n 'Credential has one or more credentialSubject ids, but presentation does not authenticate credential subject'\n ),\n }\n } else {\n credentialSubjectAuthentication = {\n isValid: true,\n }\n }\n\n return {\n ...credentialResult,\n isValid: credentialResult.isValid && credentialSubjectAuthentication.isValid,\n validations: {\n ...credentialResult.validations,\n credentialSubjectAuthentication,\n },\n }\n })\n )\n\n // Deeply nested check whether all validations have passed\n validationResults.isValid = Object.values(validationResults.validations).every((v) =>\n Array.isArray(v) ? v.every((vv) => vv.isValid) : v.isValid\n )\n\n return validationResults\n } catch (error) {\n validationResults.error = error\n return validationResults\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"W3cV2JwtCredentialService.mjs","names":["W3cV2JwtCredentialService","validationResults: W3cV2VerifyCredentialResult","credential: W3cV2JwtVerifiableCredential","signatureResult: VerifyJwsResult | undefined","validationResults: W3cV2VerifyPresentationResult","presentation: W3cV2JwtVerifiablePresentation","credentialSubjectAuthentication: SingleValidationResult"],"sources":["../../../../src/modules/vc/jwt-vc/W3cV2JwtCredentialService.ts"],"sourcesContent":["import type { AgentContext } from '../../../agent/context'\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 { SingleValidationResult, W3cV2VerifyCredentialResult, W3cV2VerifyPresentationResult } from '../models'\nimport {\n extractHolderFromPresentationCredentials,\n getVerificationMethodForJwt,\n validateAndResolveVerificationMethod,\n} from '../v2-jwt-utils'\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 validationResults.validations.dataModel = {\n isValid: true,\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 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((v) => v.isValid)\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 validations: {},\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 // 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 validationResults.validations.dataModel = {\n isValid: true,\n }\n } catch (error) {\n validationResults.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 let signatureResult: VerifyJwsResult | undefined\n try {\n // Verify the JWS signature\n 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.validations.presentationSignature = {\n isValid: false,\n error: new CredoError('Invalid JWS signature on presentation'),\n }\n } else {\n validationResults.validations.presentationSignature = {\n isValid: true,\n }\n }\n } catch (error) {\n validationResults.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.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.validations.holderIsSigner = {\n isValid: true,\n }\n }\n\n // To keep things simple, we only support JWT VCs in JWT VPs for now\n const credentials = asArray(presentation.resolvedPresentation.verifiableCredential)\n\n // Verify all credentials in parallel, and await the result\n validationResults.validations.credentials = await Promise.all(\n credentials.map(async (credential) => {\n if (!(credential.envelopedCredential instanceof W3cV2JwtVerifiableCredential)) {\n return {\n isValid: false,\n error: new CredoError(\n 'Credential is not of format JWT. Presentations in JWT format can only contain credentials in JWT format.'\n ),\n validations: {},\n }\n }\n\n const credentialResult = await this.verifyCredential(agentContext, {\n credential: credential.envelopedCredential,\n })\n\n let credentialSubjectAuthentication: SingleValidationResult\n\n // Check whether any of the credentialSubjectIds for each credential is the same as the controller of the verificationMethod\n // This authenticates the presentation creator controls one of the credentialSubject ids.\n // NOTE: this doesn't take into account the case where the credentialSubject is no the holder. In the\n // future we can add support for other flows, but for now this is the most common use case.\n // TODO: should this be handled on a higher level? I don't really see it being handled in the jsonld lib\n // or in the did-jwt-vc lib (it seems they don't even verify the credentials itself), but we probably need some\n // more experience on the use cases before we loosen the restrictions (as it means we need to handle it on a higher layer).\n const credentialSubjectIds = credential.resolvedCredential.credentialSubjectIds\n const presentationAuthenticatesCredentialSubject = credentialSubjectIds.some(\n (subjectId) => proverVerificationMethod.controller === subjectId\n )\n\n if (credentialSubjectIds.length > 0 && !presentationAuthenticatesCredentialSubject) {\n credentialSubjectAuthentication = {\n isValid: false,\n error: new CredoError(\n 'Credential has one or more credentialSubject ids, but presentation does not authenticate credential subject'\n ),\n }\n } else {\n credentialSubjectAuthentication = {\n isValid: true,\n }\n }\n\n return {\n ...credentialResult,\n isValid: credentialResult.isValid && credentialSubjectAuthentication.isValid,\n validations: {\n ...credentialResult.validations,\n credentialSubjectAuthentication,\n },\n }\n })\n )\n\n // Deeply nested check whether all validations have passed\n validationResults.isValid = Object.values(validationResults.validations).every((v) =>\n Array.isArray(v) ? v.every((vv) => vv.isValid) : v.isValid\n )\n\n return validationResults\n } catch (error) {\n validationResults.error = error\n return validationResults\n }\n }\n}\n"],"mappings":"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"}
@@ -4,8 +4,8 @@ import { CredoError } from "../../../error/CredoError.mjs";
4
4
  import "../../../error/index.mjs";
5
5
  import { JsonTransformer } from "../../../utils/JsonTransformer.mjs";
6
6
  import "../../../utils/index.mjs";
7
- import { isJsonObject } from "../../../types.mjs";
8
7
  import { JwtPayload } from "../../../crypto/jose/jwt/JwtPayload.mjs";
8
+ import { isJsonObject } from "../../../types.mjs";
9
9
  import "../../../crypto/jose/jwt/index.mjs";
10
10
  import { W3cCredential } from "../models/credential/W3cCredential.mjs";
11
11
  import { w3cDate } from "../util.mjs";
@@ -4,8 +4,8 @@ import { CredoError } from "../../../error/CredoError.mjs";
4
4
  import "../../../error/index.mjs";
5
5
  import { JsonTransformer } from "../../../utils/JsonTransformer.mjs";
6
6
  import "../../../utils/index.mjs";
7
- import { isJsonObject } from "../../../types.mjs";
8
7
  import { JwtPayload } from "../../../crypto/jose/jwt/JwtPayload.mjs";
8
+ import { isJsonObject } from "../../../types.mjs";
9
9
  import "../../../crypto/jose/jwt/index.mjs";
10
10
  import { W3cPresentation } from "../models/presentation/W3cPresentation.mjs";
11
11
 
@@ -1,11 +1,11 @@
1
1
 
2
2
 
3
- import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
- import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
3
  import { asArray, mapSingleOrArray } from "../../../../utils/array.mjs";
6
4
  import { JsonTransformer } from "../../../../utils/JsonTransformer.mjs";
7
5
  import { IsInstanceOrArrayOfInstances, IsUri } from "../../../../utils/validators.mjs";
8
6
  import "../../../../utils/index.mjs";
7
+ import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
8
+ import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
9
9
  import { CREDENTIALS_CONTEXT_V1_URL } from "../../constants.mjs";
10
10
  import { IsCredentialJsonLdContext, IsCredentialType } from "../../validators.mjs";
11
11
  import { W3cCredentialSchema } from "./W3cCredentialSchema.mjs";
@@ -1,8 +1,8 @@
1
1
 
2
2
 
3
+ import { IsUri } from "../../../../utils/validators.mjs";
3
4
  import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
5
  import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
- import { IsUri } from "../../../../utils/validators.mjs";
6
6
  import { IsString } from "class-validator";
7
7
 
8
8
  //#region src/modules/vc/models/credential/W3cCredentialSchema.ts
@@ -1,8 +1,8 @@
1
1
 
2
2
 
3
+ import { IsUri } from "../../../../utils/validators.mjs";
3
4
  import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
5
  import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
- import { IsUri } from "../../../../utils/validators.mjs";
6
6
  import { IsString } from "class-validator";
7
7
 
8
8
  //#region src/modules/vc/models/credential/W3cCredentialStatus.ts
@@ -1,8 +1,8 @@
1
1
 
2
2
 
3
+ import { IsUri, isUri } from "../../../../utils/validators.mjs";
3
4
  import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
5
  import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
- import { IsUri, isUri } from "../../../../utils/validators.mjs";
6
6
  import { Transform, TransformationType, instanceToPlain, plainToInstance } from "class-transformer";
7
7
  import { ValidateBy, buildMessage, isInstance, isString } from "class-validator";
8
8
 
@@ -1,11 +1,11 @@
1
1
 
2
2
 
3
- import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
- import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
3
  import { asArray, mapSingleOrArray } from "../../../../utils/array.mjs";
6
4
  import { JsonTransformer } from "../../../../utils/JsonTransformer.mjs";
7
5
  import { IsInstanceOrArrayOfInstances, IsNever, IsStringOrInstanceOrArrayOfInstances, IsUri } from "../../../../utils/validators.mjs";
8
6
  import "../../../../utils/index.mjs";
7
+ import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
8
+ import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
9
9
  import { CREDENTIALS_CONTEXT_V2_URL } from "../../constants.mjs";
10
10
  import { IsCredentialJsonLdContext, IsCredentialType } from "../../validators.mjs";
11
11
  import { W3cV2CredentialSchema } from "./W3cV2CredentialSchema.mjs";
@@ -1,9 +1,9 @@
1
1
 
2
2
 
3
- import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
- import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
3
  import { IsUri } from "../../../../utils/validators.mjs";
6
4
  import "../../../../utils/index.mjs";
5
+ import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
6
+ import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
7
7
  import { plainToClassFromExist } from "class-transformer";
8
8
  import { IsString } from "class-validator";
9
9
 
@@ -1,9 +1,9 @@
1
1
 
2
2
 
3
- import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
- import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
3
  import { IsUri } from "../../../../utils/validators.mjs";
6
4
  import "../../../../utils/index.mjs";
5
+ import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
6
+ import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
7
7
  import { plainToClassFromExist } from "class-transformer";
8
8
  import { IsOptional, IsString } from "class-validator";
9
9
 
@@ -1,9 +1,9 @@
1
1
 
2
2
 
3
- import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
- import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
3
  import { IsUri } from "../../../../utils/validators.mjs";
6
4
  import "../../../../utils/index.mjs";
5
+ import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
6
+ import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
7
7
  import { plainToClassFromExist } from "class-transformer";
8
8
  import { IsOptional } from "class-validator";
9
9
 
@@ -1,9 +1,9 @@
1
1
 
2
2
 
3
- import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
- import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
3
  import { IsUri } from "../../../../utils/validators.mjs";
6
4
  import "../../../../utils/index.mjs";
5
+ import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
6
+ import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
7
7
  import { plainToClassFromExist } from "class-transformer";
8
8
  import { IsOptional, IsString } from "class-validator";
9
9
 
@@ -1,9 +1,9 @@
1
1
 
2
2
 
3
- import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
- import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
3
  import { IsUri, isUri } from "../../../../utils/validators.mjs";
6
4
  import "../../../../utils/index.mjs";
5
+ import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
6
+ import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
7
7
  import { Transform, TransformationType, instanceToPlain, plainToClassFromExist, plainToInstance } from "class-transformer";
8
8
  import { ValidateBy, buildMessage, isInstance, isString } from "class-validator";
9
9
 
@@ -1,8 +1,8 @@
1
1
 
2
2
 
3
+ import { IsUri, isUri } from "../../../../utils/validators.mjs";
3
4
  import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
5
  import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
- import { IsUri, isUri } from "../../../../utils/validators.mjs";
6
6
  import { Transform, TransformationType, instanceToPlain, plainToInstance } from "class-transformer";
7
7
  import { ValidateBy, buildMessage, isInstance, isString } from "class-validator";
8
8
 
@@ -1,10 +1,10 @@
1
1
 
2
2
 
3
- import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
- import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
3
  import { JsonTransformer } from "../../../../utils/JsonTransformer.mjs";
6
4
  import { IsInstanceOrArrayOfInstances, IsUri } from "../../../../utils/validators.mjs";
7
5
  import "../../../../utils/index.mjs";
6
+ import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
7
+ import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
8
8
  import { CREDENTIALS_CONTEXT_V1_URL, VERIFIABLE_PRESENTATION_TYPE } from "../../constants.mjs";
9
9
  import { IsCredentialJsonLdContext, IsVerifiablePresentationType } from "../../validators.mjs";
10
10
  import { W3cJsonLdVerifiableCredential } from "../../data-integrity/models/W3cJsonLdVerifiableCredential.mjs";
@@ -1,9 +1,9 @@
1
1
 
2
2
 
3
- import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
- import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
3
  import { IsUri, isUri } from "../../../../utils/validators.mjs";
6
4
  import "../../../../utils/index.mjs";
5
+ import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
6
+ import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
7
7
  import { Transform, TransformationType, instanceToPlain, plainToClassFromExist, plainToInstance } from "class-transformer";
8
8
  import { ValidateBy, buildMessage, isInstance, isString } from "class-validator";
9
9
 
@@ -1,11 +1,11 @@
1
1
 
2
2
 
3
- import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
4
- import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
5
3
  import { mapSingleOrArray } from "../../../../utils/array.mjs";
6
4
  import { JsonTransformer } from "../../../../utils/JsonTransformer.mjs";
7
5
  import { IsInstanceOrArrayOfInstances, IsNever, IsUri } from "../../../../utils/validators.mjs";
8
6
  import "../../../../utils/index.mjs";
7
+ import { __decorateMetadata } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
8
+ import { __decorate } from "../../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
9
9
  import { CREDENTIALS_CONTEXT_V2_URL, VERIFIABLE_PRESENTATION_TYPE } from "../../constants.mjs";
10
10
  import { IsCredentialJsonLdContext, IsVerifiablePresentationType } from "../../validators.mjs";
11
11
  import { W3cV2EnvelopedVerifiableCredential, W3cV2EnvelopedVerifiableCredentialTransformer } from "../credential/W3cV2EnvelopedVerifiableCredential.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"W3cV2SdJwtCredentialService.d.mts","names":[],"sources":["../../../../src/modules/vc/sd-jwt-vc/W3cV2SdJwtCredentialService.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;AAqDA;AAMkB,cALL,2BAAA,CAKK;EACL;;;EA+CK,cAAA,CAAA,YAAA,EAhDA,YAgDA,EAAA,OAAA,EA/CL,+BA+CK,CAAA,EA9Cb,OA8Ca,CA9CL,8BA8CK,CAAA;EACL;;;;;;EAgGR,gBAAA,CAAA,YAAA,EAjGa,YAiGb,EAAA,OAAA,EAhGQ,iCAgGR,CAAA,EA/FA,OA+FA,CA/FQ,2BA+FR,CAAA;EA2Ca;;;;;;EA4JL,gBAAA,CAAA,YAAA,EAzMK,YAyML,EAAA,OAAA,EAxMA,iCAwMA,CAAA,EAvMR,OAuMQ,CAvMA,gCAuMA,CAAA;EAAR;;;;;;mCA5Ja,uBACL,sCACR,QAAQ;wBAwJK,uBACL,6BACR,QAAQ"}
1
+ {"version":3,"file":"W3cV2SdJwtCredentialService.d.mts","names":[],"sources":["../../../../src/modules/vc/sd-jwt-vc/W3cV2SdJwtCredentialService.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;AAqDA;AAMkB,cALL,2BAAA,CAKK;EACL;;;EA+CK,cAAA,CAAA,YAAA,EAhDA,YAgDA,EAAA,OAAA,EA/CL,+BA+CK,CAAA,EA9Cb,OA8Ca,CA9CL,8BA8CK,CAAA;EACL;;;;;;EAoGR,gBAAA,CAAA,YAAA,EArGa,YAqGb,EAAA,OAAA,EApGQ,iCAoGR,CAAA,EAnGA,OAmGA,CAnGQ,2BAmGR,CAAA;EA2Ca;;;;;;EAgKL,gBAAA,CAAA,YAAA,EA7MK,YA6ML,EAAA,OAAA,EA5MA,iCA4MA,CAAA,EA3MR,OA2MQ,CA3MA,gCA2MA,CAAA;EAAR;;;;;;mCAhKa,uBACL,sCACR,QAAQ;wBA4JK,uBACL,6BACR,QAAQ"}
@@ -2,17 +2,17 @@
2
2
 
3
3
  import { CredoError } from "../../../error/CredoError.mjs";
4
4
  import "../../../error/index.mjs";
5
- import { injectable } from "../../../plugins/index.mjs";
6
- import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
7
5
  import { asArray } from "../../../utils/array.mjs";
8
6
  import { TypedArrayEncoder } from "../../../utils/TypedArrayEncoder.mjs";
9
7
  import { MessageValidator } from "../../../utils/MessageValidator.mjs";
10
8
  import { JsonTransformer } from "../../../utils/JsonTransformer.mjs";
11
9
  import { nowInSeconds } from "../../../utils/timestamp.mjs";
12
10
  import "../../../utils/index.mjs";
11
+ import { JwtPayload } from "../../../crypto/jose/jwt/JwtPayload.mjs";
12
+ import { injectable } from "../../../plugins/index.mjs";
13
+ import { __decorate } from "../../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
13
14
  import { KeyManagementApi } from "../../kms/KeyManagementApi.mjs";
14
15
  import "../../kms/index.mjs";
15
- import { JwtPayload } from "../../../crypto/jose/jwt/JwtPayload.mjs";
16
16
  import { getPublicJwkFromVerificationMethod } from "../../dids/domain/key-type/keyDidMapping.mjs";
17
17
  import "../../../crypto/index.mjs";
18
18
  import { sdJwtVcHasher } from "./W3cV2SdJwt.mjs";
@@ -77,7 +77,7 @@ let W3cV2SdJwtCredentialService = class W3cV2SdJwtCredentialService$1 {
77
77
  try {
78
78
  if (options.credential instanceof W3cV2SdJwtVerifiableCredential) options.credential.validate();
79
79
  credential = options.credential instanceof W3cV2SdJwtVerifiableCredential ? options.credential : W3cV2SdJwtVerifiableCredential.fromCompact(options.credential);
80
- JwtPayload.fromJson(credential.sdJwt.payload).validate();
80
+ JwtPayload.fromJson(credential.sdJwt.payload).validate({ skewSeconds: agentContext.config.validitySkewSeconds });
81
81
  validationResults.validations.dataModel = { isValid: true };
82
82
  } catch (error) {
83
83
  validationResults.validations.dataModel = {
@@ -95,7 +95,7 @@ let W3cV2SdJwtCredentialService = class W3cV2SdJwtCredentialService$1 {
95
95
  kbVerifier: holder ? getSdJwtVerifier(agentContext, holder.publicJwk) : void 0
96
96
  });
97
97
  try {
98
- await sdJwt.verify(credential.encoded);
98
+ await sdJwt.verify(credential.encoded, { skewSeconds: agentContext.config.validitySkewSeconds });
99
99
  validationResults.validations.signature = { isValid: true };
100
100
  } catch (error) {
101
101
  validationResults.validations.signature = {
@@ -159,7 +159,7 @@ let W3cV2SdJwtCredentialService = class W3cV2SdJwtCredentialService$1 {
159
159
  try {
160
160
  if (options.presentation instanceof W3cV2SdJwtVerifiablePresentation) MessageValidator.validateSync(options.presentation.resolvedPresentation);
161
161
  presentation = options.presentation instanceof W3cV2SdJwtVerifiablePresentation ? options.presentation : W3cV2SdJwtVerifiablePresentation.fromCompact(options.presentation);
162
- JwtPayload.fromJson(presentation.sdJwt.payload).validate();
162
+ JwtPayload.fromJson(presentation.sdJwt.payload).validate({ skewSeconds: agentContext.config.validitySkewSeconds });
163
163
  validationResults.validations.dataModel = { isValid: true };
164
164
  } catch (error) {
165
165
  validationResults.validations.dataModel = {
@@ -177,7 +177,7 @@ let W3cV2SdJwtCredentialService = class W3cV2SdJwtCredentialService$1 {
177
177
  kbVerifier: holder ? getSdJwtVerifier(agentContext, holder.publicJwk) : void 0
178
178
  });
179
179
  try {
180
- await sdjwt.verify(presentation.encoded);
180
+ await sdjwt.verify(presentation.encoded, { skewSeconds: agentContext.config.validitySkewSeconds });
181
181
  validationResults.validations.presentationSignature = { isValid: true };
182
182
  } catch (error) {
183
183
  validationResults.validations.presentationSignature = {