@sphereon/ssi-sdk-ext.x509-utils 0.28.1-feature.esm.cjs.8 → 0.28.1-feature.esm.cjs.9

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.cjs CHANGED
@@ -1,71 +1,11 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } async function _asyncNullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return await rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var __defProp = Object.defineProperty;
8
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
- var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
19
- return to;
20
- };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
-
31
- // src/index.ts
32
- var index_exports = {};
33
- __export(index_exports, {
34
- JwkKeyUse: () => JwkKeyUse,
35
- PEMToBinary: () => PEMToBinary,
36
- PEMToDer: () => PEMToDer,
37
- PEMToHex: () => PEMToHex,
38
- PEMToJwk: () => PEMToJwk,
39
- RSASigner: () => RSASigner,
40
- SubjectAlternativeGeneralName: () => SubjectAlternativeGeneralName,
41
- areCertificatesEqual: () => areCertificatesEqual,
42
- assertCertificateMatchesClientIdScheme: () => assertCertificateMatchesClientIdScheme,
43
- base64ToHex: () => base64ToHex,
44
- cryptoSubtleImportRSAKey: () => cryptoSubtleImportRSAKey,
45
- derToPEM: () => derToPEM,
46
- generateRSAKeyAsPEM: () => generateRSAKeyAsPEM,
47
- getCertificateInfo: () => getCertificateInfo,
48
- getCertificateSubjectPublicKeyJWK: () => getCertificateSubjectPublicKeyJWK,
49
- getIssuerDN: () => getIssuerDN,
50
- getSubjectAlternativeNames: () => getSubjectAlternativeNames,
51
- getSubjectDN: () => getSubjectDN,
52
- getX509AlgorithmProvider: () => getX509AlgorithmProvider,
53
- hexKeyFromPEMBasedJwk: () => hexKeyFromPEMBasedJwk,
54
- hexToBase64: () => hexToBase64,
55
- hexToPEM: () => hexToPEM,
56
- jwkToPEM: () => jwkToPEM,
57
- parseCertificate: () => parseCertificate,
58
- pemCertChainTox5c: () => pemCertChainTox5c,
59
- pemOrDerToX509Certificate: () => pemOrDerToX509Certificate,
60
- privateKeyHexFromPEM: () => privateKeyHexFromPEM,
61
- publicKeyHexFromPEM: () => publicKeyHexFromPEM,
62
- signAlgorithmToSchemeAndHashAlg: () => signAlgorithmToSchemeAndHashAlg,
63
- toKeyObject: () => toKeyObject,
64
- validateCertificateChainMatchesClientIdScheme: () => validateCertificateChainMatchesClientIdScheme,
65
- validateX509CertificateChain: () => validateX509CertificateChain,
66
- x5cToPemCertChain: () => x5cToPemCertChain
3
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
4
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
5
+ }) : x)(function(x) {
6
+ if (typeof require !== "undefined") return require.apply(this, arguments);
7
+ throw Error('Dynamic require of "' + x + '" is not supported');
67
8
  });
68
- module.exports = __toCommonJS(index_exports);
69
9
 
70
10
  // src/types/index.ts
71
11
  var JwkKeyUse = /* @__PURE__ */ function(JwkKeyUse2) {
@@ -75,7 +15,7 @@ var JwkKeyUse = /* @__PURE__ */ function(JwkKeyUse2) {
75
15
  }({});
76
16
 
77
17
  // src/x509/rsa-key.ts
78
- var import_to_string2 = require("uint8arrays/to-string");
18
+ var _tostring = require('uint8arrays/to-string');
79
19
 
80
20
  // src/x509/crypto.ts
81
21
  var globalCrypto = /* @__PURE__ */ __name((setGlobal, suppliedCrypto) => {
@@ -87,10 +27,10 @@ var globalCrypto = /* @__PURE__ */ __name((setGlobal, suppliedCrypto) => {
87
27
  } else if (typeof global.crypto !== "undefined") {
88
28
  webcrypto = global.crypto;
89
29
  } else {
90
- if (typeof global.window?.crypto?.subtle !== "undefined") {
30
+ if (typeof _optionalChain([global, 'access', _ => _.window, 'optionalAccess', _2 => _2.crypto, 'optionalAccess', _3 => _3.subtle]) !== "undefined") {
91
31
  webcrypto = global.window.crypto;
92
32
  } else {
93
- webcrypto = require("crypto");
33
+ webcrypto = __require("crypto");
94
34
  }
95
35
  }
96
36
  if (setGlobal) {
@@ -100,10 +40,10 @@ var globalCrypto = /* @__PURE__ */ __name((setGlobal, suppliedCrypto) => {
100
40
  }, "globalCrypto");
101
41
 
102
42
  // src/x509/x509-utils.ts
103
- var import_pkijs = require("pkijs");
104
- var import_from_string = require("uint8arrays/from-string");
105
- var import_to_string = require("uint8arrays/to-string");
106
- var import_keyto = __toESM(require("@trust/keyto"), 1);
43
+ var _pkijs = require('pkijs');
44
+ var _fromstring = require('uint8arrays/from-string');
45
+
46
+ var _keyto = require('@trust/keyto'); var _keyto2 = _interopRequireDefault(_keyto);
107
47
  function pemCertChainTox5c(cert, maxDepth) {
108
48
  if (!maxDepth) {
109
49
  maxDepth = 0;
@@ -133,16 +73,16 @@ __name(x5cToPemCertChain, "x5cToPemCertChain");
133
73
  var pemOrDerToX509Certificate = /* @__PURE__ */ __name((cert) => {
134
74
  let DER = typeof cert === "string" ? cert : void 0;
135
75
  if (typeof cert === "object" && !(cert instanceof Uint8Array)) {
136
- return import_pkijs.Certificate.fromBER(cert.rawData);
76
+ return _pkijs.Certificate.fromBER(cert.rawData);
137
77
  } else if (typeof cert !== "string") {
138
- return import_pkijs.Certificate.fromBER(cert);
78
+ return _pkijs.Certificate.fromBER(cert);
139
79
  } else if (cert.includes("CERTIFICATE")) {
140
80
  DER = PEMToDer(cert);
141
81
  }
142
82
  if (!DER) {
143
83
  throw Error("Invalid cert input value supplied. PEM, DER, Bytes and X509Certificate object are supported");
144
84
  }
145
- return import_pkijs.Certificate.fromBER((0, import_from_string.fromString)(DER, "base64pad"));
85
+ return _pkijs.Certificate.fromBER(_fromstring.fromString.call(void 0, DER, "base64pad"));
146
86
  }, "pemOrDerToX509Certificate");
147
87
  var areCertificatesEqual = /* @__PURE__ */ __name((cert1, cert2) => {
148
88
  return cert1.signatureValue.isEqual(cert2.signatureValue);
@@ -159,10 +99,10 @@ var toKeyObject = /* @__PURE__ */ __name((PEM, visibility = "public") => {
159
99
  };
160
100
  }, "toKeyObject");
161
101
  var jwkToPEM = /* @__PURE__ */ __name((jwk, visibility = "public") => {
162
- return import_keyto.default.from(jwk, "jwk").toString("pem", visibility === "public" ? "public_pkcs8" : "private_pkcs8");
102
+ return _keyto2.default.from(jwk, "jwk").toString("pem", visibility === "public" ? "public_pkcs8" : "private_pkcs8");
163
103
  }, "jwkToPEM");
164
104
  var PEMToJwk = /* @__PURE__ */ __name((pem, visibility = "public") => {
165
- return import_keyto.default.from(pem, "pem").toJwk(visibility);
105
+ return _keyto2.default.from(pem, "pem").toJwk(visibility);
166
106
  }, "PEMToJwk");
167
107
  var privateKeyHexFromPEM = /* @__PURE__ */ __name((PEM) => {
168
108
  return PEMToHex(PEM);
@@ -201,19 +141,19 @@ var PEMToHex = /* @__PURE__ */ __name((PEM, headerKey) => {
201
141
  }, "PEMToHex");
202
142
  function PEMToBinary(pem) {
203
143
  const pemContents = pem.replace(/^[^]*-----BEGIN [^-]+-----/, "").replace(/-----END [^-]+-----[^]*$/, "").replace(/\s/g, "");
204
- return (0, import_from_string.fromString)(pemContents, "base64pad");
144
+ return _fromstring.fromString.call(void 0, pemContents, "base64pad");
205
145
  }
206
146
  __name(PEMToBinary, "PEMToBinary");
207
147
  var base64ToHex = /* @__PURE__ */ __name((input, inputEncoding) => {
208
148
  const base64NoNewlines = input.replace(/[^0-9A-Za-z_\-~\/+=]*/g, "");
209
- return (0, import_to_string.toString)((0, import_from_string.fromString)(base64NoNewlines, inputEncoding ? inputEncoding : "base64pad"), "base16");
149
+ return _tostring.toString.call(void 0, _fromstring.fromString.call(void 0, base64NoNewlines, inputEncoding ? inputEncoding : "base64pad"), "base16");
210
150
  }, "base64ToHex");
211
151
  var hexToBase64 = /* @__PURE__ */ __name((input, targetEncoding) => {
212
152
  let hex = typeof input === "string" ? input : input.toString(16);
213
153
  if (hex.length % 2 === 1) {
214
154
  hex = `0${hex}`;
215
155
  }
216
- return (0, import_to_string.toString)((0, import_from_string.fromString)(hex, "base16"), targetEncoding ? targetEncoding : "base64pad");
156
+ return _tostring.toString.call(void 0, _fromstring.fromString.call(void 0, hex, "base16"), targetEncoding ? targetEncoding : "base64pad");
217
157
  }, "hexToBase64");
218
158
  var hexToPEM = /* @__PURE__ */ __name((hex, type) => {
219
159
  const base64 = hexToBase64(hex, "base64pad");
@@ -234,7 +174,7 @@ function PEMToDer(pem) {
234
174
  }
235
175
  __name(PEMToDer, "PEMToDer");
236
176
  function derToPEM(cert, headerKey) {
237
- const key = headerKey ?? "CERTIFICATE";
177
+ const key = _nullishCoalesce(headerKey, () => ( "CERTIFICATE"));
238
178
  if (cert.includes(key)) {
239
179
  return cert;
240
180
  }
@@ -267,13 +207,13 @@ var usage = /* @__PURE__ */ __name((jwk) => {
267
207
  }
268
208
  if (jwk.kty === "RSA") {
269
209
  if (jwk.d) {
270
- return jwk.alg?.toUpperCase()?.includes("QAEP") ? [
210
+ return _optionalChain([jwk, 'access', _4 => _4.alg, 'optionalAccess', _5 => _5.toUpperCase, 'call', _6 => _6(), 'optionalAccess', _7 => _7.includes, 'call', _8 => _8("QAEP")]) ? [
271
211
  "encrypt"
272
212
  ] : [
273
213
  "sign"
274
214
  ];
275
215
  }
276
- return jwk.alg?.toUpperCase()?.includes("QAEP") ? [
216
+ return _optionalChain([jwk, 'access', _9 => _9.alg, 'optionalAccess', _10 => _10.toUpperCase, 'call', _11 => _11(), 'optionalAccess', _12 => _12.includes, 'call', _13 => _13("QAEP")]) ? [
277
217
  "decrypt"
278
218
  ] : [
279
219
  "verify"
@@ -334,20 +274,20 @@ var generateRSAKeyAsPEM = /* @__PURE__ */ __name(async (scheme, hashAlgorithm, m
334
274
  const keypair = await globalCrypto(false).subtle.generateKey(params, true, keyUsage);
335
275
  const pkcs8 = await globalCrypto(false).subtle.exportKey("pkcs8", keypair.privateKey);
336
276
  const uint8Array = new Uint8Array(pkcs8);
337
- return derToPEM((0, import_to_string2.toString)(uint8Array, "base64pad"), "RSA PRIVATE KEY");
277
+ return derToPEM(_tostring.toString.call(void 0, uint8Array, "base64pad"), "RSA PRIVATE KEY");
338
278
  }, "generateRSAKeyAsPEM");
339
279
 
340
280
  // src/x509/rsa-signer.ts
341
- var import_from_string2 = require("uint8arrays/from-string");
342
- var import_to_string3 = require("uint8arrays/to-string");
281
+
282
+
343
283
  var RSASigner = class {
344
284
  static {
345
285
  __name(this, "RSASigner");
346
286
  }
347
- hashAlgorithm;
348
- jwk;
349
- key;
350
- scheme;
287
+
288
+
289
+
290
+
351
291
  /**
352
292
  *
353
293
  * @param key Either in PEM or JWK format (no raw hex keys here!)
@@ -355,12 +295,12 @@ var RSASigner = class {
355
295
  */
356
296
  constructor(key, opts) {
357
297
  if (typeof key === "string") {
358
- this.jwk = PEMToJwk(key, opts?.visibility);
298
+ this.jwk = PEMToJwk(key, _optionalChain([opts, 'optionalAccess', _14 => _14.visibility]));
359
299
  } else {
360
300
  this.jwk = key;
361
301
  }
362
- this.hashAlgorithm = opts?.hashAlgorithm ?? "SHA-256";
363
- this.scheme = opts?.scheme ?? "RSA-PSS";
302
+ this.hashAlgorithm = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _15 => _15.hashAlgorithm]), () => ( "SHA-256"));
303
+ this.scheme = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _16 => _16.scheme]), () => ( "RSA-PSS"));
364
304
  }
365
305
  getImportParams() {
366
306
  if (this.scheme === "RSA-PSS") {
@@ -382,7 +322,7 @@ var RSASigner = class {
382
322
  }
383
323
  bufferToString(buf) {
384
324
  const uint8Array = new Uint8Array(buf);
385
- return (0, import_to_string3.toString)(uint8Array, "base64url");
325
+ return _tostring.toString.call(void 0, uint8Array, "base64url");
386
326
  }
387
327
  async sign(data) {
388
328
  const input = data;
@@ -395,7 +335,7 @@ var RSASigner = class {
395
335
  }
396
336
  async verify(data, signature) {
397
337
  const jws = signature.includes(".") ? signature.split(".")[2] : signature;
398
- const input = typeof data == "string" ? (0, import_from_string2.fromString)(data, "utf-8") : data;
338
+ const input = typeof data == "string" ? _fromstring.fromString.call(void 0, data, "utf-8") : data;
399
339
  let key = await this.getKey();
400
340
  if (!key.usages.includes("verify")) {
401
341
  const verifyJwk = {
@@ -406,27 +346,27 @@ var RSASigner = class {
406
346
  delete verifyJwk.key_ops;
407
347
  key = await cryptoSubtleImportRSAKey(verifyJwk, this.scheme, this.hashAlgorithm);
408
348
  }
409
- const verificationResult = await globalCrypto(false).subtle.verify(this.getImportParams(), key, (0, import_from_string2.fromString)(jws, "base64url"), input);
349
+ const verificationResult = await globalCrypto(false).subtle.verify(this.getImportParams(), key, _fromstring.fromString.call(void 0, jws, "base64url"), input);
410
350
  return verificationResult;
411
351
  }
412
352
  };
413
353
 
414
354
  // src/x509/x509-validator.ts
415
- var import_asn1_schema = require("@peculiar/asn1-schema");
416
- var import_asn1_x509 = require("@peculiar/asn1-x509");
417
- var import_x509 = require("@peculiar/x509");
418
- var import_js_x509_utils = __toESM(require("js-x509-utils"), 1);
419
- var import_pkijs2 = require("pkijs");
420
- var import_tsyringe = require("tsyringe");
421
- var import_from_string3 = require("uint8arrays/from-string");
422
- var import_to_string4 = require("uint8arrays/to-string");
355
+ var _asn1schema = require('@peculiar/asn1-schema');
356
+ var _asn1x509 = require('@peculiar/asn1-x509');
357
+ var _x509 = require('@peculiar/x509');
358
+ var _jsx509utils = require('js-x509-utils'); var _jsx509utils2 = _interopRequireDefault(_jsx509utils);
359
+
360
+ var _tsyringe = require('tsyringe');
361
+
362
+
423
363
  var defaultCryptoEngine = /* @__PURE__ */ __name(() => {
424
364
  const name = "crypto";
425
- (0, import_pkijs2.setEngine)(name, new import_pkijs2.CryptoEngine({
365
+ _pkijs.setEngine.call(void 0, name, new (0, _pkijs.CryptoEngine)({
426
366
  name,
427
367
  crypto: globalCrypto(false)
428
368
  }));
429
- return (0, import_pkijs2.getCrypto)(true);
369
+ return _pkijs.getCrypto.call(void 0, true);
430
370
  }, "defaultCryptoEngine");
431
371
  var getCertificateInfo = /* @__PURE__ */ __name(async (certificate, opts) => {
432
372
  let publicKeyJWK;
@@ -441,7 +381,7 @@ var getCertificateInfo = /* @__PURE__ */ __name(async (certificate, opts) => {
441
381
  subject: {
442
382
  dn: getSubjectDN(certificate),
443
383
  subjectAlternativeNames: getSubjectAlternativeNames(certificate, {
444
- typeFilter: opts?.sanTypeFilter
384
+ typeFilter: _optionalChain([opts, 'optionalAccess', _17 => _17.sanTypeFilter])
445
385
  })
446
386
  },
447
387
  publicKeyJWK,
@@ -489,14 +429,14 @@ var validateX509CertificateChainImpl = /* @__PURE__ */ __name(async ({ reversed,
489
429
  ...chain
490
430
  ].reverse();
491
431
  const trustedCerts = trustedPEMs ? await Promise.all(trustedPEMs.map((raw) => parseCertificate(raw))) : void 0;
492
- const blindlyTrusted = (await Promise.all(blindlyTrustedAnchors.map((raw) => {
432
+ const blindlyTrusted = await _asyncNullishCoalesce((await Promise.all(blindlyTrustedAnchors.map((raw) => {
493
433
  try {
494
434
  return parseCertificate(raw);
495
435
  } catch (e) {
496
436
  console.log(`Failed to parse blindly trusted certificate ${raw}. Error: ${e.message}`);
497
437
  return void 0;
498
438
  }
499
- }))).filter((cert) => cert !== void 0) ?? [];
439
+ }))).filter((cert) => cert !== void 0), async () => ( []));
500
440
  const leafCert = x5cOrdereredChain[0];
501
441
  const chainLength = chain.length;
502
442
  var foundTrustAnchor = void 0;
@@ -511,7 +451,7 @@ var validateX509CertificateChainImpl = /* @__PURE__ */ __name(async ({ reversed,
511
451
  critical: false,
512
452
  message: `Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`,
513
453
  detailMessage: `Blindly trusted certificate ${blindlyTrustedCert.certificateInfo.subject.dn.DN} was found in the chain.`,
514
- trustAnchor: blindlyTrustedCert?.certificateInfo,
454
+ trustAnchor: _optionalChain([blindlyTrustedCert, 'optionalAccess', _18 => _18.certificateInfo]),
515
455
  verificationTime,
516
456
  certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),
517
457
  ...client && {
@@ -537,7 +477,7 @@ var validateX509CertificateChainImpl = /* @__PURE__ */ __name(async ({ reversed,
537
477
  critical: true,
538
478
  certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),
539
479
  message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`,
540
- detailMessage: `The certificate ${currentCert.certificateInfo.subject.dn.DN} with issuer ${currentCert.x509Certificate.issuer}, is not signed by the previous certificate ${previousCert?.certificateInfo.subject.dn.DN} with subject string ${previousCert?.x509Certificate.subject}.`,
480
+ detailMessage: `The certificate ${currentCert.certificateInfo.subject.dn.DN} with issuer ${currentCert.x509Certificate.issuer}, is not signed by the previous certificate ${_optionalChain([previousCert, 'optionalAccess', _19 => _19.certificateInfo, 'access', _20 => _20.subject, 'access', _21 => _21.dn, 'access', _22 => _22.DN])} with subject string ${_optionalChain([previousCert, 'optionalAccess', _23 => _23.x509Certificate, 'access', _24 => _24.subject])}.`,
541
481
  verificationTime,
542
482
  ...client && {
543
483
  client
@@ -547,8 +487,8 @@ var validateX509CertificateChainImpl = /* @__PURE__ */ __name(async ({ reversed,
547
487
  }
548
488
  const result = await currentCert.x509Certificate.verify({
549
489
  date: verificationTime,
550
- publicKey: previousCert?.x509Certificate?.publicKey
551
- }, (0, import_pkijs2.getCrypto)()?.crypto ?? crypto ?? global.crypto);
490
+ publicKey: _optionalChain([previousCert, 'optionalAccess', _25 => _25.x509Certificate, 'optionalAccess', _26 => _26.publicKey])
491
+ }, _nullishCoalesce(_nullishCoalesce(_optionalChain([_pkijs.getCrypto.call(void 0, ), 'optionalAccess', _27 => _27.crypto]), () => ( crypto)), () => ( global.crypto)));
552
492
  if (!result) {
553
493
  if (i == 0 && !reversed && !disallowReversedChain) {
554
494
  return await validateX509CertificateChainImpl({
@@ -573,14 +513,14 @@ var validateX509CertificateChainImpl = /* @__PURE__ */ __name(async ({ reversed,
573
513
  }
574
514
  };
575
515
  }
576
- foundTrustAnchor = foundTrustAnchor ?? trustedCerts?.find((trusted) => isSameCertificate(trusted.x509Certificate, currentCert.x509Certificate));
516
+ foundTrustAnchor = _nullishCoalesce(foundTrustAnchor, () => ( _optionalChain([trustedCerts, 'optionalAccess', _28 => _28.find, 'call', _29 => _29((trusted) => isSameCertificate(trusted.x509Certificate, currentCert.x509Certificate))])));
577
517
  if (i === 0 && chainLength === 1 && allowSingleNoCAChainElement) {
578
518
  return {
579
519
  error: false,
580
520
  critical: false,
581
521
  message: `Certificate chain succeeded as allow single cert result is allowed: ${leafCert.certificateInfo.subject.dn.DN}.`,
582
522
  certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),
583
- trustAnchor: foundTrustAnchor?.certificateInfo,
523
+ trustAnchor: _optionalChain([foundTrustAnchor, 'optionalAccess', _30 => _30.certificateInfo]),
584
524
  verificationTime,
585
525
  ...client && {
586
526
  client
@@ -588,14 +528,14 @@ var validateX509CertificateChainImpl = /* @__PURE__ */ __name(async ({ reversed,
588
528
  };
589
529
  }
590
530
  }
591
- if (foundTrustAnchor?.certificateInfo || allowNoTrustAnchorsFound) {
531
+ if (_optionalChain([foundTrustAnchor, 'optionalAccess', _31 => _31.certificateInfo]) || allowNoTrustAnchorsFound) {
592
532
  return {
593
533
  error: false,
594
534
  critical: false,
595
535
  message: `Certificate chain was valid`,
596
536
  certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),
597
- detailMessage: foundTrustAnchor ? `The leaf certificate ${leafCert.certificateInfo.subject.dn.DN} is part of a chain with trust anchor ${foundTrustAnchor?.certificateInfo.subject.dn.DN}.` : `The leaf certificate ${leafCert.certificateInfo.subject.dn.DN} and chain were valid, but no trust anchor has been found. Ignoring as user allowed (allowNoTrustAnchorsFound: ${allowNoTrustAnchorsFound}).)`,
598
- trustAnchor: foundTrustAnchor?.certificateInfo,
537
+ detailMessage: foundTrustAnchor ? `The leaf certificate ${leafCert.certificateInfo.subject.dn.DN} is part of a chain with trust anchor ${_optionalChain([foundTrustAnchor, 'optionalAccess', _32 => _32.certificateInfo, 'access', _33 => _33.subject, 'access', _34 => _34.dn, 'access', _35 => _35.DN])}.` : `The leaf certificate ${leafCert.certificateInfo.subject.dn.DN} and chain were valid, but no trust anchor has been found. Ignoring as user allowed (allowNoTrustAnchorsFound: ${allowNoTrustAnchorsFound}).)`,
538
+ trustAnchor: _optionalChain([foundTrustAnchor, 'optionalAccess', _36 => _36.certificateInfo]),
599
539
  verificationTime,
600
540
  ...client && {
601
541
  client
@@ -617,13 +557,13 @@ var validateX509CertificateChainImpl = /* @__PURE__ */ __name(async ({ reversed,
617
557
  var isSameCertificate = /* @__PURE__ */ __name((cert1, cert2) => {
618
558
  return cert1.rawData.toString() === cert2.rawData.toString();
619
559
  }, "isSameCertificate");
620
- var algorithmProvider = import_tsyringe.container.resolve(import_x509.AlgorithmProvider);
560
+ var algorithmProvider = _tsyringe.container.resolve(_x509.AlgorithmProvider);
621
561
  var getX509AlgorithmProvider = /* @__PURE__ */ __name(() => {
622
562
  return algorithmProvider;
623
563
  }, "getX509AlgorithmProvider");
624
564
  var parseCertificate = /* @__PURE__ */ __name(async (rawCert) => {
625
- const x509Certificate = new import_x509.X509Certificate(rawCert);
626
- const publicKeyInfo = import_asn1_schema.AsnParser.parse(x509Certificate.publicKey.rawData, import_asn1_x509.SubjectPublicKeyInfo);
565
+ const x509Certificate = new (0, _x509.X509Certificate)(rawCert);
566
+ const publicKeyInfo = _asn1schema.AsnParser.parse(x509Certificate.publicKey.rawData, _asn1x509.SubjectPublicKeyInfo);
627
567
  const publicKeyRaw = new Uint8Array(publicKeyInfo.subjectPublicKey);
628
568
  let publicKeyJwk = void 0;
629
569
  try {
@@ -672,7 +612,7 @@ var getSubjectDN = /* @__PURE__ */ __name((cert) => {
672
612
  var getDNObject = /* @__PURE__ */ __name((typesAndValues) => {
673
613
  const DN = {};
674
614
  for (const typeAndValue of typesAndValues) {
675
- const type = rdnmap[typeAndValue.type] ?? typeAndValue.type;
615
+ const type = _nullishCoalesce(rdnmap[typeAndValue.type], () => ( typeAndValue.type));
676
616
  DN[type] = typeAndValue.value.getValue();
677
617
  }
678
618
  return DN;
@@ -681,22 +621,22 @@ var getDNString = /* @__PURE__ */ __name((typesAndValues) => {
681
621
  return Object.entries(getDNObject(typesAndValues)).map(([key, value]) => `${key}=${value}`).join(",");
682
622
  }, "getDNString");
683
623
  var getCertificateSubjectPublicKeyJWK = /* @__PURE__ */ __name(async (pemOrDerCert) => {
684
- const pemOrDerStr = typeof pemOrDerCert === "string" ? (0, import_to_string4.toString)((0, import_from_string3.fromString)(pemOrDerCert, "base64pad"), "base64pad") : pemOrDerCert instanceof Uint8Array ? (0, import_to_string4.toString)(pemOrDerCert, "base64pad") : (0, import_to_string4.toString)((0, import_from_string3.fromString)(pemOrDerCert.toString("base64"), "base64pad"), "base64pad");
624
+ const pemOrDerStr = typeof pemOrDerCert === "string" ? _tostring.toString.call(void 0, _fromstring.fromString.call(void 0, pemOrDerCert, "base64pad"), "base64pad") : pemOrDerCert instanceof Uint8Array ? _tostring.toString.call(void 0, pemOrDerCert, "base64pad") : _tostring.toString.call(void 0, _fromstring.fromString.call(void 0, pemOrDerCert.toString("base64"), "base64pad"), "base64pad");
685
625
  const pem = derToPEM(pemOrDerStr);
686
626
  const certificate = pemOrDerToX509Certificate(pem);
687
627
  var jwk;
688
628
  try {
689
- const subtle = (0, import_pkijs2.getCrypto)(true).subtle;
629
+ const subtle = _pkijs.getCrypto.call(void 0, true).subtle;
690
630
  const pk = await certificate.getPublicKey(void 0, defaultCryptoEngine());
691
631
  jwk = await subtle.exportKey("jwk", pk);
692
632
  } catch (error) {
693
- console.log(`Error in primary get JWK from cert:`, error?.message);
633
+ console.log(`Error in primary get JWK from cert:`, _optionalChain([error, 'optionalAccess', _37 => _37.message]));
694
634
  }
695
635
  if (!jwk) {
696
636
  try {
697
- jwk = await import_js_x509_utils.default.toJwk(pem, "pem");
637
+ jwk = await _jsx509utils2.default.toJwk(pem, "pem");
698
638
  } catch (error) {
699
- console.log(`Error in secondary get JWK from cert as well:`, error?.message);
639
+ console.log(`Error in secondary get JWK from cert as well:`, _optionalChain([error, 'optionalAccess', _38 => _38.message]));
700
640
  }
701
641
  }
702
642
  if (!jwk) {
@@ -745,13 +685,13 @@ var validateCertificateChainMatchesClientIdScheme = /* @__PURE__ */ __name(async
745
685
  }, "validateCertificateChainMatchesClientIdScheme");
746
686
  var getSubjectAlternativeNames = /* @__PURE__ */ __name((certificate, opts) => {
747
687
  let typeFilter;
748
- if (opts?.clientIdSchemeFilter) {
688
+ if (_optionalChain([opts, 'optionalAccess', _39 => _39.clientIdSchemeFilter])) {
749
689
  typeFilter = opts.clientIdSchemeFilter === "x509_san_dns" ? [
750
690
  2
751
691
  ] : [
752
692
  6
753
693
  ];
754
- } else if (opts?.typeFilter) {
694
+ } else if (_optionalChain([opts, 'optionalAccess', _40 => _40.typeFilter])) {
755
695
  typeFilter = Array.isArray(opts.typeFilter) ? opts.typeFilter : [
756
696
  opts.typeFilter
757
697
  ];
@@ -761,7 +701,7 @@ var getSubjectAlternativeNames = /* @__PURE__ */ __name((certificate, opts) => {
761
701
  6
762
702
  ];
763
703
  }
764
- const parsedValue = certificate.extensions?.find((ext) => ext.extnID === import_pkijs2.id_SubjectAltName)?.parsedValue;
704
+ const parsedValue = _optionalChain([certificate, 'access', _41 => _41.extensions, 'optionalAccess', _42 => _42.find, 'call', _43 => _43((ext) => ext.extnID === _pkijs.id_SubjectAltName), 'optionalAccess', _44 => _44.parsedValue]);
765
705
  if (!parsedValue) {
766
706
  return [];
767
707
  }
@@ -773,4 +713,39 @@ var getSubjectAlternativeNames = /* @__PURE__ */ __name((certificate, opts) => {
773
713
  };
774
714
  });
775
715
  }, "getSubjectAlternativeNames");
716
+
717
+
718
+
719
+
720
+
721
+
722
+
723
+
724
+
725
+
726
+
727
+
728
+
729
+
730
+
731
+
732
+
733
+
734
+
735
+
736
+
737
+
738
+
739
+
740
+
741
+
742
+
743
+
744
+
745
+
746
+
747
+
748
+
749
+
750
+ exports.JwkKeyUse = JwkKeyUse; exports.PEMToBinary = PEMToBinary; exports.PEMToDer = PEMToDer; exports.PEMToHex = PEMToHex; exports.PEMToJwk = PEMToJwk; exports.RSASigner = RSASigner; exports.SubjectAlternativeGeneralName = SubjectAlternativeGeneralName; exports.areCertificatesEqual = areCertificatesEqual; exports.assertCertificateMatchesClientIdScheme = assertCertificateMatchesClientIdScheme; exports.base64ToHex = base64ToHex; exports.cryptoSubtleImportRSAKey = cryptoSubtleImportRSAKey; exports.derToPEM = derToPEM; exports.generateRSAKeyAsPEM = generateRSAKeyAsPEM; exports.getCertificateInfo = getCertificateInfo; exports.getCertificateSubjectPublicKeyJWK = getCertificateSubjectPublicKeyJWK; exports.getIssuerDN = getIssuerDN; exports.getSubjectAlternativeNames = getSubjectAlternativeNames; exports.getSubjectDN = getSubjectDN; exports.getX509AlgorithmProvider = getX509AlgorithmProvider; exports.hexKeyFromPEMBasedJwk = hexKeyFromPEMBasedJwk; exports.hexToBase64 = hexToBase64; exports.hexToPEM = hexToPEM; exports.jwkToPEM = jwkToPEM; exports.parseCertificate = parseCertificate; exports.pemCertChainTox5c = pemCertChainTox5c; exports.pemOrDerToX509Certificate = pemOrDerToX509Certificate; exports.privateKeyHexFromPEM = privateKeyHexFromPEM; exports.publicKeyHexFromPEM = publicKeyHexFromPEM; exports.signAlgorithmToSchemeAndHashAlg = signAlgorithmToSchemeAndHashAlg; exports.toKeyObject = toKeyObject; exports.validateCertificateChainMatchesClientIdScheme = validateCertificateChainMatchesClientIdScheme; exports.validateX509CertificateChain = validateX509CertificateChain; exports.x5cToPemCertChain = x5cToPemCertChain;
776
751
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types/index.ts","../src/x509/rsa-key.ts","../src/x509/crypto.ts","../src/x509/x509-utils.ts","../src/x509/rsa-signer.ts","../src/x509/x509-validator.ts"],"sourcesContent":["/**\n *\n * @packageDocumentation\n */\nexport * from './types'\nexport * from './x509'\n","export enum JwkKeyUse {\n Encryption = 'enc',\n Signature = 'sig',\n}\n\nexport type HashAlgorithm = 'SHA-256' | 'SHA-512'\n\nexport type KeyVisibility = 'public' | 'private'\n\nexport interface X509Opts {\n cn?: string // The certificate Common Name. Will be used as the KID for the private key. Uses alias if not provided.\n privateKeyPEM?: string // Optional as you also need to provide it in hex format, but advisable to use it\n certificatePEM?: string // Optional, as long as the certificate then is part of the certificateChainPEM\n certificateChainURL?: string // Certificate chain URL. If used this is where the certificateChainPEM will be hosted/found.\n certificateChainPEM?: string // Base64 (not url!) encoded DER certificate chain. Please provide even if certificateChainURL is used!\n}\n","// @ts-ignore\nimport { KeyUsage, CryptoKey, RsaHashedImportParams, RsaHashedKeyGenParams } from 'node'\n\n// @ts-ignore\nimport { toString } from 'uint8arrays/to-string'\nimport { HashAlgorithm } from '../types'\nimport { globalCrypto } from './crypto'\n\nimport { derToPEM } from './x509-utils'\nimport { JsonWebKey } from '@sphereon/ssi-types'\n\nexport type RSASignatureSchemes = 'RSASSA-PKCS1-V1_5' | 'RSA-PSS'\n\nexport type RSAEncryptionSchemes = 'RSAES-PKCS-v1_5 ' | 'RSAES-OAEP'\n\nconst usage = (jwk: JsonWebKey): KeyUsage[] => {\n if (jwk.key_ops && jwk.key_ops.length > 0) {\n return jwk.key_ops as KeyUsage[]\n }\n if (jwk.use) {\n const usages: KeyUsage[] = []\n if (jwk.use.includes('sig')) {\n usages.push('sign', 'verify')\n } else if (jwk.use.includes('enc')) {\n usages.push('encrypt', 'decrypt')\n }\n if (usages.length > 0) {\n return usages\n }\n }\n if (jwk.kty === 'RSA') {\n if (jwk.d) {\n return jwk.alg?.toUpperCase()?.includes('QAEP') ? ['encrypt'] : ['sign']\n }\n return jwk.alg?.toUpperCase()?.includes('QAEP') ? ['decrypt'] : ['verify']\n }\n // \"decrypt\" | \"deriveBits\" | \"deriveKey\" | \"encrypt\" | \"sign\" | \"unwrapKey\" | \"verify\" | \"wrapKey\";\n return jwk.d && jwk.kty !== 'RSA' ? ['sign', 'decrypt', 'verify', 'encrypt'] : ['verify']\n}\n\nexport const signAlgorithmToSchemeAndHashAlg = (signingAlg: string) => {\n const alg = signingAlg.toUpperCase()\n let scheme: RSAEncryptionSchemes | RSASignatureSchemes\n if (alg.startsWith('RS')) {\n scheme = 'RSASSA-PKCS1-V1_5'\n } else if (alg.startsWith('PS')) {\n scheme = 'RSA-PSS'\n } else {\n throw Error(`Invalid signing algorithm supplied ${signingAlg}`)\n }\n\n const hashAlgorithm = `SHA-${alg.substring(2)}` as HashAlgorithm\n return { scheme, hashAlgorithm }\n}\n\nexport const cryptoSubtleImportRSAKey = async (\n jwk: JsonWebKey,\n scheme: RSAEncryptionSchemes | RSASignatureSchemes,\n hashAlgorithm?: HashAlgorithm\n): Promise<CryptoKey> => {\n const hashName = hashAlgorithm ? hashAlgorithm : jwk.alg ? `SHA-${jwk.alg.substring(2)}` : 'SHA-256'\n\n const importParams: RsaHashedImportParams = { name: scheme, hash: hashName }\n return await globalCrypto(false).subtle.importKey('jwk', jwk as JsonWebKey, importParams, false, usage(jwk))\n}\n\nexport const generateRSAKeyAsPEM = async (\n scheme: RSAEncryptionSchemes | RSASignatureSchemes,\n hashAlgorithm?: HashAlgorithm,\n modulusLength?: number\n): Promise<string> => {\n const hashName = hashAlgorithm ? hashAlgorithm : 'SHA-256'\n\n const params: RsaHashedKeyGenParams = {\n name: scheme,\n hash: hashName,\n modulusLength: modulusLength ? modulusLength : 2048,\n publicExponent: new Uint8Array([1, 0, 1]),\n }\n const keyUsage: KeyUsage[] = scheme === 'RSA-PSS' || scheme === 'RSASSA-PKCS1-V1_5' ? ['sign', 'verify'] : ['encrypt', 'decrypt']\n\n const keypair = await globalCrypto(false).subtle.generateKey(params, true, keyUsage)\n const pkcs8 = await globalCrypto(false).subtle.exportKey('pkcs8', keypair.privateKey)\n\n const uint8Array = new Uint8Array(pkcs8)\n return derToPEM(toString(uint8Array, 'base64pad'), 'RSA PRIVATE KEY')\n}\n","import { webcrypto } from 'node:crypto'\nexport const globalCrypto = (setGlobal: boolean, suppliedCrypto?: webcrypto.Crypto): webcrypto.Crypto => {\n let webcrypto: webcrypto.Crypto\n if (typeof suppliedCrypto !== 'undefined') {\n webcrypto = suppliedCrypto\n } else if (typeof crypto !== 'undefined') {\n webcrypto = crypto\n } else if (typeof global.crypto !== 'undefined') {\n webcrypto = global.crypto\n } else {\n // @ts-ignore\n if (typeof global.window?.crypto?.subtle !== 'undefined') {\n // @ts-ignore\n webcrypto = global.window.crypto\n } else {\n // @ts-ignore\n webcrypto = require('crypto') as webcrypto.Crypto\n }\n }\n if (setGlobal) {\n global.crypto = webcrypto\n }\n\n return webcrypto\n}\n","import { X509Certificate } from '@peculiar/x509'\nimport { Certificate } from 'pkijs'\n// @ts-ignore\nimport { fromString } from 'uint8arrays/from-string'\n// @ts-ignore\nimport { toString } from 'uint8arrays/to-string'\n// @ts-ignore\nimport keyto from '@trust/keyto'\nimport { KeyVisibility } from '../types'\n\nimport { JsonWebKey } from '@sphereon/ssi-types'\n// Based on (MIT licensed):\n// https://github.com/hildjj/node-posh/blob/master/lib/index.js\nexport function pemCertChainTox5c(cert: string, maxDepth?: number): string[] {\n if (!maxDepth) {\n maxDepth = 0\n }\n /*\n * Convert a PEM-encoded certificate to the version used in the x5c element\n * of a [JSON Web Key](http://tools.ietf.org/html/draft-ietf-jose-json-web-key).\n *\n * `cert` PEM-encoded certificate chain\n * `maxdepth` The maximum number of certificates to use from the chain.\n */\n\n const intermediate = cert\n .replace(/-----[^\\n]+\\n?/gm, ',')\n .replace(/\\n/g, '')\n .replace(/\\r/g, '')\n let x5c = intermediate.split(',').filter(function (c) {\n return c.length > 0\n })\n if (maxDepth > 0) {\n x5c = x5c.splice(0, maxDepth)\n }\n return x5c\n}\n\nexport function x5cToPemCertChain(x5c: string[], maxDepth?: number): string {\n if (!maxDepth) {\n maxDepth = 0\n }\n const length = maxDepth === 0 ? x5c.length : Math.min(maxDepth, x5c.length)\n let pem = ''\n for (let i = 0; i < length; i++) {\n pem += derToPEM(x5c[i], 'CERTIFICATE')\n }\n return pem\n}\n\nexport const pemOrDerToX509Certificate = (cert: string | Uint8Array | X509Certificate): Certificate => {\n let DER: string | undefined = typeof cert === 'string' ? cert : undefined\n if (typeof cert === 'object' && !(cert instanceof Uint8Array)) {\n // X509Certificate object\n return Certificate.fromBER(cert.rawData)\n } else if (typeof cert !== 'string') {\n return Certificate.fromBER(cert)\n } else if (cert.includes('CERTIFICATE')) {\n DER = PEMToDer(cert)\n }\n if (!DER) {\n throw Error('Invalid cert input value supplied. PEM, DER, Bytes and X509Certificate object are supported')\n }\n return Certificate.fromBER(fromString(DER, 'base64pad'))\n}\n\nexport const areCertificatesEqual = (cert1: Certificate, cert2: Certificate): boolean => {\n return cert1.signatureValue.isEqual(cert2.signatureValue)\n}\n\nexport const toKeyObject = (PEM: string, visibility: KeyVisibility = 'public') => {\n const jwk = PEMToJwk(PEM, visibility)\n const keyVisibility: KeyVisibility = jwk.d ? 'private' : 'public'\n const keyHex = keyVisibility === 'private' ? privateKeyHexFromPEM(PEM) : publicKeyHexFromPEM(PEM)\n\n return {\n pem: hexToPEM(keyHex, visibility),\n jwk,\n keyHex,\n keyType: keyVisibility,\n }\n}\n\nexport const jwkToPEM = (jwk: JsonWebKey, visibility: KeyVisibility = 'public'): string => {\n return keyto.from(jwk, 'jwk').toString('pem', visibility === 'public' ? 'public_pkcs8' : 'private_pkcs8')\n}\n\nexport const PEMToJwk = (pem: string, visibility: KeyVisibility = 'public'): JsonWebKey => {\n return keyto.from(pem, 'pem').toJwk(visibility)\n}\nexport const privateKeyHexFromPEM = (PEM: string) => {\n return PEMToHex(PEM)\n}\n\nexport const hexKeyFromPEMBasedJwk = (jwk: JsonWebKey, visibility: KeyVisibility = 'public'): string => {\n if (visibility === 'private') {\n return privateKeyHexFromPEM(jwkToPEM(jwk, 'private'))\n } else {\n return publicKeyHexFromPEM(jwkToPEM(jwk, 'public'))\n }\n}\n\nexport const publicKeyHexFromPEM = (PEM: string) => {\n const hex = PEMToHex(PEM)\n if (PEM.includes('CERTIFICATE')) {\n throw Error('Cannot directly deduce public Key from PEM Certificate yet')\n } else if (!PEM.includes('PRIVATE')) {\n return hex\n }\n const publicJwk = PEMToJwk(PEM, 'public')\n const publicPEM = jwkToPEM(publicJwk, 'public')\n return PEMToHex(publicPEM)\n}\n\nexport const PEMToHex = (PEM: string, headerKey?: string): string => {\n if (PEM.indexOf('-----BEGIN ') == -1) {\n throw Error(`PEM header not found: ${headerKey}`)\n }\n\n let strippedPem: string\n if (headerKey) {\n strippedPem = PEM.replace(new RegExp('^[^]*-----BEGIN ' + headerKey + '-----'), '')\n strippedPem = strippedPem.replace(new RegExp('-----END ' + headerKey + '-----[^]*$'), '')\n } else {\n strippedPem = PEM.replace(/^[^]*-----BEGIN [^-]+-----/, '')\n strippedPem = strippedPem.replace(/-----END [^-]+-----[^]*$/, '')\n }\n return base64ToHex(strippedPem, 'base64pad')\n}\n\nexport function PEMToBinary(pem: string): Uint8Array {\n const pemContents = pem\n .replace(/^[^]*-----BEGIN [^-]+-----/, '')\n .replace(/-----END [^-]+-----[^]*$/, '')\n .replace(/\\s/g, '')\n\n return fromString(pemContents, 'base64pad')\n}\n\n/**\n * Converts a base64 encoded string to hex string, removing any non-base64 characters, including newlines\n * @param input The input in base64, with optional newlines\n * @param inputEncoding\n */\nexport const base64ToHex = (input: string, inputEncoding?: 'base64' | 'base64pad' | 'base64url' | 'base64urlpad') => {\n const base64NoNewlines = input.replace(/[^0-9A-Za-z_\\-~\\/+=]*/g, '')\n return toString(fromString(base64NoNewlines, inputEncoding ? inputEncoding : 'base64pad'), 'base16')\n}\n\nexport const hexToBase64 = (input: number | object | string, targetEncoding?: 'base64' | 'base64pad' | 'base64url' | 'base64urlpad'): string => {\n let hex = typeof input === 'string' ? input : input.toString(16)\n if (hex.length % 2 === 1) {\n hex = `0${hex}`\n }\n return toString(fromString(hex, 'base16'), targetEncoding ? targetEncoding : 'base64pad')\n}\n\nexport const hexToPEM = (hex: string, type: KeyVisibility): string => {\n const base64 = hexToBase64(hex, 'base64pad')\n const headerKey = type === 'private' ? 'RSA PRIVATE KEY' : 'PUBLIC KEY'\n if (type === 'private') {\n const pem = derToPEM(base64, headerKey)\n try {\n PEMToJwk(pem) // We only use it to test the private key\n return pem\n } catch (error) {\n return derToPEM(base64, 'PRIVATE KEY')\n }\n }\n return derToPEM(base64, headerKey)\n}\n\nexport function PEMToDer(pem: string): string {\n return pem.replace(/(-----(BEGIN|END) CERTIFICATE-----|[\\n\\r])/g, '')\n}\n\nexport function derToPEM(cert: string, headerKey?: 'PUBLIC KEY' | 'RSA PRIVATE KEY' | 'PRIVATE KEY' | 'CERTIFICATE'): string {\n const key = headerKey ?? 'CERTIFICATE'\n if (cert.includes(key)) {\n // Was already in PEM it seems\n return cert\n }\n const matches = cert.match(/.{1,64}/g)\n if (!matches) {\n throw Error('Invalid cert input value supplied')\n }\n return `-----BEGIN ${key}-----\\n${matches.join('\\n')}\\n-----END ${key}-----\\n`\n}\n","// @ts-ignore\nimport { fromString } from 'uint8arrays/from-string'\n// @ts-ignore\nimport { toString } from 'uint8arrays/to-string'\nimport { HashAlgorithm, KeyVisibility } from '../types'\nimport { globalCrypto } from './crypto'\nimport { cryptoSubtleImportRSAKey, RSAEncryptionSchemes, RSASignatureSchemes } from './rsa-key'\nimport { PEMToJwk } from './x509-utils'\nimport { JsonWebKey } from '@sphereon/ssi-types'\n// @ts-ignore\nimport { CryptoKey, RsaPssParams, AlgorithmIdentifier } from 'node'\nexport class RSASigner {\n private readonly hashAlgorithm: HashAlgorithm\n private readonly jwk: JsonWebKey\n\n private key: CryptoKey | undefined\n private readonly scheme: RSAEncryptionSchemes | RSASignatureSchemes\n\n /**\n *\n * @param key Either in PEM or JWK format (no raw hex keys here!)\n * @param opts The algorithm and signature/encryption schemes\n */\n constructor(\n key: string | JsonWebKey,\n opts?: { hashAlgorithm?: HashAlgorithm; scheme?: RSAEncryptionSchemes | RSASignatureSchemes; visibility?: KeyVisibility }\n ) {\n if (typeof key === 'string') {\n this.jwk = PEMToJwk(key, opts?.visibility)\n } else {\n this.jwk = key\n }\n\n this.hashAlgorithm = opts?.hashAlgorithm ?? 'SHA-256'\n this.scheme = opts?.scheme ?? 'RSA-PSS'\n }\n\n private getImportParams(): AlgorithmIdentifier | RsaPssParams {\n if (this.scheme === 'RSA-PSS') {\n return { name: this.scheme, saltLength: 32 }\n }\n return { name: this.scheme /*, hash: this.hashAlgorithm*/ }\n }\n\n private async getKey(): Promise<CryptoKey> {\n if (!this.key) {\n this.key = await cryptoSubtleImportRSAKey(this.jwk, this.scheme, this.hashAlgorithm)\n }\n return this.key\n }\n\n private bufferToString(buf: ArrayBuffer) {\n const uint8Array = new Uint8Array(buf)\n return toString(uint8Array, 'base64url') // Needs to be base64url for JsonWebSignature2020. Don't change!\n }\n\n public async sign(data: Uint8Array): Promise<string> {\n const input = data\n const key = await this.getKey()\n const signature = this.bufferToString(await globalCrypto(false).subtle.sign(this.getImportParams(), key, input))\n if (!signature) {\n throw Error('Could not sign input data')\n }\n\n // base64url signature\n return signature\n }\n\n public async verify(data: string | Uint8Array, signature: string): Promise<boolean> {\n const jws = signature.includes('.') ? signature.split('.')[2] : signature\n\n const input = typeof data == 'string' ? fromString(data, 'utf-8') : data\n\n let key = await this.getKey()\n if (!key.usages.includes('verify')) {\n const verifyJwk = { ...this.jwk }\n delete verifyJwk.d\n delete verifyJwk.use\n delete verifyJwk.key_ops\n key = await cryptoSubtleImportRSAKey(verifyJwk, this.scheme, this.hashAlgorithm)\n }\n const verificationResult = await globalCrypto(false).subtle.verify(this.getImportParams(), key, fromString(jws, 'base64url'), input)\n return verificationResult\n }\n}\n","import { AsnParser } from '@peculiar/asn1-schema'\nimport { SubjectPublicKeyInfo } from '@peculiar/asn1-x509'\nimport { AlgorithmProvider, X509Certificate } from '@peculiar/x509'\n// import {calculateJwkThumbprint} from \"@sphereon/ssi-sdk-ext.key-utils\";\nimport { JWK } from '@sphereon/ssi-types'\nimport x509 from 'js-x509-utils'\nimport { AltName, AttributeTypeAndValue, Certificate, CryptoEngine, getCrypto, id_SubjectAltName, setEngine } from 'pkijs'\nimport { container } from 'tsyringe'\n// @ts-ignore\nimport { fromString } from 'uint8arrays/from-string'\n// @ts-ignore\nimport { toString } from 'uint8arrays/to-string'\nimport { globalCrypto } from './crypto'\nimport { areCertificatesEqual, derToPEM, pemOrDerToX509Certificate } from './x509-utils'\n\nexport type DNInfo = {\n DN: string\n attributes: Record<string, string>\n}\n\nexport type CertificateInfo = {\n certificate?: any // We need to fix the schema generator for this to be Certificate(Json) from pkijs\n notBefore: Date\n notAfter: Date\n publicKeyJWK?: any\n issuer: {\n dn: DNInfo\n }\n subject: {\n dn: DNInfo\n subjectAlternativeNames: SubjectAlternativeName[]\n }\n}\n\nexport type X509ValidationResult = {\n error: boolean\n critical: boolean\n message: string\n detailMessage?: string\n verificationTime: Date\n certificateChain?: Array<CertificateInfo>\n trustAnchor?: CertificateInfo\n client?: {\n // In case client id and scheme were passed in we return them for easy access. It means they are validated\n clientId: string\n clientIdScheme: ClientIdScheme\n }\n}\n\nconst defaultCryptoEngine = () => {\n const name = 'crypto'\n setEngine(name, new CryptoEngine({ name, crypto: globalCrypto(false) }))\n return getCrypto(true)\n}\n\nexport const getCertificateInfo = async (\n certificate: Certificate,\n opts?: {\n sanTypeFilter: SubjectAlternativeGeneralName | SubjectAlternativeGeneralName[]\n }\n): Promise<CertificateInfo> => {\n let publicKeyJWK: JWK | undefined\n try {\n publicKeyJWK = (await getCertificateSubjectPublicKeyJWK(certificate)) as JWK\n } catch (e) {}\n return {\n issuer: { dn: getIssuerDN(certificate) },\n subject: {\n dn: getSubjectDN(certificate),\n subjectAlternativeNames: getSubjectAlternativeNames(certificate, { typeFilter: opts?.sanTypeFilter }),\n },\n publicKeyJWK,\n notBefore: certificate.notBefore.value,\n notAfter: certificate.notAfter.value,\n // certificate\n } satisfies CertificateInfo\n}\n\nexport type X509CertificateChainValidationOpts = {\n // If no trust anchor is found, but the chain itself checks out, allow. (defaults to false:)\n allowNoTrustAnchorsFound?: boolean\n\n // Trust the supplied root from the chain, when no anchors are being passed in.\n trustRootWhenNoAnchors?: boolean\n // Do not perform a chain validation check if the chain only has a single value. This means only the certificate itself will be validated. No chain checks for CA certs will be performed. Only used when the cert has no issuer\n allowSingleNoCAChainElement?: boolean\n // WARNING: Do not use in production\n // Similar to regular trust anchors, but no validation is performed whatsoever. Do not use in production settings! Can be handy with self generated certificates as we perform many validations, making it hard to test with self-signed certs. Only applied in case a chain with 1 element is passed in to really make sure people do not abuse this option\n blindlyTrustedAnchors?: string[]\n\n disallowReversedChain?: boolean\n\n client?: {\n // If provided both are required. Validates the leaf certificate against the clientId and scheme\n clientId: string\n clientIdScheme: ClientIdScheme\n }\n}\n\nexport const validateX509CertificateChain = async ({\n chain: pemOrDerChain,\n trustAnchors,\n verificationTime = new Date(),\n opts = {\n // If no trust anchor is found, but the chain itself checks out, allow. (defaults to false:)\n allowNoTrustAnchorsFound: false,\n trustRootWhenNoAnchors: false,\n allowSingleNoCAChainElement: true,\n blindlyTrustedAnchors: [],\n disallowReversedChain: false,\n },\n}: {\n chain: (Uint8Array | string)[]\n trustAnchors?: string[]\n verificationTime?: Date\n opts?: X509CertificateChainValidationOpts\n}): Promise<X509ValidationResult> => {\n // We allow 1 reversal. We reverse by default as the implementation expects the root ca first, whilst x5c is the opposite. Reversed becomes true if the impl reverses the chain\n return await validateX509CertificateChainImpl({\n reversed: false,\n chain: [...pemOrDerChain].reverse(),\n trustAnchors,\n verificationTime,\n opts,\n })\n}\nconst validateX509CertificateChainImpl = async ({\n reversed,\n chain: pemOrDerChain,\n trustAnchors,\n verificationTime: verifyAt,\n opts,\n}: {\n reversed: boolean\n chain: (Uint8Array | string)[]\n trustAnchors?: string[]\n verificationTime: Date | string // string for REST API\n opts: X509CertificateChainValidationOpts\n}): Promise<X509ValidationResult> => {\n const verificationTime: Date = typeof verifyAt === 'string' ? new Date(verifyAt) : verifyAt\n const {\n allowNoTrustAnchorsFound = false,\n trustRootWhenNoAnchors = false,\n allowSingleNoCAChainElement = true,\n blindlyTrustedAnchors = [],\n disallowReversedChain = false,\n client,\n } = opts\n const trustedPEMs = trustRootWhenNoAnchors && !trustAnchors ? [pemOrDerChain[pemOrDerChain.length - 1]] : trustAnchors\n\n if (pemOrDerChain.length === 0) {\n return {\n error: true,\n critical: true,\n message: 'Certificate chain in DER or PEM format must not be empty',\n verificationTime,\n }\n }\n defaultCryptoEngine()\n\n // x5c always starts with the leaf cert at index 0 and then the cas. Our internal pkijs service expects it the other way around. Before calling this function the change has been revered\n const chain = await Promise.all(pemOrDerChain.map((raw) => parseCertificate(raw)))\n const x5cOrdereredChain = reversed ? [...chain] : [...chain].reverse()\n\n const trustedCerts = trustedPEMs ? await Promise.all(trustedPEMs.map((raw) => parseCertificate(raw))) : undefined\n const blindlyTrusted =\n (\n await Promise.all(\n blindlyTrustedAnchors.map((raw) => {\n try {\n return parseCertificate(raw)\n } catch (e) {\n // @ts-ignore\n console.log(`Failed to parse blindly trusted certificate ${raw}. Error: ${e.message}`)\n return undefined\n }\n })\n )\n ).filter((cert): cert is ParsedCertificate => cert !== undefined) ?? []\n const leafCert = x5cOrdereredChain[0]\n\n const chainLength = chain.length\n var foundTrustAnchor: ParsedCertificate | undefined = undefined\n for (let i = 0; i < chainLength; i++) {\n const currentCert = chain[i]\n const previousCert = i > 0 ? chain[i - 1] : undefined\n const blindlyTrustedCert = blindlyTrusted.find((trusted) => areCertificatesEqual(trusted.certificate, currentCert.certificate))\n if (blindlyTrustedCert) {\n console.log(`Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`)\n return {\n error: false,\n critical: false,\n message: `Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`,\n detailMessage: `Blindly trusted certificate ${blindlyTrustedCert.certificateInfo.subject.dn.DN} was found in the chain.`,\n trustAnchor: blindlyTrustedCert?.certificateInfo,\n verificationTime,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n ...(client && { client }),\n }\n }\n if (previousCert) {\n if (currentCert.x509Certificate.issuer !== previousCert.x509Certificate.subject) {\n if (!reversed && !disallowReversedChain) {\n return await validateX509CertificateChainImpl({\n reversed: true,\n chain: [...pemOrDerChain].reverse(),\n opts,\n verificationTime,\n trustAnchors,\n })\n }\n return {\n error: true,\n critical: true,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`,\n detailMessage: `The certificate ${currentCert.certificateInfo.subject.dn.DN} with issuer ${currentCert.x509Certificate.issuer}, is not signed by the previous certificate ${previousCert?.certificateInfo.subject.dn.DN} with subject string ${previousCert?.x509Certificate.subject}.`,\n verificationTime,\n ...(client && { client }),\n }\n }\n }\n const result = await currentCert.x509Certificate.verify(\n {\n date: verificationTime,\n publicKey: previousCert?.x509Certificate?.publicKey,\n },\n getCrypto()?.crypto ?? crypto ?? global.crypto\n )\n if (!result) {\n // First cert needs to be self signed\n if (i == 0 && !reversed && !disallowReversedChain) {\n return await validateX509CertificateChainImpl({\n reversed: true,\n chain: [...pemOrDerChain].reverse(),\n opts,\n verificationTime,\n trustAnchors,\n })\n }\n\n return {\n error: true,\n critical: true,\n message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n detailMessage: `Verification of the certificate ${currentCert.certificateInfo.subject.dn.DN} with issuer ${\n currentCert.x509Certificate.issuer\n } failed. Public key: ${JSON.stringify(currentCert.certificateInfo.publicKeyJWK)}.`,\n verificationTime,\n ...(client && { client }),\n }\n }\n\n foundTrustAnchor = foundTrustAnchor ?? trustedCerts?.find((trusted) => isSameCertificate(trusted.x509Certificate, currentCert.x509Certificate))\n\n if (i === 0 && chainLength === 1 && allowSingleNoCAChainElement) {\n return {\n error: false,\n critical: false,\n message: `Certificate chain succeeded as allow single cert result is allowed: ${leafCert.certificateInfo.subject.dn.DN}.`,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n trustAnchor: foundTrustAnchor?.certificateInfo,\n verificationTime,\n ...(client && { client }),\n }\n }\n }\n\n if (foundTrustAnchor?.certificateInfo || allowNoTrustAnchorsFound) {\n return {\n error: false,\n critical: false,\n message: `Certificate chain was valid`,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n detailMessage: foundTrustAnchor\n ? `The leaf certificate ${leafCert.certificateInfo.subject.dn.DN} is part of a chain with trust anchor ${foundTrustAnchor?.certificateInfo.subject.dn.DN}.`\n : `The leaf certificate ${leafCert.certificateInfo.subject.dn.DN} and chain were valid, but no trust anchor has been found. Ignoring as user allowed (allowNoTrustAnchorsFound: ${allowNoTrustAnchorsFound}).)`,\n trustAnchor: foundTrustAnchor?.certificateInfo,\n verificationTime,\n ...(client && { client }),\n }\n }\n\n return {\n error: true,\n critical: true,\n message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n detailMessage: `No trust anchor was found in the chain. between (intermediate) CA ${\n x5cOrdereredChain[chain.length - 1].certificateInfo.subject.dn.DN\n } and leaf ${x5cOrdereredChain[0].certificateInfo.subject.dn.DN}.`,\n verificationTime,\n ...(client && { client }),\n }\n}\n\nconst isSameCertificate = (cert1: X509Certificate, cert2: X509Certificate): boolean => {\n return cert1.rawData.toString() === cert2.rawData.toString()\n}\n\nconst algorithmProvider: AlgorithmProvider = container.resolve(AlgorithmProvider)\nexport const getX509AlgorithmProvider = (): AlgorithmProvider => {\n return algorithmProvider\n}\n\nexport type ParsedCertificate = {\n publicKeyInfo: SubjectPublicKeyInfo\n publicKeyJwk?: JWK\n publicKeyRaw: Uint8Array\n // @ts-ignore\n publicKeyAlgorithm: Algorithm\n certificateInfo: CertificateInfo\n certificate: Certificate\n x509Certificate: X509Certificate\n}\n\nexport const parseCertificate = async (rawCert: string | Uint8Array): Promise<ParsedCertificate> => {\n const x509Certificate = new X509Certificate(rawCert)\n const publicKeyInfo = AsnParser.parse(x509Certificate.publicKey.rawData, SubjectPublicKeyInfo)\n const publicKeyRaw = new Uint8Array(publicKeyInfo.subjectPublicKey)\n let publicKeyJwk: JWK | undefined = undefined\n try {\n publicKeyJwk = (await getCertificateSubjectPublicKeyJWK(new Uint8Array(x509Certificate.rawData))) as JWK\n } catch (e: any) {\n console.error(e.message)\n }\n const certificate = pemOrDerToX509Certificate(rawCert)\n const certificateInfo = await getCertificateInfo(certificate)\n const publicKeyAlgorithm = getX509AlgorithmProvider().toWebAlgorithm(publicKeyInfo.algorithm)\n return {\n publicKeyAlgorithm,\n publicKeyInfo,\n publicKeyJwk,\n publicKeyRaw,\n certificateInfo,\n certificate,\n x509Certificate,\n }\n}\n/*\n\n/!**\n *\n * @param pemOrDerChain The order must be that the Certs signing another cert must come one after another. So first the signing cert, then any cert signing that cert and so on\n * @param trustedPEMs\n * @param verificationTime\n * @param opts\n *!/\nexport const validateX509CertificateChainOrg = async ({\n chain: pemOrDerChain,\n trustAnchors,\n verificationTime = new Date(),\n opts = {\n trustRootWhenNoAnchors: false,\n allowSingleNoCAChainElement: true,\n blindlyTrustedAnchors: [],\n },\n }: {\n chain: (Uint8Array | string)[]\n trustAnchors?: string[]\n verificationTime?: Date\n opts?: X509CertificateChainValidationOpts\n}): Promise<X509ValidationResult> => {\n const {\n trustRootWhenNoAnchors = false,\n allowSingleNoCAChainElement = true,\n blindlyTrustedAnchors = [],\n client\n } = opts\n const trustedPEMs = trustRootWhenNoAnchors && !trustAnchors ? [pemOrDerChain[pemOrDerChain.length - 1]] : trustAnchors\n\n if (pemOrDerChain.length === 0) {\n return {\n error: true,\n critical: true,\n message: 'Certificate chain in DER or PEM format must not be empty',\n verificationTime,\n }\n }\n\n // x5c always starts with the leaf cert at index 0 and then the cas. Our internal pkijs service expects it the other way around\n const certs = pemOrDerChain.map(pemOrDerToX509Certificate).reverse()\n const trustedCerts = trustedPEMs ? trustedPEMs.map(pemOrDerToX509Certificate) : undefined\n defaultCryptoEngine()\n\n if (pemOrDerChain.length === 1) {\n const singleCert = typeof pemOrDerChain[0] === 'string' ? pemOrDerChain[0] : u8a.toString(pemOrDerChain[0], 'base64pad')\n const cert = pemOrDerToX509Certificate(singleCert)\n if (client) {\n const validation = await validateCertificateChainMatchesClientIdScheme(cert, client.clientId, client.clientIdScheme)\n if (validation.error) {\n return validation\n }\n }\n if (blindlyTrustedAnchors.includes(singleCert)) {\n console.log(`Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`)\n return {\n error: false,\n critical: true,\n message: `Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`,\n verificationTime,\n certificateChain: [await getCertificateInfo(cert)],\n ...(client && {client}),\n }\n }\n if (allowSingleNoCAChainElement) {\n const subjectDN = getSubjectDN(cert).DN\n if (!getIssuerDN(cert).DN || getIssuerDN(cert).DN === subjectDN) {\n const passed = await cert.verify()\n return {\n error: !passed,\n critical: true,\n message: `Certificate chain validation for ${subjectDN}: ${passed ? 'successful' : 'failed'}.`,\n verificationTime,\n certificateChain: [await getCertificateInfo(cert)],\n ...(client && {client}),\n }\n }\n }\n }\n\n const validationEngine = new CertificateChainValidationEngine({\n certs /!*crls: [crl1], ocsps: [ocsp1], *!/,\n checkDate: verificationTime,\n trustedCerts,\n })\n\n try {\n const verification = await validationEngine.verify()\n if (!verification.result || !verification.certificatePath) {\n return {\n error: true,\n critical: true,\n message: verification.resultMessage !== '' ? verification.resultMessage : `Certificate chain validation failed.`,\n verificationTime,\n ...(client && {client}),\n }\n }\n const certPath = verification.certificatePath\n if (client) {\n const clientIdValidation = await validateCertificateChainMatchesClientIdScheme(certs[0], client.clientId, client.clientIdScheme)\n if (clientIdValidation.error) {\n return clientIdValidation\n }\n }\n let certInfos: Array<CertificateInfo> | undefined\n\n for (const certificate of certPath) {\n try {\n certInfos?.push(await getCertificateInfo(certificate))\n } catch (e: any) {\n console.log(`Error getting certificate info ${e.message}`)\n }\n }\n\n\n return {\n error: false,\n critical: false,\n message: `Certificate chain was valid`,\n verificationTime,\n certificateChain: certInfos,\n ...(client && {client}),\n }\n } catch (error: any) {\n return {\n error: true,\n critical: true,\n message: `Certificate chain was invalid, ${error.message ?? '<unknown error>'}`,\n verificationTime,\n ...(client && {client}),\n }\n }\n}\n*/\n\nconst rdnmap: Record<string, string> = {\n '2.5.4.6': 'C',\n '2.5.4.10': 'O',\n '2.5.4.11': 'OU',\n '2.5.4.3': 'CN',\n '2.5.4.7': 'L',\n '2.5.4.8': 'ST',\n '2.5.4.12': 'T',\n '2.5.4.42': 'GN',\n '2.5.4.43': 'I',\n '2.5.4.4': 'SN',\n '1.2.840.113549.1.9.1': 'E-mail',\n}\n\nexport const getIssuerDN = (cert: Certificate): DNInfo => {\n return {\n DN: getDNString(cert.issuer.typesAndValues),\n attributes: getDNObject(cert.issuer.typesAndValues),\n }\n}\n\nexport const getSubjectDN = (cert: Certificate): DNInfo => {\n return {\n DN: getDNString(cert.subject.typesAndValues),\n attributes: getDNObject(cert.subject.typesAndValues),\n }\n}\n\nconst getDNObject = (typesAndValues: AttributeTypeAndValue[]): Record<string, string> => {\n const DN: Record<string, string> = {}\n for (const typeAndValue of typesAndValues) {\n const type = rdnmap[typeAndValue.type] ?? typeAndValue.type\n DN[type] = typeAndValue.value.getValue()\n }\n return DN\n}\nconst getDNString = (typesAndValues: AttributeTypeAndValue[]): string => {\n return Object.entries(getDNObject(typesAndValues))\n .map(([key, value]) => `${key}=${value}`)\n .join(',')\n}\n\nexport const getCertificateSubjectPublicKeyJWK = async (pemOrDerCert: string | Uint8Array | Certificate): Promise<JWK> => {\n const pemOrDerStr =\n typeof pemOrDerCert === 'string'\n ? toString(fromString(pemOrDerCert, 'base64pad'), 'base64pad')\n : pemOrDerCert instanceof Uint8Array\n ? toString(pemOrDerCert, 'base64pad')\n : toString(fromString(pemOrDerCert.toString('base64'), 'base64pad'), 'base64pad')\n const pem = derToPEM(pemOrDerStr)\n const certificate = pemOrDerToX509Certificate(pem)\n var jwk: JWK | undefined\n try {\n const subtle = getCrypto(true).subtle\n const pk = await certificate.getPublicKey(undefined, defaultCryptoEngine())\n jwk = (await subtle.exportKey('jwk', pk)) as JWK | undefined\n } catch (error: any) {\n console.log(`Error in primary get JWK from cert:`, error?.message)\n }\n if (!jwk) {\n try {\n jwk = (await x509.toJwk(pem, 'pem')) as JWK\n } catch (error: any) {\n console.log(`Error in secondary get JWK from cert as well:`, error?.message)\n }\n }\n if (!jwk) {\n throw Error(`Failed to get JWK from certificate ${pem}`)\n }\n return jwk\n}\n\n/**\n * otherName [0] OtherName,\n * rfc822Name [1] IA5String,\n * dNSName [2] IA5String,\n * x400Address [3] ORAddress,\n * directoryName [4] Name,\n * ediPartyName [5] EDIPartyName,\n * uniformResourceIdentifier [6] IA5String,\n * iPAddress [7] OCTET STRING,\n * registeredID [8] OBJECT IDENTIFIER }\n */\nexport enum SubjectAlternativeGeneralName {\n rfc822Name = 1, // email\n dnsName = 2,\n uniformResourceIdentifier = 6,\n ipAddress = 7,\n}\n\nexport interface SubjectAlternativeName {\n value: string\n type: SubjectAlternativeGeneralName\n}\n\nexport type ClientIdScheme = 'x509_san_dns' | 'x509_san_uri'\n\nexport const assertCertificateMatchesClientIdScheme = (certificate: Certificate, clientId: string, clientIdScheme: ClientIdScheme): void => {\n const sans = getSubjectAlternativeNames(certificate, { clientIdSchemeFilter: clientIdScheme })\n const clientIdMatches = sans.find((san) => san.value === clientId)\n if (!clientIdMatches) {\n throw Error(\n `Client id scheme ${clientIdScheme} used had no matching subject alternative names in certificate with DN ${\n getSubjectDN(certificate).DN\n }. SANS: ${sans.map((san) => san.value).join(',')}`\n )\n }\n}\n\nexport const validateCertificateChainMatchesClientIdScheme = async (\n certificate: Certificate,\n clientId: string,\n clientIdScheme: ClientIdScheme\n): Promise<X509ValidationResult> => {\n const result = {\n error: true,\n critical: true,\n message: `Client Id ${clientId} was not present in certificate using scheme ${clientIdScheme}`,\n client: {\n clientId,\n clientIdScheme,\n },\n certificateChain: [await getCertificateInfo(certificate)],\n verificationTime: new Date(),\n }\n try {\n assertCertificateMatchesClientIdScheme(certificate, clientId, clientIdScheme)\n } catch (error) {\n return result\n }\n result.error = false\n result.message = `Client Id ${clientId} was present in certificate using scheme ${clientIdScheme}`\n return result\n}\n\nexport const getSubjectAlternativeNames = (\n certificate: Certificate,\n opts?: {\n typeFilter?: SubjectAlternativeGeneralName | SubjectAlternativeGeneralName[]\n // When a clientIdchemeFilter is passed in it will always override the above type filter\n clientIdSchemeFilter?: ClientIdScheme\n }\n): SubjectAlternativeName[] => {\n let typeFilter: SubjectAlternativeGeneralName[]\n if (opts?.clientIdSchemeFilter) {\n typeFilter =\n opts.clientIdSchemeFilter === 'x509_san_dns'\n ? [SubjectAlternativeGeneralName.dnsName]\n : [SubjectAlternativeGeneralName.uniformResourceIdentifier]\n } else if (opts?.typeFilter) {\n typeFilter = Array.isArray(opts.typeFilter) ? opts.typeFilter : [opts.typeFilter]\n } else {\n typeFilter = [SubjectAlternativeGeneralName.dnsName, SubjectAlternativeGeneralName.uniformResourceIdentifier]\n }\n const parsedValue = certificate.extensions?.find((ext) => ext.extnID === id_SubjectAltName)?.parsedValue as AltName\n if (!parsedValue) {\n return []\n }\n const altNames = parsedValue.toJSON().altNames\n return altNames\n .filter((altName) => typeFilter.includes(altName.type))\n .map((altName) => {\n return { type: altName.type, value: altName.value } satisfies SubjectAlternativeName\n })\n}\n"],"mappings":"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","names":["JwkKeyUse","import_to_string","globalCrypto","setGlobal","suppliedCrypto","webcrypto","crypto","global","window","subtle","require","pemCertChainTox5c","cert","maxDepth","intermediate","replace","x5c","split","filter","c","length","splice","x5cToPemCertChain","Math","min","pem","i","derToPEM","pemOrDerToX509Certificate","DER","undefined","Uint8Array","Certificate","fromBER","rawData","includes","PEMToDer","Error","fromString","areCertificatesEqual","cert1","cert2","signatureValue","isEqual","toKeyObject","PEM","visibility","jwk","PEMToJwk","keyVisibility","d","keyHex","privateKeyHexFromPEM","publicKeyHexFromPEM","hexToPEM","keyType","jwkToPEM","keyto","from","toString","toJwk","PEMToHex","hexKeyFromPEMBasedJwk","hex","publicJwk","publicPEM","headerKey","indexOf","strippedPem","RegExp","base64ToHex","PEMToBinary","pemContents","input","inputEncoding","base64NoNewlines","hexToBase64","targetEncoding","type","base64","error","key","matches","match","join","usage","jwk","key_ops","length","use","usages","includes","push","kty","d","alg","toUpperCase","signAlgorithmToSchemeAndHashAlg","signingAlg","scheme","startsWith","Error","hashAlgorithm","substring","cryptoSubtleImportRSAKey","hashName","importParams","name","hash","globalCrypto","subtle","importKey","generateRSAKeyAsPEM","modulusLength","params","publicExponent","Uint8Array","keyUsage","keypair","generateKey","pkcs8","exportKey","privateKey","uint8Array","derToPEM","toString","import_from_string","import_to_string","RSASigner","hashAlgorithm","jwk","key","scheme","constructor","opts","PEMToJwk","visibility","getImportParams","name","saltLength","getKey","cryptoSubtleImportRSAKey","bufferToString","buf","uint8Array","Uint8Array","toString","sign","data","input","signature","globalCrypto","subtle","Error","verify","jws","includes","split","fromString","usages","verifyJwk","d","use","key_ops","verificationResult","import_pkijs","import_from_string","import_to_string","defaultCryptoEngine","name","setEngine","CryptoEngine","crypto","globalCrypto","getCrypto","getCertificateInfo","certificate","opts","publicKeyJWK","getCertificateSubjectPublicKeyJWK","e","issuer","dn","getIssuerDN","subject","getSubjectDN","subjectAlternativeNames","getSubjectAlternativeNames","typeFilter","sanTypeFilter","notBefore","value","notAfter","validateX509CertificateChain","chain","pemOrDerChain","trustAnchors","verificationTime","Date","allowNoTrustAnchorsFound","trustRootWhenNoAnchors","allowSingleNoCAChainElement","blindlyTrustedAnchors","disallowReversedChain","validateX509CertificateChainImpl","reversed","reverse","verifyAt","client","trustedPEMs","length","error","critical","message","Promise","all","map","raw","parseCertificate","x5cOrdereredChain","trustedCerts","undefined","blindlyTrusted","console","log","filter","cert","leafCert","chainLength","foundTrustAnchor","i","currentCert","previousCert","blindlyTrustedCert","find","trusted","areCertificatesEqual","detailMessage","certificateInfo","DN","trustAnchor","certificateChain","x509Certificate","result","verify","date","publicKey","global","JSON","stringify","isSameCertificate","cert1","cert2","rawData","toString","algorithmProvider","container","resolve","AlgorithmProvider","getX509AlgorithmProvider","rawCert","X509Certificate","publicKeyInfo","AsnParser","parse","SubjectPublicKeyInfo","publicKeyRaw","Uint8Array","subjectPublicKey","publicKeyJwk","pemOrDerToX509Certificate","publicKeyAlgorithm","toWebAlgorithm","algorithm","rdnmap","getDNString","typesAndValues","attributes","getDNObject","typeAndValue","type","getValue","Object","entries","key","join","pemOrDerCert","pemOrDerStr","fromString","pem","derToPEM","jwk","subtle","pk","getPublicKey","exportKey","x509","toJwk","Error","SubjectAlternativeGeneralName","assertCertificateMatchesClientIdScheme","clientId","clientIdScheme","sans","clientIdSchemeFilter","clientIdMatches","san","validateCertificateChainMatchesClientIdScheme","Array","isArray","parsedValue","extensions","ext","extnID","id_SubjectAltName","altNames","toJSON","altName","includes"]}
1
+ {"version":3,"sources":["/home/runner/work/SSI-SDK-crypto-extensions/SSI-SDK-crypto-extensions/packages/x509-utils/dist/index.cjs","../src/types/index.ts","../src/x509/rsa-key.ts","../src/x509/crypto.ts","../src/x509/x509-utils.ts","../src/x509/rsa-signer.ts","../src/x509/x509-validator.ts"],"names":["JwkKeyUse","globalCrypto","setGlobal","suppliedCrypto","webcrypto","crypto","global","window","subtle","require","pemCertChainTox5c","cert","maxDepth","intermediate","replace","x5c","split","filter","c","length","splice","x5cToPemCertChain","Math","min","pem","i","derToPEM","pemOrDerToX509Certificate","DER","undefined","Uint8Array","Certificate","fromBER","rawData","includes","PEMToDer","Error","fromString","areCertificatesEqual","cert1","cert2","signatureValue","isEqual","toKeyObject","PEM","visibility","jwk","PEMToJwk","keyVisibility","d","keyHex","privateKeyHexFromPEM","publicKeyHexFromPEM","hexToPEM","keyType","jwkToPEM","keyto","from","toString","toJwk","PEMToHex","hexKeyFromPEMBasedJwk","hex","publicJwk","publicPEM","headerKey","indexOf","strippedPem","PEMToBinary","inputEncoding","targetEncoding","input","type","key","key_ops","usages","scheme","hashAlgorithm","hashName","importKey","generateKey","exportKey","pkcs8","RSASigner","buf","data","signature","use","verifyJwk","verificationResult","id_SubjectAltName","name","publicKeyJWK","getCertificateSubjectPublicKeyJWK","certificate","getSubjectAlternativeNames","sanTypeFilter","value","pemOrDerChain","trustAnchors","verificationTime","opts","trustRootWhenNoAnchors","defaultCryptoEngine","map","chain","all","blindlyTrustedAnchors","raw","certificateInfo","client","previousCert","validateX509CertificateChainImpl","currentCert","x509Certificate","publicKey","disallowReversedChain","trustedCerts","allowSingleNoCAChainElement","allowNoTrustAnchorsFound","AlgorithmProvider","algorithmProvider","rawCert","publicKeyInfo","getX509AlgorithmProvider","publicKeyAlgorithm","publicKeyJwk","publicKeyRaw","typesAndValues","typeAndValue","DN","pemOrDerStr","pk","SubjectAlternativeGeneralName","clientIdScheme","validateCertificateChainMatchesClientIdScheme","clientId","Date","result","typeFilter","altNames"],"mappings":"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","file":"/home/runner/work/SSI-SDK-crypto-extensions/SSI-SDK-crypto-extensions/packages/x509-utils/dist/index.cjs","sourcesContent":[null,"export enum JwkKeyUse {\n Encryption = 'enc',\n Signature = 'sig',\n}\n\nexport type HashAlgorithm = 'SHA-256' | 'SHA-512'\n\nexport type KeyVisibility = 'public' | 'private'\n\nexport interface X509Opts {\n cn?: string // The certificate Common Name. Will be used as the KID for the private key. Uses alias if not provided.\n privateKeyPEM?: string // Optional as you also need to provide it in hex format, but advisable to use it\n certificatePEM?: string // Optional, as long as the certificate then is part of the certificateChainPEM\n certificateChainURL?: string // Certificate chain URL. If used this is where the certificateChainPEM will be hosted/found.\n certificateChainPEM?: string // Base64 (not url!) encoded DER certificate chain. Please provide even if certificateChainURL is used!\n}\n","// @ts-ignore\nimport { KeyUsage, CryptoKey, RsaHashedImportParams, RsaHashedKeyGenParams } from 'node'\n\n// @ts-ignore\nimport { toString } from 'uint8arrays/to-string'\nimport { HashAlgorithm } from '../types'\nimport { globalCrypto } from './crypto'\n\nimport { derToPEM } from './x509-utils'\nimport { JsonWebKey } from '@sphereon/ssi-types'\n\nexport type RSASignatureSchemes = 'RSASSA-PKCS1-V1_5' | 'RSA-PSS'\n\nexport type RSAEncryptionSchemes = 'RSAES-PKCS-v1_5 ' | 'RSAES-OAEP'\n\nconst usage = (jwk: JsonWebKey): KeyUsage[] => {\n if (jwk.key_ops && jwk.key_ops.length > 0) {\n return jwk.key_ops as KeyUsage[]\n }\n if (jwk.use) {\n const usages: KeyUsage[] = []\n if (jwk.use.includes('sig')) {\n usages.push('sign', 'verify')\n } else if (jwk.use.includes('enc')) {\n usages.push('encrypt', 'decrypt')\n }\n if (usages.length > 0) {\n return usages\n }\n }\n if (jwk.kty === 'RSA') {\n if (jwk.d) {\n return jwk.alg?.toUpperCase()?.includes('QAEP') ? ['encrypt'] : ['sign']\n }\n return jwk.alg?.toUpperCase()?.includes('QAEP') ? ['decrypt'] : ['verify']\n }\n // \"decrypt\" | \"deriveBits\" | \"deriveKey\" | \"encrypt\" | \"sign\" | \"unwrapKey\" | \"verify\" | \"wrapKey\";\n return jwk.d && jwk.kty !== 'RSA' ? ['sign', 'decrypt', 'verify', 'encrypt'] : ['verify']\n}\n\nexport const signAlgorithmToSchemeAndHashAlg = (signingAlg: string) => {\n const alg = signingAlg.toUpperCase()\n let scheme: RSAEncryptionSchemes | RSASignatureSchemes\n if (alg.startsWith('RS')) {\n scheme = 'RSASSA-PKCS1-V1_5'\n } else if (alg.startsWith('PS')) {\n scheme = 'RSA-PSS'\n } else {\n throw Error(`Invalid signing algorithm supplied ${signingAlg}`)\n }\n\n const hashAlgorithm = `SHA-${alg.substring(2)}` as HashAlgorithm\n return { scheme, hashAlgorithm }\n}\n\nexport const cryptoSubtleImportRSAKey = async (\n jwk: JsonWebKey,\n scheme: RSAEncryptionSchemes | RSASignatureSchemes,\n hashAlgorithm?: HashAlgorithm\n): Promise<CryptoKey> => {\n const hashName = hashAlgorithm ? hashAlgorithm : jwk.alg ? `SHA-${jwk.alg.substring(2)}` : 'SHA-256'\n\n const importParams: RsaHashedImportParams = { name: scheme, hash: hashName }\n return await globalCrypto(false).subtle.importKey('jwk', jwk as JsonWebKey, importParams, false, usage(jwk))\n}\n\nexport const generateRSAKeyAsPEM = async (\n scheme: RSAEncryptionSchemes | RSASignatureSchemes,\n hashAlgorithm?: HashAlgorithm,\n modulusLength?: number\n): Promise<string> => {\n const hashName = hashAlgorithm ? hashAlgorithm : 'SHA-256'\n\n const params: RsaHashedKeyGenParams = {\n name: scheme,\n hash: hashName,\n modulusLength: modulusLength ? modulusLength : 2048,\n publicExponent: new Uint8Array([1, 0, 1]),\n }\n const keyUsage: KeyUsage[] = scheme === 'RSA-PSS' || scheme === 'RSASSA-PKCS1-V1_5' ? ['sign', 'verify'] : ['encrypt', 'decrypt']\n\n const keypair = await globalCrypto(false).subtle.generateKey(params, true, keyUsage)\n const pkcs8 = await globalCrypto(false).subtle.exportKey('pkcs8', keypair.privateKey)\n\n const uint8Array = new Uint8Array(pkcs8)\n return derToPEM(toString(uint8Array, 'base64pad'), 'RSA PRIVATE KEY')\n}\n","import { webcrypto } from 'node:crypto'\nexport const globalCrypto = (setGlobal: boolean, suppliedCrypto?: webcrypto.Crypto): webcrypto.Crypto => {\n let webcrypto: webcrypto.Crypto\n if (typeof suppliedCrypto !== 'undefined') {\n webcrypto = suppliedCrypto\n } else if (typeof crypto !== 'undefined') {\n webcrypto = crypto\n } else if (typeof global.crypto !== 'undefined') {\n webcrypto = global.crypto\n } else {\n // @ts-ignore\n if (typeof global.window?.crypto?.subtle !== 'undefined') {\n // @ts-ignore\n webcrypto = global.window.crypto\n } else {\n // @ts-ignore\n webcrypto = require('crypto') as webcrypto.Crypto\n }\n }\n if (setGlobal) {\n global.crypto = webcrypto\n }\n\n return webcrypto\n}\n","import { X509Certificate } from '@peculiar/x509'\nimport { Certificate } from 'pkijs'\n// @ts-ignore\nimport { fromString } from 'uint8arrays/from-string'\n// @ts-ignore\nimport { toString } from 'uint8arrays/to-string'\n// @ts-ignore\nimport keyto from '@trust/keyto'\nimport { KeyVisibility } from '../types'\n\nimport { JsonWebKey } from '@sphereon/ssi-types'\n// Based on (MIT licensed):\n// https://github.com/hildjj/node-posh/blob/master/lib/index.js\nexport function pemCertChainTox5c(cert: string, maxDepth?: number): string[] {\n if (!maxDepth) {\n maxDepth = 0\n }\n /*\n * Convert a PEM-encoded certificate to the version used in the x5c element\n * of a [JSON Web Key](http://tools.ietf.org/html/draft-ietf-jose-json-web-key).\n *\n * `cert` PEM-encoded certificate chain\n * `maxdepth` The maximum number of certificates to use from the chain.\n */\n\n const intermediate = cert\n .replace(/-----[^\\n]+\\n?/gm, ',')\n .replace(/\\n/g, '')\n .replace(/\\r/g, '')\n let x5c = intermediate.split(',').filter(function (c) {\n return c.length > 0\n })\n if (maxDepth > 0) {\n x5c = x5c.splice(0, maxDepth)\n }\n return x5c\n}\n\nexport function x5cToPemCertChain(x5c: string[], maxDepth?: number): string {\n if (!maxDepth) {\n maxDepth = 0\n }\n const length = maxDepth === 0 ? x5c.length : Math.min(maxDepth, x5c.length)\n let pem = ''\n for (let i = 0; i < length; i++) {\n pem += derToPEM(x5c[i], 'CERTIFICATE')\n }\n return pem\n}\n\nexport const pemOrDerToX509Certificate = (cert: string | Uint8Array | X509Certificate): Certificate => {\n let DER: string | undefined = typeof cert === 'string' ? cert : undefined\n if (typeof cert === 'object' && !(cert instanceof Uint8Array)) {\n // X509Certificate object\n return Certificate.fromBER(cert.rawData)\n } else if (typeof cert !== 'string') {\n return Certificate.fromBER(cert)\n } else if (cert.includes('CERTIFICATE')) {\n DER = PEMToDer(cert)\n }\n if (!DER) {\n throw Error('Invalid cert input value supplied. PEM, DER, Bytes and X509Certificate object are supported')\n }\n return Certificate.fromBER(fromString(DER, 'base64pad'))\n}\n\nexport const areCertificatesEqual = (cert1: Certificate, cert2: Certificate): boolean => {\n return cert1.signatureValue.isEqual(cert2.signatureValue)\n}\n\nexport const toKeyObject = (PEM: string, visibility: KeyVisibility = 'public') => {\n const jwk = PEMToJwk(PEM, visibility)\n const keyVisibility: KeyVisibility = jwk.d ? 'private' : 'public'\n const keyHex = keyVisibility === 'private' ? privateKeyHexFromPEM(PEM) : publicKeyHexFromPEM(PEM)\n\n return {\n pem: hexToPEM(keyHex, visibility),\n jwk,\n keyHex,\n keyType: keyVisibility,\n }\n}\n\nexport const jwkToPEM = (jwk: JsonWebKey, visibility: KeyVisibility = 'public'): string => {\n return keyto.from(jwk, 'jwk').toString('pem', visibility === 'public' ? 'public_pkcs8' : 'private_pkcs8')\n}\n\nexport const PEMToJwk = (pem: string, visibility: KeyVisibility = 'public'): JsonWebKey => {\n return keyto.from(pem, 'pem').toJwk(visibility)\n}\nexport const privateKeyHexFromPEM = (PEM: string) => {\n return PEMToHex(PEM)\n}\n\nexport const hexKeyFromPEMBasedJwk = (jwk: JsonWebKey, visibility: KeyVisibility = 'public'): string => {\n if (visibility === 'private') {\n return privateKeyHexFromPEM(jwkToPEM(jwk, 'private'))\n } else {\n return publicKeyHexFromPEM(jwkToPEM(jwk, 'public'))\n }\n}\n\nexport const publicKeyHexFromPEM = (PEM: string) => {\n const hex = PEMToHex(PEM)\n if (PEM.includes('CERTIFICATE')) {\n throw Error('Cannot directly deduce public Key from PEM Certificate yet')\n } else if (!PEM.includes('PRIVATE')) {\n return hex\n }\n const publicJwk = PEMToJwk(PEM, 'public')\n const publicPEM = jwkToPEM(publicJwk, 'public')\n return PEMToHex(publicPEM)\n}\n\nexport const PEMToHex = (PEM: string, headerKey?: string): string => {\n if (PEM.indexOf('-----BEGIN ') == -1) {\n throw Error(`PEM header not found: ${headerKey}`)\n }\n\n let strippedPem: string\n if (headerKey) {\n strippedPem = PEM.replace(new RegExp('^[^]*-----BEGIN ' + headerKey + '-----'), '')\n strippedPem = strippedPem.replace(new RegExp('-----END ' + headerKey + '-----[^]*$'), '')\n } else {\n strippedPem = PEM.replace(/^[^]*-----BEGIN [^-]+-----/, '')\n strippedPem = strippedPem.replace(/-----END [^-]+-----[^]*$/, '')\n }\n return base64ToHex(strippedPem, 'base64pad')\n}\n\nexport function PEMToBinary(pem: string): Uint8Array {\n const pemContents = pem\n .replace(/^[^]*-----BEGIN [^-]+-----/, '')\n .replace(/-----END [^-]+-----[^]*$/, '')\n .replace(/\\s/g, '')\n\n return fromString(pemContents, 'base64pad')\n}\n\n/**\n * Converts a base64 encoded string to hex string, removing any non-base64 characters, including newlines\n * @param input The input in base64, with optional newlines\n * @param inputEncoding\n */\nexport const base64ToHex = (input: string, inputEncoding?: 'base64' | 'base64pad' | 'base64url' | 'base64urlpad') => {\n const base64NoNewlines = input.replace(/[^0-9A-Za-z_\\-~\\/+=]*/g, '')\n return toString(fromString(base64NoNewlines, inputEncoding ? inputEncoding : 'base64pad'), 'base16')\n}\n\nexport const hexToBase64 = (input: number | object | string, targetEncoding?: 'base64' | 'base64pad' | 'base64url' | 'base64urlpad'): string => {\n let hex = typeof input === 'string' ? input : input.toString(16)\n if (hex.length % 2 === 1) {\n hex = `0${hex}`\n }\n return toString(fromString(hex, 'base16'), targetEncoding ? targetEncoding : 'base64pad')\n}\n\nexport const hexToPEM = (hex: string, type: KeyVisibility): string => {\n const base64 = hexToBase64(hex, 'base64pad')\n const headerKey = type === 'private' ? 'RSA PRIVATE KEY' : 'PUBLIC KEY'\n if (type === 'private') {\n const pem = derToPEM(base64, headerKey)\n try {\n PEMToJwk(pem) // We only use it to test the private key\n return pem\n } catch (error) {\n return derToPEM(base64, 'PRIVATE KEY')\n }\n }\n return derToPEM(base64, headerKey)\n}\n\nexport function PEMToDer(pem: string): string {\n return pem.replace(/(-----(BEGIN|END) CERTIFICATE-----|[\\n\\r])/g, '')\n}\n\nexport function derToPEM(cert: string, headerKey?: 'PUBLIC KEY' | 'RSA PRIVATE KEY' | 'PRIVATE KEY' | 'CERTIFICATE'): string {\n const key = headerKey ?? 'CERTIFICATE'\n if (cert.includes(key)) {\n // Was already in PEM it seems\n return cert\n }\n const matches = cert.match(/.{1,64}/g)\n if (!matches) {\n throw Error('Invalid cert input value supplied')\n }\n return `-----BEGIN ${key}-----\\n${matches.join('\\n')}\\n-----END ${key}-----\\n`\n}\n","// @ts-ignore\nimport { fromString } from 'uint8arrays/from-string'\n// @ts-ignore\nimport { toString } from 'uint8arrays/to-string'\nimport { HashAlgorithm, KeyVisibility } from '../types'\nimport { globalCrypto } from './crypto'\nimport { cryptoSubtleImportRSAKey, RSAEncryptionSchemes, RSASignatureSchemes } from './rsa-key'\nimport { PEMToJwk } from './x509-utils'\nimport { JsonWebKey } from '@sphereon/ssi-types'\n// @ts-ignore\nimport { CryptoKey, RsaPssParams, AlgorithmIdentifier } from 'node'\nexport class RSASigner {\n private readonly hashAlgorithm: HashAlgorithm\n private readonly jwk: JsonWebKey\n\n private key: CryptoKey | undefined\n private readonly scheme: RSAEncryptionSchemes | RSASignatureSchemes\n\n /**\n *\n * @param key Either in PEM or JWK format (no raw hex keys here!)\n * @param opts The algorithm and signature/encryption schemes\n */\n constructor(\n key: string | JsonWebKey,\n opts?: { hashAlgorithm?: HashAlgorithm; scheme?: RSAEncryptionSchemes | RSASignatureSchemes; visibility?: KeyVisibility }\n ) {\n if (typeof key === 'string') {\n this.jwk = PEMToJwk(key, opts?.visibility)\n } else {\n this.jwk = key\n }\n\n this.hashAlgorithm = opts?.hashAlgorithm ?? 'SHA-256'\n this.scheme = opts?.scheme ?? 'RSA-PSS'\n }\n\n private getImportParams(): AlgorithmIdentifier | RsaPssParams {\n if (this.scheme === 'RSA-PSS') {\n return { name: this.scheme, saltLength: 32 }\n }\n return { name: this.scheme /*, hash: this.hashAlgorithm*/ }\n }\n\n private async getKey(): Promise<CryptoKey> {\n if (!this.key) {\n this.key = await cryptoSubtleImportRSAKey(this.jwk, this.scheme, this.hashAlgorithm)\n }\n return this.key\n }\n\n private bufferToString(buf: ArrayBuffer) {\n const uint8Array = new Uint8Array(buf)\n return toString(uint8Array, 'base64url') // Needs to be base64url for JsonWebSignature2020. Don't change!\n }\n\n public async sign(data: Uint8Array): Promise<string> {\n const input = data\n const key = await this.getKey()\n const signature = this.bufferToString(await globalCrypto(false).subtle.sign(this.getImportParams(), key, input))\n if (!signature) {\n throw Error('Could not sign input data')\n }\n\n // base64url signature\n return signature\n }\n\n public async verify(data: string | Uint8Array, signature: string): Promise<boolean> {\n const jws = signature.includes('.') ? signature.split('.')[2] : signature\n\n const input = typeof data == 'string' ? fromString(data, 'utf-8') : data\n\n let key = await this.getKey()\n if (!key.usages.includes('verify')) {\n const verifyJwk = { ...this.jwk }\n delete verifyJwk.d\n delete verifyJwk.use\n delete verifyJwk.key_ops\n key = await cryptoSubtleImportRSAKey(verifyJwk, this.scheme, this.hashAlgorithm)\n }\n const verificationResult = await globalCrypto(false).subtle.verify(this.getImportParams(), key, fromString(jws, 'base64url'), input)\n return verificationResult\n }\n}\n","import { AsnParser } from '@peculiar/asn1-schema'\nimport { SubjectPublicKeyInfo } from '@peculiar/asn1-x509'\nimport { AlgorithmProvider, X509Certificate } from '@peculiar/x509'\n// import {calculateJwkThumbprint} from \"@sphereon/ssi-sdk-ext.key-utils\";\nimport { JWK } from '@sphereon/ssi-types'\nimport x509 from 'js-x509-utils'\nimport { AltName, AttributeTypeAndValue, Certificate, CryptoEngine, getCrypto, id_SubjectAltName, setEngine } from 'pkijs'\nimport { container } from 'tsyringe'\n// @ts-ignore\nimport { fromString } from 'uint8arrays/from-string'\n// @ts-ignore\nimport { toString } from 'uint8arrays/to-string'\nimport { globalCrypto } from './crypto'\nimport { areCertificatesEqual, derToPEM, pemOrDerToX509Certificate } from './x509-utils'\n\nexport type DNInfo = {\n DN: string\n attributes: Record<string, string>\n}\n\nexport type CertificateInfo = {\n certificate?: any // We need to fix the schema generator for this to be Certificate(Json) from pkijs\n notBefore: Date\n notAfter: Date\n publicKeyJWK?: any\n issuer: {\n dn: DNInfo\n }\n subject: {\n dn: DNInfo\n subjectAlternativeNames: SubjectAlternativeName[]\n }\n}\n\nexport type X509ValidationResult = {\n error: boolean\n critical: boolean\n message: string\n detailMessage?: string\n verificationTime: Date\n certificateChain?: Array<CertificateInfo>\n trustAnchor?: CertificateInfo\n client?: {\n // In case client id and scheme were passed in we return them for easy access. It means they are validated\n clientId: string\n clientIdScheme: ClientIdScheme\n }\n}\n\nconst defaultCryptoEngine = () => {\n const name = 'crypto'\n setEngine(name, new CryptoEngine({ name, crypto: globalCrypto(false) }))\n return getCrypto(true)\n}\n\nexport const getCertificateInfo = async (\n certificate: Certificate,\n opts?: {\n sanTypeFilter: SubjectAlternativeGeneralName | SubjectAlternativeGeneralName[]\n }\n): Promise<CertificateInfo> => {\n let publicKeyJWK: JWK | undefined\n try {\n publicKeyJWK = (await getCertificateSubjectPublicKeyJWK(certificate)) as JWK\n } catch (e) {}\n return {\n issuer: { dn: getIssuerDN(certificate) },\n subject: {\n dn: getSubjectDN(certificate),\n subjectAlternativeNames: getSubjectAlternativeNames(certificate, { typeFilter: opts?.sanTypeFilter }),\n },\n publicKeyJWK,\n notBefore: certificate.notBefore.value,\n notAfter: certificate.notAfter.value,\n // certificate\n } satisfies CertificateInfo\n}\n\nexport type X509CertificateChainValidationOpts = {\n // If no trust anchor is found, but the chain itself checks out, allow. (defaults to false:)\n allowNoTrustAnchorsFound?: boolean\n\n // Trust the supplied root from the chain, when no anchors are being passed in.\n trustRootWhenNoAnchors?: boolean\n // Do not perform a chain validation check if the chain only has a single value. This means only the certificate itself will be validated. No chain checks for CA certs will be performed. Only used when the cert has no issuer\n allowSingleNoCAChainElement?: boolean\n // WARNING: Do not use in production\n // Similar to regular trust anchors, but no validation is performed whatsoever. Do not use in production settings! Can be handy with self generated certificates as we perform many validations, making it hard to test with self-signed certs. Only applied in case a chain with 1 element is passed in to really make sure people do not abuse this option\n blindlyTrustedAnchors?: string[]\n\n disallowReversedChain?: boolean\n\n client?: {\n // If provided both are required. Validates the leaf certificate against the clientId and scheme\n clientId: string\n clientIdScheme: ClientIdScheme\n }\n}\n\nexport const validateX509CertificateChain = async ({\n chain: pemOrDerChain,\n trustAnchors,\n verificationTime = new Date(),\n opts = {\n // If no trust anchor is found, but the chain itself checks out, allow. (defaults to false:)\n allowNoTrustAnchorsFound: false,\n trustRootWhenNoAnchors: false,\n allowSingleNoCAChainElement: true,\n blindlyTrustedAnchors: [],\n disallowReversedChain: false,\n },\n}: {\n chain: (Uint8Array | string)[]\n trustAnchors?: string[]\n verificationTime?: Date\n opts?: X509CertificateChainValidationOpts\n}): Promise<X509ValidationResult> => {\n // We allow 1 reversal. We reverse by default as the implementation expects the root ca first, whilst x5c is the opposite. Reversed becomes true if the impl reverses the chain\n return await validateX509CertificateChainImpl({\n reversed: false,\n chain: [...pemOrDerChain].reverse(),\n trustAnchors,\n verificationTime,\n opts,\n })\n}\nconst validateX509CertificateChainImpl = async ({\n reversed,\n chain: pemOrDerChain,\n trustAnchors,\n verificationTime: verifyAt,\n opts,\n}: {\n reversed: boolean\n chain: (Uint8Array | string)[]\n trustAnchors?: string[]\n verificationTime: Date | string // string for REST API\n opts: X509CertificateChainValidationOpts\n}): Promise<X509ValidationResult> => {\n const verificationTime: Date = typeof verifyAt === 'string' ? new Date(verifyAt) : verifyAt\n const {\n allowNoTrustAnchorsFound = false,\n trustRootWhenNoAnchors = false,\n allowSingleNoCAChainElement = true,\n blindlyTrustedAnchors = [],\n disallowReversedChain = false,\n client,\n } = opts\n const trustedPEMs = trustRootWhenNoAnchors && !trustAnchors ? [pemOrDerChain[pemOrDerChain.length - 1]] : trustAnchors\n\n if (pemOrDerChain.length === 0) {\n return {\n error: true,\n critical: true,\n message: 'Certificate chain in DER or PEM format must not be empty',\n verificationTime,\n }\n }\n defaultCryptoEngine()\n\n // x5c always starts with the leaf cert at index 0 and then the cas. Our internal pkijs service expects it the other way around. Before calling this function the change has been revered\n const chain = await Promise.all(pemOrDerChain.map((raw) => parseCertificate(raw)))\n const x5cOrdereredChain = reversed ? [...chain] : [...chain].reverse()\n\n const trustedCerts = trustedPEMs ? await Promise.all(trustedPEMs.map((raw) => parseCertificate(raw))) : undefined\n const blindlyTrusted =\n (\n await Promise.all(\n blindlyTrustedAnchors.map((raw) => {\n try {\n return parseCertificate(raw)\n } catch (e) {\n // @ts-ignore\n console.log(`Failed to parse blindly trusted certificate ${raw}. Error: ${e.message}`)\n return undefined\n }\n })\n )\n ).filter((cert): cert is ParsedCertificate => cert !== undefined) ?? []\n const leafCert = x5cOrdereredChain[0]\n\n const chainLength = chain.length\n var foundTrustAnchor: ParsedCertificate | undefined = undefined\n for (let i = 0; i < chainLength; i++) {\n const currentCert = chain[i]\n const previousCert = i > 0 ? chain[i - 1] : undefined\n const blindlyTrustedCert = blindlyTrusted.find((trusted) => areCertificatesEqual(trusted.certificate, currentCert.certificate))\n if (blindlyTrustedCert) {\n console.log(`Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`)\n return {\n error: false,\n critical: false,\n message: `Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`,\n detailMessage: `Blindly trusted certificate ${blindlyTrustedCert.certificateInfo.subject.dn.DN} was found in the chain.`,\n trustAnchor: blindlyTrustedCert?.certificateInfo,\n verificationTime,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n ...(client && { client }),\n }\n }\n if (previousCert) {\n if (currentCert.x509Certificate.issuer !== previousCert.x509Certificate.subject) {\n if (!reversed && !disallowReversedChain) {\n return await validateX509CertificateChainImpl({\n reversed: true,\n chain: [...pemOrDerChain].reverse(),\n opts,\n verificationTime,\n trustAnchors,\n })\n }\n return {\n error: true,\n critical: true,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`,\n detailMessage: `The certificate ${currentCert.certificateInfo.subject.dn.DN} with issuer ${currentCert.x509Certificate.issuer}, is not signed by the previous certificate ${previousCert?.certificateInfo.subject.dn.DN} with subject string ${previousCert?.x509Certificate.subject}.`,\n verificationTime,\n ...(client && { client }),\n }\n }\n }\n const result = await currentCert.x509Certificate.verify(\n {\n date: verificationTime,\n publicKey: previousCert?.x509Certificate?.publicKey,\n },\n getCrypto()?.crypto ?? crypto ?? global.crypto\n )\n if (!result) {\n // First cert needs to be self signed\n if (i == 0 && !reversed && !disallowReversedChain) {\n return await validateX509CertificateChainImpl({\n reversed: true,\n chain: [...pemOrDerChain].reverse(),\n opts,\n verificationTime,\n trustAnchors,\n })\n }\n\n return {\n error: true,\n critical: true,\n message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n detailMessage: `Verification of the certificate ${currentCert.certificateInfo.subject.dn.DN} with issuer ${\n currentCert.x509Certificate.issuer\n } failed. Public key: ${JSON.stringify(currentCert.certificateInfo.publicKeyJWK)}.`,\n verificationTime,\n ...(client && { client }),\n }\n }\n\n foundTrustAnchor = foundTrustAnchor ?? trustedCerts?.find((trusted) => isSameCertificate(trusted.x509Certificate, currentCert.x509Certificate))\n\n if (i === 0 && chainLength === 1 && allowSingleNoCAChainElement) {\n return {\n error: false,\n critical: false,\n message: `Certificate chain succeeded as allow single cert result is allowed: ${leafCert.certificateInfo.subject.dn.DN}.`,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n trustAnchor: foundTrustAnchor?.certificateInfo,\n verificationTime,\n ...(client && { client }),\n }\n }\n }\n\n if (foundTrustAnchor?.certificateInfo || allowNoTrustAnchorsFound) {\n return {\n error: false,\n critical: false,\n message: `Certificate chain was valid`,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n detailMessage: foundTrustAnchor\n ? `The leaf certificate ${leafCert.certificateInfo.subject.dn.DN} is part of a chain with trust anchor ${foundTrustAnchor?.certificateInfo.subject.dn.DN}.`\n : `The leaf certificate ${leafCert.certificateInfo.subject.dn.DN} and chain were valid, but no trust anchor has been found. Ignoring as user allowed (allowNoTrustAnchorsFound: ${allowNoTrustAnchorsFound}).)`,\n trustAnchor: foundTrustAnchor?.certificateInfo,\n verificationTime,\n ...(client && { client }),\n }\n }\n\n return {\n error: true,\n critical: true,\n message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`,\n certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo),\n detailMessage: `No trust anchor was found in the chain. between (intermediate) CA ${\n x5cOrdereredChain[chain.length - 1].certificateInfo.subject.dn.DN\n } and leaf ${x5cOrdereredChain[0].certificateInfo.subject.dn.DN}.`,\n verificationTime,\n ...(client && { client }),\n }\n}\n\nconst isSameCertificate = (cert1: X509Certificate, cert2: X509Certificate): boolean => {\n return cert1.rawData.toString() === cert2.rawData.toString()\n}\n\nconst algorithmProvider: AlgorithmProvider = container.resolve(AlgorithmProvider)\nexport const getX509AlgorithmProvider = (): AlgorithmProvider => {\n return algorithmProvider\n}\n\nexport type ParsedCertificate = {\n publicKeyInfo: SubjectPublicKeyInfo\n publicKeyJwk?: JWK\n publicKeyRaw: Uint8Array\n // @ts-ignore\n publicKeyAlgorithm: Algorithm\n certificateInfo: CertificateInfo\n certificate: Certificate\n x509Certificate: X509Certificate\n}\n\nexport const parseCertificate = async (rawCert: string | Uint8Array): Promise<ParsedCertificate> => {\n const x509Certificate = new X509Certificate(rawCert)\n const publicKeyInfo = AsnParser.parse(x509Certificate.publicKey.rawData, SubjectPublicKeyInfo)\n const publicKeyRaw = new Uint8Array(publicKeyInfo.subjectPublicKey)\n let publicKeyJwk: JWK | undefined = undefined\n try {\n publicKeyJwk = (await getCertificateSubjectPublicKeyJWK(new Uint8Array(x509Certificate.rawData))) as JWK\n } catch (e: any) {\n console.error(e.message)\n }\n const certificate = pemOrDerToX509Certificate(rawCert)\n const certificateInfo = await getCertificateInfo(certificate)\n const publicKeyAlgorithm = getX509AlgorithmProvider().toWebAlgorithm(publicKeyInfo.algorithm)\n return {\n publicKeyAlgorithm,\n publicKeyInfo,\n publicKeyJwk,\n publicKeyRaw,\n certificateInfo,\n certificate,\n x509Certificate,\n }\n}\n/*\n\n/!**\n *\n * @param pemOrDerChain The order must be that the Certs signing another cert must come one after another. So first the signing cert, then any cert signing that cert and so on\n * @param trustedPEMs\n * @param verificationTime\n * @param opts\n *!/\nexport const validateX509CertificateChainOrg = async ({\n chain: pemOrDerChain,\n trustAnchors,\n verificationTime = new Date(),\n opts = {\n trustRootWhenNoAnchors: false,\n allowSingleNoCAChainElement: true,\n blindlyTrustedAnchors: [],\n },\n }: {\n chain: (Uint8Array | string)[]\n trustAnchors?: string[]\n verificationTime?: Date\n opts?: X509CertificateChainValidationOpts\n}): Promise<X509ValidationResult> => {\n const {\n trustRootWhenNoAnchors = false,\n allowSingleNoCAChainElement = true,\n blindlyTrustedAnchors = [],\n client\n } = opts\n const trustedPEMs = trustRootWhenNoAnchors && !trustAnchors ? [pemOrDerChain[pemOrDerChain.length - 1]] : trustAnchors\n\n if (pemOrDerChain.length === 0) {\n return {\n error: true,\n critical: true,\n message: 'Certificate chain in DER or PEM format must not be empty',\n verificationTime,\n }\n }\n\n // x5c always starts with the leaf cert at index 0 and then the cas. Our internal pkijs service expects it the other way around\n const certs = pemOrDerChain.map(pemOrDerToX509Certificate).reverse()\n const trustedCerts = trustedPEMs ? trustedPEMs.map(pemOrDerToX509Certificate) : undefined\n defaultCryptoEngine()\n\n if (pemOrDerChain.length === 1) {\n const singleCert = typeof pemOrDerChain[0] === 'string' ? pemOrDerChain[0] : u8a.toString(pemOrDerChain[0], 'base64pad')\n const cert = pemOrDerToX509Certificate(singleCert)\n if (client) {\n const validation = await validateCertificateChainMatchesClientIdScheme(cert, client.clientId, client.clientIdScheme)\n if (validation.error) {\n return validation\n }\n }\n if (blindlyTrustedAnchors.includes(singleCert)) {\n console.log(`Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`)\n return {\n error: false,\n critical: true,\n message: `Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`,\n verificationTime,\n certificateChain: [await getCertificateInfo(cert)],\n ...(client && {client}),\n }\n }\n if (allowSingleNoCAChainElement) {\n const subjectDN = getSubjectDN(cert).DN\n if (!getIssuerDN(cert).DN || getIssuerDN(cert).DN === subjectDN) {\n const passed = await cert.verify()\n return {\n error: !passed,\n critical: true,\n message: `Certificate chain validation for ${subjectDN}: ${passed ? 'successful' : 'failed'}.`,\n verificationTime,\n certificateChain: [await getCertificateInfo(cert)],\n ...(client && {client}),\n }\n }\n }\n }\n\n const validationEngine = new CertificateChainValidationEngine({\n certs /!*crls: [crl1], ocsps: [ocsp1], *!/,\n checkDate: verificationTime,\n trustedCerts,\n })\n\n try {\n const verification = await validationEngine.verify()\n if (!verification.result || !verification.certificatePath) {\n return {\n error: true,\n critical: true,\n message: verification.resultMessage !== '' ? verification.resultMessage : `Certificate chain validation failed.`,\n verificationTime,\n ...(client && {client}),\n }\n }\n const certPath = verification.certificatePath\n if (client) {\n const clientIdValidation = await validateCertificateChainMatchesClientIdScheme(certs[0], client.clientId, client.clientIdScheme)\n if (clientIdValidation.error) {\n return clientIdValidation\n }\n }\n let certInfos: Array<CertificateInfo> | undefined\n\n for (const certificate of certPath) {\n try {\n certInfos?.push(await getCertificateInfo(certificate))\n } catch (e: any) {\n console.log(`Error getting certificate info ${e.message}`)\n }\n }\n\n\n return {\n error: false,\n critical: false,\n message: `Certificate chain was valid`,\n verificationTime,\n certificateChain: certInfos,\n ...(client && {client}),\n }\n } catch (error: any) {\n return {\n error: true,\n critical: true,\n message: `Certificate chain was invalid, ${error.message ?? '<unknown error>'}`,\n verificationTime,\n ...(client && {client}),\n }\n }\n}\n*/\n\nconst rdnmap: Record<string, string> = {\n '2.5.4.6': 'C',\n '2.5.4.10': 'O',\n '2.5.4.11': 'OU',\n '2.5.4.3': 'CN',\n '2.5.4.7': 'L',\n '2.5.4.8': 'ST',\n '2.5.4.12': 'T',\n '2.5.4.42': 'GN',\n '2.5.4.43': 'I',\n '2.5.4.4': 'SN',\n '1.2.840.113549.1.9.1': 'E-mail',\n}\n\nexport const getIssuerDN = (cert: Certificate): DNInfo => {\n return {\n DN: getDNString(cert.issuer.typesAndValues),\n attributes: getDNObject(cert.issuer.typesAndValues),\n }\n}\n\nexport const getSubjectDN = (cert: Certificate): DNInfo => {\n return {\n DN: getDNString(cert.subject.typesAndValues),\n attributes: getDNObject(cert.subject.typesAndValues),\n }\n}\n\nconst getDNObject = (typesAndValues: AttributeTypeAndValue[]): Record<string, string> => {\n const DN: Record<string, string> = {}\n for (const typeAndValue of typesAndValues) {\n const type = rdnmap[typeAndValue.type] ?? typeAndValue.type\n DN[type] = typeAndValue.value.getValue()\n }\n return DN\n}\nconst getDNString = (typesAndValues: AttributeTypeAndValue[]): string => {\n return Object.entries(getDNObject(typesAndValues))\n .map(([key, value]) => `${key}=${value}`)\n .join(',')\n}\n\nexport const getCertificateSubjectPublicKeyJWK = async (pemOrDerCert: string | Uint8Array | Certificate): Promise<JWK> => {\n const pemOrDerStr =\n typeof pemOrDerCert === 'string'\n ? toString(fromString(pemOrDerCert, 'base64pad'), 'base64pad')\n : pemOrDerCert instanceof Uint8Array\n ? toString(pemOrDerCert, 'base64pad')\n : toString(fromString(pemOrDerCert.toString('base64'), 'base64pad'), 'base64pad')\n const pem = derToPEM(pemOrDerStr)\n const certificate = pemOrDerToX509Certificate(pem)\n var jwk: JWK | undefined\n try {\n const subtle = getCrypto(true).subtle\n const pk = await certificate.getPublicKey(undefined, defaultCryptoEngine())\n jwk = (await subtle.exportKey('jwk', pk)) as JWK | undefined\n } catch (error: any) {\n console.log(`Error in primary get JWK from cert:`, error?.message)\n }\n if (!jwk) {\n try {\n jwk = (await x509.toJwk(pem, 'pem')) as JWK\n } catch (error: any) {\n console.log(`Error in secondary get JWK from cert as well:`, error?.message)\n }\n }\n if (!jwk) {\n throw Error(`Failed to get JWK from certificate ${pem}`)\n }\n return jwk\n}\n\n/**\n * otherName [0] OtherName,\n * rfc822Name [1] IA5String,\n * dNSName [2] IA5String,\n * x400Address [3] ORAddress,\n * directoryName [4] Name,\n * ediPartyName [5] EDIPartyName,\n * uniformResourceIdentifier [6] IA5String,\n * iPAddress [7] OCTET STRING,\n * registeredID [8] OBJECT IDENTIFIER }\n */\nexport enum SubjectAlternativeGeneralName {\n rfc822Name = 1, // email\n dnsName = 2,\n uniformResourceIdentifier = 6,\n ipAddress = 7,\n}\n\nexport interface SubjectAlternativeName {\n value: string\n type: SubjectAlternativeGeneralName\n}\n\nexport type ClientIdScheme = 'x509_san_dns' | 'x509_san_uri'\n\nexport const assertCertificateMatchesClientIdScheme = (certificate: Certificate, clientId: string, clientIdScheme: ClientIdScheme): void => {\n const sans = getSubjectAlternativeNames(certificate, { clientIdSchemeFilter: clientIdScheme })\n const clientIdMatches = sans.find((san) => san.value === clientId)\n if (!clientIdMatches) {\n throw Error(\n `Client id scheme ${clientIdScheme} used had no matching subject alternative names in certificate with DN ${\n getSubjectDN(certificate).DN\n }. SANS: ${sans.map((san) => san.value).join(',')}`\n )\n }\n}\n\nexport const validateCertificateChainMatchesClientIdScheme = async (\n certificate: Certificate,\n clientId: string,\n clientIdScheme: ClientIdScheme\n): Promise<X509ValidationResult> => {\n const result = {\n error: true,\n critical: true,\n message: `Client Id ${clientId} was not present in certificate using scheme ${clientIdScheme}`,\n client: {\n clientId,\n clientIdScheme,\n },\n certificateChain: [await getCertificateInfo(certificate)],\n verificationTime: new Date(),\n }\n try {\n assertCertificateMatchesClientIdScheme(certificate, clientId, clientIdScheme)\n } catch (error) {\n return result\n }\n result.error = false\n result.message = `Client Id ${clientId} was present in certificate using scheme ${clientIdScheme}`\n return result\n}\n\nexport const getSubjectAlternativeNames = (\n certificate: Certificate,\n opts?: {\n typeFilter?: SubjectAlternativeGeneralName | SubjectAlternativeGeneralName[]\n // When a clientIdchemeFilter is passed in it will always override the above type filter\n clientIdSchemeFilter?: ClientIdScheme\n }\n): SubjectAlternativeName[] => {\n let typeFilter: SubjectAlternativeGeneralName[]\n if (opts?.clientIdSchemeFilter) {\n typeFilter =\n opts.clientIdSchemeFilter === 'x509_san_dns'\n ? [SubjectAlternativeGeneralName.dnsName]\n : [SubjectAlternativeGeneralName.uniformResourceIdentifier]\n } else if (opts?.typeFilter) {\n typeFilter = Array.isArray(opts.typeFilter) ? opts.typeFilter : [opts.typeFilter]\n } else {\n typeFilter = [SubjectAlternativeGeneralName.dnsName, SubjectAlternativeGeneralName.uniformResourceIdentifier]\n }\n const parsedValue = certificate.extensions?.find((ext) => ext.extnID === id_SubjectAltName)?.parsedValue as AltName\n if (!parsedValue) {\n return []\n }\n const altNames = parsedValue.toJSON().altNames\n return altNames\n .filter((altName) => typeFilter.includes(altName.type))\n .map((altName) => {\n return { type: altName.type, value: altName.value } satisfies SubjectAlternativeName\n })\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sphereon/ssi-sdk-ext.x509-utils",
3
3
  "description": "Sphereon SSI-SDK plugin functions for X.509 Certificate handling.",
4
- "version": "0.28.1-feature.esm.cjs.8+4c162d1",
4
+ "version": "0.28.1-feature.esm.cjs.9+71682ea",
5
5
  "source": "./src/index.ts",
6
6
  "type": "module",
7
7
  "main": "./dist/index.cjs",
@@ -54,5 +54,5 @@
54
54
  "DID",
55
55
  "Veramo"
56
56
  ],
57
- "gitHead": "4c162d14577f462070adeea3e7ec5a443c324ee7"
57
+ "gitHead": "71682ea0c528f5b32c421245c253b3bc9d6296a0"
58
58
  }