@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.
Files changed (75) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +1 -1
  3. package/lib/acme.js +24 -13
  4. package/lib/asn1-der.js +5 -5
  5. package/lib/attrcert-sign.js +14 -14
  6. package/lib/cbor-det.js +2 -2
  7. package/lib/cmc-build.js +16 -16
  8. package/lib/cmc-verify.js +5 -5
  9. package/lib/cmp-build.js +29 -19
  10. package/lib/cmp-session.js +21 -16
  11. package/lib/cmp-verify.js +4 -4
  12. package/lib/cms-decrypt.js +8 -8
  13. package/lib/cms-encrypt.js +22 -22
  14. package/lib/cms-sign.js +17 -17
  15. package/lib/cms-verify.js +6 -6
  16. package/lib/composite-kem.js +1 -1
  17. package/lib/composite-sig.js +4 -4
  18. package/lib/constants.js +13 -9
  19. package/lib/crl-sign.js +17 -17
  20. package/lib/crmf-sign.js +11 -11
  21. package/lib/csr-sign.js +2 -2
  22. package/lib/ct.js +19 -11
  23. package/lib/edwards-point.js +2 -2
  24. package/lib/est.js +74 -43
  25. package/lib/guard-async.js +17 -1
  26. package/lib/guard-bytes.js +2 -2
  27. package/lib/guard-compress.js +5 -5
  28. package/lib/guard-identifier.js +45 -1
  29. package/lib/guard-name.js +272 -1
  30. package/lib/guard-time.js +3 -1
  31. package/lib/hpke.js +10 -10
  32. package/lib/http-digest.js +2 -2
  33. package/lib/http-transport.js +3 -3
  34. package/lib/inspect.js +9 -9
  35. package/lib/jose.js +14 -14
  36. package/lib/key.js +7 -7
  37. package/lib/lint.js +6 -4
  38. package/lib/merkle.js +2 -2
  39. package/lib/mime.js +2 -2
  40. package/lib/ocsp-verify.js +1 -1
  41. package/lib/ocsp.js +5 -5
  42. package/lib/oid.js +3 -3
  43. package/lib/path-validate.js +50 -120
  44. package/lib/pbes2.js +2 -2
  45. package/lib/pkcs12-build.js +15 -15
  46. package/lib/pki-build.js +2 -2
  47. package/lib/scep.js +47 -16
  48. package/lib/schema-all.js +1 -1
  49. package/lib/schema-attrcert.js +4 -3
  50. package/lib/schema-c509.js +23 -23
  51. package/lib/schema-cmc.js +6 -6
  52. package/lib/schema-cmp.js +3 -3
  53. package/lib/schema-cms.js +15 -8
  54. package/lib/schema-crmf.js +1 -1
  55. package/lib/schema-csr.js +1 -1
  56. package/lib/schema-engine.js +2 -1
  57. package/lib/schema-pkcs12.js +1 -1
  58. package/lib/schema-pkix.js +3 -0
  59. package/lib/schema-tsp.js +2 -2
  60. package/lib/shbs.js +2 -2
  61. package/lib/sign-scheme.js +9 -9
  62. package/lib/sigstore.js +9 -8
  63. package/lib/smime.js +12 -12
  64. package/lib/tls-cert-compress.js +6 -6
  65. package/lib/trust.js +179 -10
  66. package/lib/tsp-sign.js +11 -11
  67. package/lib/validator-attcert.js +2 -2
  68. package/lib/validator-cose.js +5 -5
  69. package/lib/validator-sig.js +3 -3
  70. package/lib/validator-tpm.js +5 -4
  71. package/lib/webauthn.js +12 -12
  72. package/lib/webcrypto.js +22 -14
  73. package/lib/x509-sign.js +8 -8
  74. package/package.json +1 -1
  75. 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];
@@ -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 = {}, guardN = 0;
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
@@ -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 || { serverAuth: false, emailProtection: false, codeSigning: false },
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
- return {
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; });
@@ -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
  }
@@ -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
@@ -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) {
@@ -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 = {}; 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 = {}; TPM_CURVE_TO_COSE[0x0003] = 1; TPM_CURVE_TO_COSE[0x0004] = 2; TPM_CURVE_TO_COSE[0x0005] = 3;
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");