@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 +106 -131
- package/dist/index.cjs.map +1 -1
- package/package.json +2 -2
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
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
104
|
-
var
|
|
105
|
-
|
|
106
|
-
var
|
|
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
|
|
76
|
+
return _pkijs.Certificate.fromBER(cert.rawData);
|
|
137
77
|
} else if (typeof cert !== "string") {
|
|
138
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
-
|
|
342
|
-
|
|
281
|
+
|
|
282
|
+
|
|
343
283
|
var RSASigner = class {
|
|
344
284
|
static {
|
|
345
285
|
__name(this, "RSASigner");
|
|
346
286
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
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
|
|
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
|
|
363
|
-
this.scheme = opts
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
416
|
-
var
|
|
417
|
-
var
|
|
418
|
-
var
|
|
419
|
-
|
|
420
|
-
var
|
|
421
|
-
|
|
422
|
-
|
|
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,
|
|
365
|
+
_pkijs.setEngine.call(void 0, name, new (0, _pkijs.CryptoEngine)({
|
|
426
366
|
name,
|
|
427
367
|
crypto: globalCrypto(false)
|
|
428
368
|
}));
|
|
429
|
-
return (0,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
551
|
-
}, (0,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
598
|
-
trustAnchor: foundTrustAnchor
|
|
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 =
|
|
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
|
|
626
|
-
const publicKeyInfo =
|
|
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]
|
|
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,
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
package/dist/index.cjs.map
CHANGED
|
@@ -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.
|
|
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": "
|
|
57
|
+
"gitHead": "71682ea0c528f5b32c421245c253b3bc9d6296a0"
|
|
58
58
|
}
|