@blamejs/pki 0.6.29 → 0.6.30

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 (58) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/lib/acme.js +6 -6
  3. package/lib/asn1-der.js +9 -7
  4. package/lib/attrcert-sign.js +8 -8
  5. package/lib/byte-reader.js +1 -1
  6. package/lib/byte-writer.js +1 -1
  7. package/lib/cmc-verify.js +4 -4
  8. package/lib/cmp-build.js +3 -3
  9. package/lib/cmp-session.js +3 -3
  10. package/lib/cms-verify.js +22 -17
  11. package/lib/composite-kem.js +2 -2
  12. package/lib/crl-sign.js +5 -5
  13. package/lib/crmf-sign.js +3 -3
  14. package/lib/csr-sign.js +2 -2
  15. package/lib/ct.js +3 -3
  16. package/lib/est.js +8 -8
  17. package/lib/framework-error.js +2 -2
  18. package/lib/hpke.js +2 -2
  19. package/lib/http-transport.js +4 -4
  20. package/lib/inspect.js +1 -1
  21. package/lib/jose.js +1 -1
  22. package/lib/key.js +7 -7
  23. package/lib/lint.js +1 -1
  24. package/lib/merkle.js +2 -6
  25. package/lib/mime.js +2 -2
  26. package/lib/ocsp.js +6 -6
  27. package/lib/oid.js +1 -1
  28. package/lib/path-validate.js +13 -13
  29. package/lib/pkcs12-build.js +4 -4
  30. package/lib/rfc3339.js +2 -2
  31. package/lib/scep.js +2 -2
  32. package/lib/schema-all.js +1 -1
  33. package/lib/schema-attrcert.js +1 -1
  34. package/lib/schema-cmc.js +2 -2
  35. package/lib/schema-cmp.js +8 -9
  36. package/lib/schema-cms.js +3 -3
  37. package/lib/schema-crmf.js +3 -3
  38. package/lib/schema-csr.js +1 -1
  39. package/lib/schema-csrattrs.js +1 -1
  40. package/lib/schema-engine.js +4 -4
  41. package/lib/schema-ocsp.js +1 -1
  42. package/lib/schema-pkcs12.js +2 -2
  43. package/lib/schema-pkcs8.js +2 -2
  44. package/lib/schema-smime.js +1 -1
  45. package/lib/schema-tsp.js +6 -6
  46. package/lib/schema-x509.js +2 -2
  47. package/lib/shbs.js +3 -4
  48. package/lib/sign-scheme.js +1 -1
  49. package/lib/sigstore.js +2 -2
  50. package/lib/smime.js +16 -16
  51. package/lib/tls-cert-compress.js +7 -7
  52. package/lib/trust.js +5 -5
  53. package/lib/tsp-sign.js +8 -6
  54. package/lib/webauthn.js +23 -19
  55. package/lib/webcrypto.js +3 -3
  56. package/lib/x509-sign.js +5 -5
  57. package/package.json +1 -1
  58. package/sbom.cdx.json +6 -6
package/lib/schema-tsp.js CHANGED
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * @intro
13
13
  * RFC 3161 Time-Stamp Protocol handling. A `TimeStampResp` is what a client
14
- * receives from a TSA -- a `PKIStatusInfo` plus, on success, a `TimeStampToken`;
14
+ * receives from a TSA: a `PKIStatusInfo` plus, on success, a `TimeStampToken`;
15
15
  * `parse` decodes it and enforces the status-to-token coupling (a granted
16
16
  * response carries a token, a rejection does not). A `TimeStampToken` is itself a
17
17
  * CMS SignedData whose encapsulated content is a `TSTInfo`, so `parseToken`
@@ -279,8 +279,8 @@ var parseRequest = pkix.makeParser({ pemLabel: null, PemError: PemError, ErrorCl
279
279
  * @spec RFC 3161
280
280
  * @related pki.schema.tsp.parseToken, pki.schema.tsp.parse
281
281
  *
282
- * Parse a bare `TSTInfo` payload (a DER `Buffer`) -- the structure a timestamp token
283
- * encapsulates -- into `{ version, policy, messageImprint, serialNumber, genTime,
282
+ * Parse a bare `TSTInfo` payload (a DER `Buffer`, the structure a timestamp token
283
+ * encapsulates) into `{ version, policy, messageImprint, serialNumber, genTime,
284
284
  * accuracy, ordering, nonce, tsa, extensions }`. `messageImprint.hashedMessage` is
285
285
  * the raw digest; `serialNumber` / `nonce` are lossless (BigInt + hex); `genTime` is
286
286
  * a `Date` with sub-second precision. A malformed structure throws a typed
@@ -312,7 +312,7 @@ var parseTstInfo = pkix.makeParser({ pemLabel: null, PemError: PemError, ErrorCl
312
312
  *
313
313
  * Parse a DER `Buffer` or a PEM string into a `TimeStampResp`: `{ status,
314
314
  * statusString, failInfo, timeStampToken }`. The status-to-token coupling is
315
- * enforced -- a granted response (status 0/1) carries `timeStampToken` (surfaced raw
315
+ * enforced: a granted response (status 0/1) carries `timeStampToken` (surfaced raw
316
316
  * for `parseToken`), any other status does not. `failInfo` decodes the
317
317
  * `PKIFailureInfo` named bits. A malformed structure throws a typed `TspError`.
318
318
  *
@@ -340,7 +340,7 @@ var parse = pkix.makeParser({ pemLabel: null, PemError: PemError, ErrorClass: Ts
340
340
  * @spec RFC 3161, RFC 5652
341
341
  * @related pki.schema.tsp.parse, pki.schema.cms.parse
342
342
  *
343
- * Parse a `TimeStampToken` (a DER `Buffer` or PEM) -- a CMS SignedData whose
343
+ * Parse a `TimeStampToken` (a DER `Buffer` or PEM): a CMS SignedData whose
344
344
  * encapsulated content is a `TSTInfo`. Composes `pki.schema.cms.parse`, asserts the
345
345
  * `id-ct-TSTInfo` content type (`tsp/wrong-econtent-type`), that the content is
346
346
  * attached (`tsp/detached-token`), the single-signer rule (`tsp/multi-signer`,
@@ -434,7 +434,7 @@ function pemDecode(text, label) { return pkix.pemDecode(text, label || null, Pem
434
434
  * @related pki.schema.tsp.pemDecode
435
435
  *
436
436
  * Wrap DER bytes in a PEM envelope. RFC 3161 defines no standard PEM label, so
437
- * `label` is REQUIRED -- the operator names the envelope explicitly (mirroring
437
+ * `label` is REQUIRED: the operator names the envelope explicitly (mirroring
438
438
  * `pemDecode`, which accepts any label). Omitting it throws `pem/bad-label`.
439
439
  *
440
440
  * @example
@@ -12,7 +12,7 @@
12
12
  *
13
13
  * @intro
14
14
  * X.509 certificate handling per RFC 5280. The seed surface is
15
- * `parse` -- turn a DER or PEM certificate into a structured,
15
+ * `parse`, which turns a DER or PEM certificate into a structured,
16
16
  * fully-decoded object: version, serial, signature algorithm, issuer
17
17
  * and subject distinguished names, validity window (as real `Date`s),
18
18
  * subject public-key info, and the extension list. The parser composes
@@ -49,7 +49,7 @@ var PemError = frameworkError.PemError;
49
49
  * @related pki.schema.x509.pemEncode
50
50
  *
51
51
  * Extract the DER bytes from a PEM block (default label `CERTIFICATE`, the
52
- * RFC 7468 sec. 5 armor -- the canonical-label default every sibling format
52
+ * RFC 7468 sec. 5 armor, the canonical-label default every sibling format
53
53
  * applies). Pass a `label` to enforce a different block type, or an explicit
54
54
  * `null` to take the first block of any type. Throws `PemError` on a
55
55
  * missing / mismatched envelope or a non-base64 body.
package/lib/shbs.js CHANGED
@@ -6,10 +6,9 @@
6
6
  * @nav Signatures
7
7
  * @title Stateful hash-based
8
8
  * @fullname Stateful hash-based signatures: LMS and XMSS
9
- * @intro Stateful hash-based signature VERIFICATION -- HSS/LMS (RFC 8554),
9
+ * @intro Stateful hash-based signature VERIFICATION: HSS/LMS (RFC 8554),
10
10
  * carried in X.509 by RFC 9802 and in CMS by RFC 9708, profiled by NIST
11
- * SP 800-208. Verify only, by deliberate design: stateful hash-based signing
12
- * is catastrophic to get wrong. Each one-time key must be used exactly once,
11
+ * SP 800-208. Verify only. Each one-time key must be used exactly once,
13
12
  * so the private key embeds a monotonic index whose state must advance and
14
13
  * persist atomically across every signature and every process restart. A single
15
14
  * index reuse (a restored VM snapshot, a crashed writer, a concurrent signer)
@@ -222,7 +221,7 @@ function _asBytes(x, label) { return guard.bytes.source(x, ShbsError, "shbs/bad-
222
221
  * @related pki.shbs.verifyLms
223
222
  *
224
223
  * Verify an HSS (Hierarchical Signature System) signature over `message` under
225
- * `publicKey` -- the wire form RFC 9802 (X.509) and RFC 9708 (CMS) carry for
224
+ * `publicKey`, the wire form RFC 9802 (X.509) and RFC 9708 (CMS) carry for
226
225
  * `id-alg-hss-lms-hashsig`. The public key and signature are the raw HSS octet
227
226
  * blobs the certificate / CMS parsers already surface (no ASN.1 wrapping). Every
228
227
  * level of the hierarchy must verify: a single failing level yields false.
@@ -46,7 +46,7 @@ var MLDSA_SUITABLE_DIGEST = {
46
46
  "ML-DSA-65": { sha384: 1, sha512: 1, shake256: 1 },
47
47
  "ML-DSA-87": { sha512: 1, shake256: 1 },
48
48
  };
49
- // @enforced-by behavioral -- an own-property table read has no rename-proof shape distinct from a
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;
52
52
  var row = MLDSA_SUITABLE_DIGEST[mlName];
package/lib/sigstore.js CHANGED
@@ -17,7 +17,7 @@
17
17
  * ephemeral, ~10 minutes); the Rekor inclusion proof folded to a Rekor-signed
18
18
  * tree root; the log entry binding to this exact signature; and the in-toto
19
19
  * subject digest the caller confirms against the published artifact. Verify-only
20
- * and offline -- every input is in the bundle or a caller argument. Reuses the
20
+ * and offline: every input is in the bundle or a caller argument. Reuses the
21
21
  * shipped X.509 parser, RFC 5280 path validator, RFC 9162 Merkle verifier, and
22
22
  * native crypto engine; the net-new codecs are the DSSE PAE byte-builder and a
23
23
  * fail-closed JSON bundle reader.
@@ -102,7 +102,7 @@ function _jsonParse(input, code, label) {
102
102
  * LEN(body) SP body`, where `LEN` is the ASCII-decimal byte length (no leading
103
103
  * zeros) and `type` is the UTF-8 `payloadType`. This is the exact preimage a DSSE
104
104
  * signature covers; `LEN` is over the decoded body byte length, never the base64
105
- * length -- any deviation is a signature-verify bypass.
105
+ * length. Any deviation is a signature-verify bypass.
106
106
  *
107
107
  * @example
108
108
  * var b = pki.sigstore.pae("application/vnd.in-toto+json", Buffer.from("{}"));
package/lib/smime.js CHANGED
@@ -12,11 +12,11 @@
12
12
  * @intro
13
13
  * RFC 8551 S/MIME assembly + verification + encryption over the shipped CMS
14
14
  * layer. `sign` wraps a MIME entity as a signed S/MIME message and `verify`
15
- * unwraps and verifies one, in both forms: `multipart/signed` (clear-signed --
15
+ * unwraps and verifies one, in both forms: `multipart/signed` (clear-signed:
16
16
  * the content stays readable, a detached CMS signature rides alongside) and
17
17
  * `application/pkcs7-mime` (opaque, where the whole entity is a base64 CMS
18
18
  * SignedData). `encrypt` envelopes a MIME entity as an opaque
19
- * `application/pkcs7-mime` message and `decrypt` opens one -- `authEnveloped-data`
19
+ * `application/pkcs7-mime` message and `decrypt` opens one: `authEnveloped-data`
20
20
  * (AES-GCM, confidentiality AND integrity, the default) or `enveloped-data`
21
21
  * (AES-CBC, confidentiality only, so `decrypt` surfaces `authenticated:false`,
22
22
  * the EFAIL / RFC 8551 sec. 3.3 no-integrity caveat). The crypto is entirely
@@ -469,7 +469,7 @@ function _base64Body(der) {
469
469
  * Assemble a signed S/MIME message (RFC 8551). `content` is the payload: a raw body wrapped as a
470
470
  * `text/plain` entity by default, or the caller's own complete MIME entity when `opts.entity` is set;
471
471
  * `signers` is the `pki.cms.sign` signer array (any RSA / RSASSA-PSS / ECDSA / EdDSA / ML-DSA / SLH-DSA
472
- * signer -- the S/MIME layer is algorithm-agnostic). Two forms via `opts.form`:
472
+ * signer: the S/MIME layer is algorithm-agnostic). Two forms via `opts.form`:
473
473
  * - `"multipart"` (default, clear-signed): a `multipart/signed` message carrying the canonical entity
474
474
  * verbatim in the first part and a DETACHED CMS SignedData (`application/pkcs7-signature`) over its
475
475
  * canonical form in the second, with `protocol="application/pkcs7-signature"` + a matching `micalg`.
@@ -490,7 +490,7 @@ function _base64Body(der) {
490
490
  * @opts hcp the Header Confidentiality Policy applied to the OUTER display copies: `"hcp_baseline"` (default) or `"hcp_no_confidentiality"`. A signed message's payload is not encrypted, so this governs presentation, not secrecy; used with `protectHeaders`.
491
491
  * @opts sid forwarded to cms.sign: the SignerIdentifier form, `"issuerAndSerial"` (default) or `"subjectKeyIdentifier"`.
492
492
  * @opts signedAttributes forwarded: `false` omits the signed-attributes set entirely (a bare-signature SignedData).
493
- * @opts additionalSignedAttributes forwarded: extra signed attributes to carry, as `[{ oid, values }]`.
493
+ * @opts additionalSignedAttributes forwarded: extra signed attributes to carry, as `[{ type, values }]`.
494
494
  * @example
495
495
  * var pair = await pki.key.generate("Ed25519");
496
496
  * var signerKeyPkcs8 = await pki.key.export(pair.privateKey);
@@ -547,7 +547,7 @@ function _capped(msg) {
547
547
  *
548
548
  * `valid` and `trusted` are separate claims, exactly as in `cms.verify`: a SignedData carries its own
549
549
  * certificates, so `valid` says the signature is sound under one of them and nothing about who signed.
550
- * Name the roots you accept in `opts.trustAnchors` and `trusted` says every signer chained to one --
550
+ * Name the roots you accept in `opts.trustAnchors` and `trusted` says every signer chained to one,
551
551
  * validated for EMAIL, at both ends of the chain. The signer certificate must carry the
552
552
  * `emailProtection` key purpose (RFC 8551 sec. 4.4.4), because a certificate restricted to `serverAuth`
553
553
  * chains to its root perfectly well and is still the wrong key to have signed a message; and the anchor's
@@ -557,8 +557,8 @@ function _capped(msg) {
557
557
  * A `micalg`
558
558
  * that disagrees with the actual digest is advisory unless `opts.strictMicalg` (then `smime/micalg-mismatch`).
559
559
  * If the message is header-protected (RFC 9788), `protectedHeaders` is the AUTHENTICATED inner header set (a
560
- * tampered outer header cannot alter it) and `headerProtection` is `{ present, mode, fromMismatch, confidential, legacy }`
561
- * -- `present` is `true` only for cryptographically-DECLARED (`hp=`) protection you may trust; `fromMismatch` is
560
+ * tampered outer header cannot alter it) and `headerProtection` is `{ present, mode, fromMismatch, confidential, legacy }`.
561
+ * `present` is `true` only for cryptographically-DECLARED (`hp=`) protection you may trust; `fromMismatch` is
562
562
  * `true` when the outer From differs from the protected one, `false` when they agree, and `null` when there was
563
563
  * no protected From to compare against, which is every message without header protection. Test it against
564
564
  * `false` rather than for falsiness: `!fromMismatch` treats the unanswered case as a passed check, and that is
@@ -569,7 +569,7 @@ function _capped(msg) {
569
569
  * whose declared `hp` is malformed, invalid, or contradicts the envelope fails closed (`smime/bad-header-protection`),
570
570
  * never a silent downgrade. `legacy` is `null` unless `opts.legacyHeaderProtection` detected a legacy RFC 8551
571
571
  * `message/rfc822` wrap (see that option), in which case it is its own `{ headers, mode, fromMismatch, confidential }`
572
- * object (`headers` an ordered `[{ name, value }]` array that retains legally-repeated fields like `Received`) -- a
572
+ * object (`headers` an ordered `[{ name, value }]` array that retains legally-repeated fields like `Received`). A
573
573
  * legacy inference is never placed in `protectedHeaders` and never sets `present: true`, because it is
574
574
  * indistinguishable from an ordinary forwarded `message/rfc822`, so a caller keying trust off `present` /
575
575
  * `protectedHeaders` cannot mistake the opt-in heuristic for authenticated headers.
@@ -582,12 +582,12 @@ function _capped(msg) {
582
582
  * extension carries none, from the subject DN's PKCS #9 `emailAddress` attribute, which RFC 8550 sec. 3
583
583
  * requires a receiving agent to recognize. Where both are present the extension wins. Only a signer
584
584
  * whose signature verified contributes an identity, so a tampered message cannot report a binding. `match` is THREE-valued and a caller enforcing sender binding tests
585
- * `match === true` -- `false` means every identity was comparable and none matched, and `null` means the
585
+ * `match === true`; `false` means every identity was comparable and none matched, and `null` means the
586
586
  * question was not answered (no `expectedSender` and no single outer `From`, a signer certificate
587
587
  * asserting no readable email identity, or an internationalized address needing an IDNA transform this
588
588
  * toolkit does not perform). `null` is not a pass. `sender.identities` lists what the certificate
589
589
  * actually asserts, `sender.checked` whether a comparison ran, and `sender.source` which input it ran
590
- * against -- `"from"` is ADVISORY, because on a message without header protection the outer From is
590
+ * against. `"from"` is ADVISORY, because on a message without header protection the outer From is
591
591
  * attacker-controlled.
592
592
  *
593
593
  * @opts certs extra signer certificates (DER `Buffer`s) to match, forwarded to `cms.verify`.
@@ -687,7 +687,7 @@ function _cmsEncryptOpts(opts) {
687
687
  * @related pki.smime.decrypt, pki.cms.encrypt
688
688
  *
689
689
  * Envelope a MIME entity as an encrypted S/MIME message (RFC 8551 sec. 3.3 / sec. 3.4). `content` is the
690
- * payload -- a raw body wrapped as a `text/plain` entity by default, or the caller's own complete MIME
690
+ * payload: a raw body wrapped as a `text/plain` entity by default, or the caller's own complete MIME
691
691
  * entity when `opts.entity` is set; `recipients` is the `pki.cms.encrypt` recipient array (any RSA-OAEP
692
692
  * ktri / EC or X25519/X448 kari / ML-KEM ori-KEM / password pwri / kek kekri: the S/MIME layer is
693
693
  * recipient-agnostic; a single descriptor is accepted and normalized to a one-element array). Enveloping
@@ -697,7 +697,7 @@ function _cmsEncryptOpts(opts) {
697
697
  * with `smime-type=enveloped-data` (confidentiality only, no integrity, RFC 8551 sec. 3.3). With
698
698
  * `opts.protectHeaders`, the message is header-protected (RFC 9788): the real `opts.headers` are inlined
699
699
  * inside the ciphertext (the payload Content-Type gains `hp="cipher"`), and only the Header-Confidentiality-
700
- * Policy-processed display copies appear outside -- the default `hcp_baseline` obscures Subject to `[...]`
700
+ * Policy-processed display copies appear outside. The default `hcp_baseline` obscures Subject to `[...]`
701
701
  * and removes Comments / Keywords, so those values live only in the ciphertext; `decrypt` recovers the real
702
702
  * inner set. Returns the assembled message bytes. Fail-closed with `SmimeError`.
703
703
  *
@@ -740,7 +740,7 @@ async function encrypt(content, recipients, opts) {
740
740
  * @spec RFC 8551, RFC 5652, RFC 5083, RFC 9788
741
741
  * @related pki.smime.encrypt, pki.cms.decrypt, pki.smime.verify
742
742
  *
743
- * Open an encrypted S/MIME message (RFC 8551 sec. 3.3 / sec. 3.4) -- an `application/pkcs7-mime` entity
743
+ * Open an encrypted S/MIME message (RFC 8551 sec. 3.3 / sec. 3.4), an `application/pkcs7-mime` entity
744
744
  * whose base64 body is a CMS EnvelopedData or AuthEnvelopedData. `keyMaterial` is the `pki.cms.decrypt`
745
745
  * key material (`{ key, cert }`, `{ password }`, or `{ kek, kekId? }`). Returns the recovered inner MIME
746
746
  * entity as `content`, the `smimeType`, `authenticated` (true only for AuthEnvelopedData; a CBC
@@ -753,7 +753,7 @@ async function encrypt(content, recipients, opts) {
753
753
  * (RFC 9788, `hp="cipher"`), `protectedHeaders` is the recovered real inner header set (the values the outer
754
754
  * Header Confidentiality Policy hid) and `headerProtection` is `{ present, mode, fromMismatch, confidential, legacy }`,
755
755
  * where `present` is `true` only for a declared `hp=` payload, and `confidential` names the fields the composer
756
- * kept end-to-end confidential (via the authenticated HP-Outer records, RFC 9788 sec. 4.3) -- so a caller can
756
+ * kept end-to-end confidential (via the authenticated HP-Outer records, RFC 9788 sec. 4.3), so a caller can
757
757
  * reply/forward without leaking them (sec. 6.1); a payload whose `hp` is malformed or contradicts the envelope
758
758
  * fails closed (`smime/bad-header-protection`). `legacy` is `null` unless `opts.legacyHeaderProtection` detected a
759
759
  * legacy RFC 8551 `message/rfc822` wrap (its own `{ headers, mode, fromMismatch, confidential }` object, where `headers`
@@ -806,7 +806,7 @@ async function decrypt(message, keyMaterial, opts) {
806
806
  * @related pki.smime.decompress, pki.cms.compress
807
807
  *
808
808
  * Compress a MIME entity as an opaque compressed S/MIME message (RFC 8551 sec. 3.6). `content` is the
809
- * payload -- a raw body wrapped as a `text/plain` entity by default, or the caller's own complete MIME
809
+ * payload: a raw body wrapped as a `text/plain` entity by default, or the caller's own complete MIME
810
810
  * entity when `opts.entity` is set. The entity is canonicalized (RFC 8551 sec. 3.1) and ZLIB-compressed
811
811
  * into a CMS `CompressedData` (`pki.cms.compress`), carried opaque in one `application/pkcs7-mime;
812
812
  * smime-type=compressed-data; name=smime.p7z` entity (base64). Compression is a size transform with NO
@@ -838,7 +838,7 @@ async function compress(content, opts) {
838
838
  * @spec RFC 8551, RFC 3274
839
839
  * @related pki.smime.compress, pki.cms.decompress, pki.smime.verify, pki.smime.decrypt
840
840
  *
841
- * Decompress a compressed S/MIME message (RFC 8551 sec. 3.6) -- an `application/pkcs7-mime` entity whose
841
+ * Decompress a compressed S/MIME message (RFC 8551 sec. 3.6), an `application/pkcs7-mime` entity whose
842
842
  * base64 body is a CMS `CompressedData`. Returns the recovered inner MIME entity as `content` plus the
843
843
  * inner `contentType` / `contentTypeName` and the `compressionAlgorithm`. The inflate is BOUNDED (a
844
844
  * decompression-bomb defense, `cms/decompress-too-large`; `opts.maxOutputBytes` tightens it downward).
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * @intro
13
13
  * TLS handshake structures that carry certificates. `decompressCertificate`
14
- * and `compressCertificate` are the RFC 8879 `CompressedCertificate` codec --
14
+ * and `compressCertificate` are the RFC 8879 `CompressedCertificate` codec:
15
15
  * the compressed form of a TLS 1.3 `Certificate` message, which shrinks the
16
16
  * largest thing a handshake sends and matters most for post-quantum chains,
17
17
  * where certificates grow by kilobytes. `parseCertificateMessage` decodes the
@@ -30,10 +30,10 @@
30
30
  * allocated), and the output must then equal that length exactly (which catches
31
31
  * the under-length direction a cap cannot see). The caller's policy cap applies
32
32
  * independently, so a peer declaring 16 MiB does not get 16 MiB. This module
33
- * decodes structure only -- it never verifies a certificate, builds a path, or
33
+ * decodes structure only. It never verifies a certificate, builds a path, or
34
34
  * speaks the handshake.
35
35
  *
36
- * All three registered algorithms -- zlib, brotli and zstd -- are implemented,
36
+ * All three registered algorithms (zlib, brotli and zstd) are implemented,
37
37
  * and each is offered only where the running Node can decompress it safely. A
38
38
  * decompressor must fault on a frame it could not finish; where one instead
39
39
  * returns a short result and reports the whole input consumed, a peer could cut
@@ -44,7 +44,7 @@
44
44
  *
45
45
  * @card
46
46
  * Encode and decode RFC 8879 TLS compressed certificate messages and the
47
- * RFC 8446 Certificate message inside them -- a two-sided decompression
47
+ * RFC 8446 Certificate message inside them: a two-sided decompression
48
48
  * bound, exact-length enforcement, per-entry certificate DER surfaced raw,
49
49
  * fail-closed. All three registered algorithms are implemented; each is
50
50
  * offered only where the running Node decompresses it safely.
@@ -138,7 +138,7 @@ function _resolveAllowed(opts) {
138
138
  * body is a framing violation (`opaque<1..2^24-1>`), not an empty certificate list.
139
139
  *
140
140
  * Throws `TlsError` with a stable `tls/*` code on any malformed input, never a raw
141
- * `TypeError`. Structure only -- no certificate here is verified or path-built.
141
+ * `TypeError`. Structure only: no certificate here is verified or path-built.
142
142
  *
143
143
  * @opts
144
144
  * maxOutputBytes - tighten the decompression cap DOWNWARD from the RFC 8446 sec. 4
@@ -221,8 +221,8 @@ function decompressCertificate(bytes, opts) {
221
221
  *
222
222
  * Decode an RFC 8446 sec. 4.4.2 `Certificate` message into its
223
223
  * `certificateRequestContext` (raw, empty in a server's handshake certificate) and its
224
- * `entries`. Each entry surfaces `certData` -- the certificate DER exactly as it appeared
225
- * on the wire, ready for `pki.schema.x509.parse` and never re-serialized, plus the raw
224
+ * `entries`. Each entry surfaces `certData` (the certificate DER exactly as it appeared
225
+ * on the wire, ready for `pki.schema.x509.parse` and never re-serialized), plus the raw
226
226
  * `extensions` bytes that follow it and `extensionList`, those bytes decoded to their
227
227
  * RFC 8446 sec. 4.2 records (`type` and raw `data` per extension). The vector's framing is
228
228
  * validated and not accepted opaquely, so a vector that cannot be a whole number of
package/lib/trust.js CHANGED
@@ -24,8 +24,8 @@
24
24
  * Everything is fail-closed and offline: the caller supplies the text (no
25
25
  * network fetch); every malformed or oversized input throws a typed
26
26
  * `trust/*` error before the offending allocation; a certificate object and
27
- * its trust object are paired by byte-exact (CKA_ISSUER, CKA_SERIAL_NUMBER)
28
- * -- never by adjacency -- and cross-checked against the parsed DER, so
27
+ * its trust object are paired by byte-exact (CKA_ISSUER, CKA_SERIAL_NUMBER),
28
+ * never by adjacency, and cross-checked against the parsed DER, so
29
29
  * trust metadata can never attach to the wrong root; only
30
30
  * `CKT_NSS_TRUSTED_DELEGATOR` grants a purpose (everything else, including
31
31
  * an absent bit, is untrusted).
@@ -441,9 +441,9 @@ function _dedupAnchors(anchors) {
441
441
  * Parse the Mozilla/NSS `certdata.txt` root-store object stream into
442
442
  * constraint-carrying trust anchors. Each CKO_CERTIFICATE object's
443
443
  * MULTILINE_OCTAL `CKA_VALUE` is decoded and parsed as a DER certificate; the
444
- * paired CKO_NSS_TRUST object -- joined by byte-exact CKA_ISSUER +
444
+ * paired CKO_NSS_TRUST object (joined by byte-exact CKA_ISSUER +
445
445
  * CKA_SERIAL_NUMBER, never adjacency, and cross-checked against the parsed
446
- * DER -- contributes the purpose trust bits (only CKT_NSS_TRUSTED_DELEGATOR
446
+ * DER) contributes the purpose trust bits (only CKT_NSS_TRUSTED_DELEGATOR
447
447
  * grants a purpose); the per-purpose distrust-after dates ride in the
448
448
  * certificate object as bare ASCII times routed through the strict DER time
449
449
  * reader. Every anchor carries the exact `{ name, publicKey, algorithm,
@@ -641,7 +641,7 @@ function _pemCell(cell) {
641
641
  * (`Common Name or Certificate Name`, `Trust Bits`, `Distrust for TLS After
642
642
  * Date`, `Distrust for S/MIME After Date`, `PEM Info`) fails closed with
643
643
  * `trust/bad-csv`. Fields follow RFC 4180 quoting (embedded commas, newlines,
644
- * doubled-quote escapes -- the PEM Info column depends on it). `Trust Bits`
644
+ * doubled-quote escapes; the PEM Info column depends on it). `Trust Bits`
645
645
  * is set-valued (Websites -> serverAuth, Email -> emailProtection, Code ->
646
646
  * codeSigning; absent -> untrusted). A DATE-only distrust cell expands to the
647
647
  * end-of-day `...T23:59:59Z` instant, matching the NSS `...235959Z`
package/lib/tsp-sign.js CHANGED
@@ -96,8 +96,8 @@ function _signingCertV2(certDer, hashName) {
96
96
  * @spec RFC 3161
97
97
  * @related pki.schema.tsp.parseToken, pki.cms.sign
98
98
  *
99
- * Create an RFC 3161 TimeStampToken over `messageImprint` (`{ hashAlgorithm, hashedMessage }`
100
- * -- the hash of the data being timestamped, computed by the requester). `tsa` is the
99
+ * Create an RFC 3161 TimeStampToken over `messageImprint` (`{ hashAlgorithm, hashedMessage }`:
100
+ * the hash of the data being timestamped, computed by the requester). `tsa` is the
101
101
  * timestamp authority's `{ cert, key }` (as `pki.cms.sign` takes them). The token is a CMS
102
102
  * SignedData whose content is a `TSTInfo` carrying the imprint, the TSA policy, a serial
103
103
  * number, and `genTime`; the RFC 3161 sec. 2.4.2 signing-certificate attribute binding the
@@ -110,6 +110,8 @@ function _signingCertV2(certDer, hashName) {
110
110
  * @opts accuracy The genTime +/- accuracy, as `{ seconds?, millis?, micros? }`.
111
111
  * @opts ordering Whether tokens from this TSA are strictly ordered in time (boolean).
112
112
  * @opts certHashAlgorithm The ESSCertIDv2 hash algorithm name. Default `sha256`.
113
+ * @opts digestAlgorithm / pss Passed through to `pki.cms.sign` (the signer digest algorithm, RSA-PSS padding).
114
+ * @opts additionalSignedAttributes Extra signed attributes to carry on the token, as `[{ type, values }]` (forwarded to `pki.cms.sign`).
113
115
  * @opts sid / pem Passed through to `pki.cms.sign` (signer identifier, PEM output).
114
116
  * @example
115
117
  * var pair = await pki.key.generate("Ed25519");
@@ -303,7 +305,7 @@ function request(messageImprint, opts) {
303
305
  * @spec RFC 3161
304
306
  * @related pki.tsp.request, pki.schema.tsp.parseRequest
305
307
  *
306
- * Parse a `TimeStampReq` (DER `Buffer` or PEM) -- the `pki.schema.tsp.parseRequest` decoder on the
308
+ * Parse a `TimeStampReq` (DER `Buffer` or PEM), the `pki.schema.tsp.parseRequest` decoder on the
307
309
  * `pki.tsp` namespace. Returns `{ version, messageImprint, reqPolicy, reqPolicyName, nonce,
308
310
  * nonceHex, certReq, extensions }`; a malformed structure throws a typed `TspError`.
309
311
  *
@@ -382,7 +384,7 @@ function response(token, opts) {
382
384
  * @spec RFC 3161
383
385
  * @related pki.tsp.response, pki.schema.tsp.parse
384
386
  *
385
- * Parse a `TimeStampResp` (DER `Buffer` or PEM) -- the shipped `pki.schema.tsp.parse` decoder on
387
+ * Parse a `TimeStampResp` (DER `Buffer` or PEM), the shipped `pki.schema.tsp.parse` decoder on
386
388
  * the `pki.tsp` namespace. Returns `{ status, statusString, failInfo, timeStampToken }` with the
387
389
  * status-to-token coupling enforced; a granted response's token is decoded via `parseToken`.
388
390
  *
@@ -535,7 +537,7 @@ function _buildTsaChains(leaf, pool) {
535
537
  * original bytes (hashed under the token's messageImprint algorithm) or a precomputed
536
538
  * `{ hashAlgorithm, hashedMessage }`. Returns `{ valid, trusted, revocationChecked,
537
539
  * anchorConstraints, genTime, accuracy, serialNumber,
538
- * serialNumberHex, policy, nonce, tsa, tstInfo, signer, code?, reason? }`. `valid` is true only
540
+ * serialNumberHex, policy, policyName, nonce, tsa, tstInfo, signer, code?, reason? }`. `valid` is true only
539
541
  * when the CMS signature, the imprint match, the eContentType, the ESSCertID(V2) binding, the
540
542
  * RFC 3161 sec. 2.3 critical single-`timeStamping` extendedKeyUsage rule, the requested nonce (when
541
543
  * supplied), and, when `trustAnchors` is supplied, the full out-of-path TSA-cert path
@@ -603,7 +605,7 @@ async function verify(token, data, opts) {
603
605
  var revocationChecked = false;
604
606
  var anchorConstraints = null;
605
607
  function fail(code, reason) {
606
- return { valid: false, trusted: false, revocationChecked: revocationChecked, anchorConstraints: anchorConstraints, code: code, reason: reason || null, genTime: tst.genTime, accuracy: tst.accuracy, serialNumber: tst.serialNumber, serialNumberHex: tst.serialNumberHex, policy: tst.policy, nonce: tst.nonce, tsa: tst.tsa, tstInfo: tst, signer: null };
608
+ return { valid: false, trusted: false, revocationChecked: revocationChecked, anchorConstraints: anchorConstraints, code: code, reason: reason || null, genTime: tst.genTime, accuracy: tst.accuracy, serialNumber: tst.serialNumber, serialNumberHex: tst.serialNumberHex, policy: tst.policy, policyName: tst.policyName, nonce: tst.nonce, tsa: tst.tsa, tstInfo: tst, signer: null };
607
609
  }
608
610
  var cmsRes = await cmsVerify.verify(tokenDer, { certs: opts.certs });
609
611
  var signer = cmsRes.signers[0];
package/lib/webauthn.js CHANGED
@@ -17,7 +17,7 @@
17
17
  * `pki.path.validate` is the caller's step: this module verifies the statement, not
18
18
  * the certificate chain. A verifier, not a ceremony client: the relying party
19
19
  * supplies the clientDataHash + any trust anchors; this module never touches a
20
- * socket. Fail-closed -- every malformed shape or failed check throws a typed
20
+ * socket. Fail-closed: every malformed shape or failed check throws a typed
21
21
  * `WebauthnError`, never a partial verdict.
22
22
  * @spec W3C WebAuthn Level 3 sec. 6.5 / 8, RFC 9052 (COSE)
23
23
  * @card Verify a WebAuthn / passkey attestation (packed / tpm / android-key / apple / fido-u2f / none).
@@ -119,8 +119,8 @@ function _decodeCoseKey(node) {
119
119
  * @spec RFC 9052, W3C WebAuthn Level 3 sec. 6.5.1
120
120
  * @related pki.webauthn.verify, pki.webauthn.verifyAssertion
121
121
  *
122
- * Decode a bare COSE_Key -- the credential public key a relying party stored at
123
- * registration -- back into the object `verifyAssertion` takes. `pki.webauthn.verify`
122
+ * Decode a bare COSE_Key, the credential public key a relying party stored at
123
+ * registration, back into the object `verifyAssertion` takes. `pki.webauthn.verify`
124
124
  * returns that object, but the durable form is bytes: the object carries `Buffer`
125
125
  * values, so a JSON round trip through a datastore yields
126
126
  * `{"type":"Buffer","data":[...]}` in place of the object that went in, and existing
@@ -279,7 +279,7 @@ function _findExt(cert, oidName) {
279
279
  * authData}`) and its authenticatorData, fail-closed. `authData` carries the decoded
280
280
  * rpIdHash / flags / signCount and, when the AT flag is set, the attestedCredentialData
281
281
  * (aaguid, credentialId, and the decoded COSE `credentialPublicKey`). `authDataBytes`
282
- * is the raw authenticatorData -- the exact bytes an attestation signature covers.
282
+ * is the raw authenticatorData, the exact bytes an attestation signature covers.
283
283
  * A malformed object throws `webauthn/bad-attestation-object`.
284
284
  *
285
285
  * @example
@@ -820,7 +820,7 @@ function _checkAndroidKeyDescription(cert, clientDataHash) {
820
820
  * The verdict field is `attestationVerified`, and the name is the point: a sound
821
821
  * attestation statement is not the same claim as an acceptable registration. The
822
822
  * statement says nothing about which relying party asked for it, or whether a user
823
- * was present -- so an attestation naming another origin's RP ID, with user presence
823
+ * was present, so an attestation naming another origin's RP ID, with user presence
824
824
  * clear, is perfectly sound and must not be registered. Supply `expectedRpId`,
825
825
  * `requireUserPresence`, `requireUserVerification` and `allowedAlgorithms` and those
826
826
  * are checked here; `bindingChecked` reports which ran, so a check that passed can be
@@ -834,18 +834,18 @@ function _checkAndroidKeyDescription(cert, clientDataHash) {
834
834
  * The verdict also carries what a relying party must STORE to run a later login:
835
835
  * `credentialId`, `credentialPublicKey` and the initial `signCount`. The credential key
836
836
  * comes back in both forms: the decoded object, and `credentialPublicKeyBytes`, which is
837
- * what a credential row should hold -- the object carries `Buffer` values, so a JSON round
837
+ * what a credential row should hold. The object carries `Buffer` values, so a JSON round
838
838
  * trip through a datastore returns `{"type":"Buffer","data":[...]}` in place of the object
839
839
  * that went in. `pki.webauthn.parseCoseKey` reads those bytes back, and
840
840
  * `verifyAssertion` accepts either form.
841
841
  *
842
- * @intro This verifies the attestation STATEMENT -- the signature and the format's
842
+ * @intro This verifies the attestation STATEMENT: the signature and the format's
843
843
  * structural bindings (the x5c leaf key == credential key, the apple nonce, the tpm
844
844
  * certInfo Name/extraData, the android KeyDescription, the fido-u2f verificationData).
845
845
  * Chaining the returned `trustPath` (the x5c certificates in `pki.path.validate`
846
- * order -- anchor-adjacent first, leaf last) to a trusted root is a separate step,
846
+ * order: anchor-adjacent first, leaf last) to a trusted root is a separate step,
847
847
  * and there are three ways to take it. Pass `opts.metadata`, a
848
- * `pki.webauthn.verifyMetadataBlob` result -- and the authenticator's registered
848
+ * `pki.webauthn.verifyMetadataBlob` result. The authenticator's registered
849
849
  * attestation roots are resolved from its own identifier and the trust path is
850
850
  * required to reach one, so an unlisted or revoked model is refused and never
851
851
  * reported as verified. Pass `opts.rootCertificates` and the path is required to
@@ -858,7 +858,7 @@ function _checkAndroidKeyDescription(cert, clientDataHash) {
858
858
  * roots are a stronger claim than a static pin and its status reports can
859
859
  * disqualify a model those roots would still accept. `anchoredTo` reports which
860
860
  * route ran, naming every route that contributed and joining them with `+` when more
861
- * than one did -- `"metadata"`, `"rootCertificates"`, and `"safetyNetRoots"` for the
861
+ * than one did: `"metadata"`, `"rootCertificates"`, and `"safetyNetRoots"` for the
862
862
  * android-safetynet chain, which anchors through the roots that format requires whether
863
863
  * or not either other route was asked for. It is `null` only when nothing anchored the
864
864
  * path. On the mixed metadata/pinned-root route `metadata` still carries the
@@ -1091,14 +1091,14 @@ void constants;
1091
1091
  * @spec FIDO Metadata Service v3.0 sec. 3.1, RFC 7515
1092
1092
  * @related pki.webauthn.verify, pki.webauthn.metadataFor
1093
1093
  *
1094
- * Verify a FIDO Metadata Service BLOB -- the signed catalogue of every registered
1095
- * authenticator model, its attestation roots, and its certification status, and
1094
+ * Verify a FIDO Metadata Service BLOB (the signed catalogue of every registered
1095
+ * authenticator model, its attestation roots, and its certification status), and
1096
1096
  * return its entries indexed by aaguid for lookup. `blob` is caller-supplied bytes or
1097
1097
  * a string; retrieval is out of scope, so this never touches the network.
1098
1098
  *
1099
1099
  * The BLOB is a JWS. Its signature is checked under the certificate in its own header,
1100
1100
  * that chain is validated to one of `opts.rootCertificates`, and only THEN is the
1101
- * payload read -- a BLOB that does not verify never reaches the JSON parser. `no` must
1101
+ * payload read. A BLOB that does not verify never reaches the JSON parser. `no` must
1102
1102
  * exceed `opts.previousNo` (rollback) and `nextUpdate` must not have passed
1103
1103
  * (freshness). Every failure is a typed `webauthn/metadata-*` throw, never a partial
1104
1104
  * result.
@@ -1224,7 +1224,7 @@ var CLIENT_DATA_TYPE = Object.assign(Object.create(null), { "webauthn.create": 1
1224
1224
  * @defends webauthn-ceremony-confusion (CWE-345)
1225
1225
  * @related pki.webauthn.verify, pki.webauthn.verifyAssertion
1226
1226
  *
1227
- * Decode the `clientDataJSON` a ceremony returns -- the half of a WebAuthn response
1227
+ * Decode the `clientDataJSON` a ceremony returns, the half of a WebAuthn response
1228
1228
  * the signature covers by digest but that no signature check ever looks inside.
1229
1229
  * Parsed through the shared fail-closed JSON guard (bounded bytes and depth,
1230
1230
  * fatal UTF-8, duplicate members refused, no prototype pollution), because these
@@ -1233,7 +1233,7 @@ var CLIENT_DATA_TYPE = Object.assign(Object.create(null), { "webauthn.create": 1
1233
1233
  * value; `type`, `origin`, `crossOrigin` and `topOrigin` come back as they were.
1234
1234
  *
1235
1235
  * Supply `expectedType`, `expectedChallenge`, `expectedOrigin` and
1236
- * `expectedTopOrigin` and each is checked here -- the challenge in constant time
1236
+ * `expectedTopOrigin` and each is checked here: the challenge in constant time
1237
1237
  * and by full value, the origins whole and case-sensitively. `checked`
1238
1238
  * reports which ran, so a check that passed is distinguishable from one that never
1239
1239
  * happened. `expectedType` is worth setting on every call: the ceremony a response
@@ -1418,7 +1418,7 @@ var _ASSERT_OPTS = Object.assign(Object.create(null), {
1418
1418
  *
1419
1419
  * Verify an authentication assertion's signature: the authenticator signs
1420
1420
  * `authenticatorData || SHA-256(clientDataJSON)` as raw bytes with the credential
1421
- * key registered earlier -- no COSE_Sign1 wrapper, so a COSE message verifier is
1421
+ * key registered earlier: no COSE_Sign1 wrapper, so a COSE message verifier is
1422
1422
  * the wrong tool and fails on structure before it ever reaches the signature. An
1423
1423
  * ES256 assertion signature is an ASN.1 DER `SEQUENCE { r, s }`, converted here
1424
1424
  * with the same order-aware reader the attestation path uses, so an r or s outside
@@ -1428,10 +1428,13 @@ var _ASSERT_OPTS = Object.assign(Object.create(null), {
1428
1428
  * registered credential key produced this response. What makes the response
1429
1429
  * ACCEPTABLE is the sec. 7.2 binding, and the caller owns most of it. Supply
1430
1430
  * `expectedRpId`, `requireUserPresence`, `requireUserVerification` and
1431
- * `allowedAlgorithms` and they are checked here -- `bindingChecked` reports which
1431
+ * `allowedAlgorithms` and they are checked here. `bindingChecked` reports which
1432
1432
  * ones ran, so a check that passed is distinguishable from one that never
1433
- * happened. The CHALLENGE and the ORIGIN stay with the caller: both live in
1434
- * clientDataJSON and are compared against state only the relying party has.
1433
+ * happened. Supply `expectedChallenge`, `expectedOrigin`, or `expectedTopOrigin`
1434
+ * together with `clientDataJSON` and the challenge and origin are checked here
1435
+ * against it; omit them and they stay with the caller to compare against the
1436
+ * clientDataJSON this call surfaces. Passing them with only `clientDataHash`
1437
+ * throws, because there is no clientDataJSON to check them against.
1435
1438
  *
1436
1439
  * Pass `previousSignCount` (the value stored at registration or the last login) and
1437
1440
  * the sec. 7.2 step 21 counter rule is applied: a counter that fails to advance is
@@ -1447,6 +1450,7 @@ var _ASSERT_OPTS = Object.assign(Object.create(null), {
1447
1450
  * credentialPublicKey -- the stored COSE key (as parseAttestationObject surfaced it)
1448
1451
  * previousSignCount -- the stored counter, enabling the sec. 7.2 step 21 rule
1449
1452
  * expectedRpId, requireUserPresence, requireUserVerification, allowedAlgorithms: the bindings above
1453
+ * expectedChallenge, expectedOrigin, expectedTopOrigin -- checked against clientDataJSON when supplied (needs clientDataJSON, not clientDataHash)
1450
1454
  *
1451
1455
  * @example
1452
1456
  * // requires: `assertion` -- credential.response from navigator.credentials.get();
package/lib/webcrypto.js CHANGED
@@ -20,7 +20,7 @@
20
20
  * Unlike the browser's built-in `crypto.subtle`, this engine is
21
21
  * **PQC-first without being PQC-only**: the FIPS 204 ML-DSA and FIPS
22
22
  * 205 SLH-DSA signature suites sit alongside the full classical set PKI
23
- * still runs on -- RSASSA-PKCS1-v1_5, RSA-PSS, RSA-OAEP, ECDSA, ECDH,
23
+ * still runs on: RSASSA-PKCS1-v1_5, RSA-PSS, RSA-OAEP, ECDSA, ECDH,
24
24
  * Ed25519 / Ed448, AES-GCM / CBC / KW, HMAC, HKDF, PBKDF2, the SHA family
25
25
  * (including legacy SHA-1 for old certificates and signatures), and the
26
26
  * SHAKE128 / SHAKE256 extendable-output functions as message digests.
@@ -193,8 +193,8 @@ var SECRET_KEY_NAMES = intrinsic.assign(intrinsic.create(null), { "AES-GCM": tru
193
193
  *
194
194
  * Opaque handle to key material, matching the W3C `CryptoKey` shape:
195
195
  * `{ type, extractable, algorithm, usages }`. The underlying
196
- * `node:crypto` KeyObject is non-enumerable and never serialized --
197
- * extract material only through `subtle.exportKey`, and only when the key
196
+ * `node:crypto` KeyObject is non-enumerable and never serialized.
197
+ * Extract material only through `subtle.exportKey`, and only when the key
198
198
  * was created `extractable`. Instances are produced by
199
199
  * `subtle.generateKey` / `subtle.importKey`; the constructor is rarely
200
200
  * called directly.
package/lib/x509-sign.js CHANGED
@@ -195,13 +195,13 @@ function _hasCriticalSan(extSpec) {
195
195
  * @defends forged-certificate-issuance (CWE-347)
196
196
  * @related pki.schema.x509.parse, pki.path.validate, pki.cms.sign
197
197
  *
198
- * Build, sign, and DER-encode an X.509 certificate. `spec` describes the certificate to issue --
198
+ * Build, sign, and DER-encode an X.509 certificate. `spec` describes the certificate to issue:
199
199
  * `subject` (a string CN, an array of RDNs, or raw Name DER), `subjectPublicKey` (the SPKI DER of the
200
200
  * key being certified), `notBefore` / `notAfter` (`Date`s), an optional `serialNumber`, and an optional
201
201
  * `extensions` object. `issuer` is the signing side: `{ key }` alone issues a self-signed certificate
202
202
  * (issuer = subject, signed with the subject's own key); `{ name, publicKey, key }` or `{ cert, key }`
203
- * issues a CA-signed one. The signing key `key` is a WebCrypto `CryptoKey` -- a `pki.key.generate`
204
- * private key passed directly, without exporting -- or a PKCS#8 private key as DER (`Buffer`) or PEM
203
+ * issues a CA-signed one. The signing key `key` is a WebCrypto `CryptoKey` (a `pki.key.generate`
204
+ * private key passed directly, without exporting) or a PKCS#8 private key as DER (`Buffer`) or PEM
205
205
  * (`string`); a public or secret CryptoKey, or a `node:crypto` KeyObject, is refused. A `subjectAltName`
206
206
  * (or any `GeneralName`) entry may be a form object (`{ dNSName: "..." }`) or a bare string classified
207
207
  * fail-closed into its form (`"host.example"`, `"a@b.example"`, `"10.0.0.1"`, `"https://host.example/"`).
@@ -213,8 +213,8 @@ function _hasCriticalSan(extSpec) {
213
213
  * (positive, <= 20 octets), the validity UTCTime/GeneralizedTime cutover, the DER DEFAULT omissions
214
214
  * (v1 tag, `critical=FALSE`, `cA=FALSE`), and the CA cross-field rules (keyCertSign and
215
215
  * pathLenConstraint require cA=TRUE) are all enforced; a violation throws a typed `CertificateError`.
216
- * Where the spec carries raw DER -- a `Name` Buffer, a pre-encoded `Extension`, an issuer `publicKey`
217
- * SPKI -- a structural fault throws `CertificateError`, while a malformed leaf inside those bytes
216
+ * Where the spec carries raw DER (a `Name` Buffer, a pre-encoded `Extension`, an issuer `publicKey`
217
+ * SPKI), a structural fault throws `CertificateError`, while a malformed leaf inside those bytes
218
218
  * throws `Asn1Error`, the same two-error contract the parsers present.
219
219
  *
220
220
  * @opts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/pki",
3
- "version": "0.6.29",
3
+ "version": "0.6.30",
4
4
  "description": "Pure-JavaScript PKI toolkit that owns its stack — X.509, ASN.1/DER, CMS, PQC-first.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",
package/sbom.cdx.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.5",
5
- "serialNumber": "urn:uuid:e72c9e5f-07a6-48ad-bf71-a361b1470bef",
5
+ "serialNumber": "urn:uuid:7606eb0a-d4b1-46ef-ab6c-eae467d83dd7",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-09-03T05:34:38.589Z",
8
+ "timestamp": "2026-09-04T06:04:55.759Z",
9
9
  "lifecycles": [
10
10
  {
11
11
  "phase": "build"
@@ -19,14 +19,14 @@
19
19
  }
20
20
  ],
21
21
  "component": {
22
- "bom-ref": "@blamejs/pki@0.6.29",
22
+ "bom-ref": "@blamejs/pki@0.6.30",
23
23
  "type": "application",
24
24
  "name": "pki",
25
- "version": "0.6.29",
25
+ "version": "0.6.30",
26
26
  "scope": "required",
27
27
  "author": "blamejs contributors",
28
28
  "description": "Pure-JavaScript PKI toolkit that owns its stack — X.509, ASN.1/DER, CMS, PQC-first.",
29
- "purl": "pkg:npm/%40blamejs/pki@0.6.29",
29
+ "purl": "pkg:npm/%40blamejs/pki@0.6.30",
30
30
  "properties": [],
31
31
  "externalReferences": [
32
32
  {
@@ -54,7 +54,7 @@
54
54
  "components": [],
55
55
  "dependencies": [
56
56
  {
57
- "ref": "@blamejs/pki@0.6.29",
57
+ "ref": "@blamejs/pki@0.6.30",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]