@sphereon/ssi-sdk.sd-jwt 0.34.1-feature.SSISDK.45.94 → 0.34.1-feature.SSISDK.46.41

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.
package/dist/index.js CHANGED
@@ -3,8 +3,9 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
3
3
 
4
4
  // src/action-handler.ts
5
5
  import { SDJwt } from "@sd-jwt/core";
6
- import { SDJwtVcInstance as SDJwtVcInstance2 } from "@sd-jwt/sd-jwt-vc";
6
+ import { SDJwtVcInstance } from "@sd-jwt/sd-jwt-vc";
7
7
  import { calculateJwkThumbprint, signatureAlgorithmFromKey } from "@sphereon/ssi-sdk-ext.key-utils";
8
+ import { decodeBase64url } from "@veramo/utils";
8
9
  import Debug from "debug";
9
10
 
10
11
  // src/defaultCallbacks.ts
@@ -80,189 +81,8 @@ function assertValidTypeMetadata(metadata, vct) {
80
81
  }
81
82
  }
82
83
  __name(assertValidTypeMetadata, "assertValidTypeMetadata");
83
- function isVcdm2SdJwtPayload(payload) {
84
- return "type" in payload && Array.isArray(payload.type) && payload.type.includes("VerifiableCredential") && "@context" in payload && (typeof payload["@context"] === "string" && payload["@context"].length > 0 || Array.isArray(payload["@context"]) && payload["@context"].length > 0 && payload["@context"].includes("https://www.w3.org/ns/credentials/v2"));
85
- }
86
- __name(isVcdm2SdJwtPayload, "isVcdm2SdJwtPayload");
87
- function isSdjwtVcPayload(payload) {
88
- return !isVcdm2SdJwtPayload(payload) && "vct" in payload && typeof payload.vct === "string";
89
- }
90
- __name(isSdjwtVcPayload, "isSdjwtVcPayload");
91
- function getIssuerFromSdJwt(payload) {
92
- let issuer;
93
- if (isSdjwtVcPayload(payload) || "iss" in payload) {
94
- issuer = payload.iss;
95
- } else if (isVcdm2SdJwtPayload(payload) || "issuer" in payload && payload.issuer) {
96
- issuer = typeof payload.issuer === "string" ? payload.issuer : payload.issuer?.id;
97
- }
98
- if (!issuer) {
99
- throw new Error("No issuer (iss or VCDM 2 issuer) found in SD-JWT or no VCDM2 SD-JWT or SD-JWT VC");
100
- }
101
- return issuer;
102
- }
103
- __name(getIssuerFromSdJwt, "getIssuerFromSdJwt");
104
-
105
- // src/sdJwtVcdm2Instance.ts
106
- import { SDJwtInstance } from "@sd-jwt/core";
107
- import { SDJWTException } from "@sd-jwt/utils";
108
- import { SDJwtVcInstance } from "@sd-jwt/sd-jwt-vc";
109
-
110
- // src/types.ts
111
- import { contextHasPlugin } from "@sphereon/ssi-sdk.agent-config";
112
- var sdJwtPluginContextMethods = [
113
- "createSdJwtVc",
114
- "createSdJwtPresentation",
115
- "verifySdJwtVc",
116
- "verifySdJwtPresentation"
117
- ];
118
- function contextHasSDJwtPlugin(context) {
119
- return contextHasPlugin(context, "verifySdJwtVc");
120
- }
121
- __name(contextHasSDJwtPlugin, "contextHasSDJwtPlugin");
122
- function isVcdm2SdJwt(type) {
123
- return type === "vc+sd-jwt" || type === "vp+sd-jwt";
124
- }
125
- __name(isVcdm2SdJwt, "isVcdm2SdJwt");
126
-
127
- // src/sdJwtVcdm2Instance.ts
128
- var SDJwtVcdmInstanceFactory = class {
129
- static {
130
- __name(this, "SDJwtVcdmInstanceFactory");
131
- }
132
- static create(type, config) {
133
- if (isVcdm2SdJwt(type)) {
134
- return new SDJwtVcdm2Instance(config);
135
- }
136
- return new SDJwtVcInstance(config);
137
- }
138
- };
139
- var SDJwtVcdm2Instance = class extends SDJwtInstance {
140
- static {
141
- __name(this, "SDJwtVcdm2Instance");
142
- }
143
- /**
144
- * The type of the SD-JWT VCDM2 set in the header.typ field.
145
- */
146
- static type = "vc+sd-jwt";
147
- userConfig = {};
148
- constructor(userConfig) {
149
- super(userConfig);
150
- if (userConfig) {
151
- this.userConfig = userConfig;
152
- }
153
- }
154
- /**
155
- * Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
156
- * @param disclosureFrame
157
- */
158
- validateReservedFields(disclosureFrame) {
159
- if (disclosureFrame?._sd && Array.isArray(disclosureFrame._sd) && disclosureFrame._sd.length > 0) {
160
- const reservedNames = [
161
- "iss",
162
- "nbf",
163
- "exp",
164
- "cnf",
165
- "@context",
166
- "type",
167
- "credentialStatus",
168
- "credentialSchema",
169
- "relatedResource"
170
- ];
171
- const reservedNamesInDisclosureFrame = disclosureFrame._sd.filter((key) => reservedNames.includes(key));
172
- if (reservedNamesInDisclosureFrame.length > 0) {
173
- throw new SDJWTException(`Cannot disclose protected field(s): ${reservedNamesInDisclosureFrame.join(", ")}`);
174
- }
175
- }
176
- }
177
- /**
178
- * Verifies the SD-JWT-VC. It will validate the signature, the keybindings when required, the status, and the VCT.
179
- * @param encodedSDJwt
180
- * @param options
181
- */
182
- async verify(encodedSDJwt, options) {
183
- const result = await super.verify(encodedSDJwt, options).then((res) => {
184
- return {
185
- payload: res.payload,
186
- header: res.header,
187
- kb: res.kb
188
- };
189
- });
190
- return result;
191
- }
192
- /**
193
- * Validates the integrity of the response if the integrity is passed. If the integrity does not match, an error is thrown.
194
- * @param integrity
195
- * @param response
196
- */
197
- async validateIntegrity(response, url, integrity) {
198
- if (integrity) {
199
- const arrayBuffer = await response.arrayBuffer();
200
- const alg = integrity.split("-")[0];
201
- const hashBuffer = await this.userConfig.hasher(arrayBuffer, alg);
202
- const integrityHash = integrity.split("-")[1];
203
- const hash = Array.from(new Uint8Array(hashBuffer)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
204
- if (hash !== integrityHash) {
205
- throw new Error(`Integrity check for ${url} failed: is ${hash}, but expected ${integrityHash}`);
206
- }
207
- }
208
- }
209
- /**
210
- * Fetches the content from the url with a timeout of 10 seconds.
211
- * @param url
212
- * @param integrity
213
- * @returns
214
- */
215
- async fetch(url, integrity) {
216
- try {
217
- const response = await fetch(url, {
218
- signal: AbortSignal.timeout(this.userConfig.timeout ?? 1e4)
219
- });
220
- if (!response.ok) {
221
- const errorText = await response.text();
222
- return Promise.reject(new Error(`Error fetching ${url}: ${response.status} ${response.statusText} - ${errorText}`));
223
- }
224
- await this.validateIntegrity(response.clone(), url, integrity);
225
- return response.json();
226
- } catch (error) {
227
- if (error.name === "TimeoutError") {
228
- throw new Error(`Request to ${url} timed out`);
229
- }
230
- throw error;
231
- }
232
- }
233
- async issue(payload, disclosureFrame, options) {
234
- if (payload.iss && !payload.issuer) {
235
- payload.issuer = {
236
- id: payload.iss
237
- };
238
- delete payload.iss;
239
- }
240
- if (payload.nbf && !payload.validFrom) {
241
- payload.validFrom = toVcdm2Date(payload.nbf);
242
- delete payload.nbf;
243
- }
244
- if (payload.exp && !payload.validUntil) {
245
- payload.validUntil = toVcdm2Date(payload.exp);
246
- delete payload.exp;
247
- }
248
- if (payload.sub && !Array.isArray(payload.credentialSubject) && !payload.credentialSubject.id) {
249
- payload.credentialSubject.id = payload.sub;
250
- delete payload.sub;
251
- }
252
- return super.issue(payload, disclosureFrame, options);
253
- }
254
- };
255
- function toVcdm2Date(value) {
256
- const num = typeof value === "string" ? Number(value) : value;
257
- if (!Number.isFinite(num)) {
258
- throw new SDJWTException(`Invalid numeric date: ${value}`);
259
- }
260
- return new Date(num * 1e3).toISOString();
261
- }
262
- __name(toVcdm2Date, "toVcdm2Date");
263
84
 
264
85
  // src/action-handler.ts
265
- import * as u8a from "uint8arrays";
266
86
  var debug = Debug("@sphereon/ssi-sdk.sd-jwt");
267
87
  var SDJwtPlugin = class {
268
88
  static {
@@ -332,11 +152,7 @@ var SDJwtPlugin = class {
332
152
  * @returns A signed SD-JWT credential.
333
153
  */
334
154
  async createSdJwtVc(args, context) {
335
- const payload = args.credentialPayload;
336
- const isVcdm2 = isVcdm2SdJwtPayload(payload);
337
- const isSdJwtVc = isSdjwtVcPayload(payload);
338
- const type = args.type ?? (isVcdm2 ? "vc+sd-jwt" : "dc+sd-jwt");
339
- const issuer = getIssuerFromSdJwt(args.credentialPayload);
155
+ const issuer = args.credentialPayload.iss;
340
156
  if (!issuer) {
341
157
  throw new Error("credential.issuer must not be empty");
342
158
  }
@@ -344,46 +160,24 @@ var SDJwtPlugin = class {
344
160
  identifier: issuer,
345
161
  resolution: args.resolution
346
162
  }, context);
347
- const signAlg = alg ?? signingKey?.alg ?? "ES256";
348
- const hashAlg = /(\d{3})$/.test(signAlg) ? `sha-${signAlg.slice(-3)}` : "sha-256";
349
- const sdjwt = SDJwtVcdmInstanceFactory.create(type, {
350
- omitTyp: true,
163
+ const sdjwt = new SDJwtVcInstance({
351
164
  signer,
352
165
  hasher: this.registeredImplementations.hasher,
353
166
  saltGenerator: this.registeredImplementations.saltGenerator,
354
- signAlg,
355
- hashAlg
167
+ signAlg: alg ?? "ES256",
168
+ hashAlg: "sha-256"
356
169
  });
357
- const header = {
358
- ...signingKey?.key.kid !== void 0 && {
359
- kid: signingKey.key.kid
360
- },
361
- ...signingKey?.key.x5c !== void 0 && {
362
- x5c: signingKey.key.x5c
363
- },
364
- ...type && {
365
- typ: type
366
- }
367
- };
368
- let credential;
369
- if (isVcdm2) {
370
- credential = await sdjwt.issue(
371
- payload,
372
- // @ts-ignore
373
- args.disclosureFrame,
374
- {
375
- header
170
+ const credential = await sdjwt.issue(args.credentialPayload, args.disclosureFrame, {
171
+ header: {
172
+ ...signingKey?.key.kid !== void 0 && {
173
+ kid: signingKey.key.kid
174
+ },
175
+ ...signingKey?.key.x5c !== void 0 && {
176
+ x5c: signingKey.key.x5c
376
177
  }
377
- );
378
- } else if (isSdJwtVc) {
379
- credential = await sdjwt.issue(payload, args.disclosureFrame, {
380
- header
381
- });
382
- } else {
383
- return Promise.reject(new Error(`invalid_argument: credential '${type}' type is not supported`));
384
- }
178
+ }
179
+ });
385
180
  return {
386
- type,
387
181
  credential
388
182
  };
389
183
  }
@@ -509,7 +303,6 @@ var SDJwtPlugin = class {
509
303
  * @returns A signed SD-JWT presentation.
510
304
  */
511
305
  async createSdJwtPresentation(args, context) {
512
- const type = args.type ?? "dc+sd-jwt";
513
306
  const cred = await SDJwt.fromEncode(args.presentation, this.registeredImplementations.hasher);
514
307
  const claims = await cred.getClaims(this.registeredImplementations.hasher);
515
308
  let holder;
@@ -530,9 +323,8 @@ var SDJwtPlugin = class {
530
323
  const { alg, signer } = await this.getSignerForIdentifier({
531
324
  identifier: holder
532
325
  }, context);
533
- const sdjwt = SDJwtVcdmInstanceFactory.create(type, {
534
- omitTyp: true,
535
- hasher: this.registeredImplementations.hasher,
326
+ const sdjwt = new SDJwtVcInstance({
327
+ hasher: this.registeredImplementations.hasher ?? defaultGenerateDigest,
536
328
  saltGenerator: this.registeredImplementations.saltGenerator,
537
329
  kbSigner: signer,
538
330
  kbSignAlg: alg ?? "ES256"
@@ -541,7 +333,6 @@ var SDJwtPlugin = class {
541
333
  kb: args.kb
542
334
  });
543
335
  return {
544
- type,
545
336
  presentation
546
337
  };
547
338
  }
@@ -552,18 +343,13 @@ var SDJwtPlugin = class {
552
343
  * @returns
553
344
  */
554
345
  async verifySdJwtVc(args, context) {
555
- const verifier = /* @__PURE__ */ __name(async (data, signature) => this.verifyCallbackImpl(sdjwt, context, data, signature), "verifier");
556
- const cred = await SDJwt.fromEncode(args.credential, this.registeredImplementations.hasher);
557
- const type = isVcdm2SdJwtPayload(cred.jwt?.payload) ? "vc+sd-jwt" : "dc+sd-jwt";
558
- const sdjwt = SDJwtVcdmInstanceFactory.create(type, {
346
+ const verifier = /* @__PURE__ */ __name(async (data, signature) => this.verify(sdjwt, context, data, signature), "verifier");
347
+ const sdjwt = new SDJwtVcInstance({
559
348
  verifier,
560
349
  hasher: this.registeredImplementations.hasher ?? defaultGenerateDigest
561
350
  });
562
- const { header = {}, payload, kb } = await sdjwt.verify(args.credential, {
563
- skewSeconds: 60 * 60 * 24 * 5
564
- });
351
+ const { header = {}, payload, kb } = await sdjwt.verify(args.credential);
565
352
  return {
566
- type,
567
353
  header,
568
354
  payload,
569
355
  kb
@@ -578,7 +364,7 @@ var SDJwtPlugin = class {
578
364
  * @param payload - The payload of the SD-JWT
579
365
  * @returns
580
366
  */
581
- verifyKb(context, data, signature, payload) {
367
+ verifyKb(sdjwt, context, data, signature, payload) {
582
368
  if (!payload.cnf) {
583
369
  throw Error("other method than cnf is not supported yet");
584
370
  }
@@ -592,10 +378,9 @@ var SDJwtPlugin = class {
592
378
  * @param signature - The signature
593
379
  * @returns
594
380
  */
595
- async verifyCallbackImpl(sdjwt, context, data, signature, opts) {
381
+ async verify(sdjwt, context, data, signature, opts) {
596
382
  const decodedVC = await sdjwt.decode(`${data}.${signature}`);
597
- const payload = decodedVC.jwt.payload;
598
- const issuer = getIssuerFromSdJwt(payload);
383
+ const issuer = decodedVC.jwt.payload.iss;
599
384
  const header = decodedVC.jwt.header;
600
385
  const x5c = header?.x5c;
601
386
  let jwk = header.jwk;
@@ -661,18 +446,14 @@ var SDJwtPlugin = class {
661
446
  */
662
447
  async verifySdJwtPresentation(args, context) {
663
448
  let sdjwt;
664
- const verifier = /* @__PURE__ */ __name(async (data, signature) => this.verifyCallbackImpl(sdjwt, context, data, signature), "verifier");
665
- const verifierKb = /* @__PURE__ */ __name(async (data, signature, payload) => this.verifyKb(context, data, signature, payload), "verifierKb");
666
- sdjwt = new SDJwtVcInstance2({
449
+ const verifier = /* @__PURE__ */ __name(async (data, signature) => this.verify(sdjwt, context, data, signature), "verifier");
450
+ const verifierKb = /* @__PURE__ */ __name(async (data, signature, payload) => this.verifyKb(sdjwt, context, data, signature, payload), "verifierKb");
451
+ sdjwt = new SDJwtVcInstance({
667
452
  verifier,
668
453
  hasher: this.registeredImplementations.hasher,
669
454
  kbVerifier: verifierKb
670
455
  });
671
- const verifierOpts = {
672
- requiredClaimKeys: args.requiredClaimKeys,
673
- keyBindingNonce: args.keyBindingNonce
674
- };
675
- return sdjwt.verify(args.presentation, verifierOpts);
456
+ return sdjwt.verify(args.presentation, args.requiredClaimKeys, args.kb);
676
457
  }
677
458
  /**
678
459
  * Fetch and validate Type Metadata.
@@ -743,7 +524,7 @@ var SDJwtPlugin = class {
743
524
  return payload.cnf.jwk;
744
525
  } else if (payload.cnf !== void 0 && "kid" in payload.cnf && typeof payload.cnf.kid === "string" && payload.cnf.kid.startsWith("did:jwk:")) {
745
526
  const encoded = this.extractBase64FromDIDJwk(payload.cnf.kid);
746
- const decoded = u8a.toString(u8a.fromString(encoded, "base64url"), "utf-8");
527
+ const decoded = decodeBase64url(encoded);
747
528
  const jwt = JSON.parse(decoded);
748
529
  return jwt;
749
530
  }
@@ -757,6 +538,19 @@ var SDJwtPlugin = class {
757
538
  return parts[2].split("#")[0];
758
539
  }
759
540
  };
541
+
542
+ // src/types.ts
543
+ import { contextHasPlugin } from "@sphereon/ssi-sdk.agent-config";
544
+ var sdJwtPluginContextMethods = [
545
+ "createSdJwtVc",
546
+ "createSdJwtPresentation",
547
+ "verifySdJwtVc",
548
+ "verifySdJwtPresentation"
549
+ ];
550
+ function contextHasSDJwtPlugin(context) {
551
+ return contextHasPlugin(context, "verifySdJwtVc");
552
+ }
553
+ __name(contextHasSDJwtPlugin, "contextHasSDJwtPlugin");
760
554
  export {
761
555
  SDJwtPlugin,
762
556
  assertValidTypeMetadata,
@@ -764,10 +558,6 @@ export {
764
558
  createIntegrity,
765
559
  extractHashFromIntegrity,
766
560
  fetchUrlWithErrorHandling,
767
- getIssuerFromSdJwt,
768
- isSdjwtVcPayload,
769
- isVcdm2SdJwt,
770
- isVcdm2SdJwtPayload,
771
561
  sdJwtPluginContextMethods,
772
562
  validateIntegrity
773
563
  };