@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 • 26.9 kB
Source Map (JSON)
{"version":3,"file":"W3cV2SdJwtCredentialService.mjs","names":[],"sources":["../../../../src/modules/vc/sd-jwt-vc/W3cV2SdJwtCredentialService.ts"],"sourcesContent":["import { type DisclosureFrame, type PresentationFrame, type SDJWTConfig, SDJwtInstance } from '@sd-jwt/core'\nimport type { AgentContext } from '../../../agent/context'\nimport { TrustedIssuerContext } from '../../../agent/TrustedIssuerContext'\nimport { JwtPayload } from '../../../crypto'\nimport { CredoError } from '../../../error'\nimport { injectable } from '../../../plugins'\nimport type { JsonObject } from '../../../types'\nimport { asArray, JsonTransformer, MessageValidator, nowInSeconds, TypedArrayEncoder } from '../../../utils'\nimport { getPublicJwkFromVerificationMethod } from '../../dids/domain/key-type/keyDidMapping'\nimport { KeyManagementApi } from '../../kms'\nimport type { IDisclosureFrame } from '../../sd-jwt-vc'\nimport { applyDisclosuresForPaths, applyDisclosuresForPayload, type ClaimPath } from '../../sd-jwt-vc/disclosureFrame'\nimport {\n extractKeyFromHolderBinding,\n getSdJwtHashingAlgorithm,\n getSdJwtSigner,\n getSdJwtVerifier,\n parseHolderBindingFromCredential,\n setJwkAlgFromJwtHeader,\n} from '../../sd-jwt-vc/utils'\nimport type {\n W3cV2JsonCredential,\n W3cV2JsonPresentation,\n W3cV2VerifyCredentialResult,\n W3cV2VerifyPresentationResult,\n} 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 W3cV2SdJwtSignCredentialOptions,\n W3cV2SdJwtSignPresentationOptions,\n W3cV2SdJwtVcPresentOptions,\n W3cV2SdJwtVerifyCredentialOptions,\n W3cV2SdJwtVerifyPresentationOptions,\n} from '../W3cV2CredentialServiceOptions'\nimport { validateW3cV2SdJwtDisclosureFrame } from './disclosureFrame'\nimport { sdJwtVcHasher } from './W3cV2SdJwt'\nimport { W3cV2SdJwtVerifiableCredential } from './W3cV2SdJwtVerifiableCredential'\nimport { W3cV2SdJwtVerifiablePresentation } from './W3cV2SdJwtVerifiablePresentation'\n\n/**\n * Supports signing and verifying W3C Verifiable Credentials and Presentations\n * secured with Selective Disclosure JSON Web Tokens (SD-JWT).\n *\n * @see https://www.w3.org/TR/vc-data-model/\n * @see https://www.w3.org/TR/vc-jose-cose/#with-sd-jwt\n */\n@injectable()\nexport class W3cV2SdJwtCredentialService {\n /**\n * Signs a credential\n */\n public async signCredential(\n agentContext: AgentContext,\n options: W3cV2SdJwtSignCredentialOptions\n ): Promise<W3cV2SdJwtVerifiableCredential> {\n // Validate the instance\n MessageValidator.validateSync(options.credential)\n\n // The JWT payload is simply the credential\n const payload = JsonTransformer.toJSON(options.credential) as W3cV2JsonCredential\n\n // Add iat and cnf to the payload\n payload.iat = nowInSeconds()\n payload.cnf = options.holder ? (await extractKeyFromHolderBinding(agentContext, options.holder)).cnf : undefined\n\n // Validate and resolve the verification method\n const publicJwk = await validateAndResolveVerificationMethod(agentContext, options.verificationMethod, [\n 'assertionMethod',\n ])\n\n // Validate the disclosure frame\n const disclosureFrame = options.disclosureFrame as DisclosureFrame<W3cV2JsonCredential> | undefined\n this.validateDisclosureFrame(disclosureFrame)\n\n publicJwk.alg = options.alg\n\n const sdJwt = new SDJwtInstance({\n ...this.getBaseSdJwtConfig(agentContext),\n signer: getSdJwtSigner(agentContext, publicJwk),\n hashAlg: getSdJwtHashingAlgorithm(options.hashingAlgorithm),\n signAlg: options.alg,\n })\n\n // Sign SD-JWT\n const compact = await sdJwt.issue<W3cV2JsonCredential>(payload, disclosureFrame, {\n header: {\n typ: 'vc+sd-jwt',\n alg: options.alg,\n kid: options.verificationMethod,\n },\n })\n\n return W3cV2SdJwtVerifiableCredential.fromCompact(compact)\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: W3cV2SdJwtVerifyCredentialOptions\n ): Promise<W3cV2VerifyCredentialResult> {\n const validationResults: W3cV2VerifyCredentialResult = {\n isValid: false,\n validations: {},\n }\n\n const sdJwt = new SDJwtInstance({\n ...this.getBaseSdJwtConfig(agentContext),\n })\n\n try {\n let credential: W3cV2SdJwtVerifiableCredential\n try {\n // If instance is provided as input, we want to validate the credential\n // Otherwise, it is done by fromCompact below\n if (options.credential instanceof W3cV2SdJwtVerifiableCredential) {\n options.credential.validate()\n }\n\n credential =\n options.credential instanceof W3cV2SdJwtVerifiableCredential\n ? options.credential\n : W3cV2SdJwtVerifiableCredential.fromCompact(options.credential)\n\n // Validate JWT payload\n JwtPayload.fromJson(credential.sdJwt.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: 'SD-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 const holderBinding = parseHolderBindingFromCredential(credential.sdJwt.prettyClaims)\n const holder = holderBinding ? await extractKeyFromHolderBinding(agentContext, holderBinding) : undefined\n\n setJwkAlgFromJwtHeader(issuerPublicKey, credential.sdJwt.header.alg)\n if (holder && credential.sdJwt.kbJwt) {\n setJwkAlgFromJwtHeader(holder.publicJwk, credential.sdJwt.kbJwt.header?.alg)\n }\n\n sdJwt.config({\n verifier: getSdJwtVerifier(agentContext, issuerPublicKey),\n kbVerifier: holder ? getSdJwtVerifier(agentContext, holder.publicJwk) : undefined,\n })\n\n try {\n await sdJwt.verify(credential.encoded, {\n skewSeconds: agentContext.config.validitySkewSeconds,\n })\n\n validationResults.validations.signature = {\n isValid: true,\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 validationResults.isValid = Object.values(validationResults.validations).every(\n (validation) => validation?.isValid === true\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: W3cV2SdJwtSignPresentationOptions\n ): Promise<W3cV2SdJwtVerifiablePresentation> {\n // Validate the instance\n MessageValidator.validateSync(options.presentation)\n\n // The JWT payload is simply the presentation\n const payload = JsonTransformer.toJSON(options.presentation) as W3cV2JsonPresentation\n\n // Add the nonce and aud to the payload\n payload.nonce = options.challenge\n payload.aud = options.domain\n\n const holder = await extractHolderFromPresentationCredentials(agentContext, options.presentation)\n\n holder.publicJwk.alg = holder.alg\n\n const sdJwt = new SDJwtInstance({\n ...this.getBaseSdJwtConfig(agentContext),\n signer: getSdJwtSigner(agentContext, holder.publicJwk),\n hashAlg: getSdJwtHashingAlgorithm(options.hashingAlgorithm),\n signAlg: holder.alg,\n })\n\n // Validate the disclosure frame\n const disclosureFrame = options.disclosureFrame as DisclosureFrame<W3cV2JsonPresentation> | undefined\n this.validateDisclosureFrame(disclosureFrame)\n\n // Sign SD-JWT\n const compact = await sdJwt.issue<W3cV2JsonPresentation>(payload, disclosureFrame, {\n header: {\n typ: 'vp+sd-jwt',\n alg: holder.alg,\n kid: holder?.cnf?.kid,\n },\n })\n\n return W3cV2SdJwtVerifiablePresentation.fromCompact(compact)\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: W3cV2SdJwtVerifyPresentationOptions\n ): Promise<W3cV2VerifyPresentationResult> {\n const validationResults: W3cV2VerifyPresentationResult = {\n isValid: false,\n presentation: {\n isValid: false,\n validations: {},\n },\n credentialEntries: [],\n }\n\n const sdjwt = new SDJwtInstance({\n ...this.getBaseSdJwtConfig(agentContext),\n })\n\n try {\n let presentation: W3cV2SdJwtVerifiablePresentation\n try {\n // If instance is provided as input, we want to validate the presentation\n if (options.presentation instanceof W3cV2SdJwtVerifiablePresentation) {\n options.presentation.validate()\n }\n\n presentation =\n options.presentation instanceof W3cV2SdJwtVerifiablePresentation\n ? options.presentation\n : W3cV2SdJwtVerifiablePresentation.fromCompact(options.presentation)\n\n // Validate JWT payload\n JwtPayload.fromJson(presentation.sdJwt.payload).validate({\n skewSeconds: agentContext.config.validitySkewSeconds,\n })\n\n this.logPresentationShouldWarnings(agentContext, presentation)\n\n // VC-JOSE-COSE: understood claims MUST be evaluated per verifier policy\n // https://www.w3.org/TR/vc-jose-cose/#validation-algorithm\n if (options.challenge !== presentation.sdJwt.prettyClaims.nonce) {\n throw new CredoError(`JWT payload 'nonce' does not match challenge '${options.challenge}'`)\n }\n\n const audArray = asArray(presentation.sdJwt.prettyClaims.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 const holderBinding = parseHolderBindingFromCredential(presentation.sdJwt.prettyClaims)\n const holder = holderBinding ? await extractKeyFromHolderBinding(agentContext, holderBinding) : undefined\n\n setJwkAlgFromJwtHeader(proverPublicKey, presentation.sdJwt.header.alg)\n if (holder && presentation.sdJwt.kbJwt) {\n setJwkAlgFromJwtHeader(holder.publicJwk, presentation.sdJwt.kbJwt.header?.alg)\n }\n\n sdjwt.config({\n verifier: getSdJwtVerifier(agentContext, proverPublicKey),\n kbVerifier: holder ? getSdJwtVerifier(agentContext, holder.publicJwk) : undefined,\n })\n\n try {\n await sdjwt.verify(presentation.encoded, {\n skewSeconds: agentContext.config.validitySkewSeconds,\n })\n\n validationResults.presentation.validations.presentationSignature = {\n isValid: true,\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 public async present(\n agentContext: AgentContext,\n options: W3cV2SdJwtVcPresentOptions\n ): Promise<W3cV2SdJwtVerifiableCredential> {\n const originalCompact =\n options.credential instanceof W3cV2SdJwtVerifiableCredential ? options.credential.encoded : options.credential\n\n const presentationFrame = options.presentationFrame as PresentationFrame<W3cV2JsonCredential>\n\n const sdjwt = new SDJwtInstance(this.getBaseSdJwtConfig(agentContext))\n const disclosedCompact = await sdjwt.present(originalCompact, presentationFrame)\n\n return W3cV2SdJwtVerifiableCredential.fromCompact(disclosedCompact)\n }\n\n /**\n * @deprecated use `applyDisclosuresForPaths` instead\n */\n public applyDisclosuresForPayload(\n compactSdJwtVc: string,\n requestedPayload: JsonObject\n ): W3cV2SdJwtVerifiableCredential {\n const sdJwt = applyDisclosuresForPayload(compactSdJwtVc, requestedPayload)\n return W3cV2SdJwtVerifiableCredential.fromCompact(sdJwt)\n }\n\n public applyDisclosuresForPaths(compactSdJwtVc: string, disclosedPaths: ClaimPath[]): W3cV2SdJwtVerifiableCredential {\n const { compact } = applyDisclosuresForPaths(compactSdJwtVc, disclosedPaths)\n return W3cV2SdJwtVerifiableCredential.fromCompact(compact)\n }\n\n private validateDisclosureFrame(disclosureFrame?: DisclosureFrame<W3cV2JsonCredential | W3cV2JsonPresentation>) {\n validateW3cV2SdJwtDisclosureFrame(disclosureFrame as IDisclosureFrame | undefined)\n }\n\n private getBaseSdJwtConfig(agentContext: AgentContext): SDJWTConfig {\n const kms = agentContext.resolve(KeyManagementApi)\n\n return {\n hasher: sdJwtVcHasher,\n saltGenerator: (length) => TypedArrayEncoder.toBase64Url(kms.randomBytes({ length })).slice(0, length),\n }\n }\n\n private logCredentialShouldWarnings(agentContext: AgentContext, credential: W3cV2SdJwtVerifiableCredential) {\n const payload = credential.sdJwt.prettyClaims\n const headerIss = credential.sdJwt.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+sd-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+sd-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+sd-jwt',\n sub: payload.sub,\n credentialSubjectIds: credential.resolvedCredential.credentialSubjectIds,\n }\n )\n }\n }\n\n private logPresentationShouldWarnings(agentContext: AgentContext, presentation: W3cV2SdJwtVerifiablePresentation) {\n const payload = presentation.sdJwt.prettyClaims\n const headerIss = presentation.sdJwt.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+sd-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+sd-jwt',\n jti: payload.jti,\n presentationId: presentation.resolvedPresentation.id,\n })\n }\n }\n}\n"],"mappings":"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"}