@blamejs/pki 0.6.13 → 0.6.15

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 (114) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/README.md +1 -1
  3. package/index.js +1 -1
  4. package/lib/acme.js +59 -815
  5. package/lib/asn1-der.js +7 -245
  6. package/lib/attrcert-sign.js +12 -260
  7. package/lib/attrcert-verify.js +1 -7
  8. package/lib/byte-reader.js +0 -8
  9. package/lib/byte-writer.js +0 -11
  10. package/lib/cbor-det.js +0 -54
  11. package/lib/cmc-build.js +15 -357
  12. package/lib/cmc-verify.js +6 -239
  13. package/lib/cmp-build.js +41 -317
  14. package/lib/cmp-session.js +73 -760
  15. package/lib/cmp-verify.js +32 -488
  16. package/lib/cms-compress.js +3 -32
  17. package/lib/cms-decrypt.js +29 -294
  18. package/lib/cms-encrypt.js +14 -234
  19. package/lib/cms-sign.js +29 -324
  20. package/lib/cms-verify.js +9 -500
  21. package/lib/composite-kem.js +2 -102
  22. package/lib/composite-sig.js +1 -77
  23. package/lib/constants.js +0 -249
  24. package/lib/crl-sign.js +9 -237
  25. package/lib/crl-verify.js +1 -10
  26. package/lib/crmf-sign.js +19 -198
  27. package/lib/crmf-verify.js +1 -12
  28. package/lib/csr-sign.js +3 -34
  29. package/lib/csr-verify.js +1 -12
  30. package/lib/ct.js +28 -253
  31. package/lib/edwards-point.js +10 -44
  32. package/lib/est.js +28 -764
  33. package/lib/framework-error.js +4 -182
  34. package/lib/guard-all.js +1 -58
  35. package/lib/guard-async.js +1 -36
  36. package/lib/guard-bytes.js +6 -650
  37. package/lib/guard-compress.js +5 -102
  38. package/lib/guard-crypto.js +1 -40
  39. package/lib/guard-der.js +2 -93
  40. package/lib/guard-encoding.js +2 -60
  41. package/lib/guard-header.js +1 -36
  42. package/lib/guard-identifier.js +7 -531
  43. package/lib/guard-intrinsic.js +1 -150
  44. package/lib/guard-json.js +10 -73
  45. package/lib/guard-limits.js +1 -77
  46. package/lib/guard-list.js +1 -49
  47. package/lib/guard-name.js +3 -209
  48. package/lib/guard-parsed.js +7 -335
  49. package/lib/guard-range.js +1 -71
  50. package/lib/guard-secret.js +1 -102
  51. package/lib/guard-text.js +1 -64
  52. package/lib/guard-time.js +1 -97
  53. package/lib/hpke.js +3 -105
  54. package/lib/http-digest.js +14 -142
  55. package/lib/http-retry-after.js +1 -47
  56. package/lib/http-transport.js +21 -131
  57. package/lib/inspect.js +30 -284
  58. package/lib/ip-utils.js +6 -47
  59. package/lib/jose.js +7 -142
  60. package/lib/key.js +2 -67
  61. package/lib/lint.js +9 -194
  62. package/lib/merkle.js +1 -27
  63. package/lib/mime.js +9 -82
  64. package/lib/ocsp-request-verify.js +1 -14
  65. package/lib/ocsp-verify.js +1 -82
  66. package/lib/ocsp.js +11 -169
  67. package/lib/oid.js +5 -337
  68. package/lib/path-validate.js +103 -1492
  69. package/lib/pbes2.js +2 -89
  70. package/lib/pkcs12-build.js +31 -379
  71. package/lib/pki-build.js +64 -290
  72. package/lib/rc2.js +2 -18
  73. package/lib/rfc3339.js +4 -27
  74. package/lib/scep.js +59 -233
  75. package/lib/schema-all.js +0 -122
  76. package/lib/schema-attrcert.js +4 -146
  77. package/lib/schema-c509.js +153 -802
  78. package/lib/schema-cmc.js +5 -220
  79. package/lib/schema-cmp.js +2 -223
  80. package/lib/schema-cms.js +13 -427
  81. package/lib/schema-crl.js +5 -68
  82. package/lib/schema-crmf.js +6 -167
  83. package/lib/schema-csr.js +1 -54
  84. package/lib/schema-csrattrs.js +2 -87
  85. package/lib/schema-engine.js +0 -152
  86. package/lib/schema-ocsp.js +0 -117
  87. package/lib/schema-pkcs12.js +2 -93
  88. package/lib/schema-pkcs8.js +3 -35
  89. package/lib/schema-pkix.js +24 -655
  90. package/lib/schema-smime.js +0 -54
  91. package/lib/schema-tsp.js +3 -99
  92. package/lib/schema-x509.js +4 -63
  93. package/lib/shbs.js +11 -95
  94. package/lib/sign-scheme.js +2 -97
  95. package/lib/sigstore.js +9 -169
  96. package/lib/sleep.js +2 -8
  97. package/lib/smime.js +15 -408
  98. package/lib/tls-cert-compress.js +0 -62
  99. package/lib/trust.js +19 -185
  100. package/lib/tsp-sign.js +16 -270
  101. package/lib/validator-all.js +1 -30
  102. package/lib/validator-attcert.js +2 -46
  103. package/lib/validator-cose.js +2 -153
  104. package/lib/validator-keydesc.js +1 -37
  105. package/lib/validator-sig.js +1 -46
  106. package/lib/validator-tls.js +1 -88
  107. package/lib/validator-tpm.js +19 -122
  108. package/lib/verify-seam.js +1 -24
  109. package/lib/webauthn-mds.js +3 -400
  110. package/lib/webauthn.js +12 -833
  111. package/lib/webcrypto.js +5 -485
  112. package/lib/x509-sign.js +4 -108
  113. package/package.json +1 -1
  114. package/sbom.cdx.json +6 -6
@@ -40,53 +40,30 @@ var oid = require("./oid");
40
40
  var constants = require("./constants");
41
41
  var frameworkError = require("./framework-error");
42
42
  var intrinsic = require("./guard-intrinsic");
43
- // Own-key membership through an operation taken at load. Written out, the question reads two
44
- // replaceable properties to answer one thing, and here it decides which response statuses and
45
- // revocation reasons are defined -- an admitted name names a status RFC 6960 never assigned.
46
43
  var _hasOwn = intrinsic.hasOwn;
47
44
 
48
45
  var OcspError = frameworkError.OcspError;
49
46
  var PemError = frameworkError.PemError;
50
47
 
51
- // The ocsp error namespace the schema engine walks under.
52
48
  var NS = pkix.makeNS("ocsp", OcspError, oid);
53
49
 
54
50
  var ALGORITHM_IDENTIFIER = pkix.algorithmIdentifier(NS);
55
51
  var NAME = pkix.name(NS);
56
52
  var EXTENSIONS = pkix.extensions(NS);
57
53
 
58
- // Version ::= INTEGER { v1(0) }. OCSP defines only v1(0), which DER forbids
59
- // encoding (it is the DEFAULT), so ANY explicitly-encoded version is a fault; the
60
- // empty accept map rejects every value and absence yields the default 1.
61
54
  var VERSION = pkix.versionReader(NS, {});
62
55
 
63
- // id-pkix-ocsp-basic is the one ResponseBytes.responseType this build decodes; any
64
- // other is recognized-and-deferred. Resolved from the registry, never a literal.
65
56
  var OID_OCSP_BASIC = oid.byName("ocspBasic");
66
57
 
67
- // id-pkix-ocsp-nonce -- the request/response binding extension whose value syntax
68
- // RFC 9654 sec. 2.1 (updating RFC 6960 sec. 4.4.1) fixes to OCTET STRING (SIZE(1..128)).
69
58
  var OID_OCSP_NONCE = oid.byName("ocspNonce");
70
59
 
71
- // OCSPResponseStatus ::= ENUMERATED. Value 4 is "not used" and >= 7 is undefined,
72
- // so both are rejected (RFC 6960 sec. 4.2.1).
73
- // OCSPResponseStatus value names -- single source pki.C.NAMES.OCSP_STATUS.
74
60
  var STATUS_NAMES = constants.NAMES.OCSP_STATUS;
75
61
 
76
- // CRLReason ::= ENUMERATED. Value 7 is "not used"; the rest are RFC 5280
77
- // sec. 5.3.1. The legal set + names live once in pkix.CRL_REASON_NAMES (shared
78
- // with the CRL reasonCode decoder, which surfaces the numeric code).
79
62
  var CRL_REASONS = pkix.CRL_REASON_NAMES;
80
63
 
81
- // ---- shared leaves ---------------------------------------------------
82
64
 
83
- // A GeneralizedTime-only leaf. OCSP times (producedAt / thisUpdate / nextUpdate /
84
- // revocationTime) are GeneralizedTime, never UTCTime (RFC 6960); assert the tag
85
- // before the codec reads it so a UTCTime is rejected ocsp/bad-time.
86
65
  var GENERALIZED_TIME = pkix.generalizedTime(NS, { code: "ocsp/bad-time", message: "OCSP time must be a GeneralizedTime (RFC 6960)" });
87
66
 
88
- // OCSPResponseStatus decode-and-whitelist leaf. read.enumerated is tag-checked, so
89
- // an INTEGER-encoded status is rejected at the leaf (asn1/unexpected-tag).
90
67
  var OCSP_RESPONSE_STATUS = schema.decode(function (n, ctx) {
91
68
  var v = asn1.read.enumerated(n);
92
69
  var key = v.toString();
@@ -94,7 +71,6 @@ var OCSP_RESPONSE_STATUS = schema.decode(function (n, ctx) {
94
71
  return { code: Number(v), name: STATUS_NAMES[key] };
95
72
  });
96
73
 
97
- // CRLReason decode-and-whitelist leaf.
98
74
  var CRL_REASON = schema.decode(function (n, ctx) {
99
75
  var v = asn1.read.enumerated(n);
100
76
  var key = v.toString();
@@ -102,44 +78,20 @@ var CRL_REASON = schema.decode(function (n, ctx) {
102
78
  return CRL_REASONS[key];
103
79
  });
104
80
 
105
- // A certs [0] SEQUENCE OF Certificate element. Unlike the CMS CertificateChoices
106
- // (a tagged CHOICE), an OCSP certs element is a plain Certificate, a universal
107
- // SEQUENCE (RFC 5280 sec. 4.1), so assert that shape before surfacing its raw DER, and
108
- // reject a non-SEQUENCE element instead of reporting arbitrary bytes as a cert.
109
81
  function certificateBytes() {
110
82
  return pkix.rawNonEmptySequence(NS, { code: "ocsp/bad-certs", message: "each certs element must be a non-empty Certificate SEQUENCE (RFC 6960 sec. 4.1.1/sec. 4.2.1)" });
111
83
  }
112
84
 
113
- // requestorName [1] EXPLICIT GeneralName (RFC 6960 sec. 4.1.1), validated and surfaced raw
114
- // via the shared pkix.generalName primitive (RFC 5280 sec. 4.2.1.6), so a malformed
115
- // GeneralName fails closed and the OCSP + TSP parsers cannot drift on this grammar.
116
85
  var GENERAL_NAME_RAW = pkix.generalName(NS, { code: "ocsp/bad-requestor-name" });
117
86
 
118
- // An OCSP signature BIT STRING is a byte string handed to a cryptographic verifier,
119
- // so it MUST be octet-aligned (0 unused bits); a non-octet-aligned signature is
120
- // malformed. Shared by the request Signature and the BasicOCSPResponse.
121
87
  function _rawSignature(field) {
122
88
  var sig = field.value;
123
89
  if (sig.unusedBits !== 0) throw NS.E("ocsp/bad-signature", "an OCSP signature BIT STRING must be octet-aligned (0 unused bits)");
124
90
  return sig.bytes;
125
91
  }
126
92
 
127
- // certs [0] EXPLICIT SEQUENCE OF Certificate, each element raw. Shared by the
128
- // request Signature and the BasicOCSPResponse.
129
- // The certs list is capped: the delegated-responder authorization loop verifies
130
- // each candidate before the response signature is checked, so an unbounded list in
131
- // a relayed / stapled response would drive unbounded pre-auth signature verifies.
132
93
  var CERTS = schema.seqOf(certificateBytes(), { assert: "sequence", code: "ocsp/bad-certs", what: "certs", max: constants.LIMITS.OCSP_MAX_CERTS, maxCode: "ocsp/too-many-certs" });
133
94
 
134
- // Validate the OCSP protocol extension values in a decoded extension list,
135
- // applied to every extension surface (request / single-request / response /
136
- // single-response) so a hostile placement cannot dodge the syntax rule. The
137
- // nonce is the one extension whose value the module names: Nonce ::= OCTET
138
- // STRING (SIZE(1..128)) (RFC 9654 sec. 2.1, updating RFC 6960 sec. 4.4.1; the 128
139
- // upper bound is the RFC 9654 responder rule; RFC 8954's was 32). The decoded
140
- // nonce bytes are surfaced on the extension as `nonce` alongside the raw value;
141
- // other extension values stay opaque (an unknown extension is representable,
142
- // not a fault).
143
95
  function _validateOcspExtensions(list) {
144
96
  if (!list) return list;
145
97
  for (var i = 0; i < list.length; i++) {
@@ -159,11 +111,7 @@ function _validateOcspExtensions(list) {
159
111
  return list;
160
112
  }
161
113
 
162
- // ---- CertID (shared request + response) ------------------------------
163
114
 
164
- // CertID ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier, issuerNameHash OCTET
165
- // STRING, issuerKeyHash OCTET STRING, serialNumber CertificateSerialNumber }
166
- // (RFC 6960 sec. 4.1.1). The two hashes are surfaced raw for the caller to verify.
167
115
  var CERT_ID = schema.seq([
168
116
  schema.field("hashAlgorithm", ALGORITHM_IDENTIFIER),
169
117
  schema.field("issuerNameHash", schema.octetString()),
@@ -182,11 +130,7 @@ var CERT_ID = schema.seq([
182
130
  },
183
131
  });
184
132
 
185
- // ---- response tree ---------------------------------------------------
186
133
 
187
- // RevokedInfo ::= SEQUENCE { revocationTime GeneralizedTime, revocationReason [0]
188
- // EXPLICIT CRLReason OPTIONAL } (RFC 6960 sec. 4.2.1). Walked on the [1] IMPLICIT node,
189
- // so assert:"constructed" (the context tag replaced the universal SEQUENCE tag).
190
134
  var REVOKED_INFO = schema.seq([
191
135
  schema.field("revocationTime", GENERALIZED_TIME),
192
136
  schema.trailing([
@@ -202,9 +146,6 @@ var REVOKED_INFO = schema.seq([
202
146
  },
203
147
  });
204
148
 
205
- // CertStatus ::= CHOICE { good [0] IMPLICIT NULL, revoked [1] IMPLICIT RevokedInfo,
206
- // unknown [2] IMPLICIT NULL } (RFC 6960 sec. 4.2.1). good/unknown are primitive empty
207
- // context nodes; revoked is a constructed context [1] whose body is RevokedInfo.
208
149
  var CERT_STATUS = schema.choice([
209
150
  { when: { tagClass: "context", tagNumber: 0 }, schema: schema.implicitNull(0) },
210
151
  { when: { tagClass: "context", tagNumber: 1 }, schema: REVOKED_INFO },
@@ -219,11 +160,6 @@ function _shapeCertStatus(field) {
219
160
  return { type: "revoked", revocationTime: ri.revocationTime, revocationReason: ri.revocationReason };
220
161
  }
221
162
 
222
- // SingleResponse ::= SEQUENCE { certID, certStatus, thisUpdate GeneralizedTime,
223
- // nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, singleExtensions [1] EXPLICIT
224
- // Extensions OPTIONAL } (RFC 6960 sec. 4.2.1). certStatus is consumed positionally
225
- // (before thisUpdate), so its context [0] good arm cannot be confused with the
226
- // trailing nextUpdate [0].
227
163
  var SINGLE_RESPONSE = schema.seq([
228
164
  schema.field("certID", CERT_ID),
229
165
  schema.field("certStatus", CERT_STATUS),
@@ -245,9 +181,6 @@ var SINGLE_RESPONSE = schema.seq([
245
181
  },
246
182
  });
247
183
 
248
- // ResponderID ::= CHOICE { byName [1] Name, byKey [2] KeyHash } (RFC 6960 sec. 4.2.1),
249
- // both EXPLICIT (the module is EXPLICIT TAGS). byKey is an EXPLICIT-wrapped universal
250
- // OCTET STRING (0xA2 04 ...) and not an IMPLICIT primitive [2].
251
184
  var RESPONDER_ID = schema.choice([
252
185
  { when: { tagClass: "context", tagNumber: 1 }, schema: schema.explicit(1, NAME, { code: "ocsp/bad-responder-id" }) },
253
186
  { when: { tagClass: "context", tagNumber: 2 }, schema: schema.explicit(2, schema.octetString(), { code: "ocsp/bad-responder-id" }) },
@@ -255,16 +188,11 @@ var RESPONDER_ID = schema.choice([
255
188
 
256
189
  function _shapeResponderID(field) {
257
190
  if (field.node.tagNumber === 1) return { byName: field.value.result };
258
- // RFC 6960 sec. 4.2.1 -- KeyHash is the SHA-1 hash of the responder's public key, so a
259
- // conformant byKey ResponderID is exactly 20 octets; reject any other length.
260
191
  var keyHash = field.value;
261
192
  if (keyHash.length !== 20) throw NS.E("ocsp/bad-responder-id", "ResponderID byKey (KeyHash) must be a 20-byte SHA-1 hash (RFC 6960 sec. 4.2.1)");
262
193
  return { byKey: keyHash };
263
194
  }
264
195
 
265
- // ResponseData ::= SEQUENCE { version [0] EXPLICIT DEFAULT v1, responderID,
266
- // producedAt GeneralizedTime, responses SEQUENCE OF SingleResponse,
267
- // responseExtensions [1] EXPLICIT Extensions OPTIONAL } (RFC 6960 sec. 4.2.1).
268
196
  var RESPONSE_DATA = schema.seq([
269
197
  schema.optional("version", VERSION, { tag: 0, explicit: true, default: 1, emptyCode: "ocsp/bad-version" }),
270
198
  schema.field("responderID", RESPONDER_ID),
@@ -286,10 +214,6 @@ var RESPONSE_DATA = schema.seq([
286
214
  },
287
215
  });
288
216
 
289
- // BasicOCSPResponse ::= SEQUENCE { tbsResponseData ResponseData, signatureAlgorithm
290
- // AlgorithmIdentifier, signature BIT STRING, certs [0] EXPLICIT SEQUENCE OF
291
- // Certificate OPTIONAL } (RFC 6960 sec. 4.2.1). tbsResponseData.node.bytes is the exact
292
- // signed region (no CMS-style re-tag divergence, the clean case).
293
217
  var BASIC_OCSP_RESPONSE = schema.seq([
294
218
  schema.field("tbsResponseData", RESPONSE_DATA),
295
219
  schema.field("signatureAlgorithm", ALGORITHM_IDENTIFIER),
@@ -315,10 +239,6 @@ var BASIC_OCSP_RESPONSE = schema.seq([
315
239
  },
316
240
  });
317
241
 
318
- // ResponseBytes ::= SEQUENCE { responseType OBJECT IDENTIFIER, response OCTET STRING }
319
- // (RFC 6960 sec. 4.2.1). For id-pkix-ocsp-basic the response OCTET STRING content is a
320
- // fresh DER BasicOCSPResponse (decoded + walked); an unknown responseType is
321
- // recognized-and-deferred with a precise ocsp/unsupported-response-type.
322
242
  var RESPONSE_BYTES = schema.seq([
323
243
  schema.field("responseType", schema.oidLeaf()),
324
244
  schema.field("response", schema.octetString()),
@@ -340,12 +260,6 @@ var RESPONSE_BYTES = schema.seq([
340
260
  },
341
261
  });
342
262
 
343
- // OCSPResponse ::= SEQUENCE { responseStatus OCSPResponseStatus, responseBytes [0]
344
- // EXPLICIT ResponseBytes OPTIONAL } (RFC 6960 sec. 4.2.1). The status <-> responseBytes
345
- // biconditional (successful iff responseBytes present) is the OCSP-specific
346
- // cross-field guard. The top-level reject code predates the
347
- // `<prefix>/not-a-<structure>` convention (ocsp/not-a-request follows it) and
348
- // stays frozen on the public error-code surface.
349
263
  var OCSP_RESPONSE = schema.seq([
350
264
  schema.field("responseStatus", OCSP_RESPONSE_STATUS),
351
265
  schema.optional("responseBytes", RESPONSE_BYTES, { tag: 0, explicit: true, emptyCode: "ocsp/bad-ocsp-response" }),
@@ -354,8 +268,6 @@ var OCSP_RESPONSE = schema.seq([
354
268
  build: function (m) {
355
269
  var status = m.fields.responseStatus.value;
356
270
  var present = m.fields.responseBytes.present;
357
- // RFC 6960 sec. 4.2.1 -- a successful response MUST carry responseBytes; any other
358
- // status MUST NOT (there is nothing to convey but the status).
359
271
  if (status.code === 0 && !present) throw NS.E("ocsp/bad-response-bytes", "a successful OCSPResponse must carry responseBytes (RFC 6960 sec. 4.2.1)");
360
272
  if (status.code !== 0 && present) throw NS.E("ocsp/bad-response-bytes", "a non-successful OCSPResponse must not carry responseBytes (RFC 6960 sec. 4.2.1)");
361
273
  var rb = present ? m.fields.responseBytes.value.result : null;
@@ -367,10 +279,7 @@ var OCSP_RESPONSE = schema.seq([
367
279
  },
368
280
  });
369
281
 
370
- // ---- request tree ----------------------------------------------------
371
282
 
372
- // Request ::= SEQUENCE { reqCert CertID, singleRequestExtensions [0] EXPLICIT
373
- // Extensions OPTIONAL } (RFC 6960 sec. 4.1.1).
374
283
  var REQUEST = schema.seq([
375
284
  schema.field("reqCert", CERT_ID),
376
285
  schema.trailing([
@@ -386,8 +295,6 @@ var REQUEST = schema.seq([
386
295
  },
387
296
  });
388
297
 
389
- // Signature ::= SEQUENCE { signatureAlgorithm AlgorithmIdentifier, signature BIT
390
- // STRING, certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } (RFC 6960 sec. 4.1.1).
391
298
  var SIGNATURE = schema.seq([
392
299
  schema.field("signatureAlgorithm", ALGORITHM_IDENTIFIER),
393
300
  schema.field("signature", schema.bitString()),
@@ -405,10 +312,6 @@ var SIGNATURE = schema.seq([
405
312
  },
406
313
  });
407
314
 
408
- // TBSRequest ::= SEQUENCE { version [0] EXPLICIT DEFAULT v1, requestorName [1]
409
- // EXPLICIT GeneralName OPTIONAL, requestList SEQUENCE OF Request, requestExtensions
410
- // [2] EXPLICIT Extensions OPTIONAL } (RFC 6960 sec. 4.1.1). requestorName is surfaced
411
- // raw (GeneralName is a wide CHOICE with no factory yet).
412
315
  var TBS_REQUEST = schema.seq([
413
316
  schema.optional("version", VERSION, { tag: 0, explicit: true, default: 1, emptyCode: "ocsp/bad-version" }),
414
317
  schema.optional("requestorName", GENERAL_NAME_RAW, { tag: 1, explicit: true, emptyCode: "ocsp/bad-requestor-name" }),
@@ -429,9 +332,6 @@ var TBS_REQUEST = schema.seq([
429
332
  },
430
333
  });
431
334
 
432
- // OCSPRequest ::= SEQUENCE { tbsRequest TBSRequest, optionalSignature [0] EXPLICIT
433
- // Signature OPTIONAL } (RFC 6960 sec. 4.1.1). tbsRequest.node.bytes is the raw signed
434
- // region for external verification.
435
335
  var OCSP_REQUEST = schema.seq([
436
336
  schema.field("tbsRequest", TBS_REQUEST),
437
337
  schema.optional("optionalSignature", SIGNATURE, { tag: 0, explicit: true, emptyCode: "ocsp/not-a-request" }),
@@ -440,9 +340,6 @@ var OCSP_REQUEST = schema.seq([
440
340
  build: function (m) {
441
341
  var tbs = m.fields.tbsRequest.value.result;
442
342
  var optionalSignature = m.fields.optionalSignature.present ? m.fields.optionalSignature.value.result : null;
443
- // RFC 6960 sec. 4.1.2 -- if the request is signed, the requestor SHALL specify its
444
- // name in requestorName (the identity the signature binds to). A signed request
445
- // without it is internally inconsistent; reject fail-closed.
446
343
  if (optionalSignature && tbs.requestorName === null) {
447
344
  throw NS.E("ocsp/missing-requestor-name", "a signed OCSPRequest must specify requestorName (RFC 6960 sec. 4.1.2)");
448
345
  }
@@ -522,11 +419,6 @@ var parseRequest = pkix.makeParser({ pemLabel: "OCSP REQUEST", PemError: PemErro
522
419
  * res.responseStatus.name; // -> "successful"
523
420
  * res.basicResponse.responses[0].certStatus.type; // -> "good" | "revoked" | "unknown"
524
421
  */
525
- // The result records the input it was derived from. A verdict verb reads the
526
- // signature, the algorithm that verifies it and the bytes it covers off this object as
527
- // three separate properties, and re-derives all three from the recorded input rather
528
- // than trusting the object it was handed -- so an object rebuilt or edited after
529
- // parsing cannot make the three describe different responses.
530
422
  var parseResponse = pkix.makeRecordingParser({ pemLabel: "OCSP RESPONSE", PemError: PemError, ErrorClass: OcspError, prefix: "ocsp", what: "OCSP response", topSchema: OCSP_RESPONSE, ns: NS }, "ocspResponse");
531
423
 
532
424
  /**
@@ -583,11 +475,6 @@ function pemDecode(text, label) { return pkix.pemDecode(text, label || "OCSP RES
583
475
  */
584
476
  function pemEncode(der, label) { return pkix.pemEncode(der, label || "OCSP RESPONSE", PemError); }
585
477
 
586
- // An OCSPResponse root is the only registered structure that leads with an
587
- // ENUMERATED child (a SEQUENCE of 1-2: responseStatus + an optional context [0]
588
- // responseBytes). Every other root leads with a SEQUENCE (x509/crl/csr/ocsp-request),
589
- // an OBJECT IDENTIFIER (cms), or an INTEGER (pkcs8), so the detector is
590
- // unconditionally exclusive.
591
478
  function matchesResponse(root) {
592
479
  var T = asn1.TAGS;
593
480
  var k = pkix.rootSequenceChildren(root, 1, 2);
@@ -597,10 +484,6 @@ function matchesResponse(root) {
597
484
  return true;
598
485
  }
599
486
 
600
- // An OCSPRequest root is a SEQUENCE of 1-2 whose first child is the tbsRequest
601
- // SEQUENCE (optionally followed by a context [0] EXPLICIT signature). It leads with
602
- // a SEQUENCE like x509/crl/csr, but those require EXACTLY 3 children (the
603
- // signed-envelope trio), while an OCSPRequest is 1-2 -- so it is excluded by arity.
604
487
  function matchesRequest(root) {
605
488
  var T = asn1.TAGS;
606
489
  var k = pkix.rootSequenceChildren(root, 1, 2);
@@ -53,27 +53,22 @@ var PemError = frameworkError.PemError;
53
53
  var NS = pkix.makeNS("pkcs12", Pkcs12Error, oid);
54
54
  var TAGS = asn1.TAGS;
55
55
 
56
- // Content types (RFC 5652 sec. 4 / RFC 7292 sec. 4.1).
57
56
  var OID_DATA = oid.byName("data");
58
57
  var OID_SIGNED_DATA = oid.byName("signedData");
59
58
  var OID_ENVELOPED_DATA = oid.byName("envelopedData");
60
59
  var OID_ENCRYPTED_DATA = oid.byName("encryptedData");
61
- // Bag types (RFC 7292 sec. 4.2).
62
60
  var OID_KEY_BAG = oid.byName("keyBag");
63
61
  var OID_SHROUDED_KEY_BAG = oid.byName("pkcs8ShroudedKeyBag");
64
62
  var OID_CERT_BAG = oid.byName("certBag");
65
63
  var OID_CRL_BAG = oid.byName("crlBag");
66
64
  var OID_SECRET_BAG = oid.byName("secretBag");
67
65
  var OID_SAFE_CONTENTS_BAG = oid.byName("safeContentsBag");
68
- // CertBag / CRLBag discriminators (sec. 4.2.3-sec. 4.2.4).
69
66
  var OID_X509_CERTIFICATE = oid.byName("x509Certificate");
70
67
  var OID_SDSI_CERTIFICATE = oid.byName("sdsiCertificate");
71
68
  var OID_X509_CRL = oid.byName("x509CRL");
72
- // Bag attributes (sec. 4.2) + the RFC 9579 MacData arm.
73
69
  var OID_FRIENDLY_NAME = oid.byName("friendlyName");
74
70
  var OID_LOCAL_KEY_ID = oid.byName("localKeyId");
75
71
  var OID_PBMAC1 = oid.byName("pbmac1");
76
- // DigestInfo ::= SEQUENCE { digestAlgorithm AlgorithmIdentifier, digest OCTET STRING }.
77
72
  var DIGEST_INFO = schema.seq([
78
73
  schema.field("digestAlgorithm", pkix.algorithmIdentifier(NS)),
79
74
  schema.field("digest", schema.octetString()),
@@ -84,14 +79,8 @@ var DIGEST_INFO = schema.seq([
84
79
  },
85
80
  });
86
81
 
87
- // PBKDF2-params + PBMAC1-params (RFC 8018 sec. 5.2 / App. A.5, RFC 9579 sec. 4) constrained to the PBMAC1
88
- // profile -- keyLength MUST be present, the prf DEFAULT is enforced non-canonical. Shared with CMP PBMAC1
89
- // protection verification, so the reader lives once in schema-pkix (ns-parameterized) instead of a second
90
- // copy per format; composed here with the pkcs12 namespace so it emits pkcs12/bad-mac-data.
91
82
  var PBMAC1_PARAMS = pkix.pbmac1Params(NS);
92
83
 
93
- // MacData ::= SEQUENCE { mac DigestInfo, macSalt OCTET STRING,
94
- // iterations INTEGER DEFAULT 1 }.
95
84
  var MAC_DATA = schema.seq([
96
85
  schema.field("mac", DIGEST_INFO),
97
86
  schema.field("macSalt", schema.octetString()),
@@ -99,8 +88,6 @@ var MAC_DATA = schema.seq([
99
88
  ], {
100
89
  assert: "sequence", code: "pkcs12/bad-mac-data", what: "MacData",
101
90
  build: function (m, ctx) {
102
- // X.690 sec. 11.5 -- a DEFAULT-valued component must be omitted from a DER
103
- // encoding, so an explicitly-encoded iterations = 1 is non-canonical.
104
91
  var it = m.fields.iterations;
105
92
  var iterations = 1;
106
93
  if (it.present) {
@@ -111,8 +98,6 @@ var MAC_DATA = schema.seq([
111
98
  var di = m.fields.mac.value.result;
112
99
  var pbmac1 = null;
113
100
  if (di.digestAlgorithm.oid === OID_PBMAC1) {
114
- // RFC 9579 sec. 4 -- the PBMAC1 algorithm identifier MUST carry PBMAC1-params
115
- // (the KDF and MAC scheme a verifier needs live there, not in MacData).
116
101
  if (di.digestAlgorithm.parameters === null) {
117
102
  throw ctx.E("pkcs12/bad-mac-data", "a PBMAC1 MacData must carry PBMAC1-params (RFC 9579 sec. 4)");
118
103
  }
@@ -132,10 +117,6 @@ var MAC_DATA = schema.seq([
132
117
  },
133
118
  });
134
119
 
135
- // CertBag ::= SEQUENCE { certId OID, certValue [0] EXPLICIT ANY } (sec. 4.2.3):
136
- // x509Certificate wraps the DER certificate in an OCTET STRING; sdsiCertificate
137
- // is an IA5String. Both arms of the closed set are accepted; the value is
138
- // surfaced raw (byte-exact), never re-encoded or recursively parsed.
139
120
  var CERT_BAG = schema.seq([
140
121
  schema.field("certId", schema.oidLeaf()),
141
122
  schema.field("certValue", schema.explicit(0, schema.any(), { code: "pkcs12/bad-bag-value", what: "certValue" })),
@@ -157,7 +138,6 @@ var CERT_BAG = schema.seq([
157
138
  },
158
139
  });
159
140
 
160
- // CRLBag ::= SEQUENCE { crlId OID, crlValue [0] EXPLICIT ANY } (sec. 4.2.4).
161
141
  var CRL_BAG = schema.seq([
162
142
  schema.field("crlId", schema.oidLeaf()),
163
143
  schema.field("crlValue", schema.explicit(0, schema.any(), { code: "pkcs12/bad-bag-value", what: "crlValue" })),
@@ -172,9 +152,6 @@ var CRL_BAG = schema.seq([
172
152
  },
173
153
  });
174
154
 
175
- // SecretBag ::= SEQUENCE { secretTypeId OID, secretValue [0] EXPLICIT ANY }
176
- // (sec. 4.2.5). SecretTypes is an open set, so the type is surfaced by OID with
177
- // the value raw -- an unrecognized secret is representable, not a fault.
178
155
  var SECRET_BAG = schema.seq([
179
156
  schema.field("secretTypeId", schema.oidLeaf()),
180
157
  schema.field("secretValue", schema.explicit(0, schema.any(), { code: "pkcs12/bad-bag-value", what: "secretValue" })),
@@ -186,11 +163,6 @@ var SECRET_BAG = schema.seq([
186
163
  },
187
164
  });
188
165
 
189
- // SafeBag ::= SEQUENCE { bagId OID, bagValue [0] EXPLICIT ANY DEFINED BY bagId,
190
- // bagAttributes SET OF PKCS12Attribute OPTIONAL } (sec. 4.2).
191
- // The build surfaces the structural record (bagId + the inner value node +
192
- // decoded attributes); the bagId dispatch happens in _buildBag, where the
193
- // per-parse recursion state lives.
194
166
  var SAFE_BAG = schema.seq([
195
167
  schema.field("bagId", schema.oidLeaf()),
196
168
  schema.field("bagValue", schema.explicit(0, schema.any(), { code: "pkcs12/bad-bag-value", what: "bagValue" })),
@@ -210,16 +182,12 @@ var SAFE_BAG = schema.seq([
210
182
  for (var i = 0; i < items.length; i++) {
211
183
  var a = items[i].value.result;
212
184
  attributes.push(a);
213
- // friendlyName / localKeyId are SINGLE VALUE TRUE (PKCS#9 / RFC 2985):
214
- // exactly one value, at most one instance of each attribute.
215
185
  if (a.type === OID_FRIENDLY_NAME) {
216
186
  if (seen[a.type] || a.values.length !== 1) throw ctx.E("pkcs12/bad-friendly-name", "friendlyName carries exactly one BMPString value (PKCS#9 SINGLE VALUE)");
217
187
  friendlyName = _bmpValue(a.values[0], ctx);
218
188
  }
219
189
  if (a.type === OID_LOCAL_KEY_ID) {
220
190
  if (seen[a.type] || a.values.length !== 1) throw ctx.E("pkcs12/bad-local-key-id", "localKeyId carries exactly one OCTET STRING value (PKCS#9 SINGLE VALUE)");
221
- // The value bytes are a raw wire slice out of a store whose content
222
- // is normatively BER, so the re-decode follows the same BER rules.
223
191
  localKeyId = _octetContent(asn1.decode(a.values[0], { ber: true }), ctx, "a localKeyId value", "pkcs12/bad-local-key-id");
224
192
  }
225
193
  seen[a.type] = true;
@@ -235,15 +203,11 @@ var SAFE_BAG = schema.seq([
235
203
  },
236
204
  });
237
205
 
238
- // SafeContents ::= SEQUENCE OF SafeBag (sec. 4.2). Strictly a SEQUENCE: a SET OF
239
- // here is a known producer divergence and rejects.
240
206
  var SAFE_CONTENTS = schema.seqOf(SAFE_BAG, {
241
207
  code: "pkcs12/bad-safe-contents", what: "SafeContents",
242
208
  max: C.LIMITS.PKCS12_MAX_ELEMENTS, maxCode: "pkcs12/too-many-elements",
243
209
  });
244
210
 
245
- // AuthenticatedSafe ::= SEQUENCE OF ContentInfo (sec. 4.1), each element parsed
246
- // structurally here and dispatched by contentType in _dispatchSafes.
247
211
  var AS_ELEMENT = schema.seq([
248
212
  schema.field("contentType", schema.oidLeaf()),
249
213
  schema.field("content", schema.explicit(0, schema.any(), { code: "pkcs12/bad-safe-contentinfo", what: "safe ContentInfo content" })),
@@ -258,8 +222,6 @@ var AUTHENTICATED_SAFE = schema.seqOf(AS_ELEMENT, {
258
222
  max: C.LIMITS.PKCS12_MAX_ELEMENTS, maxCode: "pkcs12/too-many-elements",
259
223
  });
260
224
 
261
- // The authSafe ContentInfo (sec. 4): contentType is data (password integrity) or
262
- // signedData (public-key integrity) and nothing else.
263
225
  var AUTH_SAFE = schema.seq([
264
226
  schema.field("contentType", schema.oidLeaf()),
265
227
  schema.field("content", schema.explicit(0, schema.any(), { code: "pkcs12/bad-authsafe", what: "authSafe content" })),
@@ -270,8 +232,6 @@ var AUTH_SAFE = schema.seq([
270
232
  },
271
233
  });
272
234
 
273
- // PFX ::= SEQUENCE { version INTEGER {v3(3)}, authSafe ContentInfo,
274
- // macData MacData OPTIONAL } (sec. 4).
275
235
  var PFX = schema.seq([
276
236
  schema.field("version", pkix.versionReader(NS, { "3": 3 })),
277
237
  schema.field("authSafe", AUTH_SAFE),
@@ -283,18 +243,9 @@ var PFX = schema.seq([
283
243
  var authSafe = m.fields.authSafe.value.result;
284
244
  var macPresent = m.fields.macData.present;
285
245
  var mac = macPresent ? m.fields.macData.value.result : null;
286
- // Every re-decode below shares one budget, so nesting chained across
287
- // OCTET-STRING (and delegation) boundaries cannot restart the caps.
288
246
  var state = { budget: { remaining: C.LIMITS.PKCS12_MAX_REDECODES }, bagDepth: 0 };
289
247
 
290
248
  if (authSafe.contentType === OID_DATA) {
291
- // sec. 5.1 step 5B -- the MAC covers the value octets of the id-data OCTET
292
- // STRING (the AuthenticatedSafe encoding), excluding the TLV header.
293
- // MacData itself is OPTIONAL in the PFX syntax: a store without it
294
- // (OpenSSL `pkcs12 -export -nomac`) carries no integrity protection at
295
- // all, which is a policy concern for the caller. It is surfaced as
296
- // integrityMode "none", never rejected by a parser whose job is to
297
- // surface integrity inputs and not to verify them.
298
249
  var macedBytes = _octetContent(authSafe.innerNode, ctx, "an id-data authSafe content", "pkcs12/bad-authsafe");
299
250
  var dispatched = _dispatchSafes(_walkAuthenticatedSafe(macedBytes, state, ctx), state, ctx);
300
251
  return {
@@ -303,7 +254,6 @@ var PFX = schema.seq([
303
254
  };
304
255
  }
305
256
  if (authSafe.contentType === OID_SIGNED_DATA) {
306
- // sec. 4 integrity coherence: public-key integrity has no MacData.
307
257
  if (macPresent) throw ctx.E("pkcs12/bad-integrity-mode", "an id-signedData authSafe (public-key integrity) must omit macData (RFC 7292 sec. 4)");
308
258
  var signed = cms.walkSignedData(authSafe.innerNode);
309
259
  if (signed.encapContentInfo.eContentType !== OID_DATA) {
@@ -312,8 +262,6 @@ var PFX = schema.seq([
312
262
  if (signed.encapContentInfo.eContent === null) {
313
263
  throw ctx.E("pkcs12/bad-authsafe", "a public-key-integrity authSafe must carry attached eContent (RFC 7292 sec. 4.1)");
314
264
  }
315
- // A signer-less SignedData carries no integrity at all, the one thing
316
- // public-key-integrity mode exists to provide.
317
265
  if (signed.signerInfos.length < 1) {
318
266
  throw ctx.E("pkcs12/bad-authsafe", "a public-key-integrity authSafe must carry at least one SignerInfo (RFC 7292 sec. 4)");
319
267
  }
@@ -328,8 +276,6 @@ var PFX = schema.seq([
328
276
  },
329
277
  });
330
278
 
331
- // The value octets of a universal OCTET STRING node (a BER constructed string
332
- // arrives already reassembled to primitive content by the codec's ber mode).
333
279
  function _octetContent(node, ctx, what, code) {
334
280
  if (!(node && node.tagClass === "universal" && node.tagNumber === TAGS.OCTET_STRING && node.content)) {
335
281
  throw ctx.E(code || "pkcs12/bad-bag-value", what + " must be an OCTET STRING");
@@ -337,11 +283,6 @@ function _octetContent(node, ctx, what, code) {
337
283
  return node.content;
338
284
  }
339
285
 
340
- // RFC 7292 sec. 4.1 -- a privacy-mode safe wraps a SafeContents, so the encrypted
341
- // content's declared type must be id-data whichever CMS privacy structure
342
- // carries it, and the ciphertext must be attached: CMS permits a detached
343
- // EncryptedContentInfo, but here the ciphertext is the safe's contents, and a
344
- // safe without it holds nothing a passphrase could ever recover.
345
286
  function _privacySafe(content, ctx) {
346
287
  if (content.encryptedContentInfo.contentType !== OID_DATA) {
347
288
  throw ctx.E("pkcs12/bad-safe-contentinfo-type",
@@ -354,8 +295,6 @@ function _privacySafe(content, ctx) {
354
295
  return content;
355
296
  }
356
297
 
357
- // A PKCS#9 SINGLE-VALUE BMPString attribute value (friendlyName), decoded
358
- // UTF-16BE by the codec's string reader (even length + surrogate rules there).
359
298
  function _bmpValue(bytes, ctx) {
360
299
  var node = asn1.decode(bytes, { ber: true });
361
300
  if (!(node.tagClass === "universal" && node.tagNumber === TAGS.BMP_STRING)) {
@@ -364,7 +303,6 @@ function _bmpValue(bytes, ctx) {
364
303
  return asn1.read.string(node);
365
304
  }
366
305
 
367
- // Re-decode the AuthenticatedSafe blob (BER content region, budgeted).
368
306
  function _walkAuthenticatedSafe(bytes, state, ctx) {
369
307
  return schema.embeddedDer(AUTHENTICATED_SAFE, bytes, ctx, {
370
308
  code: "pkcs12/bad-der", what: "the AuthenticatedSafe", ber: true,
@@ -372,16 +310,8 @@ function _walkAuthenticatedSafe(bytes, state, ctx) {
372
310
  });
373
311
  }
374
312
 
375
- // Dispatch each AuthenticatedSafe element by contentType (sec. 4.1): id-data
376
- // carries plaintext SafeContents (re-decoded here); the two privacy modes are
377
- // full CMS structures validated by the CMS module on the already-decoded node
378
- // -- ciphertext stays opaque inside the CMS surface.
379
- // @internal -- re-parse a DECRYPTED privacy-safe's plaintext (a SafeContents ::= SEQUENCE OF SafeBag) through
380
- // the same strict SAFE_CONTENTS walk and bag dispatch the plaintext path uses, so a decrypted blob shares every
381
- // PKCS12_MAX_* cap and produces the identical bag records. Consumed by pki.pkcs12.open for an encrypted safe.
313
+ // @internal
382
314
  function walkSafeContents(der) {
383
- // PKCS#12 content regions are normatively BER (RFC 7292 sec. 4.1), so a decrypted SafeContents may use an
384
- // indefinite-length SEQUENCE, exactly as the plaintext-safe path (_dispatchSafes) decodes it with ber:true.
385
315
  var walked = schema.walk(SAFE_CONTENTS, asn1.decode(der, { ber: true }), NS);
386
316
  var state = { budget: { remaining: C.LIMITS.PKCS12_MAX_REDECODES }, bagDepth: 0 };
387
317
  var bags = [];
@@ -405,9 +335,6 @@ function _dispatchSafes(asMatch, state, ctx) {
405
335
  } else if (el.contentType === OID_ENCRYPTED_DATA) {
406
336
  encryptedSafes.push({ type: "encryptedData", content: _privacySafe(cms.walkEncryptedData(el.innerNode), ctx) });
407
337
  } else if (el.contentType === OID_ENVELOPED_DATA) {
408
- // Surface the raw EnvelopedData DER alongside the walked structure: public-key privacy opens by driving
409
- // pki.cms.decrypt, which re-parses strict DER (it takes no pre-parsed object), so pkcs12.open reconstructs
410
- // the ContentInfo around these bytes and never re-serializes the recipientInfos the integrity check trusts.
411
338
  encryptedSafes.push({ type: "envelopedData", content: _privacySafe(cms.walkEnvelopedData(el.innerNode), ctx), envelopedDataDer: el.innerNode.bytes });
412
339
  } else {
413
340
  throw ctx.E("pkcs12/bad-safe-contentinfo-type", "an AuthenticatedSafe element must be id-data, id-encryptedData, or id-envelopedData (RFC 7292 sec. 4.1), got " +
@@ -417,21 +344,15 @@ function _dispatchSafes(asMatch, state, ctx) {
417
344
  return { safeBags: safeBags, encryptedSafes: encryptedSafes };
418
345
  }
419
346
 
420
- // bagId dispatch (sec. 4.2, Appendix D). The bag-type set is closed: an
421
- // unrecognized bagId rejects. Key material delegates to the exported PKCS#8
422
- // parsers; cert / CRL / secret values are surfaced raw.
423
347
  function _buildBag(rec, state, ctx) {
424
348
  var bag = {
425
349
  type: null, bagId: rec.bagId,
426
350
  friendlyName: rec.friendlyName, localKeyId: rec.localKeyId, attributes: rec.attributes,
427
351
  };
428
- // Key bags are walked from the decoded node, since their wire bytes may carry
429
- // BER shapes the strict pkcs8 parse entry refuses, and the node already
430
- // exists (no re-decode).
431
352
  if (rec.bagId === OID_KEY_BAG) {
432
353
  bag.type = "keyBag";
433
354
  bag.key = pkcs8.walkPrivateKeyInfo(rec.valueNode);
434
- bag.keyDer = rec.valueNode.bytes; // the raw PrivateKeyInfo DER (pki.pkcs12.open surfaces it verbatim)
355
+ bag.keyDer = rec.valueNode.bytes;
435
356
  return bag;
436
357
  }
437
358
  if (rec.bagId === OID_SHROUDED_KEY_BAG) {
@@ -458,8 +379,6 @@ function _buildBag(rec, state, ctx) {
458
379
  return bag;
459
380
  }
460
381
  if (rec.bagId === OID_SAFE_CONTENTS_BAG) {
461
- // sec. 4.2.6 recursion -- bounded independently of the codec depth cap so a
462
- // chain across re-decode boundaries cannot restart it.
463
382
  if (state.bagDepth + 1 > C.LIMITS.PKCS12_MAX_BAG_DEPTH) {
464
383
  throw ctx.E("pkcs12/too-deep", "safeContentsBag nesting exceeds the depth cap " + C.LIMITS.PKCS12_MAX_BAG_DEPTH);
465
384
  }
@@ -523,11 +442,6 @@ function _buildBag(rec, state, ctx) {
523
442
  * var store = pki.schema.pkcs12.parse(der);
524
443
  * store.safeBags.map(function (b) { return b.type; });
525
444
  */
526
- // The result records the input it was derived from. pki.pkcs12.verifyMac and open read
527
- // the MACed byte range and the bags returned as verified off this object as two
528
- // separate properties, and re-derive both from the recorded input rather than trusting
529
- // the object -- so "verify this" and "return that" cannot come to name different
530
- // stores, whether by rebuilding the object or by editing it after parsing.
531
445
  var parse = pkix.makeRecordingParser({
532
446
  pemLabel: "PKCS12", PemError: PemError, ErrorClass: Pkcs12Error,
533
447
  prefix: "pkcs12", what: "PFX", topSchema: PFX, ns: NS, ber: true,
@@ -576,11 +490,6 @@ function pemDecode(text, label) { return pkix.pemDecode(text, label || "PKCS12",
576
490
  */
577
491
  function pemEncode(der, label) { return pkix.pemEncode(der, label || "PKCS12", PemError); }
578
492
 
579
- // A PFX root leads with a universal INTEGER (version), colliding with the
580
- // PKCS#8 detector on the first child -- so the discriminators are children[1]
581
- // (a ContentInfo: SEQUENCE of exactly 2, OID first, [0] constructed second --
582
- // a shape a PrivateKeyInfo's AlgorithmIdentifier never presents) and
583
- // children[2] (a SEQUENCE MacData or absent, never PKCS#8's OCTET STRING).
584
493
  function matches(root) {
585
494
  var k = pkix.rootSequenceChildren(root, 2, 3);
586
495
  if (!k) return false;