@blamejs/pki 0.6.39 → 0.6.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/lib/acme.js +24 -13
- package/lib/asn1-der.js +5 -5
- package/lib/attrcert-sign.js +16 -16
- package/lib/cbor-det.js +2 -2
- package/lib/cmc-build.js +16 -16
- package/lib/cmc-verify.js +5 -5
- package/lib/cmp-build.js +29 -19
- package/lib/cmp-session.js +25 -20
- package/lib/cmp-verify.js +8 -12
- package/lib/cms-decrypt.js +8 -8
- package/lib/cms-encrypt.js +22 -22
- package/lib/cms-sign.js +17 -17
- package/lib/cms-verify.js +13 -13
- package/lib/composite-kem.js +1 -1
- package/lib/composite-sig.js +4 -4
- package/lib/constants.js +13 -9
- package/lib/crl-sign.js +25 -25
- package/lib/crmf-sign.js +11 -11
- package/lib/csr-sign.js +4 -4
- package/lib/ct.js +33 -25
- package/lib/edwards-point.js +2 -2
- package/lib/est.js +74 -43
- package/lib/guard-async.js +17 -1
- package/lib/guard-bytes.js +3 -3
- package/lib/guard-compress.js +5 -5
- package/lib/guard-identifier.js +46 -2
- package/lib/guard-json.js +1 -1
- package/lib/guard-list.js +16 -0
- package/lib/guard-name.js +1 -1
- package/lib/guard-parsed.js +1 -1
- package/lib/guard-time.js +3 -1
- package/lib/guard-verdict.js +7 -1
- package/lib/hpke.js +10 -10
- package/lib/http-digest.js +2 -2
- package/lib/http-transport.js +3 -3
- package/lib/inspect.js +9 -9
- package/lib/ip-utils.js +1 -1
- package/lib/jose.js +14 -14
- package/lib/key.js +7 -7
- package/lib/lint.js +6 -4
- package/lib/merkle.js +2 -2
- package/lib/mime.js +2 -2
- package/lib/ocsp-verify.js +1 -1
- package/lib/ocsp.js +5 -5
- package/lib/oid.js +3 -3
- package/lib/path-validate.js +127 -117
- package/lib/pbes2.js +2 -2
- package/lib/pkcs12-build.js +26 -24
- package/lib/pki-build.js +2 -2
- package/lib/scep.js +47 -16
- package/lib/schema-all.js +1 -1
- package/lib/schema-attrcert.js +4 -3
- package/lib/schema-c509.js +23 -23
- package/lib/schema-cmc.js +6 -6
- package/lib/schema-cmp.js +3 -3
- package/lib/schema-cms.js +15 -8
- package/lib/schema-crmf.js +1 -1
- package/lib/schema-csr.js +1 -1
- package/lib/schema-engine.js +2 -1
- package/lib/schema-pkcs12.js +1 -1
- package/lib/schema-pkix.js +3 -0
- package/lib/schema-tsp.js +2 -2
- package/lib/shbs.js +2 -2
- package/lib/sign-scheme.js +9 -9
- package/lib/sigstore.js +24 -14
- package/lib/smime.js +16 -16
- package/lib/tls-cert-compress.js +6 -6
- package/lib/trust.js +9 -9
- package/lib/tsp-sign.js +30 -30
- package/lib/validator-attcert.js +2 -2
- package/lib/validator-cose.js +5 -5
- package/lib/validator-sig.js +3 -3
- package/lib/validator-tpm.js +5 -4
- package/lib/webauthn.js +58 -54
- package/lib/webcrypto.js +22 -14
- package/lib/x509-sign.js +8 -8
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/constants.js
CHANGED
|
@@ -75,14 +75,14 @@ var DAYS_PER_WEEK = 7;
|
|
|
75
75
|
* var oneYear = pki.C.TIME.days(365);
|
|
76
76
|
* // -> 31536000000
|
|
77
77
|
*/
|
|
78
|
-
var TIME = {
|
|
78
|
+
var TIME = Object.assign(Object.create(null), {
|
|
79
79
|
milliseconds: function (n) { return _scale(n, "C.TIME.milliseconds", 1); },
|
|
80
80
|
seconds: function (n) { return _scale(n, "C.TIME.seconds", MS_PER_SECOND); },
|
|
81
81
|
minutes: function (n) { return _scale(n, "C.TIME.minutes", SECONDS_PER_MINUTE * MS_PER_SECOND); },
|
|
82
82
|
hours: function (n) { return _scale(n, "C.TIME.hours", MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND); },
|
|
83
83
|
days: function (n) { return _scale(n, "C.TIME.days", HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND); },
|
|
84
84
|
weeks: function (n) { return _scale(n, "C.TIME.weeks", DAYS_PER_WEEK * HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE * MS_PER_SECOND); },
|
|
85
|
-
};
|
|
85
|
+
});
|
|
86
86
|
|
|
87
87
|
var BYTES_PER_KIB = 1024;
|
|
88
88
|
|
|
@@ -101,14 +101,14 @@ var BYTES_PER_KIB = 1024;
|
|
|
101
101
|
* var cap = pki.C.BYTES.mib(16);
|
|
102
102
|
* // -> 16777216
|
|
103
103
|
*/
|
|
104
|
-
var BYTES = {
|
|
104
|
+
var BYTES = Object.assign(Object.create(null), {
|
|
105
105
|
b: function (n) { return _scale(n, "C.BYTES.b", 1); },
|
|
106
106
|
kib: function (n) { return _scale(n, "C.BYTES.kib", BYTES_PER_KIB); },
|
|
107
107
|
mib: function (n) { return _scale(n, "C.BYTES.mib", BYTES_PER_KIB * BYTES_PER_KIB); },
|
|
108
108
|
gib: function (n) { return _scale(n, "C.BYTES.gib", BYTES_PER_KIB * BYTES_PER_KIB * BYTES_PER_KIB); },
|
|
109
|
-
};
|
|
109
|
+
});
|
|
110
110
|
|
|
111
|
-
var LIMITS = {
|
|
111
|
+
var LIMITS = Object.assign(Object.create(null), {
|
|
112
112
|
DER_MAX_BYTES: BYTES.mib(16),
|
|
113
113
|
DER_MAX_DEPTH: 64,
|
|
114
114
|
DER_MAX_ITEMS: 4000000,
|
|
@@ -169,9 +169,9 @@ var LIMITS = {
|
|
|
169
169
|
TRUST_MAX_OBJECTS: 10000,
|
|
170
170
|
TRUST_MAX_CSV_ROWS: 10000,
|
|
171
171
|
TRUST_MAX_CSV_FIELD_BYTES: BYTES.kib(64),
|
|
172
|
-
};
|
|
172
|
+
});
|
|
173
173
|
|
|
174
|
-
var NAMES = {
|
|
174
|
+
var NAMES = Object.assign(Object.create(null), {
|
|
175
175
|
DN_SHORT: {
|
|
176
176
|
commonName: "CN", surname: "SN", serialNumber: "SERIALNUMBER", countryName: "C",
|
|
177
177
|
localityName: "L", stateOrProvinceName: "ST", streetAddress: "STREET",
|
|
@@ -227,9 +227,13 @@ var NAMES = {
|
|
|
227
227
|
"SLH-DSA-SHA2-128s": "SLH-DSA-SHA2-128s", "SLH-DSA-SHA2-128f": "SLH-DSA-SHA2-128f",
|
|
228
228
|
"SLH-DSA-SHA2-192s": "SLH-DSA-SHA2-192s", "SLH-DSA-SHA2-256s": "SLH-DSA-SHA2-256s",
|
|
229
229
|
},
|
|
230
|
-
};
|
|
230
|
+
});
|
|
231
231
|
|
|
232
|
-
|
|
232
|
+
/** @internal Each inner table is looked up by a name a certificate supplies, so it answers from
|
|
233
|
+
* its own entries alone rather than from whatever Object.prototype carries under that name. */
|
|
234
|
+
Object.keys(NAMES).forEach(function (k) {
|
|
235
|
+
NAMES[k] = Object.freeze(Object.assign(Object.create(null), NAMES[k]));
|
|
236
|
+
});
|
|
233
237
|
Object.freeze(NAMES);
|
|
234
238
|
|
|
235
239
|
var VERSION = require("../package.json").version;
|
package/lib/crl-sign.js
CHANGED
|
@@ -58,28 +58,28 @@ var CRL_REASON = constants.NAMES.CRL_REASON;
|
|
|
58
58
|
var REASON_BY_NAME = intrinsic.create(null);
|
|
59
59
|
Object.keys(CRL_REASON).forEach(function (v) { REASON_BY_NAME[CRL_REASON[v]] = Number(v); });
|
|
60
60
|
|
|
61
|
-
var KNOWN_CRL_EXT_KEYS = { authorityKeyIdentifier: 1, issuingDistributionPoint: 1, deltaCRLIndicator: 1, freshestCRL: 1, authorityInfoAccess: 1 };
|
|
62
|
-
var KNOWN_SPEC_KEYS = {
|
|
61
|
+
var KNOWN_CRL_EXT_KEYS = intrinsic.assign(intrinsic.create(null), { authorityKeyIdentifier: 1, issuingDistributionPoint: 1, deltaCRLIndicator: 1, freshestCRL: 1, authorityInfoAccess: 1 });
|
|
62
|
+
var KNOWN_SPEC_KEYS = intrinsic.assign(intrinsic.create(null), {
|
|
63
63
|
issuer: 1, thisUpdate: 1, nextUpdate: 1, revoked: 1, crlNumber: 1, extensions: 1,
|
|
64
|
-
};
|
|
65
|
-
var KNOWN_SPEC_KEYS_ISSUER_NAMED = {
|
|
64
|
+
});
|
|
65
|
+
var KNOWN_SPEC_KEYS_ISSUER_NAMED = intrinsic.assign(intrinsic.create(null), {
|
|
66
66
|
thisUpdate: 1, nextUpdate: 1, revoked: 1, crlNumber: 1, extensions: 1,
|
|
67
|
-
};
|
|
68
|
-
var KNOWN_ISSUER_CERT_KEYS = { key: 1, cert: 1 };
|
|
69
|
-
var KNOWN_ISSUER_EXPLICIT_KEYS = { key: 1, name: 1, publicKey: 1 };
|
|
70
|
-
var KNOWN_SIGN_OPTS = { digestAlgorithm: 1, pem: 1, pss: 1 };
|
|
67
|
+
});
|
|
68
|
+
var KNOWN_ISSUER_CERT_KEYS = intrinsic.assign(intrinsic.create(null), { key: 1, cert: 1 });
|
|
69
|
+
var KNOWN_ISSUER_EXPLICIT_KEYS = intrinsic.assign(intrinsic.create(null), { key: 1, name: 1, publicKey: 1 });
|
|
70
|
+
var KNOWN_SIGN_OPTS = intrinsic.assign(intrinsic.create(null), { digestAlgorithm: 1, pem: 1, pss: 1 });
|
|
71
71
|
|
|
72
|
-
var KNOWN_IDP_KEYS = { fullName: 1, onlyContainsUserCerts: 1, onlyContainsCACerts: 1, onlyContainsAttributeCerts: 1, indirectCRL: 1 };
|
|
72
|
+
var KNOWN_IDP_KEYS = intrinsic.assign(intrinsic.create(null), { fullName: 1, onlyContainsUserCerts: 1, onlyContainsCACerts: 1, onlyContainsAttributeCerts: 1, indirectCRL: 1 });
|
|
73
73
|
|
|
74
|
-
var KNOWN_REVOKED_KEYS = {
|
|
74
|
+
var KNOWN_REVOKED_KEYS = intrinsic.assign(intrinsic.create(null), {
|
|
75
75
|
serialNumber: 1, revocationDate: 1, reason: 1, invalidityDate: 1, certificateIssuer: 1, extensions: 1,
|
|
76
|
-
};
|
|
76
|
+
});
|
|
77
77
|
|
|
78
|
-
var REQUIRED_CRITICALITY =
|
|
78
|
+
var REQUIRED_CRITICALITY = intrinsic.create(null);
|
|
79
79
|
[["cRLNumber", false], ["authorityKeyIdentifier", false], ["freshestCRL", false], ["authorityInfoAccess", false],
|
|
80
80
|
["issuingDistributionPoint", true], ["deltaCRLIndicator", true]].forEach(function (r) { REQUIRED_CRITICALITY[O(r[0])] = r[1]; });
|
|
81
81
|
|
|
82
|
-
var REQUIRED_ENTRY_CRITICALITY =
|
|
82
|
+
var REQUIRED_ENTRY_CRITICALITY = intrinsic.create(null);
|
|
83
83
|
[["reasonCode", false], ["invalidityDate", false]].forEach(function (r) { REQUIRED_ENTRY_CRITICALITY[O(r[0])] = r[1]; });
|
|
84
84
|
|
|
85
85
|
var _CERT_ISSUER_DEFERRED = "certificateIssuer (indirect CRLs) is not yet supported -- pki.path.crlChecker skips a CRL carrying any critical entry extension other than reasonCode, so an indirect CRL would never be authoritative for revocation. Re-enabled once the checker processes certificateIssuer / indirect CRLs.";
|
|
@@ -189,7 +189,7 @@ function _aiaValue(spec) {
|
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
function _buildCrlExtensions(spec, ctx) {
|
|
192
|
-
var out = [], seen =
|
|
192
|
+
var out = [], seen = intrinsic.create(null), isDelta = false;
|
|
193
193
|
function push(oidName, critical, valueDer) {
|
|
194
194
|
var id = O(oidName);
|
|
195
195
|
if (seen[id]) throw _err("crl/bad-input", "duplicate CRL extension " + oidName + " (RFC 5280 sec. 5.2 -- at most one instance)");
|
|
@@ -255,7 +255,7 @@ function _buildCrlExtensions(spec, ctx) {
|
|
|
255
255
|
|
|
256
256
|
function _buildRevoked(entryList, isDelta) {
|
|
257
257
|
if (!Array.isArray(entryList)) throw _err("crl/bad-input", "revoked must be an array of revoked-certificate entries");
|
|
258
|
-
var anyExt = false, seenSerials =
|
|
258
|
+
var anyExt = false, seenSerials = intrinsic.create(null);
|
|
259
259
|
var entries = _b.reqDenseArray(entryList, "revoked").map(function (e, idx) {
|
|
260
260
|
if (!e || typeof e !== "object" || Buffer.isBuffer(e)) throw _err("crl/bad-input", "each revoked entry must be an object");
|
|
261
261
|
guard.identifier.assertKnownKeys(e, KNOWN_REVOKED_KEYS, _err, "crl/bad-input", function (k) {
|
|
@@ -268,7 +268,7 @@ function _buildRevoked(entryList, isDelta) {
|
|
|
268
268
|
if (seenSerials[serialKey]) throw _err("crl/bad-input", "revoked entry [" + idx + "] duplicates a serial number already listed in this CRL (RFC 5280 sec. 5.1.2.6)");
|
|
269
269
|
seenSerials[serialKey] = true;
|
|
270
270
|
var children = [serialTlv, _timeDer(e.revocationDate, "revocationDate")];
|
|
271
|
-
var entryExts = [], seen =
|
|
271
|
+
var entryExts = [], seen = intrinsic.create(null);
|
|
272
272
|
function pushE(oidName, critical, valueDer) {
|
|
273
273
|
var id = O(oidName);
|
|
274
274
|
if (seen[id]) throw _err("crl/bad-input", "duplicate entry extension " + oidName + " in revoked entry [" + idx + "]");
|
|
@@ -525,14 +525,14 @@ function _verify(crl, issuer) {
|
|
|
525
525
|
return crlVerify.verifyCrlSignature(parsed, resolved.spki).then(function (sigOk) {
|
|
526
526
|
var signatureValid = sigOk === true;
|
|
527
527
|
var valid = issuerMaySign && signatureValid;
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
528
|
+
return guard.verdict.of(
|
|
529
|
+
{ valid: valid, issuerMaySign: issuerMaySign, signatureValid: signatureValid, issuer: parsed.issuer },
|
|
530
|
+
valid ? null : {
|
|
531
|
+
code: !issuerMaySign ? "crl/issuer-may-not-sign" : "crl/bad-signature",
|
|
532
|
+
reason: !issuerMaySign
|
|
533
|
+
? "the issuer certificate is not this CRL's issuer, or its keyUsage does not assert cRLSign (RFC 5280 sec. 4.2.1.3)"
|
|
534
|
+
: "the CRL signature did not verify under the issuer key",
|
|
535
|
+
});
|
|
536
536
|
});
|
|
537
537
|
}
|
|
538
538
|
|
|
@@ -602,7 +602,7 @@ function _serialHexOf(serial) {
|
|
|
602
602
|
* { cert: signerCertDer, key: signerKeyPkcs8 });
|
|
603
603
|
* pki.crl.isRevoked(crlDer, 0x1234n) ? "revoked" : "not listed";
|
|
604
604
|
*/
|
|
605
|
-
var KNOWN_IS_REVOKED_KEYS = { time: 1, historicalMode: 1 };
|
|
605
|
+
var KNOWN_IS_REVOKED_KEYS = intrinsic.assign(intrinsic.create(null), { time: 1, historicalMode: 1 });
|
|
606
606
|
function isRevoked(crl, serialNumber, opts) {
|
|
607
607
|
var o = guard.identifier.optionsObject(opts, _err, "crl/bad-input", "pki.crl.isRevoked options");
|
|
608
608
|
guard.identifier.assertKnownKeys(o, KNOWN_IS_REVOKED_KEYS, _err, "crl/bad-input", function (k) {
|
package/lib/crmf-sign.js
CHANGED
|
@@ -47,8 +47,8 @@ var _b = pkiBuild.makeBuilder({
|
|
|
47
47
|
NAME_SCHEMA: pkix.name(NS), SPKI_SCHEMA: pkix.spki(NS), EXT_DECODERS: EXT_DECODERS,
|
|
48
48
|
});
|
|
49
49
|
|
|
50
|
-
var KNOWN_SPEC_KEYS = { certReqId: 1, certTemplate: 1, controls: 1, regInfo: 1, pop: 1 };
|
|
51
|
-
var POP_KEYS_BY_ARM = {
|
|
50
|
+
var KNOWN_SPEC_KEYS = intrinsic.assign(intrinsic.create(null), { certReqId: 1, certTemplate: 1, controls: 1, regInfo: 1, pop: 1 });
|
|
51
|
+
var POP_KEYS_BY_ARM = intrinsic.assign(intrinsic.create(null), {
|
|
52
52
|
raVerified: { type: 1, raVerified: 1 },
|
|
53
53
|
signature: { type: 1, sender: 1 },
|
|
54
54
|
subsequentMessage: { type: 1, method: 1, subsequentMessage: 1 },
|
|
@@ -59,14 +59,14 @@ var POP_KEYS_BY_ARM = {
|
|
|
59
59
|
agreeMAC: { type: 1, method: 1 },
|
|
60
60
|
thisMessage: { type: 1, method: 1 },
|
|
61
61
|
dhMAC: { type: 1, method: 1 },
|
|
62
|
-
};
|
|
63
|
-
var KNOWN_BATCH_KEYS = { messages: 1 };
|
|
64
|
-
var KNOWN_TEMPLATE_KEYS = { version: 1, subject: 1, publicKey: 1, validity: 1, extensions: 1, issuer: 1 };
|
|
65
|
-
var REVOCATION_TEMPLATE_KEYS = { version: 1, subject: 1, publicKey: 1, validity: 1, extensions: 1, issuer: 1, serialNumber: 1 };
|
|
62
|
+
});
|
|
63
|
+
var KNOWN_BATCH_KEYS = intrinsic.assign(intrinsic.create(null), { messages: 1 });
|
|
64
|
+
var KNOWN_TEMPLATE_KEYS = intrinsic.assign(intrinsic.create(null), { version: 1, subject: 1, publicKey: 1, validity: 1, extensions: 1, issuer: 1 });
|
|
65
|
+
var REVOCATION_TEMPLATE_KEYS = intrinsic.assign(intrinsic.create(null), { version: 1, subject: 1, publicKey: 1, validity: 1, extensions: 1, issuer: 1, serialNumber: 1 });
|
|
66
66
|
function _ctlUtf8(v) { return b.utf8(String(v)); }
|
|
67
67
|
function _ctlSpki(v) { var k = _b.reqDer(v, "protocolEncrKey (an SPKI DER)"); _b.assertValidSpki(k, "protocolEncrKey"); return b.raw(k); }
|
|
68
|
-
var CONTROL_VALUE = { regToken: _ctlUtf8, authenticator: _ctlUtf8, oldCertID: function (v) { return _encodeCertId(v); }, protocolEncrKey: _ctlSpki };
|
|
69
|
-
var REGINFO_VALUE = { utf8Pairs: _ctlUtf8 };
|
|
68
|
+
var CONTROL_VALUE = intrinsic.assign(intrinsic.create(null), { regToken: _ctlUtf8, authenticator: _ctlUtf8, oldCertID: function (v) { return _encodeCertId(v); }, protocolEncrKey: _ctlSpki });
|
|
69
|
+
var REGINFO_VALUE = intrinsic.assign(intrinsic.create(null), { utf8Pairs: _ctlUtf8 });
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
function _encodeOptionalValidity(validity) {
|
|
@@ -106,7 +106,7 @@ function _encodeCertTemplate(tpl, opts) {
|
|
|
106
106
|
function _buildAttrTypeAndValues(spec, code, label, valueMap) {
|
|
107
107
|
if (Array.isArray(spec)) {
|
|
108
108
|
if (!spec.length) throw _err(code, label + " must carry at least one entry");
|
|
109
|
-
var seenA =
|
|
109
|
+
var seenA = intrinsic.create(null);
|
|
110
110
|
return b.sequence(pkiBuild.reqDenseArray(spec, label, _err, code).map(function (e, i) {
|
|
111
111
|
var der = _b.reqDer(e, label + " [" + i + "]");
|
|
112
112
|
var n;
|
|
@@ -120,7 +120,7 @@ function _buildAttrTypeAndValues(spec, code, label, valueMap) {
|
|
|
120
120
|
}));
|
|
121
121
|
}
|
|
122
122
|
if (!spec || typeof spec !== "object") throw _err("crmf/bad-input", label + " must be an object or an array of pre-encoded AttributeTypeAndValue DER");
|
|
123
|
-
var out = [], seen =
|
|
123
|
+
var out = [], seen = intrinsic.create(null);
|
|
124
124
|
guard.identifier.assertKnownKeys(spec, valueMap, _err, "crmf/bad-input", function (k) {
|
|
125
125
|
return "unknown " + label + " " + JSON.stringify(k) + "; pass a pre-encoded AttributeTypeAndValue DER via the array form for a " + label + " entry outside " + Object.keys(valueMap).join("/");
|
|
126
126
|
});
|
|
@@ -147,7 +147,7 @@ function _encodeCertId(id) {
|
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
var POPO_PRIVKEY_TAGS = intrinsic.assign(intrinsic.create(null), { keyEncipherment: 2, keyAgreement: 3 });
|
|
150
|
-
var SUBSEQUENT_MESSAGE = { encrCert: 0n, challengeResp: 1n };
|
|
150
|
+
var SUBSEQUENT_MESSAGE = intrinsic.assign(intrinsic.create(null), { encrCert: 0n, challengeResp: 1n });
|
|
151
151
|
var DEPRECATED_POPO_METHOD = intrinsic.assign(intrinsic.create(null), { thisMessage: "encryptedKey", dhMAC: "agreeMAC" });
|
|
152
152
|
|
|
153
153
|
function _encKeyWithID(privateKeyDer, identifier) {
|
package/lib/csr-sign.js
CHANGED
|
@@ -29,7 +29,7 @@ require("./path-validate");
|
|
|
29
29
|
var csrVerify = require("./csr-verify");
|
|
30
30
|
|
|
31
31
|
var CsrError = frameworkError.CsrError;
|
|
32
|
-
var KNOWN_SPEC_KEYS = { subject: 1, subjectPublicKey: 1, extensionRequest: 1, challengePassword: 1, attributes: 1 };
|
|
32
|
+
var KNOWN_SPEC_KEYS = Object.assign(Object.create(null), { subject: 1, subjectPublicKey: 1, extensionRequest: 1, challengePassword: 1, attributes: 1 });
|
|
33
33
|
var b = asn1.build;
|
|
34
34
|
function _err(code, message, cause) { return new CsrError(code, message, cause); }
|
|
35
35
|
function _signE(kind, message, cause) { return new CsrError("csr/" + kind, message, cause); }
|
|
@@ -106,7 +106,7 @@ function _sign(spec, key, opts) {
|
|
|
106
106
|
_b.assertValidSpki(subjectSpki, "spec.subjectPublicKey");
|
|
107
107
|
var subjectDer = _b.encodeName(spec.subject == null ? [] : spec.subject);
|
|
108
108
|
|
|
109
|
-
var attrs = [], seenAttr =
|
|
109
|
+
var attrs = [], seenAttr = Object.create(null);
|
|
110
110
|
function addAttr(attrType, valueTlv) {
|
|
111
111
|
if (seenAttr[attrType]) throw _err("csr/bad-input", "duplicate " + (oid.name(attrType) || attrType) + " attribute");
|
|
112
112
|
seenAttr[attrType] = true;
|
|
@@ -205,14 +205,14 @@ function verify(request) { return guard.async.deferred(function () { return _ver
|
|
|
205
205
|
function _verify(request) {
|
|
206
206
|
var parsed = _coerceCsr(request);
|
|
207
207
|
return Promise.resolve(csrVerify.verifyCsrSignature(parsed)).then(function (ok) {
|
|
208
|
-
return {
|
|
208
|
+
return guard.verdict.of({
|
|
209
209
|
valid: ok === true,
|
|
210
210
|
verified: ok === true,
|
|
211
211
|
subject: parsed.subject,
|
|
212
212
|
subjectPublicKeyInfo: parsed.subjectPublicKeyInfo,
|
|
213
213
|
attributes: parsed.attributes,
|
|
214
214
|
certificationRequestInfoBytes: parsed.certificationRequestInfoBytes,
|
|
215
|
-
};
|
|
215
|
+
});
|
|
216
216
|
});
|
|
217
217
|
}
|
|
218
218
|
|
package/lib/ct.js
CHANGED
|
@@ -64,10 +64,10 @@ var C = constants;
|
|
|
64
64
|
|
|
65
65
|
function _ctErr(c, m, cause) { return new CtError(c, m, cause); }
|
|
66
66
|
|
|
67
|
-
var HASH_ALGORITHMS = {
|
|
67
|
+
var HASH_ALGORITHMS = intrinsic.assign(intrinsic.create(null), {
|
|
68
68
|
0: "none", 1: "md5", 2: "sha1", 3: "sha224", 4: "sha256", 5: "sha384", 6: "sha512",
|
|
69
|
-
};
|
|
70
|
-
var SIGNATURE_ALGORITHMS = { 0: "anonymous", 1: "rsa", 2: "dsa", 3: "ecdsa" };
|
|
69
|
+
});
|
|
70
|
+
var SIGNATURE_ALGORITHMS = intrinsic.assign(intrinsic.create(null), { 0: "anonymous", 1: "rsa", 2: "dsa", 3: "ecdsa" });
|
|
71
71
|
|
|
72
72
|
var SCT_MIN_BODY = 47;
|
|
73
73
|
var LOGID_BYTES = 32;
|
|
@@ -290,8 +290,8 @@ function reconstructSignedData(entry, sct) {
|
|
|
290
290
|
return Buffer.concat(parts);
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
-
var CT_HASH = { sha256: "SHA-256" };
|
|
294
|
-
var CT_EC_CURVE =
|
|
293
|
+
var CT_HASH = intrinsic.assign(intrinsic.create(null), { sha256: "SHA-256" });
|
|
294
|
+
var CT_EC_CURVE = intrinsic.create(null);
|
|
295
295
|
CT_EC_CURVE[oid.byName("prime256v1")] = { curve: "P-256", coordLen: 32 };
|
|
296
296
|
|
|
297
297
|
function _spkiAlg(spki) {
|
|
@@ -551,7 +551,7 @@ async function signSct(entry, logKey, opts) {
|
|
|
551
551
|
var priv = await subtle.importKey("pkcs8", mat.pkcs8, imp, false, ["sign"]);
|
|
552
552
|
var sigRaw = Buffer.from(await subtle.sign(sign, priv, preimage));
|
|
553
553
|
var signature = ecdsaDer ? validator.sig.rawToEcdsaDer(sigRaw, coordLen) : sigRaw;
|
|
554
|
-
return {
|
|
554
|
+
return guard.verdict.of({
|
|
555
555
|
version: 0,
|
|
556
556
|
logId: logId, logIdHex: logId.toString("hex"),
|
|
557
557
|
timestamp: timestamp,
|
|
@@ -559,11 +559,11 @@ async function signSct(entry, logKey, opts) {
|
|
|
559
559
|
hashAlg: hashAlg, sigAlg: sigAlg,
|
|
560
560
|
signatureAlgorithm: { hash: hashAlg, hashName: HASH_ALGORITHMS[hashAlg] || null, signature: sigAlg, signatureName: SIGNATURE_ALGORITHMS[sigAlg] || null },
|
|
561
561
|
signature: signature,
|
|
562
|
-
};
|
|
562
|
+
});
|
|
563
563
|
}
|
|
564
564
|
|
|
565
565
|
|
|
566
|
-
var LOG_STATE_TRUST = { pending: "no", qualified: "yes", usable: "yes", readonly: "yes", retired: "conditional", rejected: "no" };
|
|
566
|
+
var LOG_STATE_TRUST = intrinsic.assign(intrinsic.create(null), { pending: "no", qualified: "yes", usable: "yes", readonly: "yes", retired: "conditional", rejected: "no" });
|
|
567
567
|
|
|
568
568
|
function _parseLogState(state) {
|
|
569
569
|
if (state == null || typeof state !== "object") throw _ctErr("ct/bad-state", "a CT log entry is missing its state");
|
|
@@ -766,17 +766,17 @@ async function verifySctWithLogList(entry, sct, logList, opts) {
|
|
|
766
766
|
var c = _classifyLog(sct, logList, entry, opts);
|
|
767
767
|
if (c.status !== "ok") throw _ctErr(c.code, c.message);
|
|
768
768
|
var valid = await verifySct(entry, sct, c.log.key);
|
|
769
|
-
return {
|
|
769
|
+
return guard.verdict.of({
|
|
770
770
|
valid: valid,
|
|
771
771
|
logId: c.log.logId,
|
|
772
772
|
logIdHex: c.log.logIdHex,
|
|
773
773
|
operator: c.log.operator,
|
|
774
774
|
logState: c.log.state.name,
|
|
775
775
|
timestamp: sct.timestamp,
|
|
776
|
-
};
|
|
776
|
+
});
|
|
777
777
|
}
|
|
778
778
|
|
|
779
|
-
var _VERIFY_SCT_LIST_OPTS = { minScts: 1, minOperators: 1, certNotAfter: 1, at: 1 };
|
|
779
|
+
var _VERIFY_SCT_LIST_OPTS = intrinsic.assign(intrinsic.create(null), { minScts: 1, minOperators: 1, certNotAfter: 1, at: 1 });
|
|
780
780
|
|
|
781
781
|
function _policyCount(v, name) {
|
|
782
782
|
if (v == null) return null;
|
|
@@ -860,37 +860,37 @@ async function verifySctList(entry, list, logList, opts) {
|
|
|
860
860
|
try { c = _classifyLog(sct, logList, entry, opts); }
|
|
861
861
|
catch (e) {
|
|
862
862
|
if (!(e && e.isPkiError)) throw e;
|
|
863
|
-
row.code = e.code; row.reason = e.message;
|
|
863
|
+
row.code = e.code; row.reason = e.message; guard.list.append(results, row); continue;
|
|
864
864
|
}
|
|
865
865
|
if (c.log) { row.operator = c.log.operator; row.logState = c.log.state.name; }
|
|
866
|
-
if (c.status !== "ok") { row.code = c.code; row.reason = c.message;
|
|
866
|
+
if (c.status !== "ok") { row.code = c.code; row.reason = c.message; guard.list.append(results, row); continue; }
|
|
867
867
|
var ok;
|
|
868
868
|
try { ok = await verifySct(entry, sct, c.log.key); }
|
|
869
869
|
catch (e) {
|
|
870
870
|
if (!(e && e.isPkiError)) throw e;
|
|
871
|
-
row.code = e.code; row.reason = e.message;
|
|
871
|
+
row.code = e.code; row.reason = e.message; guard.list.append(results, row); continue;
|
|
872
872
|
}
|
|
873
873
|
if (ok === true && atMs != null && sct.timestamp > atMs) {
|
|
874
874
|
row.code = "ct/future-timestamp"; row.reason = "the SCT timestamp is later than the validation time (RFC 6962 sec. 5.2)";
|
|
875
|
-
|
|
875
|
+
guard.list.append(results, row); continue;
|
|
876
876
|
}
|
|
877
877
|
row.valid = ok === true;
|
|
878
878
|
if (row.valid && !seenLogs[sct.logIdHex]) {
|
|
879
879
|
seenLogs[sct.logIdHex] = true;
|
|
880
880
|
validScts++;
|
|
881
|
-
if (c.log.operator != null && !seenOps[c.log.operator]) { seenOps[c.log.operator] = true;
|
|
881
|
+
if (c.log.operator != null && !seenOps[c.log.operator]) { seenOps[c.log.operator] = true; guard.list.append(operators, c.log.operator); }
|
|
882
882
|
}
|
|
883
|
-
|
|
883
|
+
guard.list.append(results, row);
|
|
884
884
|
}
|
|
885
885
|
var operatorCount = operators.length;
|
|
886
886
|
var policyOk = validScts >= minScts && operatorCount >= minOperators;
|
|
887
|
-
return {
|
|
887
|
+
return guard.verdict.of({
|
|
888
888
|
valid: policyOk,
|
|
889
889
|
policyOk: policyOk, totalScts: scts.length + unknownScts, validScts: validScts, unknownScts: unknownScts,
|
|
890
890
|
operatorCount: operatorCount, operators: operators, required: { minScts: minScts, minOperators: minOperators },
|
|
891
891
|
results: results,
|
|
892
892
|
reason: policyOk ? null : ("CT policy not met: " + validScts + " valid SCT(s) from " + operatorCount + " distinct operator(s); require at least " + minScts + " SCT(s) from at least " + minOperators + " operator(s)"),
|
|
893
|
-
};
|
|
893
|
+
});
|
|
894
894
|
}
|
|
895
895
|
|
|
896
896
|
function _asParsedCert(v, field) {
|
|
@@ -1029,7 +1029,7 @@ async function verifyLogListSignature(json, signature, publicKey) {
|
|
|
1029
1029
|
|
|
1030
1030
|
var DEFAULT_FETCH_TIMEOUT = C.TIME.seconds(30);
|
|
1031
1031
|
var MAX_FETCH_TIMEOUT = C.TIME.seconds(600);
|
|
1032
|
-
var KNOWN_FETCH_OPTS = { url: 1, signerKey: 1, sigUrl: 1, transport: 1, tls: 1, headers: 1, timeout: 1, maxResponseBytes: 1, requireJsonContentType: 1 };
|
|
1032
|
+
var KNOWN_FETCH_OPTS = intrinsic.assign(intrinsic.create(null), { url: 1, signerKey: 1, sigUrl: 1, transport: 1, tls: 1, headers: 1, timeout: 1, maxResponseBytes: 1, requireJsonContentType: 1 });
|
|
1033
1033
|
|
|
1034
1034
|
function _tlsForFetch(opts) {
|
|
1035
1035
|
var t = opts.tls || {};
|
|
@@ -1038,6 +1038,12 @@ function _tlsForFetch(opts) {
|
|
|
1038
1038
|
|
|
1039
1039
|
function _sameOrigin(a, b) { return new URL(a).origin === new URL(b).origin; }
|
|
1040
1040
|
|
|
1041
|
+
/** @internal Refused at the door and again where the value is used. */
|
|
1042
|
+
function _assertTransport(opts) {
|
|
1043
|
+
return guard.identifier.assertCallableOption(opts, "transport", _ctErr, "ct/bad-input", "opts.transport",
|
|
1044
|
+
"(request) => Promise<{ status, headers, body }>");
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1041
1047
|
function _fetchCtypeToken(headers) { return String((headers || {})["content-type"] || "").split(";")[0].trim().toLowerCase(); }
|
|
1042
1048
|
|
|
1043
1049
|
function _parseHttpsUrl(u, label) {
|
|
@@ -1060,7 +1066,7 @@ function _fetchBody(transport, url, req, label) {
|
|
|
1060
1066
|
return transport({ method: "GET", url: url, headers: req.headers, tls: req.tls, timeout: req.timeout, maxResponseBytes: req.maxResponseBytes });
|
|
1061
1067
|
}).then(function (res) {
|
|
1062
1068
|
res = res || {};
|
|
1063
|
-
var h =
|
|
1069
|
+
var h = intrinsic.create(null);
|
|
1064
1070
|
Object.keys(res.headers || {}).forEach(function (k) { h[k.toLowerCase()] = res.headers[k]; });
|
|
1065
1071
|
var body = guard.bytes.isByteSource(res.body)
|
|
1066
1072
|
? guard.bytes.source(res.body, CtError, "ct/bad-input", label)
|
|
@@ -1116,13 +1122,15 @@ function _fetchBody(transport, url, req, label) {
|
|
|
1116
1122
|
async function fetchLogList(opts) {
|
|
1117
1123
|
opts = opts || {};
|
|
1118
1124
|
guard.identifier.assertKnownKeys(opts, KNOWN_FETCH_OPTS, _ctErr, "ct/bad-input", "unknown opts field ");
|
|
1125
|
+
/** @internal Read once, at the door, and carried from here. Asking again would let an option that
|
|
1126
|
+
* answers differently on each read hand back something other than the value that was checked. */
|
|
1127
|
+
var transport = _assertTransport(opts);
|
|
1119
1128
|
if (opts.signerKey == null) throw _ctErr("ct/bad-input", "opts.signerKey is required -- the caller-pinned CT log-list distributor SPKI (there is no baked-in key)");
|
|
1120
1129
|
if (opts.url == null) throw _ctErr("ct/bad-input", "opts.url is required -- the log_list.json URL (there is no baked-in vendor URL)");
|
|
1121
1130
|
var jsonParsed = _parseHttpsUrl(opts.url, "URL");
|
|
1122
1131
|
var jsonUrl = jsonParsed.href;
|
|
1123
1132
|
var sigUrl = opts.sigUrl != null ? _parseHttpsUrl(opts.sigUrl, "signature URL").href : _sigUrlFor(jsonParsed);
|
|
1124
1133
|
if (!_sameOrigin(jsonUrl, sigUrl)) throw _ctErr("ct/bad-input", "opts.sigUrl must share the log-list URL's origin (" + jsonParsed.origin + "); a cross-origin detached-signature host is not supported");
|
|
1125
|
-
var transport = opts.transport;
|
|
1126
1134
|
if (!transport) {
|
|
1127
1135
|
var t = opts.tls || {};
|
|
1128
1136
|
var hasAnchors = t.anchors !== undefined && t.anchors !== null && !(Array.isArray(t.anchors) && t.anchors.length === 0);
|
|
@@ -1131,7 +1139,7 @@ async function fetchLogList(opts) {
|
|
|
1131
1139
|
}
|
|
1132
1140
|
var timeout = guard.limits.cap(opts.timeout, "timeout", DEFAULT_FETCH_TIMEOUT, { E: _ctErr, code: "ct/bad-input", min: 1, max: MAX_FETCH_TIMEOUT });
|
|
1133
1141
|
var maxResponseBytes = guard.limits.cap(opts.maxResponseBytes, "maxResponseBytes", C.LIMITS.CT_LOG_LIST_MAX_BYTES, { E: _ctErr, code: "ct/bad-input", min: 1, max: C.LIMITS.CT_LOG_LIST_MAX_BYTES });
|
|
1134
|
-
var headers =
|
|
1142
|
+
var headers = intrinsic.create(null);
|
|
1135
1143
|
Object.keys(opts.headers || {}).forEach(function (k) {
|
|
1136
1144
|
var lk = k.toLowerCase();
|
|
1137
1145
|
if (lk !== "content-length" && lk !== "transfer-encoding") headers[k] = opts.headers[k];
|
|
@@ -1143,10 +1151,10 @@ async function fetchLogList(opts) {
|
|
|
1143
1151
|
var ok = await verifyLogListSignature(jsonRes.body, sigRes.body, opts.signerKey);
|
|
1144
1152
|
if (ok !== true) throw _ctErr("ct/log-list-untrusted", "the CT log-list detached signature did not verify against the pinned distributor key -- the fetched list is untrusted and was not parsed");
|
|
1145
1153
|
var parsed = parseLogList(jsonRes.body);
|
|
1146
|
-
return {
|
|
1154
|
+
return guard.verdict.of({
|
|
1147
1155
|
logs: parsed.logs, byLogId: parsed.byLogId, version: parsed.version, timestamp: parsed.timestamp,
|
|
1148
1156
|
raw: { json: jsonRes.body, sig: sigRes.body }, status: jsonRes.status, contentType: jsonRes.contentType, tls: jsonRes.tls,
|
|
1149
|
-
};
|
|
1157
|
+
});
|
|
1150
1158
|
}
|
|
1151
1159
|
|
|
1152
1160
|
module.exports = {
|
package/lib/edwards-point.js
CHANGED
|
@@ -11,10 +11,10 @@ var SQRTM1 = _pow(2n, (P25519 - 1n) / 4n, P25519);
|
|
|
11
11
|
var P448 = (1n << 448n) - (1n << 224n) - 1n;
|
|
12
12
|
var D448 = P448 - 39081n;
|
|
13
13
|
|
|
14
|
-
var CURVE = {
|
|
14
|
+
var CURVE = Object.assign(Object.create(null), {
|
|
15
15
|
6: { p: P25519, d: D25519, a: P25519 - 1n, len: 32, signBit: 255n },
|
|
16
16
|
7: { p: P448, d: D448, a: 1n, len: 57, signBit: 455n },
|
|
17
|
-
};
|
|
17
|
+
});
|
|
18
18
|
|
|
19
19
|
function _mul(x, y, p) { return (x % p) * (y % p) % p; }
|
|
20
20
|
function _pow(b, e, p) { var r = 1n; b %= p; while (e > 0n) { if (e & 1n) r = r * b % p; b = b * b % p; e >>= 1n; } return r; }
|