@sphereon/ssi-sdk.sd-jwt 0.32.1-next.54 → 0.33.1-feature.vcdm2.4

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 (43) hide show
  1. package/dist/action-handler.d.ts.map +1 -1
  2. package/dist/action-handler.js +246 -247
  3. package/dist/action-handler.js.map +1 -1
  4. package/dist/defaultCallbacks.d.ts +2 -2
  5. package/dist/defaultCallbacks.d.ts.map +1 -1
  6. package/dist/defaultCallbacks.js +12 -50
  7. package/dist/defaultCallbacks.js.map +1 -1
  8. package/dist/index.js +3 -21
  9. package/dist/index.js.map +1 -1
  10. package/dist/trustAnchors.js +2 -5
  11. package/dist/trustAnchors.js.map +1 -1
  12. package/dist/types.d.ts +4 -4
  13. package/dist/types.d.ts.map +1 -1
  14. package/dist/types.js +4 -8
  15. package/dist/types.js.map +1 -1
  16. package/dist/utils.d.ts +15 -2
  17. package/dist/utils.d.ts.map +1 -1
  18. package/dist/utils.js +32 -52
  19. package/dist/utils.js.map +1 -1
  20. package/package.json +20 -20
  21. package/src/__tests__/resources/BoardingPassCredential-vct.json +196 -0
  22. package/src/__tests__/resources/LoyaltyProgram Account VC Schema V0.1 sd-jwt-schema.json +97 -0
  23. package/src/__tests__/resources/LoyaltyProgramAccountCredential-vct.json +126 -0
  24. package/src/__tests__/resources/boarding Pass VC Schema V1.0 sd-jwt.json +156 -0
  25. package/src/__tests__/resources/boardingpass-logo.png +0 -0
  26. package/src/__tests__/resources/boardingpass.svg +1 -0
  27. package/src/__tests__/resources/e-passport.svg +1 -0
  28. package/src/__tests__/resources/ePassport VC Schema V1.0.sd-jwt.json +226 -0
  29. package/src/__tests__/resources/ePassportCredential-vct.json +226 -0
  30. package/src/__tests__/resources/epassport-logo.png +0 -0
  31. package/src/__tests__/resources/loyaltyprogramaccount-icon.png +0 -0
  32. package/src/__tests__/resources/loyaltyprogramaccount.png +0 -0
  33. package/src/__tests__/resources/loyaltyprogramaccount.svg +1 -0
  34. package/src/__tests__/resources/travel-agency VC Employee v0.1 sd-jwt-schema.json +115 -0
  35. package/src/__tests__/resources/travel-agency-EmployeeAgencyCredential-vct.json +146 -0
  36. package/src/__tests__/resources/travel-agency-vc-employee-logo.png +0 -0
  37. package/src/__tests__/resources/travel-agency-vc-employee.svg +1 -0
  38. package/src/__tests__/sd-jwt-integrity.test.ts +100 -0
  39. package/src/__tests__/sd-jwt.test.ts +4 -4
  40. package/src/action-handler.ts +51 -18
  41. package/src/defaultCallbacks.ts +5 -4
  42. package/src/types.ts +4 -4
  43. package/src/utils.ts +48 -4
@@ -1 +1 @@
1
- {"version":3,"file":"action-handler.d.ts","sourceRoot":"","sources":["../src/action-handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAkB,MAAM,mBAAmB,CAAA;AACnE,OAAO,EAA8D,MAAM,EAAY,MAAM,eAAe,CAAA;AAE5G,OAAO,EAAE,kCAAkC,EAAE,MAAM,kCAAkC,CAAA;AACrF,OAAO,EAAO,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAU3C,OAAO,EAEL,oCAAoC,EAGpC,4BAA4B,EAC5B,8BAA8B,EAC9B,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,4BAA4B,EAC5B,8BAA8B,EAC9B,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EAEnB,WAAW,EACX,aAAa,EACd,MAAM,SAAS,CAAA;AAIhB;;;GAGG;AACH,qBAAa,WAAY,YAAW,YAAY;IAE9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IAC5C,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAqB;IAC/D,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,cAAc,CAAC,CAAQ;gBAG7B,yBAAyB,CAAC,EAAE,mBAAmB,GAAG;QAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAChC,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,EACD,iBAAiB,CAAC,EAAE,MAAM,EAAE;IAoB9B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAM7B;YAEa,sBAAsB;IAiBpC;;;;;OAKG;IACG,aAAa,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAwBvG;;;;;OAKG;IACG,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC;IA8CtF;;;;;OAKG;IACG,uBAAuB,CAAC,IAAI,EAAE,4BAA4B,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,8BAA8B,CAAC;IA8BrI;;;;;OAKG;IACG,aAAa,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IASvG;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ;IAOhB;;;;;;;OAOG;IACG,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAC,aAAa,CAAC,EAAE,kCAAkC,CAAA;KAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAgE/K;;;;;OAKG;IACG,uBAAuB,CAAC,IAAI,EAAE,4BAA4B,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAcrI;;;;;OAKG;IACG,gCAAgC,CAAC,IAAI,EAAE,oCAAoC,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAiBzI,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,uBAAuB;CAQhC"}
1
+ {"version":3,"file":"action-handler.d.ts","sourceRoot":"","sources":["../src/action-handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAkB,MAAM,mBAAmB,CAAA;AACnE,OAAO,EAAsE,MAAM,EAAY,MAAM,eAAe,CAAA;AAEpH,OAAO,EAAE,kCAAkC,EAAE,MAAM,kCAAkC,CAAA;AACrF,OAAO,EAAmB,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAM3C,OAAO,EAEL,oCAAoC,EAGpC,4BAA4B,EAC5B,8BAA8B,EAC9B,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,YAAY,EACZ,4BAA4B,EAC5B,8BAA8B,EAC9B,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EAEnB,WAAW,EACX,aAAa,EACd,MAAM,SAAS,CAAA;AAIhB;;;GAGG;AACH,qBAAa,WAAY,YAAW,YAAY;IAE9C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAU;IAC5C,OAAO,CAAC,QAAQ,CAAC,yBAAyB,CAAqB;IAC/D,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,cAAc,CAAC,CAAQ;gBAG7B,yBAAyB,CAAC,EAAE,mBAAmB,GAAG;QAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAChC,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,EACD,iBAAiB,CAAC,EAAE,MAAM,EAAE;IAoB9B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAM7B;YAEa,sBAAsB;IAiBpC;;;;;OAKG;IACG,aAAa,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAwBvG;;;;;OAKG;IACG,UAAU,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,aAAa,CAAC;IA8CtF;;;;;OAKG;IACG,uBAAuB,CAAC,IAAI,EAAE,4BAA4B,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,8BAA8B,CAAC;IA8BrI;;;;;OAKG;IACG,aAAa,CAAC,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IASvG;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ;IAOhB;;;;;;;OAOG;IACG,MAAM,CACV,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,kCAAkC,CAAA;KAAE,GAC5D,OAAO,CAAC,OAAO,CAAC;IAgEnB;;;;;OAKG;IACG,uBAAuB,CAAC,IAAI,EAAE,4BAA4B,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,8BAA8B,CAAC;IAcrI;;;;;OAKG;IACG,gCAAgC,CAAC,IAAI,EAAE,oCAAoC,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAiDzI,OAAO,CAAC,uBAAuB;IAQ/B,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,uBAAuB;CAOhC"}
@@ -1,73 +1,60 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.SDJwtPlugin = void 0;
16
- const core_1 = require("@sd-jwt/core");
17
- const sd_jwt_vc_1 = require("@sd-jwt/sd-jwt-vc");
18
- const ssi_sdk_ext_key_utils_1 = require("@sphereon/ssi-sdk-ext.key-utils");
19
- const utils_1 = require("@veramo/utils");
20
- const debug_1 = __importDefault(require("debug"));
21
- const defaultCallbacks_1 = require("./defaultCallbacks");
22
- const trustAnchors_1 = require("./trustAnchors");
23
- const utils_2 = require("./utils");
24
- const debug = (0, debug_1.default)('@sphereon/ssi-sdk.sd-jwt');
1
+ import { SDJwt } from '@sd-jwt/core';
2
+ import { SDJwtVcInstance } from '@sd-jwt/sd-jwt-vc';
3
+ import { calculateJwkThumbprint, signatureAlgorithmFromKey } from '@sphereon/ssi-sdk-ext.key-utils';
4
+ import { decodeBase64url } from '@veramo/utils';
5
+ import Debug from 'debug';
6
+ import { defaultGenerateDigest, defaultGenerateSalt, defaultVerifySignature } from './defaultCallbacks';
7
+ import { funkeTestCA, sphereonCA } from './trustAnchors';
8
+ import { assertValidTypeMetadata, fetchUrlWithErrorHandling, validateIntegrity } from './utils';
9
+ const debug = Debug('@sphereon/ssi-sdk.sd-jwt');
25
10
  /**
26
11
  * @beta
27
12
  * SD-JWT plugin
28
13
  */
29
- class SDJwtPlugin {
14
+ export class SDJwtPlugin {
15
+ // @ts-ignore
16
+ trustAnchorsInPEM;
17
+ registeredImplementations;
18
+ _signers;
19
+ _defaultSigner;
30
20
  constructor(registeredImplementations, trustAnchorsInPEM) {
31
- var _a;
32
- // map the methods your plugin is declaring to their implementation
33
- this.methods = {
34
- createSdJwtVc: this.createSdJwtVc.bind(this),
35
- createSdJwtPresentation: this.createSdJwtPresentation.bind(this),
36
- verifySdJwtVc: this.verifySdJwtVc.bind(this),
37
- verifySdJwtPresentation: this.verifySdJwtPresentation.bind(this),
38
- fetchSdJwtTypeMetadataFromVctUrl: this.fetchSdJwtTypeMetadataFromVctUrl.bind(this),
39
- };
40
- this.trustAnchorsInPEM = trustAnchorsInPEM !== null && trustAnchorsInPEM !== void 0 ? trustAnchorsInPEM : [];
21
+ this.trustAnchorsInPEM = trustAnchorsInPEM ?? [];
41
22
  if (!registeredImplementations) {
42
23
  registeredImplementations = {};
43
24
  }
44
- if (typeof (registeredImplementations === null || registeredImplementations === void 0 ? void 0 : registeredImplementations.hasher) !== 'function') {
45
- registeredImplementations.hasher = defaultCallbacks_1.defaultGenerateDigest;
25
+ if (typeof registeredImplementations?.hasher !== 'function') {
26
+ registeredImplementations.hasher = defaultGenerateDigest;
46
27
  }
47
- if (typeof (registeredImplementations === null || registeredImplementations === void 0 ? void 0 : registeredImplementations.saltGenerator) !== 'function') {
48
- registeredImplementations.saltGenerator = defaultCallbacks_1.defaultGenerateSalt;
28
+ if (typeof registeredImplementations?.saltGenerator !== 'function') {
29
+ registeredImplementations.saltGenerator = defaultGenerateSalt;
49
30
  }
50
31
  this.registeredImplementations = registeredImplementations;
51
- this._signers = (_a = registeredImplementations === null || registeredImplementations === void 0 ? void 0 : registeredImplementations.signers) !== null && _a !== void 0 ? _a : {};
52
- this._defaultSigner = registeredImplementations === null || registeredImplementations === void 0 ? void 0 : registeredImplementations.defaultSigner;
32
+ this._signers = registeredImplementations?.signers ?? {};
33
+ this._defaultSigner = registeredImplementations?.defaultSigner;
53
34
  // Verify signature default is used below in the methods if not provided here, as it needs the context of the agent
54
35
  }
55
- getSignerForIdentifier(args, context) {
56
- return __awaiter(this, void 0, void 0, function* () {
57
- const { identifier, resolution } = args;
58
- if (Object.keys(this._signers).includes(identifier) && typeof this._signers[identifier] === 'function') {
59
- return { signer: this._signers[identifier] };
60
- }
61
- else if (typeof this._defaultSigner === 'function') {
62
- return { signer: this._defaultSigner };
63
- }
64
- const signingKey = yield this.getSignKey({ identifier, vmRelationship: 'assertionMethod', resolution }, context);
65
- const { key, alg } = signingKey;
66
- const signer = (data) => __awaiter(this, void 0, void 0, function* () {
67
- return context.agent.keyManagerSign({ keyRef: key.kmsKeyRef, data });
68
- });
69
- return { signer, alg, signingKey };
70
- });
36
+ // map the methods your plugin is declaring to their implementation
37
+ methods = {
38
+ createSdJwtVc: this.createSdJwtVc.bind(this),
39
+ createSdJwtPresentation: this.createSdJwtPresentation.bind(this),
40
+ verifySdJwtVc: this.verifySdJwtVc.bind(this),
41
+ verifySdJwtPresentation: this.verifySdJwtPresentation.bind(this),
42
+ fetchSdJwtTypeMetadataFromVctUrl: this.fetchSdJwtTypeMetadataFromVctUrl.bind(this),
43
+ };
44
+ async getSignerForIdentifier(args, context) {
45
+ const { identifier, resolution } = args;
46
+ if (Object.keys(this._signers).includes(identifier) && typeof this._signers[identifier] === 'function') {
47
+ return { signer: this._signers[identifier] };
48
+ }
49
+ else if (typeof this._defaultSigner === 'function') {
50
+ return { signer: this._defaultSigner };
51
+ }
52
+ const signingKey = await this.getSignKey({ identifier, vmRelationship: 'assertionMethod', resolution }, context);
53
+ const { key, alg } = signingKey;
54
+ const signer = async (data) => {
55
+ return context.agent.keyManagerSign({ keyRef: key.kmsKeyRef, data });
56
+ };
57
+ return { signer, alg, signingKey };
71
58
  }
72
59
  /**
73
60
  * Create a signed SD-JWT credential.
@@ -75,25 +62,26 @@ class SDJwtPlugin {
75
62
  * @param context - This reserved param is automatically added and handled by the framework, *do not override*
76
63
  * @returns A signed SD-JWT credential.
77
64
  */
78
- createSdJwtVc(args, context) {
79
- return __awaiter(this, void 0, void 0, function* () {
80
- const issuer = args.credentialPayload.iss;
81
- if (!issuer) {
82
- throw new Error('credential.issuer must not be empty');
83
- }
84
- const { alg, signer, signingKey } = yield this.getSignerForIdentifier({ identifier: issuer, resolution: args.resolution }, context);
85
- const sdjwt = new sd_jwt_vc_1.SDJwtVcInstance({
86
- signer,
87
- hasher: this.registeredImplementations.hasher,
88
- saltGenerator: this.registeredImplementations.saltGenerator,
89
- signAlg: alg !== null && alg !== void 0 ? alg : 'ES256',
90
- hashAlg: 'SHA-256',
91
- });
92
- const credential = yield sdjwt.issue(args.credentialPayload, args.disclosureFrame, {
93
- header: Object.assign(Object.assign({}, ((signingKey === null || signingKey === void 0 ? void 0 : signingKey.key.kid) !== undefined && { kid: signingKey.key.kid })), ((signingKey === null || signingKey === void 0 ? void 0 : signingKey.key.x5c) !== undefined && { x5c: signingKey.key.x5c })),
94
- });
95
- return { credential };
65
+ async createSdJwtVc(args, context) {
66
+ const issuer = args.credentialPayload.iss;
67
+ if (!issuer) {
68
+ throw new Error('credential.issuer must not be empty');
69
+ }
70
+ const { alg, signer, signingKey } = await this.getSignerForIdentifier({ identifier: issuer, resolution: args.resolution }, context);
71
+ const sdjwt = new SDJwtVcInstance({
72
+ signer,
73
+ hasher: this.registeredImplementations.hasher,
74
+ saltGenerator: this.registeredImplementations.saltGenerator,
75
+ signAlg: alg ?? 'ES256',
76
+ hashAlg: 'sha-256',
96
77
  });
78
+ const credential = await sdjwt.issue(args.credentialPayload, args.disclosureFrame, {
79
+ header: {
80
+ ...(signingKey?.key.kid !== undefined && { kid: signingKey.key.kid }),
81
+ ...(signingKey?.key.x5c !== undefined && { x5c: signingKey.key.x5c }),
82
+ },
83
+ });
84
+ return { credential };
97
85
  }
98
86
  /**
99
87
  * Get the key to sign the SD-JWT
@@ -101,58 +89,55 @@ class SDJwtPlugin {
101
89
  * @param context - agent instance
102
90
  * @returns the key to sign the SD-JWT
103
91
  */
104
- getSignKey(args, context) {
105
- return __awaiter(this, void 0, void 0, function* () {
106
- var _a, _b, _c, _d;
107
- // TODO Using identifierManagedGetByDid now (new managed identifier resolution). Evaluate of we need to implement more identifier types here
108
- const { identifier, resolution } = Object.assign({}, args);
109
- if (resolution) {
110
- const key = resolution.key;
111
- const alg = yield (0, ssi_sdk_ext_key_utils_1.signatureAlgorithmFromKey)({ key });
112
- switch (resolution.method) {
113
- case 'did':
114
- debug(`Signing key ${key.publicKeyHex} found for identifier ${identifier}`);
115
- return { alg, key: Object.assign(Object.assign({}, key), { kmsKeyRef: resolution.kmsKeyRef, kid: resolution.kid }) };
116
- default:
117
- if (((_a = key.meta) === null || _a === void 0 ? void 0 : _a.x509) && key.meta.x509.x5c) {
118
- return { alg, key: { kid: resolution.kid, kmsKeyRef: resolution.kmsKeyRef, x5c: key.meta.x509.x5c } };
119
- }
120
- else if ((_b = key.meta) === null || _b === void 0 ? void 0 : _b.jwkThumbprint) {
121
- return { alg, key: { kid: resolution.kid, kmsKeyRef: resolution.kmsKeyRef, jwkThumbprint: key.meta.jwkThumbprint } };
122
- }
123
- else {
124
- return { alg, key: { kid: resolution.kid, kmsKeyRef: resolution.kmsKeyRef } };
125
- }
126
- }
92
+ async getSignKey(args, context) {
93
+ // TODO Using identifierManagedGetByDid now (new managed identifier resolution). Evaluate of we need to implement more identifier types here
94
+ const { identifier, resolution } = { ...args };
95
+ if (resolution) {
96
+ const key = resolution.key;
97
+ const alg = await signatureAlgorithmFromKey({ key });
98
+ switch (resolution.method) {
99
+ case 'did':
100
+ debug(`Signing key ${key.publicKeyHex} found for identifier ${identifier}`);
101
+ return { alg, key: { ...key, kmsKeyRef: resolution.kmsKeyRef, kid: resolution.kid } };
102
+ default:
103
+ if (key.meta?.x509 && key.meta.x509.x5c) {
104
+ return { alg, key: { kid: resolution.kid, kmsKeyRef: resolution.kmsKeyRef, x5c: key.meta.x509.x5c } };
105
+ }
106
+ else if (key.meta?.jwkThumbprint) {
107
+ return { alg, key: { kid: resolution.kid, kmsKeyRef: resolution.kmsKeyRef, jwkThumbprint: key.meta.jwkThumbprint } };
108
+ }
109
+ else {
110
+ return { alg, key: { kid: resolution.kid, kmsKeyRef: resolution.kmsKeyRef } };
111
+ }
127
112
  }
128
- else if (identifier.startsWith('did:')) {
129
- const didIdentifier = yield context.agent.identifierManagedGetByDid({ identifier });
130
- if (!didIdentifier) {
131
- throw new Error(`No identifier found with the given did: ${identifier}`);
132
- }
133
- const key = didIdentifier.key;
134
- const alg = yield (0, ssi_sdk_ext_key_utils_1.signatureAlgorithmFromKey)({ key });
135
- debug(`Signing key ${key.publicKeyHex} found for identifier ${identifier}`);
136
- return { alg, key: Object.assign(Object.assign({}, key), { kmsKeyRef: didIdentifier.kmsKeyRef, kid: didIdentifier.kid }) };
113
+ }
114
+ else if (identifier.startsWith('did:')) {
115
+ const didIdentifier = await context.agent.identifierManagedGetByDid({ identifier });
116
+ if (!didIdentifier) {
117
+ throw new Error(`No identifier found with the given did: ${identifier}`);
118
+ }
119
+ const key = didIdentifier.key;
120
+ const alg = await signatureAlgorithmFromKey({ key });
121
+ debug(`Signing key ${key.publicKeyHex} found for identifier ${identifier}`);
122
+ return { alg, key: { ...key, kmsKeyRef: didIdentifier.kmsKeyRef, kid: didIdentifier.kid } };
123
+ }
124
+ else {
125
+ const kidIdentifier = await context.agent.identifierManagedGetByKid({ identifier });
126
+ if (!kidIdentifier) {
127
+ throw new Error(`No identifier found with the given kid: ${identifier}`);
128
+ }
129
+ const key = kidIdentifier.key;
130
+ const alg = await signatureAlgorithmFromKey({ key });
131
+ if (key.meta?.x509 && key.meta.x509.x5c) {
132
+ return { alg, key: { kid: kidIdentifier.kid, kmsKeyRef: kidIdentifier.kmsKeyRef, x5c: key.meta.x509.x5c } };
133
+ }
134
+ else if (key.meta?.jwkThumbprint) {
135
+ return { alg, key: { kid: kidIdentifier.kid, kmsKeyRef: kidIdentifier.kmsKeyRef, jwkThumbprint: key.meta.jwkThumbprint } };
137
136
  }
138
137
  else {
139
- const kidIdentifier = yield context.agent.identifierManagedGetByKid({ identifier });
140
- if (!kidIdentifier) {
141
- throw new Error(`No identifier found with the given kid: ${identifier}`);
142
- }
143
- const key = kidIdentifier.key;
144
- const alg = yield (0, ssi_sdk_ext_key_utils_1.signatureAlgorithmFromKey)({ key });
145
- if (((_c = key.meta) === null || _c === void 0 ? void 0 : _c.x509) && key.meta.x509.x5c) {
146
- return { alg, key: { kid: kidIdentifier.kid, kmsKeyRef: kidIdentifier.kmsKeyRef, x5c: key.meta.x509.x5c } };
147
- }
148
- else if ((_d = key.meta) === null || _d === void 0 ? void 0 : _d.jwkThumbprint) {
149
- return { alg, key: { kid: kidIdentifier.kid, kmsKeyRef: kidIdentifier.kmsKeyRef, jwkThumbprint: key.meta.jwkThumbprint } };
150
- }
151
- else {
152
- return { alg, key: { kid: kidIdentifier.kid, kmsKeyRef: kidIdentifier.kmsKeyRef } };
153
- }
138
+ return { alg, key: { kid: kidIdentifier.kid, kmsKeyRef: kidIdentifier.kmsKeyRef } };
154
139
  }
155
- });
140
+ }
156
141
  }
157
142
  /**
158
143
  * Create a signed SD-JWT presentation.
@@ -160,39 +145,36 @@ class SDJwtPlugin {
160
145
  * @param context - This reserved param is automatically added and handled by the framework, *do not override*
161
146
  * @returns A signed SD-JWT presentation.
162
147
  */
163
- createSdJwtPresentation(args, context) {
164
- return __awaiter(this, void 0, void 0, function* () {
165
- var _a, _b, _c;
166
- const cred = yield core_1.SDJwt.fromEncode(args.presentation, this.registeredImplementations.hasher);
167
- const claims = yield cred.getClaims(this.registeredImplementations.hasher);
168
- let holder;
169
- // we primarly look for a cnf field, if it's not there we look for a sub field. If this is also not given, we throw an error since we can not sign it.
170
- if (args.holder) {
171
- holder = args.holder;
172
- }
173
- else if ((_a = claims.cnf) === null || _a === void 0 ? void 0 : _a.jwk) {
174
- const jwk = claims.cnf.jwk;
175
- holder = (0, ssi_sdk_ext_key_utils_1.calculateJwkThumbprint)({ jwk: jwk });
176
- }
177
- else if ((_b = claims.cnf) === null || _b === void 0 ? void 0 : _b.kid) {
178
- holder = (_c = claims.cnf) === null || _c === void 0 ? void 0 : _c.kid;
179
- }
180
- else if (claims.sub) {
181
- holder = claims.sub;
182
- }
183
- else {
184
- throw new Error('invalid_argument: credential does not include a holder reference');
185
- }
186
- const { alg, signer } = yield this.getSignerForIdentifier({ identifier: holder }, context);
187
- const sdjwt = new sd_jwt_vc_1.SDJwtVcInstance({
188
- hasher: this.registeredImplementations.hasher,
189
- saltGenerator: this.registeredImplementations.saltGenerator,
190
- kbSigner: signer,
191
- kbSignAlg: alg !== null && alg !== void 0 ? alg : 'ES256',
192
- });
193
- const presentation = yield sdjwt.present(args.presentation, args.presentationFrame, { kb: args.kb });
194
- return { presentation };
148
+ async createSdJwtPresentation(args, context) {
149
+ const cred = await SDJwt.fromEncode(args.presentation, this.registeredImplementations.hasher);
150
+ const claims = await cred.getClaims(this.registeredImplementations.hasher);
151
+ let holder;
152
+ // we primarly look for a cnf field, if it's not there we look for a sub field. If this is also not given, we throw an error since we can not sign it.
153
+ if (args.holder) {
154
+ holder = args.holder;
155
+ }
156
+ else if (claims.cnf?.jwk) {
157
+ const jwk = claims.cnf.jwk;
158
+ holder = calculateJwkThumbprint({ jwk: jwk });
159
+ }
160
+ else if (claims.cnf?.kid) {
161
+ holder = claims.cnf?.kid;
162
+ }
163
+ else if (claims.sub) {
164
+ holder = claims.sub;
165
+ }
166
+ else {
167
+ throw new Error('invalid_argument: credential does not include a holder reference');
168
+ }
169
+ const { alg, signer } = await this.getSignerForIdentifier({ identifier: holder }, context);
170
+ const sdjwt = new SDJwtVcInstance({
171
+ hasher: this.registeredImplementations.hasher ?? defaultGenerateDigest,
172
+ saltGenerator: this.registeredImplementations.saltGenerator,
173
+ kbSigner: signer,
174
+ kbSignAlg: alg ?? 'ES256',
195
175
  });
176
+ const presentation = await sdjwt.present(args.presentation, args.presentationFrame, { kb: args.kb });
177
+ return { presentation };
196
178
  }
197
179
  /**
198
180
  * Verify a signed SD-JWT credential.
@@ -200,14 +182,12 @@ class SDJwtPlugin {
200
182
  * @param context - This reserved param is automatically added and handled by the framework, *do not override*
201
183
  * @returns
202
184
  */
203
- verifySdJwtVc(args, context) {
204
- return __awaiter(this, void 0, void 0, function* () {
205
- // callback
206
- const verifier = (data, signature) => __awaiter(this, void 0, void 0, function* () { return this.verify(sdjwt, context, data, signature); });
207
- const sdjwt = new sd_jwt_vc_1.SDJwtVcInstance({ verifier, hasher: this.registeredImplementations.hasher });
208
- const { header = {}, payload, kb } = yield sdjwt.verify(args.credential);
209
- return { header, payload: payload, kb };
210
- });
185
+ async verifySdJwtVc(args, context) {
186
+ // callback
187
+ const verifier = async (data, signature) => this.verify(sdjwt, context, data, signature);
188
+ const sdjwt = new SDJwtVcInstance({ verifier, hasher: this.registeredImplementations.hasher ?? defaultGenerateDigest });
189
+ const { header = {}, payload, kb } = await sdjwt.verify(args.credential);
190
+ return { header, payload: payload, kb };
211
191
  }
212
192
  /**
213
193
  * Verify the key binding of a SD-JWT by validating the signature of the key bound to the SD-JWT
@@ -232,66 +212,63 @@ class SDJwtPlugin {
232
212
  * @param signature - The signature
233
213
  * @returns
234
214
  */
235
- verify(sdjwt, context, data, signature, opts) {
236
- return __awaiter(this, void 0, void 0, function* () {
237
- var _a, _b, _c, _d, _e, _f;
238
- const decodedVC = yield sdjwt.decode(`${data}.${signature}`);
239
- const issuer = decodedVC.jwt.payload.iss;
240
- const header = decodedVC.jwt.header;
241
- const x5c = header === null || header === void 0 ? void 0 : header.x5c;
242
- let jwk = header.jwk;
243
- if (x5c) {
244
- const trustAnchors = new Set([...this.trustAnchorsInPEM]);
245
- if (trustAnchors.size === 0) {
246
- trustAnchors.add(trustAnchors_1.sphereonCA);
247
- trustAnchors.add(trustAnchors_1.funkeTestCA);
248
- }
249
- const certificateValidationResult = yield context.agent.x509VerifyCertificateChain({
250
- chain: x5c,
251
- trustAnchors: Array.from(trustAnchors),
252
- // TODO: Defaults to allowing untrusted certs! Fine for now, not when wallets go mainstream
253
- opts: (_a = opts === null || opts === void 0 ? void 0 : opts.x5cValidation) !== null && _a !== void 0 ? _a : { trustRootWhenNoAnchors: true, allowNoTrustAnchorsFound: true },
254
- });
255
- if (certificateValidationResult.error || !(certificateValidationResult === null || certificateValidationResult === void 0 ? void 0 : certificateValidationResult.certificateChain)) {
256
- return Promise.reject(Error(`Certificate chain validation failed. ${certificateValidationResult.message}`));
257
- }
258
- const certInfo = certificateValidationResult.certificateChain[0];
259
- jwk = certInfo.publicKeyJWK;
215
+ async verify(sdjwt, context, data, signature, opts) {
216
+ const decodedVC = await sdjwt.decode(`${data}.${signature}`);
217
+ const issuer = decodedVC.jwt.payload.iss;
218
+ const header = decodedVC.jwt.header;
219
+ const x5c = header?.x5c;
220
+ let jwk = header.jwk;
221
+ if (x5c) {
222
+ const trustAnchors = new Set([...this.trustAnchorsInPEM]);
223
+ if (trustAnchors.size === 0) {
224
+ trustAnchors.add(sphereonCA);
225
+ trustAnchors.add(funkeTestCA);
260
226
  }
261
- if (!jwk && ((_b = header.kid) === null || _b === void 0 ? void 0 : _b.includes('did:'))) {
262
- const didDoc = yield context.agent.resolveDid({ didUrl: header.kid });
263
- if (!didDoc) {
264
- throw new Error('invalid_issuer: issuer did not resolve to a did document');
265
- }
266
- //TODO SDK-20: This should be checking for an assertionMethod and not just an verificationMethod with an id
267
- const didDocumentKey = (_d = (_c = didDoc.didDocument) === null || _c === void 0 ? void 0 : _c.verificationMethod) === null || _d === void 0 ? void 0 : _d.find((key) => key.id);
268
- if (!didDocumentKey) {
269
- throw new Error('invalid_issuer: issuer did document does not include referenced key');
270
- }
271
- //FIXME SDK-21: in case it's another did method, the value of the key can be also encoded as a base64url
272
- // needs more checks. some DID methods do not expose the keys as publicKeyJwk
273
- jwk = didDocumentKey.publicKeyJwk;
227
+ const certificateValidationResult = await context.agent.x509VerifyCertificateChain({
228
+ chain: x5c,
229
+ trustAnchors: Array.from(trustAnchors),
230
+ // TODO: Defaults to allowing untrusted certs! Fine for now, not when wallets go mainstream
231
+ opts: opts?.x5cValidation ?? { trustRootWhenNoAnchors: true, allowNoTrustAnchorsFound: true },
232
+ });
233
+ if (certificateValidationResult.error || !certificateValidationResult?.certificateChain) {
234
+ return Promise.reject(Error(`Certificate chain validation failed. ${certificateValidationResult.message}`));
274
235
  }
275
- if (!jwk && issuer.includes('did:')) {
276
- // TODO refactor
277
- const didDoc = yield context.agent.resolveDid({ didUrl: issuer });
278
- if (!didDoc) {
279
- throw new Error('invalid_issuer: issuer did not resolve to a did document');
280
- }
281
- //TODO SDK-20: This should be checking for an assertionMethod and not just an verificationMethod with an id
282
- const didDocumentKey = (_f = (_e = didDoc.didDocument) === null || _e === void 0 ? void 0 : _e.verificationMethod) === null || _f === void 0 ? void 0 : _f.find((key) => key.id);
283
- if (!didDocumentKey) {
284
- throw new Error('invalid_issuer: issuer did document does not include referenced key');
285
- }
286
- //FIXME SDK-21: in case it's another did method, the value of the key can be also encoded as a base64url
287
- // needs more checks. some DID methods do not expose the keys as publicKeyJwk
288
- jwk = didDocumentKey.publicKeyJwk;
236
+ const certInfo = certificateValidationResult.certificateChain[0];
237
+ jwk = certInfo.publicKeyJWK;
238
+ }
239
+ if (!jwk && header.kid?.includes('did:')) {
240
+ const didDoc = await context.agent.resolveDid({ didUrl: header.kid });
241
+ if (!didDoc) {
242
+ throw new Error('invalid_issuer: issuer did not resolve to a did document');
289
243
  }
290
- if (!jwk) {
291
- throw new Error('No valid public key found for signature verification');
244
+ //TODO SDK-20: This should be checking for an assertionMethod and not just an verificationMethod with an id
245
+ const didDocumentKey = didDoc.didDocument?.verificationMethod?.find((key) => key.id);
246
+ if (!didDocumentKey) {
247
+ throw new Error('invalid_issuer: issuer did document does not include referenced key');
292
248
  }
293
- return this.verifySignatureCallback(context)(data, signature, jwk);
294
- });
249
+ //FIXME SDK-21: in case it's another did method, the value of the key can be also encoded as a base64url
250
+ // needs more checks. some DID methods do not expose the keys as publicKeyJwk
251
+ jwk = didDocumentKey.publicKeyJwk;
252
+ }
253
+ if (!jwk && issuer.includes('did:')) {
254
+ // TODO refactor
255
+ const didDoc = await context.agent.resolveDid({ didUrl: issuer });
256
+ if (!didDoc) {
257
+ throw new Error('invalid_issuer: issuer did not resolve to a did document');
258
+ }
259
+ //TODO SDK-20: This should be checking for an assertionMethod and not just an verificationMethod with an id
260
+ const didDocumentKey = didDoc.didDocument?.verificationMethod?.find((key) => key.id);
261
+ if (!didDocumentKey) {
262
+ throw new Error('invalid_issuer: issuer did document does not include referenced key');
263
+ }
264
+ //FIXME SDK-21: in case it's another did method, the value of the key can be also encoded as a base64url
265
+ // needs more checks. some DID methods do not expose the keys as publicKeyJwk
266
+ jwk = didDocumentKey.publicKeyJwk;
267
+ }
268
+ if (!jwk) {
269
+ throw new Error('No valid public key found for signature verification');
270
+ }
271
+ return this.verifySignatureCallback(context)(data, signature, jwk);
295
272
  }
296
273
  /**
297
274
  * Verify a signed SD-JWT presentation.
@@ -299,18 +276,16 @@ class SDJwtPlugin {
299
276
  * @param context - This reserved param is automatically added and handled by the framework, *do not override*
300
277
  * @returns
301
278
  */
302
- verifySdJwtPresentation(args, context) {
303
- return __awaiter(this, void 0, void 0, function* () {
304
- let sdjwt;
305
- const verifier = (data, signature) => __awaiter(this, void 0, void 0, function* () { return this.verify(sdjwt, context, data, signature); });
306
- const verifierKb = (data, signature, payload) => __awaiter(this, void 0, void 0, function* () { return this.verifyKb(sdjwt, context, data, signature, payload); });
307
- sdjwt = new sd_jwt_vc_1.SDJwtVcInstance({
308
- verifier,
309
- hasher: this.registeredImplementations.hasher,
310
- kbVerifier: verifierKb,
311
- });
312
- return sdjwt.verify(args.presentation, args.requiredClaimKeys, args.kb);
279
+ async verifySdJwtPresentation(args, context) {
280
+ let sdjwt;
281
+ const verifier = async (data, signature) => this.verify(sdjwt, context, data, signature);
282
+ const verifierKb = async (data, signature, payload) => this.verifyKb(sdjwt, context, data, signature, payload);
283
+ sdjwt = new SDJwtVcInstance({
284
+ verifier,
285
+ hasher: this.registeredImplementations.hasher,
286
+ kbVerifier: verifierKb,
313
287
  });
288
+ return sdjwt.verify(args.presentation, args.requiredClaimKeys, args.kb);
314
289
  }
315
290
  /**
316
291
  * Fetch and validate Type Metadata.
@@ -318,37 +293,62 @@ class SDJwtPlugin {
318
293
  * @param context - This reserved param is automatically added and handled by the framework, *do not override*
319
294
  * @returns
320
295
  */
321
- fetchSdJwtTypeMetadataFromVctUrl(args, context) {
322
- return __awaiter(this, void 0, void 0, function* () {
323
- const { vct, opts } = args;
324
- const url = new URL(vct);
325
- const response = yield (0, utils_2.fetchUrlWithErrorHandling)(url.toString());
326
- const metadata = yield response.json();
327
- (0, utils_2.assertValidTypeMetadata)(metadata, vct);
328
- if ((opts === null || opts === void 0 ? void 0 : opts.integrity) && opts.hasher) {
329
- if (!(yield (0, utils_2.validateIntegrity)(metadata, opts.integrity, opts.hasher))) {
330
- throw new Error(`Integrity check failed. vct: ${vct}`);
296
+ async fetchSdJwtTypeMetadataFromVctUrl(args, context) {
297
+ const { vct, vctIntegrity, opts } = args;
298
+ const url = new URL(vct);
299
+ const response = await fetchUrlWithErrorHandling(url.toString());
300
+ const metadata = await response.json();
301
+ assertValidTypeMetadata(metadata, vct);
302
+ const validate = async (vct, input, integrityValue, hasher) => {
303
+ if (hasher && integrityValue) {
304
+ const validation = await validateIntegrity({ integrityValue, input, hasher });
305
+ if (!validation) {
306
+ return Promise.reject(Error(`Integrity check failed for vct: ${vct}, extends: ${metadata.extends}, integrity: ${integrityValue}}`));
331
307
  }
332
308
  }
333
- return metadata;
334
- });
309
+ };
310
+ const hasher = (opts?.hasher ?? this.registeredImplementations.hasher ?? defaultGenerateDigest);
311
+ if (hasher) {
312
+ if (vctIntegrity) {
313
+ await validate(vct, metadata, vctIntegrity, hasher);
314
+ const vctValidation = await validateIntegrity({ integrityValue: vctIntegrity, input: metadata, hasher });
315
+ if (!vctValidation) {
316
+ return Promise.reject(Error(`Integrity check failed for vct: ${vct}, integrity: ${vctIntegrity}`));
317
+ }
318
+ }
319
+ if (metadata['extends#integrity']) {
320
+ const extendsMetadata = await this.fetchSdJwtTypeMetadataFromVctUrl({ vct: metadata['extends#integrity'], opts }, context);
321
+ await validate(vct, extendsMetadata, metadata['extends#integrity'], hasher);
322
+ }
323
+ if (metadata['schema_uri#integrity']) {
324
+ const schemaResponse = await fetchUrlWithErrorHandling(metadata.schema_uri);
325
+ const schema = await schemaResponse.json();
326
+ await validate(vct, schema, metadata['schema_uri#integrity'], hasher);
327
+ }
328
+ metadata.display?.forEach((display) => {
329
+ const simpleLogoIntegrity = display.rendering?.simple?.logo?.['uri#integrity'];
330
+ if (simpleLogoIntegrity) {
331
+ console.log('TODO: Logo integrity check');
332
+ }
333
+ });
334
+ }
335
+ return metadata;
335
336
  }
336
337
  verifySignatureCallback(context) {
337
338
  if (typeof this.registeredImplementations.verifySignature === 'function') {
338
339
  return this.registeredImplementations.verifySignature;
339
340
  }
340
- return (0, defaultCallbacks_1.defaultVerifySignature)(context);
341
+ return defaultVerifySignature(context);
341
342
  }
342
343
  getJwk(payload) {
343
- var _a;
344
- if (((_a = payload.cnf) === null || _a === void 0 ? void 0 : _a.jwk) !== undefined) {
344
+ if (payload.cnf?.jwk !== undefined) {
345
345
  return payload.cnf.jwk;
346
346
  }
347
347
  else if (payload.cnf !== undefined && 'kid' in payload.cnf && typeof payload.cnf.kid === 'string' && payload.cnf.kid.startsWith('did:jwk:')) {
348
348
  // extract JWK from kid FIXME isn't there a did function for this already? Otherwise create one
349
349
  // FIXME this is a quick-fix to make verification but we need a real solution
350
350
  const encoded = this.extractBase64FromDIDJwk(payload.cnf.kid);
351
- const decoded = (0, utils_1.decodeBase64url)(encoded);
351
+ const decoded = decodeBase64url(encoded);
352
352
  const jwt = JSON.parse(decoded);
353
353
  return jwt;
354
354
  }
@@ -362,5 +362,4 @@ class SDJwtPlugin {
362
362
  return parts[2].split('#')[0];
363
363
  }
364
364
  }
365
- exports.SDJwtPlugin = SDJwtPlugin;
366
365
  //# sourceMappingURL=action-handler.js.map