@sphereon/ssi-sdk-ext.x509-utils 0.26.1-next.9 → 0.27.1-fix.6
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/x509/crypto.d.ts +2 -0
- package/dist/x509/crypto.d.ts.map +1 -0
- package/dist/x509/crypto.js +28 -0
- package/dist/x509/crypto.js.map +1 -0
- package/dist/x509/rsa-key.d.ts.map +1 -1
- package/dist/x509/rsa-key.js +4 -3
- package/dist/x509/rsa-key.js.map +1 -1
- package/dist/x509/rsa-signer.d.ts.map +1 -1
- package/dist/x509/rsa-signer.js +3 -2
- package/dist/x509/rsa-signer.js.map +1 -1
- package/dist/x509/x509-validator.d.ts +4 -15
- package/dist/x509/x509-validator.d.ts.map +1 -1
- package/dist/x509/x509-validator.js +175 -91
- package/dist/x509/x509-validator.js.map +1 -1
- package/package.json +2 -2
- package/src/x509/crypto.ts +19 -0
- package/src/x509/rsa-key.ts +4 -3
- package/src/x509/rsa-signer.ts +3 -2
- package/src/x509/x509-validator.ts +211 -159
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.d.ts","sourceRoot":"","sources":["../../src/x509/crypto.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,cAAe,OAAO,mBAAmB,MAAM,KAAG,MAkB1E,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.globalCrypto = void 0;
|
|
4
|
+
const globalCrypto = (setGlobal, suppliedCrypto) => {
|
|
5
|
+
var _a, _b;
|
|
6
|
+
let webcrypto;
|
|
7
|
+
if (typeof suppliedCrypto !== 'undefined') {
|
|
8
|
+
webcrypto = suppliedCrypto;
|
|
9
|
+
}
|
|
10
|
+
else if (typeof crypto !== 'undefined') {
|
|
11
|
+
webcrypto = crypto;
|
|
12
|
+
}
|
|
13
|
+
else if (typeof global.crypto !== 'undefined') {
|
|
14
|
+
webcrypto = global.crypto;
|
|
15
|
+
}
|
|
16
|
+
else if (typeof ((_b = (_a = global.window) === null || _a === void 0 ? void 0 : _a.crypto) === null || _b === void 0 ? void 0 : _b.subtle) !== 'undefined') {
|
|
17
|
+
webcrypto = global.window.crypto;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
webcrypto = require('crypto');
|
|
21
|
+
}
|
|
22
|
+
if (setGlobal) {
|
|
23
|
+
global.crypto = webcrypto;
|
|
24
|
+
}
|
|
25
|
+
return webcrypto;
|
|
26
|
+
};
|
|
27
|
+
exports.globalCrypto = globalCrypto;
|
|
28
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/x509/crypto.ts"],"names":[],"mappings":";;;AAAO,MAAM,YAAY,GAAG,CAAC,SAAkB,EAAE,cAAuB,EAAU,EAAE;;IAClF,IAAI,SAAiB,CAAA;IACrB,IAAI,OAAO,cAAc,KAAK,WAAW,EAAE,CAAC;QAC1C,SAAS,GAAG,cAAc,CAAA;IAC5B,CAAC;SAAM,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QACzC,SAAS,GAAG,MAAM,CAAA;IACpB,CAAC;SAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;QAChD,SAAS,GAAG,MAAM,CAAC,MAAM,CAAA;IAC3B,CAAC;SAAM,IAAI,OAAO,CAAA,MAAA,MAAA,MAAM,CAAC,MAAM,0CAAE,MAAM,0CAAE,MAAM,CAAA,KAAK,WAAW,EAAE,CAAC;QAChE,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAA;IAClC,CAAC;SAAM,CAAC;QACN,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAW,CAAA;IACzC,CAAC;IACD,IAAI,SAAS,EAAE,CAAC;QACd,MAAM,CAAC,MAAM,GAAG,SAAS,CAAA;IAC3B,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC,CAAA;AAlBY,QAAA,YAAY,gBAkBxB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsa-key.d.ts","sourceRoot":"","sources":["../../src/x509/rsa-key.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"rsa-key.d.ts","sourceRoot":"","sources":["../../src/x509/rsa-key.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAKxC,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG,SAAS,CAAA;AAEjE,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,GAAG,YAAY,CAAA;AA2BpE,eAAO,MAAM,+BAA+B,eAAgB,MAAM;;;CAajE,CAAA;AAED,eAAO,MAAM,wBAAwB,QAC9B,UAAU,UACP,oBAAoB,GAAG,mBAAmB,kBAClC,aAAa,KAC5B,OAAO,CAAC,SAAS,CAKnB,CAAA;AAED,eAAO,MAAM,mBAAmB,WACtB,oBAAoB,GAAG,mBAAmB,kBAClC,aAAa,kBACb,MAAM,KACrB,OAAO,CAAC,MAAM,CAgBhB,CAAA"}
|
package/dist/x509/rsa-key.js
CHANGED
|
@@ -34,6 +34,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
35
|
exports.generateRSAKeyAsPEM = exports.cryptoSubtleImportRSAKey = exports.signAlgorithmToSchemeAndHashAlg = void 0;
|
|
36
36
|
const u8a = __importStar(require("uint8arrays"));
|
|
37
|
+
const crypto_1 = require("./crypto");
|
|
37
38
|
const x509_utils_1 = require("./x509-utils");
|
|
38
39
|
const usage = (jwk) => {
|
|
39
40
|
var _a, _b, _c, _d;
|
|
@@ -80,7 +81,7 @@ exports.signAlgorithmToSchemeAndHashAlg = signAlgorithmToSchemeAndHashAlg;
|
|
|
80
81
|
const cryptoSubtleImportRSAKey = (jwk, scheme, hashAlgorithm) => __awaiter(void 0, void 0, void 0, function* () {
|
|
81
82
|
const hashName = hashAlgorithm ? hashAlgorithm : jwk.alg ? `SHA-${jwk.alg.substring(2)}` : 'SHA-256';
|
|
82
83
|
const importParams = { name: scheme, hash: hashName };
|
|
83
|
-
return yield
|
|
84
|
+
return yield (0, crypto_1.globalCrypto)(false).subtle.importKey('jwk', jwk, importParams, false, usage(jwk));
|
|
84
85
|
});
|
|
85
86
|
exports.cryptoSubtleImportRSAKey = cryptoSubtleImportRSAKey;
|
|
86
87
|
const generateRSAKeyAsPEM = (scheme, hashAlgorithm, modulusLength) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -92,8 +93,8 @@ const generateRSAKeyAsPEM = (scheme, hashAlgorithm, modulusLength) => __awaiter(
|
|
|
92
93
|
publicExponent: new Uint8Array([1, 0, 1]),
|
|
93
94
|
};
|
|
94
95
|
const keyUsage = scheme === 'RSA-PSS' || scheme === 'RSASSA-PKCS1-V1_5' ? ['sign', 'verify'] : ['encrypt', 'decrypt'];
|
|
95
|
-
const keypair = yield
|
|
96
|
-
const pkcs8 = yield
|
|
96
|
+
const keypair = yield (0, crypto_1.globalCrypto)(false).subtle.generateKey(params, true, keyUsage);
|
|
97
|
+
const pkcs8 = yield (0, crypto_1.globalCrypto)(false).subtle.exportKey('pkcs8', keypair.privateKey);
|
|
97
98
|
const uint8Array = new Uint8Array(pkcs8);
|
|
98
99
|
return (0, x509_utils_1.derToPEM)(u8a.toString(uint8Array, 'base64pad'), 'RSA PRIVATE KEY');
|
|
99
100
|
});
|
package/dist/x509/rsa-key.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsa-key.js","sourceRoot":"","sources":["../../src/x509/rsa-key.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAAkC;
|
|
1
|
+
{"version":3,"file":"rsa-key.js","sourceRoot":"","sources":["../../src/x509/rsa-key.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsa-signer.d.ts","sourceRoot":"","sources":["../../src/x509/rsa-signer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"rsa-signer.d.ts","sourceRoot":"","sources":["../../src/x509/rsa-signer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAEvD,OAAO,EAA4B,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAG/F,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;IAEhC,OAAO,CAAC,GAAG,CAAuB;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4C;IAEnE;;;;OAIG;gBAED,GAAG,EAAE,MAAM,GAAG,UAAU,EACxB,IAAI,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,aAAa,CAAC;QAAC,MAAM,CAAC,EAAE,oBAAoB,GAAG,mBAAmB,CAAC;QAAC,UAAU,CAAC,EAAE,aAAa,CAAA;KAAE;IAY3H,OAAO,CAAC,eAAe;YAOT,MAAM;IAOpB,OAAO,CAAC,cAAc;IAKT,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAYvC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAgBpF"}
|
package/dist/x509/rsa-signer.js
CHANGED
|
@@ -34,6 +34,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
34
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
35
35
|
exports.RSASigner = void 0;
|
|
36
36
|
const u8a = __importStar(require("uint8arrays"));
|
|
37
|
+
const crypto_1 = require("./crypto");
|
|
37
38
|
const rsa_key_1 = require("./rsa-key");
|
|
38
39
|
const x509_utils_1 = require("./x509-utils");
|
|
39
40
|
class RSASigner {
|
|
@@ -75,7 +76,7 @@ class RSASigner {
|
|
|
75
76
|
return __awaiter(this, void 0, void 0, function* () {
|
|
76
77
|
const input = data;
|
|
77
78
|
const key = yield this.getKey();
|
|
78
|
-
const signature = this.bufferToString(yield
|
|
79
|
+
const signature = this.bufferToString(yield (0, crypto_1.globalCrypto)(false).subtle.sign(this.getImportParams(), key, input));
|
|
79
80
|
if (!signature) {
|
|
80
81
|
throw Error('Could not sign input data');
|
|
81
82
|
}
|
|
@@ -95,7 +96,7 @@ class RSASigner {
|
|
|
95
96
|
delete verifyJwk.key_ops;
|
|
96
97
|
key = yield (0, rsa_key_1.cryptoSubtleImportRSAKey)(verifyJwk, this.scheme, this.hashAlgorithm);
|
|
97
98
|
}
|
|
98
|
-
const verificationResult = yield
|
|
99
|
+
const verificationResult = yield (0, crypto_1.globalCrypto)(false).subtle.verify(this.getImportParams(), key, u8a.fromString(jws, 'base64url'), input);
|
|
99
100
|
return verificationResult;
|
|
100
101
|
});
|
|
101
102
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rsa-signer.js","sourceRoot":"","sources":["../../src/x509/rsa-signer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAAkC;AAElC,uCAA+F;AAC/F,6CAAuC;AAEvC,MAAa,SAAS;IAOpB;;;;OAIG;IACH,YACE,GAAwB,EACxB,IAAyH;;QAEzH,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,IAAI,CAAC,GAAG,GAAG,IAAA,qBAAQ,EAAC,GAAG,EAAE,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,UAAU,CAAC,CAAA;QAC5C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QAChB,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,aAAa,mCAAI,SAAS,CAAA;QACrD,IAAI,CAAC,MAAM,GAAG,MAAA,IAAI,aAAJ,IAAI,uBAAJ,IAAI,CAAE,MAAM,mCAAI,SAAS,CAAA;IACzC,CAAC;IAEO,eAAe;QACrB,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,CAAA;QAC9C,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,8BAA8B,EAAE,CAAA;IAC7D,CAAC;IAEa,MAAM;;YAClB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACd,IAAI,CAAC,GAAG,GAAG,MAAM,IAAA,kCAAwB,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAA;YACtF,CAAC;YACD,OAAO,IAAI,CAAC,GAAG,CAAA;QACjB,CAAC;KAAA;IAEO,cAAc,CAAC,GAAgB;QACrC,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,CAAA;QACtC,OAAO,GAAG,CAAC,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA,CAAC,gEAAgE;IAC/G,CAAC;IAEY,IAAI,CAAC,IAAgB;;YAChC,MAAM,KAAK,GAAG,IAAI,CAAA;YAClB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAA;YAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"rsa-signer.js","sourceRoot":"","sources":["../../src/x509/rsa-signer.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,6 +23,7 @@ export type X509ValidationResult = {
|
|
|
23
23
|
error: boolean;
|
|
24
24
|
critical: boolean;
|
|
25
25
|
message: string;
|
|
26
|
+
detailMessage?: string;
|
|
26
27
|
verificationTime: Date;
|
|
27
28
|
certificateChain?: Array<CertificateInfo>;
|
|
28
29
|
trustAnchor?: CertificateInfo;
|
|
@@ -35,6 +36,7 @@ export declare const getCertificateInfo: (certificate: Certificate, opts?: {
|
|
|
35
36
|
sanTypeFilter: SubjectAlternativeGeneralName | SubjectAlternativeGeneralName[];
|
|
36
37
|
}) => Promise<CertificateInfo>;
|
|
37
38
|
export type X509CertificateChainValidationOpts = {
|
|
39
|
+
allowNoTrustAnchorsFound?: boolean;
|
|
38
40
|
trustRootWhenNoAnchors?: boolean;
|
|
39
41
|
allowSingleNoCAChainElement?: boolean;
|
|
40
42
|
blindlyTrustedAnchors?: string[];
|
|
@@ -53,7 +55,7 @@ export declare const validateX509CertificateChain: ({ chain: pemOrDerChain, trus
|
|
|
53
55
|
export declare const getX509AlgorithmProvider: () => AlgorithmProvider;
|
|
54
56
|
export type ParsedCertificate = {
|
|
55
57
|
publicKeyInfo: SubjectPublicKeyInfo;
|
|
56
|
-
publicKeyJwk
|
|
58
|
+
publicKeyJwk?: JWK;
|
|
57
59
|
publicKeyRaw: Uint8Array;
|
|
58
60
|
publicKeyAlgorithm: Algorithm;
|
|
59
61
|
certificateInfo: CertificateInfo;
|
|
@@ -61,22 +63,9 @@ export type ParsedCertificate = {
|
|
|
61
63
|
x509Certificate: X509Certificate;
|
|
62
64
|
};
|
|
63
65
|
export declare const parseCertificate: (rawCert: string | Uint8Array) => Promise<ParsedCertificate>;
|
|
64
|
-
/**
|
|
65
|
-
*
|
|
66
|
-
* @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
|
|
67
|
-
* @param trustedPEMs
|
|
68
|
-
* @param verificationTime
|
|
69
|
-
* @param opts
|
|
70
|
-
*/
|
|
71
|
-
export declare const validateX509CertificateChainOrg: ({ chain: pemOrDerChain, trustAnchors, verificationTime, opts, }: {
|
|
72
|
-
chain: (Uint8Array | string)[];
|
|
73
|
-
trustAnchors?: string[];
|
|
74
|
-
verificationTime?: Date;
|
|
75
|
-
opts?: X509CertificateChainValidationOpts;
|
|
76
|
-
}) => Promise<X509ValidationResult>;
|
|
77
66
|
export declare const getIssuerDN: (cert: Certificate) => DNInfo;
|
|
78
67
|
export declare const getSubjectDN: (cert: Certificate) => DNInfo;
|
|
79
|
-
export declare const getCertificateSubjectPublicKeyJWK: (pemOrDerCert: string | Uint8Array | Certificate) => Promise<
|
|
68
|
+
export declare const getCertificateSubjectPublicKeyJWK: (pemOrDerCert: string | Uint8Array | Certificate) => Promise<JWK>;
|
|
80
69
|
/**
|
|
81
70
|
* otherName [0] OtherName,
|
|
82
71
|
* rfc822Name [1] IA5String,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"x509-validator.d.ts","sourceRoot":"","sources":["../../src/x509/x509-validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEnE,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AAEzC,OAAO,
|
|
1
|
+
{"version":3,"file":"x509-validator.d.ts","sourceRoot":"","sources":["../../src/x509/x509-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,7 +35,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.getSubjectAlternativeNames = exports.validateCertificateChainMatchesClientIdScheme = exports.assertCertificateMatchesClientIdScheme = exports.SubjectAlternativeGeneralName = exports.getCertificateSubjectPublicKeyJWK = exports.getSubjectDN = exports.getIssuerDN = exports.
|
|
38
|
+
exports.getSubjectAlternativeNames = exports.validateCertificateChainMatchesClientIdScheme = exports.assertCertificateMatchesClientIdScheme = exports.SubjectAlternativeGeneralName = exports.getCertificateSubjectPublicKeyJWK = exports.getSubjectDN = exports.getIssuerDN = exports.parseCertificate = exports.getX509AlgorithmProvider = exports.validateX509CertificateChain = exports.getCertificateInfo = void 0;
|
|
39
39
|
const asn1_schema_1 = require("@peculiar/asn1-schema");
|
|
40
40
|
const asn1_x509_1 = require("@peculiar/asn1-x509");
|
|
41
41
|
const x509_1 = require("@peculiar/x509");
|
|
@@ -43,37 +43,26 @@ const js_x509_utils_1 = __importDefault(require("js-x509-utils"));
|
|
|
43
43
|
const pkijs_1 = require("pkijs");
|
|
44
44
|
const tsyringe_1 = require("tsyringe");
|
|
45
45
|
const u8a = __importStar(require("uint8arrays"));
|
|
46
|
+
const crypto_1 = require("./crypto");
|
|
46
47
|
const x509_utils_1 = require("./x509-utils");
|
|
47
48
|
const defaultCryptoEngine = () => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if ('webkitSubtle' in self.crypto) {
|
|
52
|
-
engineName = 'safari';
|
|
53
|
-
}
|
|
54
|
-
(0, pkijs_1.setEngine)(engineName, new pkijs_1.CryptoEngine({ name: engineName, crypto: crypto }));
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
else if (typeof crypto !== 'undefined' && 'webcrypto' in crypto) {
|
|
58
|
-
const name = 'NodeJS ^15';
|
|
59
|
-
const nodeCrypto = crypto.webcrypto;
|
|
60
|
-
// @ts-ignore
|
|
61
|
-
(0, pkijs_1.setEngine)(name, new pkijs_1.CryptoEngine({ name, crypto: nodeCrypto }));
|
|
62
|
-
}
|
|
63
|
-
else if (typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined') {
|
|
64
|
-
const name = 'crypto';
|
|
65
|
-
(0, pkijs_1.setEngine)(name, new pkijs_1.CryptoEngine({ name, crypto: crypto }));
|
|
66
|
-
}
|
|
49
|
+
const name = 'crypto';
|
|
50
|
+
(0, pkijs_1.setEngine)(name, new pkijs_1.CryptoEngine({ name, crypto: (0, crypto_1.globalCrypto)(false) }));
|
|
51
|
+
return (0, pkijs_1.getCrypto)(true);
|
|
67
52
|
};
|
|
68
53
|
const getCertificateInfo = (certificate, opts) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
-
|
|
54
|
+
let publicKeyJWK;
|
|
55
|
+
try {
|
|
56
|
+
publicKeyJWK = (yield (0, exports.getCertificateSubjectPublicKeyJWK)(certificate));
|
|
57
|
+
}
|
|
58
|
+
catch (e) { }
|
|
70
59
|
return {
|
|
71
60
|
issuer: { dn: (0, exports.getIssuerDN)(certificate) },
|
|
72
61
|
subject: {
|
|
73
62
|
dn: (0, exports.getSubjectDN)(certificate),
|
|
74
63
|
subjectAlternativeNames: (0, exports.getSubjectAlternativeNames)(certificate, { typeFilter: opts === null || opts === void 0 ? void 0 : opts.sanTypeFilter }),
|
|
75
64
|
},
|
|
76
|
-
publicKeyJWK
|
|
65
|
+
publicKeyJWK,
|
|
77
66
|
notBefore: certificate.notBefore.value,
|
|
78
67
|
notAfter: certificate.notAfter.value,
|
|
79
68
|
// certificate
|
|
@@ -81,6 +70,8 @@ const getCertificateInfo = (certificate, opts) => __awaiter(void 0, void 0, void
|
|
|
81
70
|
});
|
|
82
71
|
exports.getCertificateInfo = getCertificateInfo;
|
|
83
72
|
const validateX509CertificateChain = (_a) => __awaiter(void 0, [_a], void 0, function* ({ chain: pemOrDerChain, trustAnchors, verificationTime = new Date(), opts = {
|
|
73
|
+
// If no trust anchor is found, but the chain itself checks out, allow. (defaults to false:)
|
|
74
|
+
allowNoTrustAnchorsFound: false,
|
|
84
75
|
trustRootWhenNoAnchors: false,
|
|
85
76
|
allowSingleNoCAChainElement: true,
|
|
86
77
|
blindlyTrustedAnchors: [],
|
|
@@ -89,7 +80,7 @@ const validateX509CertificateChain = (_a) => __awaiter(void 0, [_a], void 0, fun
|
|
|
89
80
|
// 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
|
|
90
81
|
return yield validateX509CertificateChainImpl({
|
|
91
82
|
reversed: false,
|
|
92
|
-
chain: pemOrDerChain.reverse(),
|
|
83
|
+
chain: [...pemOrDerChain].reverse(),
|
|
93
84
|
trustAnchors,
|
|
94
85
|
verificationTime,
|
|
95
86
|
opts,
|
|
@@ -99,7 +90,7 @@ exports.validateX509CertificateChain = validateX509CertificateChain;
|
|
|
99
90
|
const validateX509CertificateChainImpl = (_a) => __awaiter(void 0, [_a], void 0, function* ({ reversed, chain: pemOrDerChain, trustAnchors, verificationTime: verifyAt, opts, }) {
|
|
100
91
|
var _b, _c, _d, _e, _f;
|
|
101
92
|
const verificationTime = typeof verifyAt === 'string' ? new Date(verifyAt) : verifyAt;
|
|
102
|
-
const { trustRootWhenNoAnchors = false, allowSingleNoCAChainElement = true, blindlyTrustedAnchors = [], disallowReversedChain = false, client, } = opts;
|
|
93
|
+
const { allowNoTrustAnchorsFound = false, trustRootWhenNoAnchors = false, allowSingleNoCAChainElement = true, blindlyTrustedAnchors = [], disallowReversedChain = false, client, } = opts;
|
|
103
94
|
const trustedPEMs = trustRootWhenNoAnchors && !trustAnchors ? [pemOrDerChain[pemOrDerChain.length - 1]] : trustAnchors;
|
|
104
95
|
if (pemOrDerChain.length === 0) {
|
|
105
96
|
return {
|
|
@@ -110,59 +101,73 @@ const validateX509CertificateChainImpl = (_a) => __awaiter(void 0, [_a], void 0,
|
|
|
110
101
|
};
|
|
111
102
|
}
|
|
112
103
|
defaultCryptoEngine();
|
|
113
|
-
// x5c always starts with the leaf cert at index 0 and then the cas. Our internal pkijs service expects it the other way around
|
|
104
|
+
// 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
|
|
114
105
|
const chain = yield Promise.all(pemOrDerChain.map((raw) => (0, exports.parseCertificate)(raw)));
|
|
106
|
+
const x5cOrdereredChain = reversed ? [...chain] : [...chain].reverse();
|
|
115
107
|
const trustedCerts = trustedPEMs ? yield Promise.all(trustedPEMs.map((raw) => (0, exports.parseCertificate)(raw))) : undefined;
|
|
116
|
-
const blindlyTrusted = (_b = (yield Promise.all(blindlyTrustedAnchors.map((raw) =>
|
|
117
|
-
|
|
108
|
+
const blindlyTrusted = (_b = (yield Promise.all(blindlyTrustedAnchors.map((raw) => {
|
|
109
|
+
try {
|
|
110
|
+
return (0, exports.parseCertificate)(raw);
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
console.log(`Failed to parse blindly trusted certificate ${raw}. Error: ${e.message}`);
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
}))).filter((cert) => cert !== undefined)) !== null && _b !== void 0 ? _b : [];
|
|
118
|
+
const leafCert = x5cOrdereredChain[0];
|
|
118
119
|
const chainLength = chain.length;
|
|
119
120
|
var foundTrustAnchor = undefined;
|
|
120
121
|
for (let i = 0; i < chainLength; i++) {
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
|
|
122
|
+
const currentCert = chain[i];
|
|
123
|
+
const previousCert = i > 0 ? chain[i - 1] : undefined;
|
|
124
|
+
const blindlyTrustedCert = blindlyTrusted.find((trusted) => (0, x509_utils_1.areCertificatesEqual)(trusted.certificate, currentCert.certificate));
|
|
125
|
+
if (blindlyTrustedCert) {
|
|
124
126
|
console.log(`Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`);
|
|
125
|
-
return Object.assign({ error: false, critical: false, message: `Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`, verificationTime, certificateChain:
|
|
127
|
+
return Object.assign({ error: false, critical: false, message: `Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`, detailMessage: `Blindly trusted certificate ${blindlyTrustedCert.certificateInfo.subject.dn.DN} was found in the chain.`, trustAnchor: blindlyTrustedCert === null || blindlyTrustedCert === void 0 ? void 0 : blindlyTrustedCert.certificateInfo, verificationTime, certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo) }, (client && { client }));
|
|
126
128
|
}
|
|
127
|
-
if (
|
|
128
|
-
if (
|
|
129
|
+
if (previousCert) {
|
|
130
|
+
if (currentCert.x509Certificate.issuer !== previousCert.x509Certificate.subject) {
|
|
129
131
|
if (!reversed && !disallowReversedChain) {
|
|
130
132
|
return yield validateX509CertificateChainImpl({
|
|
131
133
|
reversed: true,
|
|
132
|
-
chain: pemOrDerChain.reverse(),
|
|
134
|
+
chain: [...pemOrDerChain].reverse(),
|
|
133
135
|
opts,
|
|
134
136
|
verificationTime,
|
|
135
137
|
trustAnchors,
|
|
136
138
|
});
|
|
137
139
|
}
|
|
138
|
-
return Object.assign({ error: true, critical: true, message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`, verificationTime }, (client && { client }));
|
|
140
|
+
return Object.assign({ error: true, critical: true, certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo), message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`, detailMessage: `The certificate ${currentCert.certificateInfo.subject.dn.DN} with issuer ${currentCert.x509Certificate.issuer}, is not signed by the previous certificate ${previousCert === null || previousCert === void 0 ? void 0 : previousCert.certificateInfo.subject.dn.DN} with subject string ${previousCert === null || previousCert === void 0 ? void 0 : previousCert.x509Certificate.subject}.`, verificationTime }, (client && { client }));
|
|
139
141
|
}
|
|
140
142
|
}
|
|
141
|
-
const result = yield
|
|
143
|
+
const result = yield currentCert.x509Certificate.verify({
|
|
142
144
|
date: verificationTime,
|
|
143
|
-
publicKey: (_c =
|
|
145
|
+
publicKey: (_c = previousCert === null || previousCert === void 0 ? void 0 : previousCert.x509Certificate) === null || _c === void 0 ? void 0 : _c.publicKey,
|
|
144
146
|
}, (_f = (_e = (_d = (0, pkijs_1.getCrypto)()) === null || _d === void 0 ? void 0 : _d.crypto) !== null && _e !== void 0 ? _e : crypto) !== null && _f !== void 0 ? _f : global.crypto);
|
|
145
147
|
if (!result) {
|
|
148
|
+
// First cert needs to be self signed
|
|
146
149
|
if (i == 0 && !reversed && !disallowReversedChain) {
|
|
147
150
|
return yield validateX509CertificateChainImpl({
|
|
148
151
|
reversed: true,
|
|
149
|
-
chain: pemOrDerChain.reverse(),
|
|
152
|
+
chain: [...pemOrDerChain].reverse(),
|
|
150
153
|
opts,
|
|
151
154
|
verificationTime,
|
|
152
155
|
trustAnchors,
|
|
153
156
|
});
|
|
154
157
|
}
|
|
155
|
-
return Object.assign({ error: true, critical: true, message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`, verificationTime }, (client && { client }));
|
|
158
|
+
return Object.assign({ error: true, critical: true, message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`, certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo), detailMessage: `Verification of the certificate ${currentCert.certificateInfo.subject.dn.DN} with issuer ${currentCert.x509Certificate.issuer} failed. Public key: ${JSON.stringify(currentCert.certificateInfo.publicKeyJWK)}.`, verificationTime }, (client && { client }));
|
|
156
159
|
}
|
|
157
|
-
foundTrustAnchor = foundTrustAnchor !== null && foundTrustAnchor !== void 0 ? foundTrustAnchor : trustedCerts === null || trustedCerts === void 0 ? void 0 : trustedCerts.find((trusted) => isSameCertificate(trusted.x509Certificate,
|
|
160
|
+
foundTrustAnchor = foundTrustAnchor !== null && foundTrustAnchor !== void 0 ? foundTrustAnchor : trustedCerts === null || trustedCerts === void 0 ? void 0 : trustedCerts.find((trusted) => isSameCertificate(trusted.x509Certificate, currentCert.x509Certificate));
|
|
158
161
|
if (i === 0 && chainLength === 1 && allowSingleNoCAChainElement) {
|
|
159
|
-
return Object.assign({ error: false, critical: false, message: `Certificate chain succeeded as allow single cert result is allowed: ${leafCert.certificateInfo.subject.dn.DN}.`, trustAnchor: foundTrustAnchor === null || foundTrustAnchor === void 0 ? void 0 : foundTrustAnchor.certificateInfo, verificationTime }, (client && { client }));
|
|
162
|
+
return Object.assign({ error: false, critical: false, message: `Certificate chain succeeded as allow single cert result is allowed: ${leafCert.certificateInfo.subject.dn.DN}.`, certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo), trustAnchor: foundTrustAnchor === null || foundTrustAnchor === void 0 ? void 0 : foundTrustAnchor.certificateInfo, verificationTime }, (client && { client }));
|
|
160
163
|
}
|
|
161
164
|
}
|
|
162
|
-
if (foundTrustAnchor) {
|
|
163
|
-
return Object.assign({ error: false, critical: false, message: `Certificate chain was valid`,
|
|
165
|
+
if ((foundTrustAnchor === null || foundTrustAnchor === void 0 ? void 0 : foundTrustAnchor.certificateInfo) || allowNoTrustAnchorsFound) {
|
|
166
|
+
return Object.assign({ error: false, critical: false, message: `Certificate chain was valid`, certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo), detailMessage: foundTrustAnchor
|
|
167
|
+
? `The leaf certificate ${leafCert.certificateInfo.subject.dn.DN} is part of a chain with trust anchor ${foundTrustAnchor === null || foundTrustAnchor === void 0 ? void 0 : foundTrustAnchor.certificateInfo.subject.dn.DN}.`
|
|
168
|
+
: `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}).)`, trustAnchor: foundTrustAnchor === null || foundTrustAnchor === void 0 ? void 0 : foundTrustAnchor.certificateInfo, verificationTime }, (client && { client }));
|
|
164
169
|
}
|
|
165
|
-
return Object.assign({ error: true, critical: true, message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`, verificationTime }, (client && { client }));
|
|
170
|
+
return Object.assign({ error: true, critical: true, message: `Certificate chain validation failed for ${leafCert.certificateInfo.subject.dn.DN}.`, certificateChain: x5cOrdereredChain.map((cert) => cert.certificateInfo), detailMessage: `No trust anchor was found in the chain. between (intermediate) CA ${x5cOrdereredChain[chain.length - 1].certificateInfo.subject.dn.DN} and leaf ${x5cOrdereredChain[0].certificateInfo.subject.dn.DN}.`, verificationTime }, (client && { client }));
|
|
166
171
|
});
|
|
167
172
|
const isSameCertificate = (cert1, cert2) => {
|
|
168
173
|
return cert1.rawData.toString() === cert2.rawData.toString();
|
|
@@ -176,7 +181,13 @@ const parseCertificate = (rawCert) => __awaiter(void 0, void 0, void 0, function
|
|
|
176
181
|
const x509Certificate = new x509_1.X509Certificate(rawCert);
|
|
177
182
|
const publicKeyInfo = asn1_schema_1.AsnParser.parse(x509Certificate.publicKey.rawData, asn1_x509_1.SubjectPublicKeyInfo);
|
|
178
183
|
const publicKeyRaw = new Uint8Array(publicKeyInfo.subjectPublicKey);
|
|
179
|
-
|
|
184
|
+
let publicKeyJwk = undefined;
|
|
185
|
+
try {
|
|
186
|
+
publicKeyJwk = (yield (0, exports.getCertificateSubjectPublicKeyJWK)(new Uint8Array(x509Certificate.rawData)));
|
|
187
|
+
}
|
|
188
|
+
catch (e) {
|
|
189
|
+
console.error(e.message);
|
|
190
|
+
}
|
|
180
191
|
const certificate = (0, x509_utils_1.pemOrDerToX509Certificate)(rawCert);
|
|
181
192
|
const certificateInfo = yield (0, exports.getCertificateInfo)(certificate);
|
|
182
193
|
const publicKeyAlgorithm = (0, exports.getX509AlgorithmProvider)().toWebAlgorithm(publicKeyInfo.algorithm);
|
|
@@ -191,81 +202,142 @@ const parseCertificate = (rawCert) => __awaiter(void 0, void 0, void 0, function
|
|
|
191
202
|
};
|
|
192
203
|
});
|
|
193
204
|
exports.parseCertificate = parseCertificate;
|
|
194
|
-
|
|
205
|
+
/*
|
|
206
|
+
|
|
207
|
+
/!**
|
|
195
208
|
*
|
|
196
209
|
* @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
|
|
197
210
|
* @param trustedPEMs
|
|
198
211
|
* @param verificationTime
|
|
199
212
|
* @param opts
|
|
200
|
-
|
|
201
|
-
const validateX509CertificateChainOrg =
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
213
|
+
*!/
|
|
214
|
+
export const validateX509CertificateChainOrg = async ({
|
|
215
|
+
chain: pemOrDerChain,
|
|
216
|
+
trustAnchors,
|
|
217
|
+
verificationTime = new Date(),
|
|
218
|
+
opts = {
|
|
219
|
+
trustRootWhenNoAnchors: false,
|
|
220
|
+
allowSingleNoCAChainElement: true,
|
|
221
|
+
blindlyTrustedAnchors: [],
|
|
222
|
+
},
|
|
223
|
+
}: {
|
|
224
|
+
chain: (Uint8Array | string)[]
|
|
225
|
+
trustAnchors?: string[]
|
|
226
|
+
verificationTime?: Date
|
|
227
|
+
opts?: X509CertificateChainValidationOpts
|
|
228
|
+
}): Promise<X509ValidationResult> => {
|
|
229
|
+
const {
|
|
230
|
+
trustRootWhenNoAnchors = false,
|
|
231
|
+
allowSingleNoCAChainElement = true,
|
|
232
|
+
blindlyTrustedAnchors = [],
|
|
233
|
+
client
|
|
234
|
+
} = opts
|
|
235
|
+
const trustedPEMs = trustRootWhenNoAnchors && !trustAnchors ? [pemOrDerChain[pemOrDerChain.length - 1]] : trustAnchors
|
|
236
|
+
|
|
209
237
|
if (pemOrDerChain.length === 0) {
|
|
210
238
|
return {
|
|
211
239
|
error: true,
|
|
212
240
|
critical: true,
|
|
213
241
|
message: 'Certificate chain in DER or PEM format must not be empty',
|
|
214
242
|
verificationTime,
|
|
215
|
-
}
|
|
243
|
+
}
|
|
216
244
|
}
|
|
245
|
+
|
|
217
246
|
// x5c always starts with the leaf cert at index 0 and then the cas. Our internal pkijs service expects it the other way around
|
|
218
|
-
const certs = pemOrDerChain.map(
|
|
219
|
-
const trustedCerts = trustedPEMs ? trustedPEMs.map(
|
|
220
|
-
defaultCryptoEngine()
|
|
247
|
+
const certs = pemOrDerChain.map(pemOrDerToX509Certificate).reverse()
|
|
248
|
+
const trustedCerts = trustedPEMs ? trustedPEMs.map(pemOrDerToX509Certificate) : undefined
|
|
249
|
+
defaultCryptoEngine()
|
|
250
|
+
|
|
221
251
|
if (pemOrDerChain.length === 1) {
|
|
222
|
-
const singleCert = typeof pemOrDerChain[0] === 'string' ? pemOrDerChain[0] : u8a.toString(pemOrDerChain[0], 'base64pad')
|
|
223
|
-
const cert =
|
|
252
|
+
const singleCert = typeof pemOrDerChain[0] === 'string' ? pemOrDerChain[0] : u8a.toString(pemOrDerChain[0], 'base64pad')
|
|
253
|
+
const cert = pemOrDerToX509Certificate(singleCert)
|
|
224
254
|
if (client) {
|
|
225
|
-
const validation =
|
|
255
|
+
const validation = await validateCertificateChainMatchesClientIdScheme(cert, client.clientId, client.clientIdScheme)
|
|
226
256
|
if (validation.error) {
|
|
227
|
-
return validation
|
|
257
|
+
return validation
|
|
228
258
|
}
|
|
229
259
|
}
|
|
230
260
|
if (blindlyTrustedAnchors.includes(singleCert)) {
|
|
231
|
-
console.log(`Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`)
|
|
232
|
-
return
|
|
261
|
+
console.log(`Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`)
|
|
262
|
+
return {
|
|
263
|
+
error: false,
|
|
264
|
+
critical: true,
|
|
265
|
+
message: `Certificate chain validation success as single cert if blindly trusted. WARNING: ONLY USE FOR TESTING PURPOSES.`,
|
|
266
|
+
verificationTime,
|
|
267
|
+
certificateChain: [await getCertificateInfo(cert)],
|
|
268
|
+
...(client && {client}),
|
|
269
|
+
}
|
|
233
270
|
}
|
|
234
271
|
if (allowSingleNoCAChainElement) {
|
|
235
|
-
const subjectDN =
|
|
236
|
-
if (!
|
|
237
|
-
const passed =
|
|
238
|
-
return
|
|
272
|
+
const subjectDN = getSubjectDN(cert).DN
|
|
273
|
+
if (!getIssuerDN(cert).DN || getIssuerDN(cert).DN === subjectDN) {
|
|
274
|
+
const passed = await cert.verify()
|
|
275
|
+
return {
|
|
276
|
+
error: !passed,
|
|
277
|
+
critical: true,
|
|
278
|
+
message: `Certificate chain validation for ${subjectDN}: ${passed ? 'successful' : 'failed'}.`,
|
|
279
|
+
verificationTime,
|
|
280
|
+
certificateChain: [await getCertificateInfo(cert)],
|
|
281
|
+
...(client && {client}),
|
|
282
|
+
}
|
|
239
283
|
}
|
|
240
284
|
}
|
|
241
285
|
}
|
|
242
|
-
|
|
243
|
-
|
|
286
|
+
|
|
287
|
+
const validationEngine = new CertificateChainValidationEngine({
|
|
288
|
+
certs /!*crls: [crl1], ocsps: [ocsp1], *!/,
|
|
244
289
|
checkDate: verificationTime,
|
|
245
290
|
trustedCerts,
|
|
246
|
-
})
|
|
291
|
+
})
|
|
292
|
+
|
|
247
293
|
try {
|
|
248
|
-
const verification =
|
|
294
|
+
const verification = await validationEngine.verify()
|
|
249
295
|
if (!verification.result || !verification.certificatePath) {
|
|
250
|
-
return
|
|
296
|
+
return {
|
|
297
|
+
error: true,
|
|
298
|
+
critical: true,
|
|
299
|
+
message: verification.resultMessage !== '' ? verification.resultMessage : `Certificate chain validation failed.`,
|
|
300
|
+
verificationTime,
|
|
301
|
+
...(client && {client}),
|
|
302
|
+
}
|
|
251
303
|
}
|
|
252
|
-
const certPath = verification.certificatePath
|
|
304
|
+
const certPath = verification.certificatePath
|
|
253
305
|
if (client) {
|
|
254
|
-
const clientIdValidation =
|
|
306
|
+
const clientIdValidation = await validateCertificateChainMatchesClientIdScheme(certs[0], client.clientId, client.clientIdScheme)
|
|
255
307
|
if (clientIdValidation.error) {
|
|
256
|
-
return clientIdValidation
|
|
308
|
+
return clientIdValidation
|
|
257
309
|
}
|
|
258
310
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
311
|
+
let certInfos: Array<CertificateInfo> | undefined
|
|
312
|
+
|
|
313
|
+
for (const certificate of certPath) {
|
|
314
|
+
try {
|
|
315
|
+
certInfos?.push(await getCertificateInfo(certificate))
|
|
316
|
+
} catch (e: any) {
|
|
317
|
+
console.log(`Error getting certificate info ${e.message}`)
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
return {
|
|
323
|
+
error: false,
|
|
324
|
+
critical: false,
|
|
325
|
+
message: `Certificate chain was valid`,
|
|
326
|
+
verificationTime,
|
|
327
|
+
certificateChain: certInfos,
|
|
328
|
+
...(client && {client}),
|
|
329
|
+
}
|
|
330
|
+
} catch (error: any) {
|
|
331
|
+
return {
|
|
332
|
+
error: true,
|
|
333
|
+
critical: true,
|
|
334
|
+
message: `Certificate chain was invalid, ${error.message ?? '<unknown error>'}`,
|
|
335
|
+
verificationTime,
|
|
336
|
+
...(client && {client}),
|
|
337
|
+
}
|
|
266
338
|
}
|
|
267
|
-
}
|
|
268
|
-
|
|
339
|
+
}
|
|
340
|
+
*/
|
|
269
341
|
const rdnmap = {
|
|
270
342
|
'2.5.4.6': 'C',
|
|
271
343
|
'2.5.4.10': 'O',
|
|
@@ -309,21 +381,33 @@ const getDNString = (typesAndValues) => {
|
|
|
309
381
|
};
|
|
310
382
|
const getCertificateSubjectPublicKeyJWK = (pemOrDerCert) => __awaiter(void 0, void 0, void 0, function* () {
|
|
311
383
|
const pemOrDerStr = typeof pemOrDerCert === 'string'
|
|
312
|
-
? pemOrDerCert
|
|
384
|
+
? u8a.toString(u8a.fromString(pemOrDerCert, 'base64pad'), 'base64pad')
|
|
313
385
|
: pemOrDerCert instanceof Uint8Array
|
|
314
386
|
? u8a.toString(pemOrDerCert, 'base64pad')
|
|
315
|
-
: pemOrDerCert.toString('base64');
|
|
387
|
+
: u8a.toString(u8a.fromString(pemOrDerCert.toString('base64'), 'base64pad'), 'base64pad');
|
|
316
388
|
const pem = (0, x509_utils_1.derToPEM)(pemOrDerStr);
|
|
317
389
|
const certificate = (0, x509_utils_1.pemOrDerToX509Certificate)(pem);
|
|
390
|
+
var jwk;
|
|
318
391
|
try {
|
|
319
392
|
const subtle = (0, pkijs_1.getCrypto)(true).subtle;
|
|
320
|
-
const pk = yield certificate.getPublicKey();
|
|
321
|
-
|
|
393
|
+
const pk = yield certificate.getPublicKey(undefined, defaultCryptoEngine());
|
|
394
|
+
jwk = (yield subtle.exportKey('jwk', pk));
|
|
322
395
|
}
|
|
323
396
|
catch (error) {
|
|
324
397
|
console.log(`Error in primary get JWK from cert:`, error === null || error === void 0 ? void 0 : error.message);
|
|
325
398
|
}
|
|
326
|
-
|
|
399
|
+
if (!jwk) {
|
|
400
|
+
try {
|
|
401
|
+
jwk = (yield js_x509_utils_1.default.toJwk(pem, 'pem'));
|
|
402
|
+
}
|
|
403
|
+
catch (error) {
|
|
404
|
+
console.log(`Error in secondary get JWK from cert as well:`, error === null || error === void 0 ? void 0 : error.message);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (!jwk) {
|
|
408
|
+
throw Error(`Failed to get JWK from certificate ${pem}`);
|
|
409
|
+
}
|
|
410
|
+
return jwk;
|
|
327
411
|
});
|
|
328
412
|
exports.getCertificateSubjectPublicKeyJWK = getCertificateSubjectPublicKeyJWK;
|
|
329
413
|
/**
|