UNPKG

@credo-ts/core

Version:

<p align="center"> <br /> <img alt="Credo Logo" src="https://github.com/openwallet-foundation/credo-ts/blob/c7886cb8377ceb8ee4efe8d264211e561a75072d/images/credo-logo.png" height="250px" /> </p> <h1 align="center"><b>Credo - Core</b></h1

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