@blamejs/pki 0.6.40 → 0.6.42
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/README.md +1 -1
- package/lib/acme.js +24 -13
- package/lib/asn1-der.js +5 -5
- package/lib/attrcert-sign.js +14 -14
- 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 +21 -16
- package/lib/cmp-verify.js +4 -4
- 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 +6 -6
- 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 +17 -17
- package/lib/crmf-sign.js +11 -11
- package/lib/csr-sign.js +2 -2
- package/lib/ct.js +19 -11
- 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 +2 -2
- package/lib/guard-compress.js +5 -5
- package/lib/guard-identifier.js +45 -1
- package/lib/guard-name.js +272 -1
- package/lib/guard-time.js +3 -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/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 +50 -120
- package/lib/pbes2.js +2 -2
- package/lib/pkcs12-build.js +15 -15
- 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 +9 -8
- package/lib/smime.js +12 -12
- package/lib/tls-cert-compress.js +6 -6
- package/lib/trust.js +179 -10
- package/lib/tsp-sign.js +11 -11
- 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 +12 -12
- 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/shbs.js
CHANGED
|
@@ -48,8 +48,8 @@ function _deriveWinternitz(n, w) {
|
|
|
48
48
|
return { p: u + v, ls: 16 - v * w };
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
var LMS_SETS =
|
|
52
|
-
var LMOTS_SETS =
|
|
51
|
+
var LMS_SETS = Object.create(null);
|
|
52
|
+
var LMOTS_SETS = Object.create(null);
|
|
53
53
|
(function seed() {
|
|
54
54
|
var heights = [5, 10, 15, 20, 25];
|
|
55
55
|
var ws = [1, 2, 4, 8];
|
package/lib/sign-scheme.js
CHANGED
|
@@ -26,26 +26,26 @@ var _isU8 = intrinsic.types.isUint8Array;
|
|
|
26
26
|
|
|
27
27
|
var HASH = intrinsic.assign(intrinsic.create(null), { sha256: "SHA-256", sha384: "SHA-384", sha512: "SHA-512" });
|
|
28
28
|
var NODE_DIGEST = intrinsic.assign(intrinsic.create(null), { sha256: "sha256", sha384: "sha384", sha512: "sha512", shake128: "shake128", shake256: "shake256" });
|
|
29
|
-
var PSS_SALT = { "SHA-256": 32, "SHA-384": 48, "SHA-512": 64 };
|
|
30
|
-
var ECDSA_ALG = { sha256: "ecdsaWithSHA256", sha384: "ecdsaWithSHA384", sha512: "ecdsaWithSHA512" };
|
|
31
|
-
var RSA_PKCS1_SIG = { sha256: "sha256WithRSAEncryption", sha384: "sha384WithRSAEncryption", sha512: "sha512WithRSAEncryption" };
|
|
32
|
-
var HASH_NAME_BY_OID =
|
|
29
|
+
var PSS_SALT = intrinsic.assign(intrinsic.create(null), { "SHA-256": 32, "SHA-384": 48, "SHA-512": 64 });
|
|
30
|
+
var ECDSA_ALG = intrinsic.assign(intrinsic.create(null), { sha256: "ecdsaWithSHA256", sha384: "ecdsaWithSHA384", sha512: "ecdsaWithSHA512" });
|
|
31
|
+
var RSA_PKCS1_SIG = intrinsic.assign(intrinsic.create(null), { sha256: "sha256WithRSAEncryption", sha384: "sha384WithRSAEncryption", sha512: "sha512WithRSAEncryption" });
|
|
32
|
+
var HASH_NAME_BY_OID = intrinsic.create(null);
|
|
33
33
|
HASH_NAME_BY_OID[O("sha256")] = "sha256";
|
|
34
34
|
HASH_NAME_BY_OID[O("sha384")] = "sha384";
|
|
35
35
|
HASH_NAME_BY_OID[O("sha512")] = "sha512";
|
|
36
|
-
var EC_BY_CURVE_OID =
|
|
36
|
+
var EC_BY_CURVE_OID = intrinsic.create(null);
|
|
37
37
|
EC_BY_CURVE_OID[O("prime256v1")] = { curve: "P-256", coordLen: 32 };
|
|
38
38
|
EC_BY_CURVE_OID[O("secp384r1")] = { curve: "P-384", coordLen: 48 };
|
|
39
39
|
EC_BY_CURVE_OID[O("secp521r1")] = { curve: "P-521", coordLen: 66 };
|
|
40
|
-
var MLDSA_BY_OID =
|
|
40
|
+
var MLDSA_BY_OID = intrinsic.create(null);
|
|
41
41
|
MLDSA_BY_OID[O("id-ml-dsa-44")] = "ML-DSA-44";
|
|
42
42
|
MLDSA_BY_OID[O("id-ml-dsa-65")] = "ML-DSA-65";
|
|
43
43
|
MLDSA_BY_OID[O("id-ml-dsa-87")] = "ML-DSA-87";
|
|
44
|
-
var MLDSA_SUITABLE_DIGEST = {
|
|
44
|
+
var MLDSA_SUITABLE_DIGEST = intrinsic.assign(intrinsic.create(null), {
|
|
45
45
|
"ML-DSA-44": { sha256: 1, sha384: 1, sha512: 1, shake256: 1 },
|
|
46
46
|
"ML-DSA-65": { sha384: 1, sha512: 1, shake256: 1 },
|
|
47
47
|
"ML-DSA-87": { sha512: 1, shake256: 1 },
|
|
48
|
-
};
|
|
48
|
+
});
|
|
49
49
|
// @enforced-by behavioral -- an own-property table read has no rename-proof shape distinct from a legitimate lookup, so a RED conformance vector is the guard
|
|
50
50
|
function mldsaDigestSuitable(mlName, md) {
|
|
51
51
|
if (!intrinsic.hasOwn(MLDSA_SUITABLE_DIGEST, mlName)) return false;
|
|
@@ -53,7 +53,7 @@ function mldsaDigestSuitable(mlName, md) {
|
|
|
53
53
|
return !!row && intrinsic.hasOwn(row, md) && !!row[md];
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
var SLHDSA_BY_OID =
|
|
56
|
+
var SLHDSA_BY_OID = intrinsic.create(null);
|
|
57
57
|
[["sha2-128s", "sha256"], ["sha2-128f", "sha256"], ["sha2-192s", "sha512"], ["sha2-192f", "sha512"],
|
|
58
58
|
["sha2-256s", "sha512"], ["sha2-256f", "sha512"], ["shake-128s", "shake128"], ["shake-128f", "shake128"],
|
|
59
59
|
["shake-192s", "shake256"], ["shake-192f", "shake256"], ["shake-256s", "shake256"], ["shake-256f", "shake256"]
|
package/lib/sigstore.js
CHANGED
|
@@ -70,14 +70,14 @@ function _stripTrailingEquals(s) {
|
|
|
70
70
|
return s.slice(0, i);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
var _BUNDLE_MEDIA_TYPES = {
|
|
73
|
+
var _BUNDLE_MEDIA_TYPES = Object.assign(Object.create(null), {
|
|
74
74
|
"application/vnd.dev.sigstore.bundle.v0.1+json": 1,
|
|
75
75
|
"application/vnd.dev.sigstore.bundle.v0.2+json": 1,
|
|
76
76
|
"application/vnd.dev.sigstore.bundle.v0.3+json": 1,
|
|
77
77
|
"application/vnd.dev.sigstore.bundle+json;version=0.1": 1,
|
|
78
78
|
"application/vnd.dev.sigstore.bundle+json;version=0.2": 1,
|
|
79
79
|
"application/vnd.dev.sigstore.bundle+json;version=0.3": 1
|
|
80
|
-
};
|
|
80
|
+
});
|
|
81
81
|
function _isBundleMediaType(mt) {
|
|
82
82
|
return typeof mt === "string" && Object.prototype.hasOwnProperty.call(_BUNDLE_MEDIA_TYPES, mt);
|
|
83
83
|
}
|
|
@@ -363,7 +363,7 @@ function _pathToAnchor(leaf, anchor, intBySubject) {
|
|
|
363
363
|
/** @internal Issuers are collected leaf-first and the path is assembled once, so no element is
|
|
364
364
|
* ever moved to a new index: an indexed setter has nothing to intercept and cannot replace the
|
|
365
365
|
* leaf the preceding signature checks authenticated. */
|
|
366
|
-
var above = [], cur = leaf, seen =
|
|
366
|
+
var above = [], cur = leaf, seen = Object.create(null), guardN = 0;
|
|
367
367
|
function assemble() {
|
|
368
368
|
var path = [];
|
|
369
369
|
for (var k = above.length - 1; k >= 0; k--) guard.list.append(path, above[k]);
|
|
@@ -390,7 +390,7 @@ function _pathToAnchor(leaf, anchor, intBySubject) {
|
|
|
390
390
|
async function _verifyChain(leaf, chainDers, fulcioRoots, timeMs) {
|
|
391
391
|
var roots = _normRoots(fulcioRoots);
|
|
392
392
|
var bundleLinks = chainDers.slice(1).map(function (d, i) { return _parseCert(d, "bundle intermediate [" + i + "]"); });
|
|
393
|
-
var intBySubject =
|
|
393
|
+
var intBySubject = Object.create(null);
|
|
394
394
|
function addInt(c) { guard.list.append(intBySubject[_dn(c, "subject")] = intBySubject[_dn(c, "subject")] || [], c); }
|
|
395
395
|
roots.forEach(function (r) { addInt(r.cert); });
|
|
396
396
|
bundleLinks.forEach(addInt);
|
|
@@ -421,7 +421,7 @@ async function _verifyChain(leaf, chainDers, fulcioRoots, timeMs) {
|
|
|
421
421
|
var SAN_OID = oid.byName("subjectAltName");
|
|
422
422
|
var FULCIO_PREFIX = oid.byName("otherName").split(".").slice(0, -1).join(".") + ".";
|
|
423
423
|
function _identity(leaf) {
|
|
424
|
-
var out = { san: null, extensions:
|
|
424
|
+
var out = { san: null, extensions: Object.create(null) };
|
|
425
425
|
try {
|
|
426
426
|
(leaf.extensions || []).forEach(function (ext) {
|
|
427
427
|
if (ext.oid === SAN_OID) { out.san = _sanValue(ext); return; }
|
|
@@ -435,7 +435,7 @@ function _identity(leaf) {
|
|
|
435
435
|
}
|
|
436
436
|
return out;
|
|
437
437
|
}
|
|
438
|
-
var GN_TYPE = { 1: "rfc822Name", 2: "dNSName", 6: "uri" };
|
|
438
|
+
var GN_TYPE = Object.assign(Object.create(null), { 1: "rfc822Name", 2: "dNSName", 6: "uri" });
|
|
439
439
|
function _sanValue(ext) {
|
|
440
440
|
var seq = asn1.decode(ext.value);
|
|
441
441
|
var names = [];
|
|
@@ -467,10 +467,11 @@ function _fulcioExtValue(ext, leafArc) {
|
|
|
467
467
|
}
|
|
468
468
|
|
|
469
469
|
var IDENTITY_FIELDS = ["san", "issuer", "sourceRepositoryURI"];
|
|
470
|
-
var IDENTITY_KEYS = { san: 1, issuer: 1, sourceRepositoryURI: 1 };
|
|
471
|
-
var _VERIFY_BUNDLE_OPTS = { fulcioRoots: 1, rekorKeys: 1, identity: 1, predicateType: 1, time: 1 };
|
|
470
|
+
var IDENTITY_KEYS = Object.assign(Object.create(null), { san: 1, issuer: 1, sourceRepositoryURI: 1 });
|
|
471
|
+
var _VERIFY_BUNDLE_OPTS = Object.assign(Object.create(null), { fulcioRoots: 1, rekorKeys: 1, identity: 1, predicateType: 1, time: 1 });
|
|
472
472
|
|
|
473
473
|
function _checkIdentity(id, policy) {
|
|
474
|
+
// allow:registry-table-inherits-object-prototype -- the identityChecked record an operator reads by field name, whose three keys are the fixed IDENTITY_FIELDS rather than anything the bundle supplies
|
|
474
475
|
var ran = { san: false, issuer: false, sourceRepositoryURI: false };
|
|
475
476
|
if (policy === undefined || policy === null) return ran;
|
|
476
477
|
if (typeof policy !== "object" || Array.isArray(policy)) {
|
package/lib/smime.js
CHANGED
|
@@ -48,21 +48,21 @@ var SmimeError = frameworkError.SmimeError;
|
|
|
48
48
|
|
|
49
49
|
function _err(code, msg, cause) { return new SmimeError(code, msg, cause); }
|
|
50
50
|
|
|
51
|
-
var SIGN_OPTS = {
|
|
51
|
+
var SIGN_OPTS = Object.assign(Object.create(null), {
|
|
52
52
|
form: 1, entity: 1, contentType: 1, signingTime: 1, protectHeaders: 1, headers: 1, hcp: 1,
|
|
53
53
|
sid: 1, signedAttributes: 1, additionalSignedAttributes: 1,
|
|
54
|
-
};
|
|
55
|
-
var VERIFY_OPTS = {
|
|
54
|
+
});
|
|
55
|
+
var VERIFY_OPTS = Object.assign(Object.create(null), {
|
|
56
56
|
certs: 1, trustAnchors: 1, time: 1, requiredEku: 1, checkPurpose: 1, strictMicalg: 1,
|
|
57
57
|
legacyHeaderProtection: 1, expectedSender: 1,
|
|
58
|
-
};
|
|
59
|
-
var ENCRYPT_OPTS = {
|
|
58
|
+
});
|
|
59
|
+
var ENCRYPT_OPTS = Object.assign(Object.create(null), {
|
|
60
60
|
entity: 1, contentType: 1, protectHeaders: 1, headers: 1, hcp: 1,
|
|
61
61
|
contentEncryptionAlgorithm: 1, oaepHash: 1, keyIdentifier: 1, ukm: 1,
|
|
62
|
-
};
|
|
63
|
-
var DECRYPT_OPTS = { recipientIndex: 1, maxIterations: 1, strictSmimeType: 1, legacyHeaderProtection: 1 };
|
|
64
|
-
var COMPRESS_OPTS = { entity: 1, contentType: 1, level: 1 };
|
|
65
|
-
var DECOMPRESS_OPTS = { maxOutputBytes: 1 };
|
|
62
|
+
});
|
|
63
|
+
var DECRYPT_OPTS = Object.assign(Object.create(null), { recipientIndex: 1, maxIterations: 1, strictSmimeType: 1, legacyHeaderProtection: 1 });
|
|
64
|
+
var COMPRESS_OPTS = Object.assign(Object.create(null), { entity: 1, contentType: 1, level: 1 });
|
|
65
|
+
var DECOMPRESS_OPTS = Object.assign(Object.create(null), { maxOutputBytes: 1 });
|
|
66
66
|
|
|
67
67
|
function _knownOpts(opts, known, verb) {
|
|
68
68
|
guard.identifier.assertKnownKeys(opts, known, _err, "smime/bad-input", function (k) {
|
|
@@ -76,7 +76,7 @@ function _isPkcs7(type, kind) {
|
|
|
76
76
|
return t === "application/pkcs7-" + kind || t === "application/x-pkcs7-" + kind;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
var MICALG = { sha1: "sha-1", sha224: "sha-224", sha256: "sha-256", sha384: "sha-384", sha512: "sha-512", md5: "md5", shake128: "shake128", shake256: "shake256" };
|
|
79
|
+
var MICALG = Object.assign(Object.create(null), { sha1: "sha-1", sha224: "sha-224", sha256: "sha-256", sha384: "sha-384", sha512: "sha-512", md5: "md5", shake128: "shake128", shake256: "shake256" });
|
|
80
80
|
|
|
81
81
|
function _entityBytes(content, opts) {
|
|
82
82
|
var raw = guard.bytes.view(content, SmimeError, "smime/bad-input", "content");
|
|
@@ -320,7 +320,7 @@ var SMTP_UTF8_MAILBOX = oid.byName("smtpUtf8Mailbox");
|
|
|
320
320
|
var EMAIL_ADDRESS_ATTR = oid.byName("emailAddress");
|
|
321
321
|
var _extNs = pkix.makeNS("smime", SmimeError, oid);
|
|
322
322
|
var _extDecoders = pkix.certExtensionDecoders(_extNs);
|
|
323
|
-
var _extCtx = { E: function (c, m, cause) { return new SmimeError(c, m, cause); }, oid: oid };
|
|
323
|
+
var _extCtx = Object.assign(Object.create(null), { E: function (c, m, cause) { return new SmimeError(c, m, cause); }, oid: oid });
|
|
324
324
|
function _signerEmails(certDer) {
|
|
325
325
|
var out = { addresses: [], unreadable: 0 };
|
|
326
326
|
var parsed = null;
|
|
@@ -875,7 +875,7 @@ function _decodeCms(ent) {
|
|
|
875
875
|
|
|
876
876
|
function _toBuf(v) { return Buffer.isBuffer(v) ? v : Buffer.from(v); }
|
|
877
877
|
|
|
878
|
-
var CERTS_ONLY_OPTS = { crls: 1 };
|
|
878
|
+
var CERTS_ONLY_OPTS = Object.assign(Object.create(null), { crls: 1 });
|
|
879
879
|
|
|
880
880
|
/**
|
|
881
881
|
* @primitive pki.smime.buildCertsOnly
|
package/lib/tls-cert-compress.js
CHANGED
|
@@ -62,17 +62,17 @@ var zlib = require("zlib");
|
|
|
62
62
|
var TlsError = frameworkError.TlsError;
|
|
63
63
|
function _err(code, message, cause) { return new TlsError(code, message, cause); }
|
|
64
64
|
|
|
65
|
-
var ALG_BY_NUMBER = { 1: "zlib", 2: "brotli", 3: "zstd" };
|
|
66
|
-
var ALG_BY_NAME =
|
|
65
|
+
var ALG_BY_NUMBER = intrinsic.assign(intrinsic.create(null), { 1: "zlib", 2: "brotli", 3: "zstd" });
|
|
66
|
+
var ALG_BY_NAME = intrinsic.create(null);
|
|
67
67
|
Object.keys(ALG_BY_NUMBER).forEach(function (n) { ALG_BY_NAME[ALG_BY_NUMBER[n]] = Number(n); });
|
|
68
68
|
|
|
69
|
-
var COMPRESS = { zlib: zlib.deflateSync, brotli: zlib.brotliCompressSync, zstd: zlib.zstdCompressSync };
|
|
69
|
+
var COMPRESS = intrinsic.assign(intrinsic.create(null), { zlib: zlib.deflateSync, brotli: zlib.brotliCompressSync, zstd: zlib.zstdCompressSync });
|
|
70
70
|
|
|
71
|
-
var LEVEL_OPT = {
|
|
71
|
+
var LEVEL_OPT = intrinsic.assign(intrinsic.create(null), {
|
|
72
72
|
zlib: function (n) { return { level: n }; },
|
|
73
73
|
brotli: function (n) { var p = {}; p[zlib.constants.BROTLI_PARAM_QUALITY] = n; return { params: p }; },
|
|
74
74
|
zstd: function (n) { var p = {}; p[zlib.constants.ZSTD_c_compressionLevel] = n; return { params: p }; },
|
|
75
|
-
};
|
|
75
|
+
});
|
|
76
76
|
|
|
77
77
|
var SUPPORTED = guard.compress.algorithms().filter(function (n) {
|
|
78
78
|
return _hasOwn(ALG_BY_NAME, n) && typeof COMPRESS[n] === "function";
|
|
@@ -81,7 +81,7 @@ var SUPPORTED = guard.compress.algorithms().filter(function (n) {
|
|
|
81
81
|
var MIN_CERT_MSG_BYTES = validator.tls.MIN_CERT_MSG_BYTES;
|
|
82
82
|
var MAX_VECTOR_24 = validator.tls.MAX_VECTOR_24;
|
|
83
83
|
|
|
84
|
-
var FRAMING_CODES = { truncated: "tls/truncated", framing: "tls/bad-framing", trailing: "tls/trailing-data" };
|
|
84
|
+
var FRAMING_CODES = intrinsic.assign(intrinsic.create(null), { truncated: "tls/truncated", framing: "tls/bad-framing", trailing: "tls/trailing-data" });
|
|
85
85
|
|
|
86
86
|
var HEADER_BYTES = 8;
|
|
87
87
|
|
package/lib/trust.js
CHANGED
|
@@ -327,7 +327,7 @@ function _certEntry(obj) {
|
|
|
327
327
|
function _trustEntry(obj) {
|
|
328
328
|
var issuer = _requireOctal(obj, "CKA_ISSUER", "trust");
|
|
329
329
|
var serial = _requireOctal(obj, "CKA_SERIAL_NUMBER", "trust");
|
|
330
|
-
var purposes = { serverAuth: false, emailProtection: false, codeSigning: false };
|
|
330
|
+
var purposes = intrinsic.assign(intrinsic.create(null), { serverAuth: false, emailProtection: false, codeSigning: false });
|
|
331
331
|
PURPOSE_ATTRS.forEach(function (pair) {
|
|
332
332
|
var a = obj.attrs[pair[0]];
|
|
333
333
|
if (!a) return;
|
|
@@ -364,15 +364,15 @@ function _mkAnchor(cert, meta) {
|
|
|
364
364
|
var _DERIVED_FROM = new WeakMap();
|
|
365
365
|
|
|
366
366
|
function _copyPurposes(src) {
|
|
367
|
-
return {
|
|
367
|
+
return intrinsic.assign(intrinsic.create(null), {
|
|
368
368
|
serverAuth: !!src && src.serverAuth === true,
|
|
369
369
|
emailProtection: !!src && src.emailProtection === true,
|
|
370
370
|
codeSigning: !!src && src.codeSigning === true,
|
|
371
|
-
};
|
|
371
|
+
});
|
|
372
372
|
}
|
|
373
373
|
|
|
374
374
|
function _copyDistrustAfter(src) {
|
|
375
|
-
var out =
|
|
375
|
+
var out = intrinsic.create(null);
|
|
376
376
|
if (!src || typeof src !== "object") return out;
|
|
377
377
|
Object.keys(src).forEach(function (k) {
|
|
378
378
|
out[k] = guard.time.isDate(src[k]) ? new Date(guard.time.instantOf(src[k])) : src[k];
|
|
@@ -521,7 +521,7 @@ function parseCertdata(text) {
|
|
|
521
521
|
anchors: _dedupAnchors(certs.map(function (c) {
|
|
522
522
|
return _mkAnchor(c.cert, {
|
|
523
523
|
distrustAfter: c.distrustAfter,
|
|
524
|
-
purposes: c.purposes ||
|
|
524
|
+
purposes: c.purposes || _copyPurposes(null),
|
|
525
525
|
label: c.label,
|
|
526
526
|
mozillaCaPolicy: c.mozillaCaPolicy,
|
|
527
527
|
});
|
|
@@ -579,15 +579,15 @@ function _csvRows(text) {
|
|
|
579
579
|
return rows;
|
|
580
580
|
}
|
|
581
581
|
|
|
582
|
-
var _TRUST_BIT_TOKENS = {
|
|
582
|
+
var _TRUST_BIT_TOKENS = intrinsic.assign(intrinsic.create(null), {
|
|
583
583
|
"websites": "serverAuth", "server authentication": "serverAuth",
|
|
584
584
|
"email": "emailProtection", "secure email": "emailProtection",
|
|
585
585
|
"code": "codeSigning", "code signing": "codeSigning",
|
|
586
586
|
"client authentication": null, "document signing": null,
|
|
587
587
|
"time stamping": null, "ocsp signing": null,
|
|
588
|
-
};
|
|
588
|
+
});
|
|
589
589
|
function _trustBits(cell) {
|
|
590
|
-
var purposes = { serverAuth: false, emailProtection: false, codeSigning: false };
|
|
590
|
+
var purposes = intrinsic.assign(intrinsic.create(null), { serverAuth: false, emailProtection: false, codeSigning: false });
|
|
591
591
|
String(cell).split(";").forEach(function (tok) {
|
|
592
592
|
var t = tok.trim();
|
|
593
593
|
if (t === "") return;
|
|
@@ -722,8 +722,39 @@ function parseCcadbCsv(text) {
|
|
|
722
722
|
* store catches the wrong root before a single validation runs (the
|
|
723
723
|
* authoritative gate stays inside `validate`).
|
|
724
724
|
*
|
|
725
|
+
* `opts.nameConstraints` attaches the namespace a root program trusts a root
|
|
726
|
+
* for, when that is narrower than the root certificate itself states. Such a
|
|
727
|
+
* restriction lives in the program's data rather than in any `nameConstraints`
|
|
728
|
+
* extension the certificate carries, so it has to be supplied here. It is a
|
|
729
|
+
* `{ permitted, excluded }` pair of `{ tag, base }` subtrees, the same shape
|
|
730
|
+
* `pki.path.validate` takes for `opts.initialPermittedSubtrees`, and validate
|
|
731
|
+
* seeds it as the RFC 5280 sec. 6.1.1(h)(i) initial value: it intersects with
|
|
732
|
+
* every certificate's own constraints, so a leaf must satisfy both, and an
|
|
733
|
+
* excluded subtree rejects whatever is permitted. The subtrees are copied out
|
|
734
|
+
* of the caller's object, so changing that object afterwards does not change
|
|
735
|
+
* the namespace an anchor already vouches for. An overlay naming no subtree,
|
|
736
|
+
* or one supplying its subtrees through an accessor, is refused rather than
|
|
737
|
+
* carried, since either would widen the namespace the operator meant to
|
|
738
|
+
* restrict. A verdict reports `anchorConstraints.nameConstraintsApplied`.
|
|
739
|
+
*
|
|
740
|
+
* A base is held to the form its tag names, and one outside that form is
|
|
741
|
+
* refused here rather than carried to a comparison that cannot reach a verdict
|
|
742
|
+
* on it. Tag 1 (`rfc822Name`) is a mailbox, a host name, or a host name written
|
|
743
|
+
* as a subtree with a leading dot, and a mailbox may name its domain as a
|
|
744
|
+
* bracketed address literal; tag 2 (`dNSName`) is a host name, with or
|
|
745
|
+
* without that leading dot; tag 6 (`uniformResourceIdentifier`) is the dotted
|
|
746
|
+
* host name a certificate's URI is compared by, not a URI; tag 4
|
|
747
|
+
* (`directoryName`) is `{ rdns }` naming at least one relative name, whose
|
|
748
|
+
* attribute types are dotted-decimal object identifiers and whose values are
|
|
749
|
+
* strings; tag 7 (`iPAddress`) is 8 bytes for IPv4 or 32 for IPv6, an address
|
|
750
|
+
* followed by its mask. A host name is labels of letters, digits and hyphens,
|
|
751
|
+
* with a hyphen at neither edge of a label, 63 characters to a label and 253 to
|
|
752
|
+
* the name, and it may carry the one trailing dot the comparison strips. Tags
|
|
753
|
+
* outside that set are refused.
|
|
754
|
+
*
|
|
725
755
|
* @opts
|
|
726
756
|
* purpose: string // "serverAuth" | "emailProtection" | "codeSigning"; fail-fast purpose check
|
|
757
|
+
* nameConstraints: { permitted?: [{ tag, base }], excluded?: [{ tag, base }] } // the root program's applied namespace; tags 1, 2, 4, 6, 7
|
|
727
758
|
*
|
|
728
759
|
* @example
|
|
729
760
|
* var ca = await pki.key.generate("Ed25519");
|
|
@@ -746,7 +777,138 @@ function parseCcadbCsv(text) {
|
|
|
746
777
|
* await pki.path.validate([pki.schema.x509.parse(der)],
|
|
747
778
|
* { time: new Date("2026-06-01T00:00:00Z"), trustAnchors: anchor, checkPurpose: "serverAuth" });
|
|
748
779
|
*/
|
|
749
|
-
var _ANCHOR_OPTS = { purpose: 1 };
|
|
780
|
+
var _ANCHOR_OPTS = intrinsic.assign(intrinsic.create(null), { purpose: 1, nameConstraints: 1 });
|
|
781
|
+
|
|
782
|
+
/** @internal A subtree list copied entry by entry, reading `tag` and `base` from their own data
|
|
783
|
+
* properties. An accessor could answer with a narrow subtree while it is checked and a wide one
|
|
784
|
+
* when it is read again, and a dropped entry widens the namespace the anchor vouches for, so a
|
|
785
|
+
* list that does not describe itself in plain values is refused rather than partly copied. */
|
|
786
|
+
function _copySubtrees(list, where) {
|
|
787
|
+
if (list === undefined || list === null) return [];
|
|
788
|
+
if (!intrinsic.isArray(list) || intrinsic.types.isProxy(list)) {
|
|
789
|
+
throw E("trust/bad-input", "anchor: nameConstraints." + where + " must be a plain array of { tag, base } subtree entries");
|
|
790
|
+
}
|
|
791
|
+
var out = [];
|
|
792
|
+
for (var i = 0; i < list.length; i++) {
|
|
793
|
+
var d = intrinsic.getOwnPropertyDescriptor(list, i);
|
|
794
|
+
if (!d || !_hasOwn(d, "value")) {
|
|
795
|
+
throw E("trust/bad-input", "anchor: nameConstraints." + where + " entry " + i + " must be a data property, not a hole or an accessor");
|
|
796
|
+
}
|
|
797
|
+
var st = d.value;
|
|
798
|
+
if (!st || typeof st !== "object" || intrinsic.types.isProxy(st)) {
|
|
799
|
+
throw E("trust/bad-input", "anchor: nameConstraints." + where + " entry " + i + " must be a { tag, base } object");
|
|
800
|
+
}
|
|
801
|
+
var tagD = intrinsic.getOwnPropertyDescriptor(st, "tag");
|
|
802
|
+
var baseD = intrinsic.getOwnPropertyDescriptor(st, "base");
|
|
803
|
+
if (!tagD || !_hasOwn(tagD, "value") || !baseD || !_hasOwn(baseD, "value")) {
|
|
804
|
+
throw E("trust/bad-input", "anchor: nameConstraints." + where + " entry " + i + " must carry its own tag and base as plain values");
|
|
805
|
+
}
|
|
806
|
+
var tag = tagD.value;
|
|
807
|
+
if (typeof tag !== "number" || !intrinsic.isInteger(tag) || tag < 0 || tag > 8) {
|
|
808
|
+
throw E("trust/bad-input", "anchor: nameConstraints." + where + " entry " + i + " tag must be a GeneralName tag number 0..8, got " + guard.text.showValue(tag));
|
|
809
|
+
}
|
|
810
|
+
_assertSubtreeBaseForm(tag, baseD.value, where, i);
|
|
811
|
+
/** @internal Appended through the list guard: a setter planted on the array prototype swallows
|
|
812
|
+
* a plain index assignment, and a subtree list that came back empty would restrict nothing. */
|
|
813
|
+
guard.list.append(out, { tag: tag, base: _copySubtreeBase(tag, baseD.value, where) });
|
|
814
|
+
}
|
|
815
|
+
return out;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
/** @internal The base of one subtree, copied by its name form so the anchor holds no reference the
|
|
819
|
+
* caller can still reach. A byte base is snapshotted through the byte guard, which accepts every
|
|
820
|
+
* source `pki.path.validate` does rather than Buffers alone, so bytes changed afterwards do not
|
|
821
|
+
* change the namespace. A directoryName goes through the guard that owns distinguished-name
|
|
822
|
+
* capture, which refuses a Proxy or an accessor anywhere in the name instead of running it: reading
|
|
823
|
+
* such a name is caller code, and it could clear the restriction it is being asked to describe. */
|
|
824
|
+
function _copySubtreeBase(tag, base, where) {
|
|
825
|
+
if (typeof base === "string") return base;
|
|
826
|
+
if (tag === 7) {
|
|
827
|
+
return guard.bytes.snapshotSource(base, TrustError, "trust/bad-input", "anchor: nameConstraints." + where + " iPAddress base");
|
|
828
|
+
}
|
|
829
|
+
var rdns = guard.name.capturedRdns(base, E, "trust/bad-input", "anchor: nameConstraints." + where + " directoryName base");
|
|
830
|
+
if (rdns === undefined) {
|
|
831
|
+
throw E("trust/bad-input", "anchor: nameConstraints." + where + " directoryName base must carry its own rdns array");
|
|
832
|
+
}
|
|
833
|
+
return { rdns: rdns };
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
var _NC_KEYS = intrinsic.assign(intrinsic.create(null), { permitted: 1, excluded: 1 });
|
|
837
|
+
|
|
838
|
+
/** @internal One of the overlay's two subtree lists, taken from its own data property. A list the
|
|
839
|
+
* object only inherits is refused rather than read as absent: treating it as absent drops the
|
|
840
|
+
* restriction it carries, and dropping an exclusion admits the namespace it was written to keep
|
|
841
|
+
* out. An accessor is refused for the same reason, since it decides what it says while it is read. */
|
|
842
|
+
function _subtreeListDescriptor(nc, key) {
|
|
843
|
+
var d = intrinsic.getOwnPropertyDescriptor(nc, key);
|
|
844
|
+
if (d === undefined) {
|
|
845
|
+
if (key in intrinsic.Object(nc)) {
|
|
846
|
+
throw E("trust/bad-input", "anchor: opts.nameConstraints." + key + " must be the object's own property, not one it inherits");
|
|
847
|
+
}
|
|
848
|
+
return undefined;
|
|
849
|
+
}
|
|
850
|
+
if (!_hasOwn(d, "value")) {
|
|
851
|
+
throw E("trust/bad-input", "anchor: opts.nameConstraints." + key + " must be a plain value, not an accessor");
|
|
852
|
+
}
|
|
853
|
+
return d;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
/** @internal A subtree base held to the form its tag names, so a base that cannot describe a
|
|
857
|
+
* namespace is refused here rather than carried to the validator, and so no shape falls through to
|
|
858
|
+
* being returned by reference: a base the anchor still shares with the caller is one the caller can
|
|
859
|
+
* complete afterwards, which moves the namespace an anchor has already vouched for. */
|
|
860
|
+
function _assertSubtreeBaseForm(tag, base, where, index) {
|
|
861
|
+
var who = "anchor: nameConstraints." + where + " entry " + index;
|
|
862
|
+
if (tag === 1 || tag === 2 || tag === 6) {
|
|
863
|
+
var why = guard.name.constraintBaseRefusal(tag, base);
|
|
864
|
+
if (why !== null) throw E("trust/bad-input", who + " base " + why);
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
if (tag === 7) {
|
|
868
|
+
if (!guard.bytes.isByteSource(base)) throw E("trust/bad-input", who + " iPAddress base must be a byte source");
|
|
869
|
+
/** @internal An iPAddress subtree is an address followed by its mask, so 8 bytes for IPv4 and
|
|
870
|
+
* 32 for IPv6. Any other length names no range, and the validator refuses it later; refusing it
|
|
871
|
+
* here means the anchor an operator is handed is one that can be enforced. */
|
|
872
|
+
var ipLen = guard.bytes.lengthOf(guard.bytes.source(base, TrustError, "trust/bad-input", who + " iPAddress base"));
|
|
873
|
+
if (ipLen !== 8 && ipLen !== 32) {
|
|
874
|
+
throw E("trust/bad-input", who + " iPAddress base must be 8 bytes (IPv4 address and mask) or 32 (IPv6), got " + ipLen);
|
|
875
|
+
}
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
if (tag === 4) {
|
|
879
|
+
if (base === null || typeof base !== "object") throw E("trust/bad-input", who + " directoryName base must be an object carrying rdns");
|
|
880
|
+
return;
|
|
881
|
+
}
|
|
882
|
+
throw E("trust/bad-input", who + " tag " + tag + " names a form this overlay cannot constrain; use tag 1, 2, 4, 6 or 7");
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
/** @internal The overlay a root program applies to a root outside any nameConstraints extension the
|
|
886
|
+
* certificate carries. It only ever narrows, so an absent one is the status quo and is left off the
|
|
887
|
+
* anchor entirely; a malformed one is refused, since carrying it wrongly would widen a namespace the
|
|
888
|
+
* operator meant to restrict. The subtrees are held to their shapes again by `pki.path.validate`,
|
|
889
|
+
* which is where the RFC 5280 sec. 6.1.1(h)(i) seeding happens. */
|
|
890
|
+
function _copyNameConstraints(nc) {
|
|
891
|
+
if (nc === undefined || nc === null) return null;
|
|
892
|
+
if (typeof nc !== "object" || intrinsic.isArray(nc) || intrinsic.types.isProxy(nc)) {
|
|
893
|
+
throw E("trust/bad-input", "anchor: opts.nameConstraints must be a { permitted, excluded } object of { tag, base } subtree entries");
|
|
894
|
+
}
|
|
895
|
+
/** @internal Runs before the membership tests below, which is what makes them safe to ask: this
|
|
896
|
+
* refuses an overlay inheriting from a Proxy, whose has trap would otherwise answer `in` with
|
|
897
|
+
* caller code while the lists are being read. It also names a misspelled field, which would
|
|
898
|
+
* otherwise be read as an absent list, and an absent excluded list admits the namespace the
|
|
899
|
+
* operator wrote it to keep out. */
|
|
900
|
+
guard.identifier.assertKnownKeys(nc, _NC_KEYS, E, "trust/bad-input", "anchor: opts.nameConstraints has an unknown field ");
|
|
901
|
+
var pD = _subtreeListDescriptor(nc, "permitted");
|
|
902
|
+
var eD = _subtreeListDescriptor(nc, "excluded");
|
|
903
|
+
var out = {
|
|
904
|
+
permitted: _copySubtrees(pD ? pD.value : null, "permitted"),
|
|
905
|
+
excluded: _copySubtrees(eD ? eD.value : null, "excluded"),
|
|
906
|
+
};
|
|
907
|
+
if (!out.permitted.length && !out.excluded.length) {
|
|
908
|
+
throw E("trust/bad-input", "anchor: opts.nameConstraints names no subtree; omit it rather than passing an empty restriction");
|
|
909
|
+
}
|
|
910
|
+
return out;
|
|
911
|
+
}
|
|
750
912
|
function anchor(entry, opts) {
|
|
751
913
|
if (!entry || typeof entry !== "object") {
|
|
752
914
|
throw E("trust/bad-input", "anchor expects a trust-store entry ({ name, publicKey, algorithm, ... })");
|
|
@@ -770,7 +932,8 @@ function anchor(entry, opts) {
|
|
|
770
932
|
if (!derived && (entry.purposes != null || (entry.distrustAfter && Object.keys(entry.distrustAfter).length))) {
|
|
771
933
|
throw E("trust/bad-input", "this entry carries a trust store's per-purpose metadata but is not the entry the store produced -- it has been rebuilt, and the metadata is a statement about the key the store read, not about whichever key the copy now names. Pass pki.trust.parseCertdata / parseCcadbCsv output unmodified");
|
|
772
934
|
}
|
|
773
|
-
|
|
935
|
+
var nameConstraints = _copyNameConstraints(opts.nameConstraints);
|
|
936
|
+
var out = {
|
|
774
937
|
name: _copyName(meta.name),
|
|
775
938
|
publicKey: Buffer.isBuffer(meta.publicKey) ? Buffer.from(meta.publicKey) : meta.publicKey,
|
|
776
939
|
algorithm: meta.algorithm,
|
|
@@ -779,6 +942,12 @@ function anchor(entry, opts) {
|
|
|
779
942
|
distrustAfter: _copyDistrustAfter(meta.distrustAfter),
|
|
780
943
|
purposes: _copyPurposes(meta.purposes),
|
|
781
944
|
};
|
|
945
|
+
/** @internal Set only when an overlay was supplied, so an anchor without one is the object this
|
|
946
|
+
* verb returned before the option existed, and defined rather than assigned: an accessor planted
|
|
947
|
+
* on Object.prototype under this name would otherwise take the assignment and leave the anchor
|
|
948
|
+
* carrying no restriction at all. */
|
|
949
|
+
if (nameConstraints) guard.verdict.set(out, "nameConstraints", nameConstraints);
|
|
950
|
+
return out;
|
|
782
951
|
}
|
|
783
952
|
|
|
784
953
|
module.exports = {
|
package/lib/tsp-sign.js
CHANGED
|
@@ -48,9 +48,9 @@ var _b = pkiBuild.makeBuilder({
|
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
var NODE_DIGEST = intrinsic.assign(intrinsic.create(null), { sha256: "sha256", sha384: "sha384", sha512: "sha512" });
|
|
51
|
-
var HASH_LEN = { sha256: 32, sha384: 48, sha512: 64 };
|
|
51
|
+
var HASH_LEN = intrinsic.assign(intrinsic.create(null), { sha256: 32, sha384: 48, sha512: 64 });
|
|
52
52
|
|
|
53
|
-
var _REVOCATION_RANK = { "false": 0, "undetermined": 1, "waived": 2, "determined": 3 };
|
|
53
|
+
var _REVOCATION_RANK = intrinsic.assign(intrinsic.create(null), { "false": 0, "undetermined": 1, "waived": 2, "determined": 3 });
|
|
54
54
|
function _rankRevocation(v) {
|
|
55
55
|
var r = _REVOCATION_RANK[String(v)];
|
|
56
56
|
return r === undefined ? 0 : r;
|
|
@@ -132,12 +132,12 @@ function sign(messageImprint, tsa, opts) {
|
|
|
132
132
|
], _sign);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
var _TSA_KEYS = { cert: 1, key: 1 };
|
|
136
|
-
var _IMPRINT_KEYS = { hashAlgorithm: 1, hashedMessage: 1 };
|
|
137
|
-
var _SIGN_OPTS = {
|
|
135
|
+
var _TSA_KEYS = intrinsic.assign(intrinsic.create(null), { cert: 1, key: 1 });
|
|
136
|
+
var _IMPRINT_KEYS = intrinsic.assign(intrinsic.create(null), { hashAlgorithm: 1, hashedMessage: 1 });
|
|
137
|
+
var _SIGN_OPTS = intrinsic.assign(intrinsic.create(null), {
|
|
138
138
|
policy: 1, serialNumber: 1, genTime: 1, nonce: 1, accuracy: 1, ordering: 1, sid: 1,
|
|
139
139
|
digestAlgorithm: 1, certHashAlgorithm: 1, additionalSignedAttributes: 1, pss: 1, pem: 1,
|
|
140
|
-
};
|
|
140
|
+
});
|
|
141
141
|
|
|
142
142
|
function _sign(messageImprint, tsa, opts) {
|
|
143
143
|
opts = opts || {};
|
|
@@ -187,7 +187,7 @@ function _sign(messageImprint, tsa, opts) {
|
|
|
187
187
|
});
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
var _ACCURACY_KEYS = { seconds: 1, millis: 1, micros: 1 };
|
|
190
|
+
var _ACCURACY_KEYS = intrinsic.assign(intrinsic.create(null), { seconds: 1, millis: 1, micros: 1 });
|
|
191
191
|
|
|
192
192
|
function _accuracy(a) {
|
|
193
193
|
guard.identifier.assertKnownKeys(a, _ACCURACY_KEYS, _err, "tsp/bad-input", function (k) {
|
|
@@ -260,7 +260,7 @@ function _assertImprint(mi) {
|
|
|
260
260
|
* var sha256Digest = Buffer.from(await pki.webcrypto.subtle.digest("SHA-256", Buffer.from("hello")));
|
|
261
261
|
* var req = pki.tsp.request({ hashAlgorithm: "sha256", hashedMessage: sha256Digest }, { nonce: 0x0102030405060708n, certReq: true });
|
|
262
262
|
*/
|
|
263
|
-
var _REQUEST_OPTS = { reqPolicy: 1, nonce: 1, certReq: 1, extensions: 1, pem: 1 };
|
|
263
|
+
var _REQUEST_OPTS = intrinsic.assign(intrinsic.create(null), { reqPolicy: 1, nonce: 1, certReq: 1, extensions: 1, pem: 1 });
|
|
264
264
|
|
|
265
265
|
function request(messageImprint, opts) {
|
|
266
266
|
opts = opts || {};
|
|
@@ -282,7 +282,7 @@ function request(messageImprint, opts) {
|
|
|
282
282
|
if (opts.certReq === true) guard.list.append(fields,b.boolean(true));
|
|
283
283
|
if (opts.extensions != null) {
|
|
284
284
|
if (!Array.isArray(opts.extensions) || !guard.list.allMatch(opts.extensions, function (e) { return guard.bytes.isByteSource(e); })) throw _err("tsp/bad-input", "extensions must be an array of encoded Extension DER buffers");
|
|
285
|
-
var seenExt =
|
|
285
|
+
var seenExt = intrinsic.create(null);
|
|
286
286
|
var encoded = opts.extensions.map(function (e, i) {
|
|
287
287
|
var der = guard.bytes.source(e, TspError, "tsp/bad-input", "an extension");
|
|
288
288
|
_b.assertValidExtension(der, i);
|
|
@@ -347,7 +347,7 @@ function parseRequest(input) { return schemaTsp.parseRequest(input); }
|
|
|
347
347
|
* var resp = pki.tsp.response(token, {}); // granted
|
|
348
348
|
* var rej = pki.tsp.response(null, { status: 2, failInfo: ["badAlg"] }); // rejection
|
|
349
349
|
*/
|
|
350
|
-
var _RESPONSE_OPTS = { status: 1, statusString: 1, failInfo: 1, pem: 1 };
|
|
350
|
+
var _RESPONSE_OPTS = intrinsic.assign(intrinsic.create(null), { status: 1, statusString: 1, failInfo: 1, pem: 1 });
|
|
351
351
|
|
|
352
352
|
function response(token, opts) {
|
|
353
353
|
opts = opts || {};
|
|
@@ -585,7 +585,7 @@ function _buildTsaChains(leaf, pool) {
|
|
|
585
585
|
* res.valid; // boolean; pass opts.trustAnchors to also chain the TSA cert to a root
|
|
586
586
|
* res.genTime; // Date, read from the verified eContent
|
|
587
587
|
*/
|
|
588
|
-
var _VERIFY_OPTS = { certs: 1, trustAnchors: 1, nonce: 1, reqPolicy: 1, revocationChecker: 1 };
|
|
588
|
+
var _VERIFY_OPTS = intrinsic.assign(intrinsic.create(null), { certs: 1, trustAnchors: 1, nonce: 1, reqPolicy: 1, revocationChecker: 1 });
|
|
589
589
|
|
|
590
590
|
function _anyCritical(extensions) {
|
|
591
591
|
return guard.list.anyMatches(extensions, function (e) { return !!e && !!e.critical; });
|
package/lib/validator-attcert.js
CHANGED
|
@@ -25,7 +25,7 @@ function assertNotCa(cert, exts, E, code) {
|
|
|
25
25
|
function packedCert(cert, exts, E, code) {
|
|
26
26
|
requireV3(cert, E, code);
|
|
27
27
|
assertNotCa(cert, exts, E, code);
|
|
28
|
-
var have =
|
|
28
|
+
var have = Object.create(null);
|
|
29
29
|
(cert.subject.rdns || []).forEach(function (rdn) { rdn.forEach(function (a) { have[a.type] = a.value; }); });
|
|
30
30
|
if (have[oid.byName("countryName")] == null || have[oid.byName("organizationName")] == null || have[oid.byName("commonName")] == null) {
|
|
31
31
|
throw new E(code, "the packed attestation certificate subject MUST set C, O, OU, and CN (WebAuthn 8.2.1)");
|
|
@@ -46,7 +46,7 @@ function aikCert(cert, exts, E, code) {
|
|
|
46
46
|
}
|
|
47
47
|
var san = exts.decode(cert, "subjectAltName");
|
|
48
48
|
var dirName = san && san.value && san.value.names && san.value.names.filter(function (n) { return n.tagNumber === 4; })[0];
|
|
49
|
-
var types =
|
|
49
|
+
var types = Object.create(null);
|
|
50
50
|
if (dirName && dirName.value && dirName.value.rdns) {
|
|
51
51
|
dirName.value.rdns.forEach(function (rdn) { rdn.forEach(function (a) { types[a.type] = true; }); });
|
|
52
52
|
}
|
package/lib/validator-cose.js
CHANGED
|
@@ -9,20 +9,20 @@ var oid = require("./oid");
|
|
|
9
9
|
var edwardsPoint = require("./edwards-point");
|
|
10
10
|
var nodeCrypto = require("crypto");
|
|
11
11
|
|
|
12
|
-
var EC2_CRV_LEN = { 1: 32, 2: 48, 3: 66 };
|
|
13
|
-
var EC2_CRV_OID = { 1: "prime256v1", 2: "secp384r1", 3: "secp521r1" };
|
|
14
|
-
var OKP_CRV = { 6: { oid: "Ed25519", len: 32 }, 7: { oid: "Ed448", len: 57 } };
|
|
12
|
+
var EC2_CRV_LEN = Object.assign(Object.create(null), { 1: 32, 2: 48, 3: 66 });
|
|
13
|
+
var EC2_CRV_OID = Object.assign(Object.create(null), { 1: "prime256v1", 2: "secp384r1", 3: "secp521r1" });
|
|
14
|
+
var OKP_CRV = Object.assign(Object.create(null), { 6: { oid: "Ed25519", len: 32 }, 7: { oid: "Ed448", len: 57 } });
|
|
15
15
|
var RSA_MIN_MODULUS_BITS = 2048;
|
|
16
16
|
var RSA_MAX_EXPONENT_BYTES = 8;
|
|
17
17
|
function _modulusBits(n) { return (n.length - 1) * 8 + (32 - Math.clz32(n[0])); }
|
|
18
18
|
|
|
19
|
-
var ALG_PROFILE = {
|
|
19
|
+
var ALG_PROFILE = Object.assign(Object.create(null), {
|
|
20
20
|
"-7": { kty: 2, crv: 1 }, "-35": { kty: 2, crv: 2 }, "-36": { kty: 2, crv: 3 },
|
|
21
21
|
"-9": { kty: 2, crv: 1 }, "-51": { kty: 2, crv: 2 }, "-52": { kty: 2, crv: 3 },
|
|
22
22
|
"-8": { kty: 1, crv: 6 }, "-19": { kty: 1, crv: 6 }, "-53": { kty: 1, crv: 7 },
|
|
23
23
|
"-257": { kty: 3 }, "-258": { kty: 3 }, "-259": { kty: 3 },
|
|
24
24
|
"-37": { kty: 3 }, "-38": { kty: 3 }, "-39": { kty: 3 }, "-65535": { kty: 3 },
|
|
25
|
-
};
|
|
25
|
+
});
|
|
26
26
|
|
|
27
27
|
// @enforced-by validator-shape-reinlined
|
|
28
28
|
// @validator-shape kty\s*===\s*2n
|
package/lib/validator-sig.js
CHANGED
|
@@ -15,12 +15,12 @@ function rawToEcdsaDer(raw, coordLen) {
|
|
|
15
15
|
return asn1.build.sequence([asn1.build.integer(r), asn1.build.integer(s)]);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
var CURVE_FIELD_BYTES = { "P-256": 32, "P-384": 48, "P-521": 66 };
|
|
19
|
-
var CURVE_ORDER = {
|
|
18
|
+
var CURVE_FIELD_BYTES = Object.assign(Object.create(null), { "P-256": 32, "P-384": 48, "P-521": 66 });
|
|
19
|
+
var CURVE_ORDER = Object.assign(Object.create(null), {
|
|
20
20
|
"P-256": BigInt("0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551"),
|
|
21
21
|
"P-384": BigInt("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973"),
|
|
22
22
|
"P-521": BigInt("0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409"),
|
|
23
|
-
};
|
|
23
|
+
});
|
|
24
24
|
|
|
25
25
|
// @enforced-by behavioral -- a DER ECDSA-Sig-Value decode has no rename-proof code shape distinct
|
|
26
26
|
function ecdsaDerToP1363(der, curve, E, code) {
|
package/lib/validator-tpm.js
CHANGED
|
@@ -8,9 +8,9 @@ var guard = require("./guard-all");
|
|
|
8
8
|
|
|
9
9
|
var TPM_GENERATED_VALUE = 0xff544347;
|
|
10
10
|
var TPM_ST_ATTEST_CERTIFY = 0x8017;
|
|
11
|
-
var TPM_ALG = { RSA: 0x0001, SHA1: 0x0004, SHA256: 0x000b, SHA384: 0x000c, SHA512: 0x000d, NULL: 0x0010, ECC: 0x0023 };
|
|
12
|
-
var TPM_ALG_HASH =
|
|
13
|
-
var TPM_CURVE_TO_COSE =
|
|
11
|
+
var TPM_ALG = Object.assign(Object.create(null), { RSA: 0x0001, SHA1: 0x0004, SHA256: 0x000b, SHA384: 0x000c, SHA512: 0x000d, NULL: 0x0010, ECC: 0x0023 });
|
|
12
|
+
var TPM_ALG_HASH = Object.create(null); TPM_ALG_HASH[TPM_ALG.SHA1] = "sha1"; TPM_ALG_HASH[TPM_ALG.SHA256] = "sha256"; TPM_ALG_HASH[TPM_ALG.SHA384] = "sha384"; TPM_ALG_HASH[TPM_ALG.SHA512] = "sha512";
|
|
13
|
+
var TPM_CURVE_TO_COSE = Object.create(null); TPM_CURVE_TO_COSE[0x0003] = 1; TPM_CURVE_TO_COSE[0x0004] = 2; TPM_CURVE_TO_COSE[0x0005] = 3;
|
|
14
14
|
|
|
15
15
|
function _ucmp(a, b) {
|
|
16
16
|
function strip(x) { var i = 0; while (i < x.length - 1 && x[i] === 0) i++; return x.subarray(i); }
|
|
@@ -32,6 +32,7 @@ var TPMA_OBJECT_RESERVED = 0xfff0f009;
|
|
|
32
32
|
|
|
33
33
|
// @enforced-by behavioral -- a bit-position table lookup has no rename-proof code shape; the RED
|
|
34
34
|
function _decodeAttributes(oa) {
|
|
35
|
+
// allow:registry-table-inherits-object-prototype -- the attributes record an operator reads as result.tpm.attributes by field name, whose keys are the fixed TPMA_OBJECT_BITS list rather than anything the attestation supplies
|
|
35
36
|
var out = {};
|
|
36
37
|
Object.keys(TPMA_OBJECT_BITS).forEach(function (n) { out[n] = ((oa >>> TPMA_OBJECT_BITS[n]) & 1) === 1; });
|
|
37
38
|
return out;
|
|
@@ -112,7 +113,7 @@ function normalizeObjectAttributePolicy(policy, E, code) {
|
|
|
112
113
|
if (policy === undefined) return null;
|
|
113
114
|
if (!policy || typeof policy !== "object" || Array.isArray(policy)) throw new E(code, "opts.tpmPolicy must be an object");
|
|
114
115
|
guard.identifier.assertKnownKeys(policy, _TPM_POLICY_KEYS, function (c, m) { return new E(c, m); }, code, "opts.tpmPolicy has an unknown key ");
|
|
115
|
-
var want =
|
|
116
|
+
var want = Object.create(null);
|
|
116
117
|
if (policy.profile !== undefined) {
|
|
117
118
|
var preset = TPM_POLICY_PROFILES[guard.text.keyOf(policy.profile)];
|
|
118
119
|
if (!preset) throw new E(code, "opts.tpmPolicy.profile " + guard.text.showValue(policy.profile) + " is not a defined profile");
|