@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/CHANGELOG.md CHANGED
@@ -4,6 +4,23 @@ All notable changes to `@blamejs/pki` are documented here. The format
4
4
  follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this
5
5
  project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## v0.6.30 — 2026-09-04
8
+
9
+ Reference documentation is corrected across the toolkit: a mistyped signed-attribute field name, and options and return fields the code accepts or returns that the reference had omitted.
10
+
11
+ ### Changed
12
+
13
+ - Options and return fields the code accepts or returns are now documented across pki.cms, pki.tsp, pki.pkcs12, pki.hpke, pki.path, pki.ocsp, pki.asn1, pki.est, pki.acme, and pki.webauthn. In particular, pki.webauthn.verifyAssertion is documented as checking the challenge and origin when expectedChallenge / expectedOrigin / expectedTopOrigin are supplied with clientDataJSON.
14
+ - Reference prose across the toolkit and the documentation site is reworded for consistency.
15
+
16
+ ### Fixed
17
+
18
+ - pki.smime.sign documented additionalSignedAttributes as [{ oid, values }]; the code reads the type field, so a caller following the reference would pass an unrecognized field. The correct form is [{ type, values }].
19
+ - pki.ocsp.buildErrorResponse is documented as returning a Buffer; the signature previously showed Buffer | string, but the verb has no PEM option and every path returns DER.
20
+ - The pki.schema.all example output lists csrattrs, which the enumeration returns between cmp and ocsp-request.
21
+ - The pki.acme.client method list documents updateAccount and listOrders, which the client returns.
22
+ - pki.tsp.verify now includes policyName on a failure verdict; it already returned the resolved policy name on a valid verdict and the raw policy on both, so a refused token carries the same descriptive fields as a valid one.
23
+
7
24
  ## v0.6.29 — 2026-09-03
8
25
 
9
26
  The EST, ACME, and CMP clients reach a CA through a forward HTTP proxy, with the same opts.proxy the SCEP client already accepts.
package/lib/acme.js CHANGED
@@ -513,7 +513,7 @@ function validate(kind, obj) {
513
513
  * @related pki.acme.validate
514
514
  *
515
515
  * Classify an ACME JSON object into exactly one kind by its discriminating
516
- * member set -- `"jws"`, `"problem"`, `"directory"`, `"order"`, `"authorization"`,
516
+ * member set: `"jws"`, `"problem"`, `"directory"`, `"order"`, `"authorization"`,
517
517
  * `"challenge"`, `"account"`, `"renewalInfo"`, or `"unknown"`. The discriminators
518
518
  * are proven mutually exclusive; a DER structure identifies as `"unknown"`.
519
519
  *
@@ -1109,7 +1109,7 @@ async function finalize(o) {
1109
1109
  * @related pki.acme.http01, pki.acme.dns01
1110
1110
  *
1111
1111
  * Build a challenge-response POST (RFC 8555 sec. 7.5.1): a kid-signed JWS whose
1112
- * payload is the type-defined response object -- `{}` for the three registered
1112
+ * payload is the type-defined response object: `{}` for the three registered
1113
1113
  * challenge types (http-01 / dns-01 / tls-alpn-01), which is DISTINCT from a
1114
1114
  * POST-as-GET empty payload. `opts` = `{ key, alg, nonce, url, kid, payload? }`
1115
1115
  * (payload default `{}`; pass a custom object for a future challenge type).
@@ -1139,7 +1139,7 @@ function challengeResponse(o) {
1139
1139
  * @related pki.acme.validate
1140
1140
  *
1141
1141
  * Build a deactivation POST (RFC 8555 sec. 7.3.6 account / sec. 7.5.2
1142
- * authorization): a kid-signed JWS with the payload `{"status":"deactivated"}` --
1142
+ * authorization): a kid-signed JWS with the payload `{"status":"deactivated"}`,
1143
1143
  * the only client-settable status. `opts` = `{ key, alg, nonce, url, kid }`.
1144
1144
  *
1145
1145
  * @example
@@ -1196,7 +1196,7 @@ function updateAccount(o) {
1196
1196
  * Build a revokeCert request (RFC 8555 sec. 7.6): a JWS whose payload `certificate`
1197
1197
  * is the base64url of the DER certificate and optional `reason` is an assigned
1198
1198
  * RFC 5280 CRLReason (0-6, 8-10; 7 is unassigned). Signed EITHER by the account key (`kid` mode) OR by the
1199
- * certificate key (`jwk` mode) -- pass exactly one. `opts` = `{ key, alg, nonce,
1199
+ * certificate key (`jwk` mode). Pass exactly one. `opts` = `{ key, alg, nonce,
1200
1200
  * url, certificate (DER Buffer), reason?, kid? | jwk? }`.
1201
1201
  *
1202
1202
  * @example
@@ -1347,7 +1347,7 @@ function parseAriCertId(certId) {
1347
1347
  *
1348
1348
  * Validate an ARI RenewalInfo object (RFC 9773 sec. 4.2): a `suggestedWindow` with
1349
1349
  * RFC 3339 `start` and `end`, `end` strictly after `start` (an inverted or
1350
- * zero-width window throws `acme/bad-renewal-window` -- the client treats it as no
1350
+ * zero-width window throws `acme/bad-renewal-window`: the client treats it as no
1351
1351
  * response, defusing a renewal stampede), and an optional `explanationURL`.
1352
1352
  * Returns the object.
1353
1353
  *
@@ -1758,7 +1758,7 @@ function _parseLinkNext(headers, base) { var m = _parseLinkRelation(headers, bas
1758
1758
  * capped by a poll count and a total-wait budget. Returns a client
1759
1759
  * object: `directory`, `newAccount`, `newOrder`, `newAuthz`, `getOrder` / `getAuthorization` / `getChallenge`,
1760
1760
  * `respondToChallenge`, `finalize`, `pollOrder` / `pollAuthorization`, `downloadCertificate`,
1761
- * `revokeCert`, `deactivateAccount` / `deactivateAuthorization`, `keyChange`, `renewalInfo`, `renewalWindow`, `scheduleRenewal`.
1761
+ * `revokeCert`, `deactivateAccount` / `deactivateAuthorization`, `updateAccount`, `listOrders`, `keyChange`, `renewalInfo`, `renewalWindow`, `scheduleRenewal`.
1762
1762
  *
1763
1763
  * @opts
1764
1764
  * - `accountKey` / `accountJwk` / `alg` -- REQUIRED: the account private key, its public JWK, and the JWS alg.
package/lib/asn1-der.js CHANGED
@@ -23,8 +23,8 @@
23
23
  * turn a node into a JS value (BigInt, dotted OID, Date, string); the
24
24
  * `build.*` helpers construct canonical DER from JS values. Because DER
25
25
  * is canonical, each value the `build.*` helpers emit has exactly one
26
- * valid encoding -- byte-identical to any other conformant DER encoder's
27
- * output -- and decoding it reproduces the value it was built from.
26
+ * valid encoding, byte-identical to any other conformant DER encoder's
27
+ * output, and decoding it reproduces the value it was built from.
28
28
  *
29
29
  * @card
30
30
  * Strict, fail-closed DER decode / encode with a navigable node tree
@@ -112,9 +112,10 @@ function _asBuffer(input, who) {
112
112
  *
113
113
  * Parse DER into a node tree. Each node is
114
114
  * `{ tagClass, constructed, tagNumber, header, length, content, children,
115
- * bytes }`, where `content` is the primitive value slice, `children` the
116
- * decoded sub-nodes of a constructed node, and `bytes` the full TLV slice
117
- * (all zero-copy views over the input).
115
+ * bytes, contentStart, contentEnd }`, where `content` is the primitive value slice, `children` the
116
+ * decoded sub-nodes of a constructed node, `bytes` the full TLV slice, and
117
+ * `contentStart` / `contentEnd` the content slice's byte offsets in the input
118
+ * (all slices are zero-copy views over the input).
118
119
  *
119
120
  * Throws `Asn1Error` on any non-DER shape: indefinite length, a
120
121
  * non-minimal length or a length that overruns the buffer, trailing bytes
@@ -124,13 +125,14 @@ function _asBuffer(input, who) {
124
125
  * `ber: true` is a scoped relaxation for formats whose content regions are
125
126
  * normatively BER (RFC 7292 PKCS#12): it accepts an indefinite length on a
126
127
  * constructed value and a constructed OCTET STRING, whose segments are
127
- * reassembled into one primitive `content`. Nothing else is relaxed --
128
+ * reassembled into one primitive `content`. Nothing else is relaxed:
128
129
  * definite lengths stay minimal, an indefinite length on a primitive value
129
130
  * and a foreign-type segment still reject, and the size / depth caps hold.
130
131
  *
131
132
  * @opts
132
133
  * maxBytes: number, // default: C.LIMITS.DER_MAX_BYTES (16 MiB)
133
134
  * maxDepth: number, // default: C.LIMITS.DER_MAX_DEPTH (64)
135
+ * maxItems: number, // default: C.LIMITS.DER_MAX_ITEMS (total decoded node cap)
134
136
  * allowTrailing: boolean, // default false; allow bytes after the top TLV
135
137
  * ber: boolean, // default false; accept indefinite lengths +
136
138
  * // constructed OCTET STRINGs (BER content regions)
@@ -680,7 +682,7 @@ function encodeIdentifier(classBits, constructed, tagNumber) {
680
682
  * @spec X.690, ISO/IEC 8825-1
681
683
  * @related pki.asn1.decode
682
684
  *
683
- * Low-level TLV encoder -- prepend the identifier + DER length to a content
685
+ * Low-level TLV encoder: prepend the identifier + DER length to a content
684
686
  * buffer. Most callers use the higher-level `build.*` helpers; this is the
685
687
  * escape hatch for context-tagged and implicitly-tagged constructions.
686
688
  *
@@ -583,17 +583,17 @@ function _unsupportedCritical(ac) {
583
583
  * @defends attribute-certificate-forgery (CWE-347)
584
584
  * @related pki.attrcert.sign, pki.path.validate, pki.schema.attrcert.parse
585
585
  *
586
- * Verify an RFC 5755 attribute certificate. An AC carries privilege attributes -- a role, a group, a
587
- * clearance -- so a consumer that reads them without this grants privileges on unauthenticated
586
+ * Verify an RFC 5755 attribute certificate. An AC carries privilege attributes (a role, a group, a
587
+ * clearance), so a consumer that reads them without this grants privileges on unauthenticated
588
588
  * input. `ac` is a DER `Buffer`, a PEM string, or a parsed attribute certificate; `issuer` is
589
589
  * `{ name, publicKey }`, the AC issuer this verifier trusts as an AC issuer, which section 5 item 4
590
590
  * makes the verifier's own configuration and this verb therefore refuses to infer from the AC.
591
- * `issuer.name` takes every form `pki.attrcert.sign` accepts for the issuing AA -- a string, an
592
- * array of RDNs, or raw `Name` DER -- and is compared as a distinguished name (RFC 5280 section
591
+ * `issuer.name` takes every form `pki.attrcert.sign` accepts for the issuing AA (a string, an
592
+ * array of RDNs, or raw `Name` DER) and is compared as a distinguished name (RFC 5280 section
593
593
  * 7.1), so an AC issued under a multi-RDN authority name is verifiable under that same name.
594
594
  *
595
595
  * Both options are read at the call, before signature verification suspends it, so a caller that
596
- * reuses or rewrites its options object -- including calling `setTime` on the `Date` it passed in --
596
+ * reuses or rewrites its options object (including calling `setTime` on the `Date` it passed in)
597
597
  * cannot change the verdict that call returns.
598
598
  *
599
599
  * The checks it performs are section 5's items 2, 4, 5, 6 and 7: the signature over the exact
@@ -613,7 +613,7 @@ function _unsupportedCritical(ac) {
613
613
  * (RFC 5280 sec. 7.2), a mailbox matches its local-part exactly and its host-part case-insensitively
614
614
  * (sec. 7.5), and a directoryName goes through the same distinguished-name comparison the rest of
615
615
  * the toolkit uses (sec. 7.1). A URI compares as encoded, because sec. 7.4 makes URI equality a full
616
- * RFC 3987 normalization -- percent-encoding, path segments and scheme-based rules -- and a partial
616
+ * RFC 3987 normalization (percent-encoding, path segments and scheme-based rules) and a partial
617
617
  * one could match a URI it should not. A form with no comparison here (otherName, ediPartyName,
618
618
  * x400Address) leaves `targetingChecked: false` and never a pass. Every one of those limits can
619
619
  * refuse a target a fuller comparison would accept, and none can accept one it would refuse.
@@ -627,8 +627,8 @@ function _unsupportedCritical(ac) {
627
627
  *
628
628
  * Revocation is section 6, outside the seven. This verb implements that section's "never revoke"
629
629
  * scheme, which AC users MUST support: it holds no revocation evidence and follows no pointer out
630
- * of the certificate. The section states the consequence -- "If only the 'never revoke' scheme is
631
- * supported, then all ACs that do not contain a noRevAvail extension, MUST be rejected" -- because
630
+ * of the certificate. The section states the consequence, "If only the 'never revoke' scheme is
631
+ * supported, then all ACs that do not contain a noRevAvail extension, MUST be rejected", because
632
632
  * an issuer that omits noRevAvail is stating that revocation status checks are supported, and a
633
633
  * verdict that skipped one would grant privileges the issuer expected to be able to withdraw. So an
634
634
  * AC carrying `noRevAvail` verifies with `revocationChecked: true` and `noRevAvail: true`, and one
@@ -3,7 +3,7 @@
3
3
  "use strict";
4
4
  /**
5
5
  * @internal
6
- * lib/byte-reader.js -- a bounded big-endian byte cursor: the shared ENCODING-layer
6
+ * lib/byte-reader.js: a bounded big-endian byte cursor, the shared ENCODING-layer
7
7
  * primitive under the toolkit's non-ASN.1 length-prefixed wire formats (TLS-vector
8
8
  * SCTs in pki.ct, the packed big-endian TPM2B_* / authenticatorData structures in
9
9
  * pki.webauthn). Every read is length-checked against a hard [pos, end) window
@@ -3,7 +3,7 @@
3
3
  "use strict";
4
4
  /**
5
5
  * @internal
6
- * lib/byte-writer.js -- a growable big-endian byte sink: the ENCODING-layer twin of
6
+ * lib/byte-writer.js: a growable big-endian byte sink, the ENCODING-layer twin of
7
7
  * lib/byte-reader.js, the shared producer under the toolkit's non-ASN.1 length-prefixed
8
8
  * wire formats (the TLS-vector SCT list pki.ct emits; any future TLS-presentation
9
9
  * producer). Every fixed-width integer is range-checked against its field width and
package/lib/cmc-verify.js CHANGED
@@ -200,11 +200,11 @@ function _governingStatus(statuses, outcome) {
200
200
  * Interpret a Full PKI Response into one terminal verdict. `response` is the DER or a PEM `CMS`
201
201
  * block; an already-parsed message is interpreted too, but only under `allowUnverified: true`,
202
202
  * because both carriers authenticate over BYTES and a parsed object the caller still owns pins
203
- * none. `sent` is what the client retained from its request --
203
+ * none. `sent` is what the client retained from its request:
204
204
  * `transactionId`, `senderNonce`, `dataReturn`, and `bodyPartIDs` (every identifier the request
205
205
  * carried). Each of those is checked only if it was sent, and once sent an absent or differing
206
206
  * echo is a refusal: that asymmetry is the replay defense. `bodyPartIDs` is the same rule applied
207
- * to what the response is ABOUT -- a status naming a body part the request never sent is refused
207
+ * to what the response is ABOUT: a status naming a body part the request never sent is refused
208
208
  * with `cmc/body-part-unknown`, which the transaction and nonce cannot catch, since a server can
209
209
  * echo both correctly while reporting on something else.
210
210
  *
@@ -229,7 +229,7 @@ function _governingStatus(statuses, outcome) {
229
229
  * The carrier's signature MUST be verified (RFC 5272 sec. 3.2.1.3.4). A conforming SignedData
230
230
  * carries its own signer certificate, so the ordinary case needs nothing from the caller: the
231
231
  * signature is checked and the verdict reports `signatureVerified: true`. Where the signer cannot be
232
- * found -- not embedded and not supplied -- the posture is fail-closed with a NAMED opt-out rather
232
+ * found (not embedded and not supplied), the posture is fail-closed with a NAMED opt-out rather
233
233
  * than a silent one: pass `certs` with the responder's certificate, or `allowUnverified: true` and
234
234
  * the verdict reports `signatureVerified: false`. Doing neither is refused, because that is the case
235
235
  * where a caller would otherwise assume a check happened. The opt-out covers "could not check",
@@ -245,7 +245,7 @@ function _governingStatus(statuses, outcome) {
245
245
  * who holds the key gets an authenticated verdict instead of the unauthenticated opt-out.
246
246
  *
247
247
  * Nothing is trusted here. `certificates` is the CMS certificate bag, where RFC 5272 sec. 4.2
248
- * puts the issued certificates -- surfaced raw for the caller to run through `pki.path.validate`,
248
+ * puts the issued certificates, surfaced raw for the caller to run through `pki.path.validate`,
249
249
  * and a Publish Trust Anchors control is surfaced as `publishTrustAnchors` with `trusted: false`,
250
250
  * never added to any store (RFC 5272 sec. 6.15 makes accepting one a four-part manual decision).
251
251
  * The CMS signature is likewise the caller's to verify through `pki.cms.verify`.
package/lib/cmp-build.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * @title Certificate management protocol messages
9
9
  * @fullname CMP (Certificate Management Protocol, RFC 4210)
10
10
  * @intro The RFC 9810 Certificate Management Protocol producing side. `pki.cmp.build` assembles a
11
- * `PKIMessage` -- a `PKIHeader` (sender / recipient / transaction metadata), a `PKIBody` carrying one
11
+ * `PKIMessage`: a `PKIHeader` (sender / recipient / transaction metadata), a `PKIBody` carrying one
12
12
  * request or transaction (an `ir` / `cr` / `kur` certificate request via `pki.crmf.build`, a `p10cr`
13
13
  * PKCS#10 via `pki.csr.sign`, a `certConf` / `pollReq` / `genm` / `rr`, or a `nested` wrapper of other
14
14
  * PKIMessages an RA forwards), and an optional
@@ -682,7 +682,7 @@ function _collectExtraCerts(opts, protCertDer) {
682
682
  * @spec RFC 9810, RFC 9481, RFC 9579
683
683
  * @related pki.schema.cmp.parse
684
684
  *
685
- * Build an RFC 9810 CMP `PKIMessage` -- the producing-side inverse of `pki.schema.cmp.parse`. `message` is
685
+ * Build an RFC 9810 CMP `PKIMessage`, the producing-side inverse of `pki.schema.cmp.parse`. `message` is
686
686
  * `{ header, body }`: `header` carries the `sender` / `recipient` GeneralNames plus optional transaction
687
687
  * metadata (`transactionID`, `senderNonce`, `messageTime`, `freeText`, `generalInfo`, ...); `body` is a
688
688
  * single-key object naming the arm. Request-side: `{ ir }` / `{ cr }` / `{ kur }` / `{ krr }` (key recovery,
@@ -924,7 +924,7 @@ function wellKnownUrl(base, opts) {
924
924
  *
925
925
  * Build an RFC 9811 sec. 3.4 CMP request-URI under the `/.well-known/cmp` prefix (RFC 8615). The four forms:
926
926
  * `<base>/.well-known/cmp`, `.../<operation>`, `.../p/<label>`, and `.../p/<label>/<operation>`. A pure string
927
- * builder over an authority-rooted well-known path (RFC 8615) -- https vs http is left to the transport (both
927
+ * builder over an authority-rooted well-known path (RFC 8615): https vs http is left to the transport (both
928
928
  * forms are accepted, RFC 9811 sec. 3.4), but the `base` MUST be an http(s) URL. It rejects (`cmp/bad-url`) an
929
929
  * unparseable `base`, a non-http(s) scheme (`file:`/`data:`/a custom scheme has an opaque origin), a `base`
930
930
  * carrying a path / query / fragment (a well-known URI is authority-rooted; a path would capture it), and a
@@ -265,14 +265,14 @@ function _certConfHash(certDer) {
265
265
  * requirements, whose template must omit `publicKey`, `serialNumber`, `signingAlg`, `issuerUID` and
266
266
  * `subjectUID`, and whose `keySpec` states key requirements as `algId` (a non-RSA AlgorithmIdentifier) or
267
267
  * `rsaKeyLen` (a positive integer); and `{ crlUpdate: { issuer, dpn?, thisUpdate? } }` for a CRL from a
268
- * named source, held to that source -- the issuer under the RFC 5280 sec. 7.1 rule, a distribution point
269
- * against the CRL's own `issuingDistributionPoint` where it states one -- and to the supplied `thisUpdate`.
268
+ * named source, held to that source (the issuer under the RFC 5280 sec. 7.1 rule, a distribution point
269
+ * against the CRL's own `issuingDistributionPoint` where it states one) and to the supplied `thisUpdate`.
270
270
  * A request naming both sends the dpn (sec. 4.3.4: the dpn choice when a distribution point name is
271
271
  * available) and holds the answer to the issuer as well. The issuer is REQUIRED, since a distribution
272
272
  * point name alone leaves the answer unbound: a complete CRL states no scope to compare it against.
273
273
  * Terminal `outcome`: `answered` (with `operation`, `present`, and the decoded `value`),
274
274
  * `rejected`, or `poll-timeout`. An absent response value is `present: false` with a null `value`, which is
275
- * how each of the four says "nothing available" -- never conflated with an empty result. Delayed delivery
275
+ * how each of the four says "nothing available", never conflated with an empty result. Delayed delivery
276
276
  * for both verbs arrives as an error message carrying the `waiting` status (sec. 4.4) and drives the same
277
277
  * bounded poll loop, with the `pollReq` referring to the whole message.
278
278
  *
package/lib/cms-verify.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * @nav Verification
7
7
  * @title CMS
8
8
  * @fullname CMS (Cryptographic Message Syntax) signing and verification
9
- * @intro Verify a CMS SignedData signature (RFC 5652 sec. 5) -- the structure S/MIME signed
9
+ * @intro Verify a CMS SignedData signature (RFC 5652 sec. 5), the structure S/MIME signed
10
10
  * mail, RFC 3161 timestamp tokens, and code-signing all rest on. `verify(cms, opts)` parses
11
11
  * the SignedData (over the strict `pki.schema.cms` codec), locates each SignerInfo's signer
12
12
  * certificate by its issuerAndSerialNumber or subjectKeyIdentifier, and checks the signature
@@ -406,7 +406,7 @@ async function _verifyOneCountersig(vDer, targetSig, parsedCerts) {
406
406
 
407
407
  /**
408
408
  * @primitive pki.cms.verify
409
- * @signature pki.cms.verify(input, opts?) -> Promise<{ valid, trusted, eContentType, signers }>
409
+ * @signature pki.cms.verify(input, opts?) -> Promise<{ valid, trusted, eContentType, eContent, signers }>
410
410
  * @since 0.2.14
411
411
  * @status stable
412
412
  * @spec RFC 5652
@@ -416,15 +416,16 @@ async function _verifyOneCountersig(vDer, targetSig, parsedCerts) {
416
416
  * @related pki.schema.cms.parse, pki.path.validate
417
417
  *
418
418
  * Verify a CMS SignedData signature (RFC 5652 sec. 5). `input` is a PEM string, a DER
419
- * `Buffer`, or a parsed `pki.schema.cms` object. Returns `{ valid, trusted, eContentType, signers }`
420
- * where each `signers[i]` is `{ ok, sid, cert, trusted, signedAttributesPresent }` (`cert` the
421
- * matched signer certificate DER) or carries a `code` on a structural failure; `valid` is true when
419
+ * `Buffer`, or a parsed `pki.schema.cms` object. Returns `{ valid, trusted, eContentType, eContent, signers }`
420
+ * (`eContent` the encapsulated content when present, else null) where each `signers[i]` is
421
+ * `{ ok, sid, cert, trusted, signedAttributesPresent, signedAttributes, unsignedAttrs, digestAlgorithm, countersignatures }`
422
+ * (`cert` the matched signer certificate DER) or carries a `code` on a structural failure; `valid` is true when
422
423
  * there is at least one signer and every signer verified.
423
424
  *
424
425
  * `eContentType` and `signedAttributesPresent` are there for a caller whose profile is stricter
425
- * than RFC 5652's. Signing WITH attributes and signing the content directly are different claims --
426
+ * than RFC 5652's. Signing WITH attributes and signing the content directly are different claims:
426
427
  * attributes bind a content type and a signing time alongside the digest, content-only binds
427
- * nothing but the bytes -- and one message may carry a signer of each. A profile that requires
428
+ * nothing but the bytes. One message may carry a signer of each. A profile that requires
428
429
  * attributes (RFC 8551 S/MIME does) or a particular content type can enforce it from the verdict,
429
430
  * with no need to parse the message a second time.
430
431
  *
@@ -434,9 +435,8 @@ async function _verifyOneCountersig(vDer, targetSig, parsedCerts) {
434
435
  * certificate, sign with it, and embed it, so that says nothing about WHO signed. `trusted` says
435
436
  * every signer chained to a root named in `opts.trustAnchors`, validated through the same RFC 5280
436
437
  * path engine `pki.path.validate` uses. Without anchors there is nothing to chain to and `trusted`
437
- * is `false` -- a definite answer, not a missing one. Anchors that cannot be read are a
438
- * configuration fault and throw. Absorbing them into `trusted: false` would report a verdict
439
- * about the message for a check that never ran.
438
+ * is `false`, a definite answer, not a missing one. Anchors that cannot be read are a
439
+ * configuration fault and throw.
440
440
  *
441
441
  * Trust is decided from the certificate the SignerInfo selected, the one reported as
442
442
  * `signers[i].cert`, never from another certificate that happens to share its key. A
@@ -706,6 +706,9 @@ function _addCert(out, der) {
706
706
  * @opts eContentType The encapsulated content type (an OID name). Default `data`.
707
707
  * @opts signedAttributes Include signed attributes (content-type, message-digest, signing-time);
708
708
  * false signs the content directly. Default true.
709
+ * @opts additionalSignedAttributes Extra signed attributes to add to every SignerInfo, each
710
+ * `{ type, values }` (`type` an OID name or dotted string, `values` an
711
+ * array of DER value `Buffer`s). Covered by the signature.
709
712
  * @opts signingTime A `Date` for the signing-time attribute, or false to omit it.
710
713
  * @opts sid `"issuerAndSerial"` (default) or `"ski"` (subjectKeyIdentifier).
711
714
  * @opts certificates Embed the signer certificates in the output. Default true.
@@ -739,7 +742,7 @@ var sign = cmsSign.sign;
739
742
  * Add one or more countersignatures to an existing CMS SignedData (RFC 5652 sec. 11.4). A
740
743
  * countersignature is itself a `SignerInfo` whose signature covers the CONTENTS of the countersigned
741
744
  * SignerInfo's signature value (not the content), attached as the `id-countersignature` unsigned
742
- * attribute -- the construction Authenticode timestamps and signature-attestation workflows rest on.
745
+ * attribute, the construction Authenticode timestamps and signature-attestation workflows rest on.
743
746
  * `cms` is the SignedData (a DER `Buffer` or a PEM `CMS` string; the wire bytes are preserved, so
744
747
  * the countersigned primary still verifies byte-for-byte). Each `signers[i]` is the same descriptor
745
748
  * `pki.cms.sign` takes (`{ cert, key, digestAlgorithm?, pss? }`, any RSA / RSASSA-PSS / ECDSA /
@@ -784,7 +787,7 @@ var countersign = cmsSign.countersign;
784
787
  * Encrypt content as a CMS EnvelopedData (CBC content), AuthEnvelopedData (AEAD content, the
785
788
  * default), or EncryptedData. `recipients` is an ARRAY of recipient descriptors for the enveloped
786
789
  * family, each wrapping the same fresh content-encryption key: `{ cert }` auto-dispatches off the
787
- * recipient certificate's public-key algorithm -- RSA yields a ktri with RSAES-OAEP-SHA256 (PKCS#1
790
+ * recipient certificate's public-key algorithm: RSA yields a ktri with RSAES-OAEP-SHA256 (PKCS#1
788
791
  * v1.5 is never emitted); EC P-256/384/521 a kari with ephemeral-static ECDH and the X9.63 KDF;
789
792
  * X25519/X448 a kari per RFC 8418 (HKDF); ML-KEM-512/768/1024 an ori/KEMRecipientInfo per RFC
790
793
  * 9629 + 9936; a composite ML-KEM (id-MLKEM768-* / id-MLKEM1024-*, draft-lamps-pq-composite-kem) the
@@ -827,7 +830,7 @@ var encrypt = cmsEncrypt.encrypt;
827
830
  * @spec RFC 5652, RFC 2104, RFC 4231, RFC 3370
828
831
  * @related pki.cms.decrypt, pki.schema.cms.parse
829
832
  *
830
- * Produce a CMS AuthenticatedData (RFC 5652 sec. 9): CLEARTEXT content plus a MAC (HMAC-SHA-2) --
833
+ * Produce a CMS AuthenticatedData (RFC 5652 sec. 9): CLEARTEXT content plus a MAC (HMAC-SHA-2),
831
834
  * authenticated but not encrypted, the authenticated-only sibling of AuthEnvelopedData. A single
832
835
  * fresh MAC key is minted and wrapped for every recipient with the same RecipientInfo model
833
836
  * `pki.cms.encrypt` uses for a content-encryption key, so `recipients` is the identical array of
@@ -835,8 +838,8 @@ var encrypt = cmsEncrypt.encrypt;
835
838
  * `{ password }` (pwri), or `{ kek, kekId }` (kekri). By default the MAC covers the authenticated
836
839
  * attributes (a content-type and a message-digest = digest of the content) re-tagged to the EXPLICIT
837
840
  * SET OF (RFC 5652 sec. 9.2); with `authenticatedAttributes: false` (id-data content only) it covers
838
- * the content octets directly. `pki.cms.decrypt` recovers the MAC key, recomputes the MAC, and --
839
- * with authenticated attributes -- independently confirms the message-digest before releasing the
841
+ * the content octets directly. `pki.cms.decrypt` recovers the MAC key, recomputes the MAC, and
842
+ * (with authenticated attributes) independently confirms the message-digest before releasing the
840
843
  * content, returning `authenticated: true`. Malformed input throws a typed `CmsError`.
841
844
  *
842
845
  * @opts macAlgorithm `"hmac-sha256"` (default) / `"hmac-sha384"` / `"hmac-sha512"`.
@@ -847,6 +850,8 @@ var encrypt = cmsEncrypt.encrypt;
847
850
  * @opts authAttrs Extra authenticated attributes appended to the content-type + message-digest pair.
848
851
  * @opts contentType The encapsulated content type (an OID name). Default `data`.
849
852
  * @opts keyIdentifier `"issuerAndSerial"` (default) or `"subjectKeyIdentifier"`.
853
+ * @opts oaepHash The RSAES-OAEP hash for ktri recipients wrapping the MAC key: `"sha256"` (default) / `"sha384"` / `"sha512"`.
854
+ * @opts ukm User keying material (a Buffer) for kari / kemri recipients.
850
855
  * @opts pem Return a PEM string (`-----BEGIN CMS-----`) instead of a DER Buffer.
851
856
  * @example
852
857
  * // authenticate a message to an RSA recipient, then verify the MAC via decrypt
@@ -890,7 +895,7 @@ var authenticate = cmsEncrypt.authenticate;
890
895
  * recipient type: a `ktri` or ephemeral-static `kari` message is minted by anyone holding the recipient's
891
896
  * PUBLIC key, and a `pwri` or `kekri` message by any co-recipient sharing the secret. Read
892
897
  * `authenticated: true` as "these bytes were not altered after the key was chosen", and do not read it as
893
- * a sender identity -- to bind one, verify a signature (`pki.cms.verify`) over the plaintext.
898
+ * a sender identity. To bind one, verify a signature (`pki.cms.verify`) over the plaintext.
894
899
  * `authenticatedBy` names what the integrity rests on (`"content-encryption-key"` for AEAD,
895
900
  * `"message-authentication-key"` for AuthenticatedData, `null` for an unauthenticated cipher).
896
901
  * `originatorInfo` is surfaced as the sender supplied it and is UNAUTHENTICATED: it sits outside the
@@ -958,7 +963,7 @@ var compress = cmsCompress.compress;
958
963
  * decompression-bomb / resource-exhaustion defense (CWE-409): a cap breach throws
959
964
  * `cms/decompress-too-large`, and every malformed / truncated / corrupt stream collapses to the uniform
960
965
  * `cms/decompress-failed`. `opts.maxOutputBytes` tightens the cap DOWNWARD only. The verdict carries NO
961
- * `authenticated` / `valid` field -- CompressedData is not a security assertion (RFC 8551 sec. 2.4.5).
966
+ * `authenticated` / `valid` field. CompressedData is not a security assertion (RFC 8551 sec. 2.4.5).
962
967
  *
963
968
  * @opts maxOutputBytes Lower the decompressed-output cap (a DoS bound; downward only).
964
969
  * @example
@@ -13,8 +13,8 @@
13
13
  * recovers the same secret from that ciphertext and the composite private key. Each component KEM
14
14
  * runs independently, and the two secrets are mixed through the SHA3-256 combiner that also binds the
15
15
  * traditional ciphertext, the traditional public key, and a per-algorithm label. All twelve registered
16
- * algorithms -- ML-KEM-768 and ML-KEM-1024 paired with RSA-OAEP 2048/3072/4096, ECDH over
17
- * P-256/P-384/P-521 and brainpool, X25519, and X448 -- are verified against the draft Appendix G
16
+ * algorithms (ML-KEM-768 and ML-KEM-1024 paired with RSA-OAEP 2048/3072/4096, ECDH over
17
+ * P-256/P-384/P-521 and brainpool, X25519, and X448) are verified against the draft Appendix G
18
18
  * known-answer vectors.
19
19
  * @spec draft-ietf-lamps-pq-composite-kem
20
20
  * @card Establish a shared secret with a hybrid post-quantum plus traditional KEM.
package/lib/crl-sign.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * @fullname CRLs (certificate revocation lists): read, sign and shard
10
10
  * @intro The X.509 CRL producing side. `pki.crl.sign` builds a `TBSCertList`, signs it, and emits a
11
11
  * `CertificateList` (RFC 5280 sec. 5) that `pki.schema.crl.parse`, `pki.path.crlChecker`, and OpenSSL
12
- * all accept -- over any signature algorithm the toolkit registry resolves: RSA (PKCS#1 v1.5 / PSS),
12
+ * all accept, over any signature algorithm the toolkit registry resolves: RSA (PKCS#1 v1.5 / PSS),
13
13
  * ECDSA, EdDSA, ML-DSA, SLH-DSA, and the composite (hybrid) arms. `pki.crl.verify` checks a CRL
14
14
  * signature through the one path-validation signature engine, and `pki.crl.isRevoked` looks a serial up
15
15
  * in a parsed CRL. Parsing lives at `pki.schema.crl.parse`.
@@ -413,7 +413,7 @@ function _sign(spec, issuer, opts) {
413
413
  * @defends crl-forgery (CWE-347)
414
414
  * @related pki.schema.crl.parse, pki.crl.verify, pki.path.crlChecker
415
415
  *
416
- * Build, sign, and DER-encode an X.509 certificate revocation list. `spec` describes the CRL --
416
+ * Build, sign, and DER-encode an X.509 certificate revocation list. `spec` describes the CRL:
417
417
  * `thisUpdate` / `nextUpdate` (`Date`s), an optional `crlNumber`, a `revoked` array (each entry a
418
418
  * `serialNumber` + `revocationDate` with an optional `reason` or `invalidityDate`),
419
419
  * and an optional `extensions` object (`authorityKeyIdentifier`, `issuingDistributionPoint`,
@@ -491,8 +491,8 @@ function _issuerMaySign(parsed, cert) {
491
491
  * Verify a CRL's signature over its exact parsed `tbsCertList` bytes under the issuer public key. `crl`
492
492
  * is a DER `Buffer`, a PEM string, or a parsed CRL; `issuer` is `{ cert }` (DER/PEM/parsed), `{ publicKey }`
493
493
  * (SPKI DER), or a raw SPKI `Buffer`. Verification composes the one path-validation signature engine
494
- * `pki.path.crlChecker` uses -- the same algorithm-confusion (RFC 9814 sec. 4 key-OID == sig-OID) and
495
- * EdDSA low-order-point gates -- so there is no second, weaker CRL verifier. The verdict's `valid` is
494
+ * `pki.path.crlChecker` uses, the same algorithm-confusion (RFC 9814 sec. 4 key-OID == sig-OID) and
495
+ * EdDSA low-order-point gates, so there is no second, weaker CRL verifier. The verdict's `valid` is
496
496
  * `false` on any verification fault, and `signatureValid` reports the signature check on its own; malformed
497
497
  * input throws a typed `CrlError`.
498
498
  *
@@ -571,7 +571,7 @@ function _serialHexOf(serial) {
571
571
  * refused rather than answered from (`crl/not-current`): one whose `thisUpdate` is later, one whose
572
572
  * `nextUpdate` has passed, and one carrying no `nextUpdate` at all, which states no window and so cannot
573
573
  * be told from a replayed copy. Without `opts.time` currency goes unasked and the verb is the structural
574
- * lookup it has always been -- `null` then means "not listed on this CRL", which is weaker than "not
574
+ * lookup it has always been; `null` then means "not listed on this CRL", which is weaker than "not
575
575
  * revoked". `pki.path.crlChecker` decides currency against the material it fetched and is the verb to
576
576
  * reach for when the answer has to mean the stronger thing.
577
577
  *
package/lib/crmf-sign.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * @title Certificate request messages
9
9
  * @fullname CRMF (Certificate Request Message Format, RFC 4211)
10
10
  * @intro The RFC 4211 certificate-request-message producing side. `pki.crmf.build` assembles a
11
- * `CertReqMessages` -- one or more `CertReqMsg`, each a `CertRequest` (a `CertTemplate` of the requested
11
+ * `CertReqMessages`: one or more `CertReqMsg`, each a `CertRequest` (a `CertTemplate` of the requested
12
12
  * certificate fields plus optional controls) paired with a proof of possession. The common proof is a
13
13
  * `POPOSigningKey` signature over the `CertRequest`, made with the private half of the key being
14
14
  * certified (the requester proves possession, exactly as a PKCS#10 CSR does). The message drops into a
@@ -355,7 +355,7 @@ function _buildProofOfPossession(pop, certReqDer, template, signingKey, opts) {
355
355
  * subjectKeyIdentifier, or pre-encoded Extension DER), and an optional `version` (2)), optional `controls`
356
356
  * and `regInfo` (an object of regToken / authenticator / utf8Pairs / oldCertID / protocolEncrKey, or
357
357
  * pre-encoded AttributeTypeAndValue DER), and an optional `pop` selector. `key` (or `{ key }`) is the
358
- * REQUESTER's private key -- the private half of `certTemplate.publicKey`; the message carries a
358
+ * REQUESTER's private key, the private half of `certTemplate.publicKey`; the message carries a
359
359
  * `POPOSigningKey` proof of possession signed with it (verified before the message is returned), exactly
360
360
  * as a PKCS#10 CSR proves possession. The signature algorithm is resolved from the requested public key
361
361
  * (RSA PKCS#1 v1.5 / PSS, ECDSA, EdDSA, ML-DSA, SLH-DSA, or a composite arm). `key` is optional: omit it
@@ -373,7 +373,7 @@ function _buildProofOfPossession(pop, certReqDer, template, signingKey, opts) {
373
373
  * content type is `id-ct-encKeyWithID`. RFC 9810 sec. 5.2.8.3.1 permits it only where archival is
374
374
  * intended, so it takes `pop.archive: true`; `pop.privateKey` is the PKCS#8 DER, `pop.recipients` the CMS
375
375
  * recipients to envelope it to, and `pop.identifier` (a string or GeneralName) is required, because
376
- * sec. 4.2.1 makes it mandatory whenever the purpose is proving possession -- without it a decrypting
376
+ * sec. 4.2.1 makes it mandatory whenever the purpose is proving possession: without it a decrypting
377
377
  * agent cannot tell whose key it holds. `pop.contentEncryptionAlgorithm` defaults to `aes-256-cbc`; an
378
378
  * AEAD algorithm is refused, since it would produce an `AuthEnvelopedData` this field cannot carry.
379
379
  *
package/lib/csr-sign.js CHANGED
@@ -179,8 +179,8 @@ function _coerceCsr(request) {
179
179
  * requested extension, so none of them were altered after signing. It says nothing about who the
180
180
  * producer is: the key is self-asserted, the name is self-asserted, and a requester free to choose
181
181
  * both can prove possession of a key they generated a moment ago under any name they like. Binding
182
- * that name to an identity is the enrollment protocol's job -- `pki.est`, `pki.cmc`, `pki.cmp`, or
183
- * an out-of-band check -- and remains one after this returns `true`.
182
+ * that name to an identity is the enrollment protocol's job (`pki.est`, `pki.cmc`, `pki.cmp`, or
183
+ * an out-of-band check), and remains one after this returns `true`.
184
184
  *
185
185
  * Verification composes the one path-validation signature engine, with the same algorithm-confusion
186
186
  * (RFC 9814 sec. 4 key-OID == sig-OID) and EdDSA low-order-point gates, rather than the self-check
package/lib/ct.js CHANGED
@@ -34,7 +34,7 @@
34
34
  *
35
35
  * @card
36
36
  * Parse RFC 6962 Certificate Transparency SCT lists from a certificate or OCSP
37
- * extension -- per-SCT logId / timestamp (BigInt) / algorithm / raw signature,
37
+ * extension: per-SCT logId / timestamp (BigInt) / algorithm / raw signature,
38
38
  * the signed-preimage reconstruction surfaced for external verification,
39
39
  * bounded TLS-struct decode, fail-closed.
40
40
  */
@@ -230,13 +230,13 @@ function _u24Bytes(n) {
230
230
  * `entry` selects the log-entry arm:
231
231
  * - `{ entryType: 0, leafCert: <DER Buffer> }`, an SCT delivered over TLS /
232
232
  * OCSP, signed over `x509_entry(0)` with the leaf certificate.
233
- * - `{ entryType: 1, tbsCertificate: <DER Buffer>, issuerKeyHash: <32B> }` --
233
+ * - `{ entryType: 1, tbsCertificate: <DER Buffer>, issuerKeyHash: <32B> }`,
234
234
  * an SCT EMBEDDED in a certificate, signed over `precert_entry(1)` with the
235
235
  * issuer key hash + the precertificate TBS (the TBS with only the SCT
236
236
  * extension removed). `issuerKeyHash` is SHA-256 of the issuer's SPKI DER.
237
237
  *
238
238
  * The preimage reuses the parsed SCT's raw `extensions` byte-for-byte and
239
- * re-emits the fixed-width scalars canonically. This never verifies anything --
239
+ * re-emits the fixed-width scalars canonically. This never verifies anything;
240
240
  * a verifier hashes the returned bytes and checks the signature with the log's
241
241
  * public key (compose `webcrypto`). Throws `CtError` (`ct/bad-entry-type`,
242
242
  * `ct/bad-issuer-key-hash`, `ct/bad-tbs-length`) on a malformed entry, and
package/lib/est.js CHANGED
@@ -11,15 +11,15 @@
11
11
  *
12
12
  * @intro
13
13
  * Enrollment over Secure Transport (RFC 7030, updated by RFC 8951 and RFC 9908).
14
- * The network verbs -- `cacerts`, `simpleenroll`, `simplereenroll` -- run the thin
14
+ * The network verbs (`cacerts`, `simpleenroll`, `simplereenroll`) run the thin
15
15
  * RFC 7030 client: they compose the codecs below over the shared `pki.transport`
16
16
  * (a caller MAY inject `opts.transport`; the default is a fail-closed
17
17
  * `pki.transport.https`). This module opens no socket itself: the sole socket
18
18
  * choke point is `pki.transport`, so the verbs stay a thin, fail-closed shell:
19
19
  * https-only (`est/insecure-url`), an explicit trust anchor required
20
20
  * (`est/no-trust-anchors`), same-origin redirects followed but a downgrade / loop
21
- * refused, a 202 Retry-After SURFACED and never slept, HTTP Basic answered only
22
- * after the transport authenticated the server, and the issued certificate chosen
21
+ * refused, a 202 Retry-After SURFACED and never slept, HTTP Basic or Digest answered
22
+ * only after the transport authenticated the server, and the issued certificate chosen
23
23
  * by public-key match. Under them sit the transport-agnostic codecs, validators, and
24
24
  * request builders over the shipped CMS / CSR / PKCS#8 / X.509 parsers:
25
25
  * `transferDecode` / `transferEncode` are the RFC 8951
@@ -30,9 +30,9 @@
30
30
  * `parseServerKeygenResponse` dispatches the two-part key + certificate
31
31
  * response with recipient-arm coherence; `classifyResponse` is the HTTP status
32
32
  * / content-type / Retry-After state machine (202 accepted-not-ready surfaces
33
- * `retryAfterSeconds` -- never an internal sleep; 204/404 on /csrattrs is a
33
+ * `retryAfterSeconds`, never an internal sleep; 204/404 on /csrattrs is a
34
34
  * "none available" verdict, not an error). The builders assemble the CSR
35
- * attributes EST adds -- a channel-binding challengePassword, the
35
+ * attributes EST adds: a channel-binding challengePassword, the
36
36
  * out-of-band-key identifiers, SMIMECapabilities, and the RFC 9908
37
37
  * template-priority enroll plan.
38
38
  *
@@ -536,7 +536,7 @@ var NOT_IMPLEMENTED_OPS = { fullcmc: 1 };
536
536
  *
537
537
  * Classify an EST HTTP response into a verdict or a typed fault. A 200 requires
538
538
  * the operation's exact content-type (`est/bad-content-type`); a 202 requires a
539
- * Retry-After (absent -> `est/missing-retry-after`) -- a delay-seconds value is
539
+ * Retry-After (absent -> `est/missing-retry-after`): a delay-seconds value is
540
540
  * surfaced as bounded `retryAfterSeconds`, an HTTP-date as absolute
541
541
  * `retryAfterDate` (epoch ms; `retryAfterSeconds` too when `opts.now` is given),
542
542
  * and any other value is `est/bad-retry-after` (never slept on either way);
@@ -1006,7 +1006,7 @@ function _certsResult(op, res, opts, csrSpki) {
1006
1006
  * surfaced as `issuedCertificates` (with `certificate` the first), distinct from `certificates`,
1007
1007
  * which is the whole returned bag including any chain. Where the requested keys are distinct that
1008
1008
  * list is in request order; where several requests deliberately SHARE one key it is not, and does
1009
- * not claim to be -- the public key is the only identification sec. 4.1 sanctions, so when it is
1009
+ * not claim to be: the public key is the only identification sec. 4.1 sanctions, so when it is
1010
1010
  * shared nothing in the response says which of those requests a given certificate answers. That arm reports `signatureVerified: false`: a certs-only body is
1011
1011
  * a degenerate SignedData with no signers by definition, so its security rests on the authenticated
1012
1012
  * TLS channel, not on a signature.
@@ -1434,7 +1434,7 @@ function cacerts(baseUrl, opts) {
1434
1434
  * @opts
1435
1435
  * - `transport` / `tls` / `label` / `timeout` / `maxResponseBytes` / `maxRedirects` / `proxy` / `now`, as in pki.est.cacerts.
1436
1436
  * - `strict`: reject an enroll response that carries more than the single issued certificate.
1437
- * - `username` / `password` -- HTTP Basic credentials, answered only after server authorization (empty username allowed).
1437
+ * - `username` / `password` / `auth` -- HTTP credentials: top-level `username` / `password` mean Basic; `auth` (`{ scheme: "basic" | "digest", username, password, ... }`, as in pki.est.cacerts) selects Basic or Digest. Answered only after server authorization (empty username allowed).
1438
1438
  * - `allowCrossOriginRedirect` -- opt in to following a cross-origin redirect on this POST.
1439
1439
  * @example
1440
1440
  * var req = await pki.csr.sign({ subject: "device.example", subjectPublicKey: signerSpki }, { key: signerKeyPkcs8 });
@@ -90,8 +90,8 @@ class PkiError extends Error {
90
90
  * @status stable
91
91
  * @spec internal (design: error-class factory)
92
92
  *
93
- * Factory that produces a `PkiError` subclass with the standard shape --
94
- * eliminating the per-domain boilerplate. The returned constructor takes
93
+ * Factory that produces a `PkiError` subclass with the standard shape. The
94
+ * returned constructor takes
95
95
  * `(code, message)`, stamps `name`, sets an `is<Name>` flag, and exposes
96
96
  * a `.factory` static for the common `var _err = XxxError.factory` shape.
97
97
  * The `code` must be a `domain/reason` string (the base-class contract);
package/lib/hpke.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * @nav Protocols
7
7
  * @title HPKE
8
8
  * @fullname HPKE (Hybrid Public Key Encryption, RFC 9180)
9
- * @intro Hybrid Public Key Encryption (RFC 9180) -- the standard construction
9
+ * @intro Hybrid Public Key Encryption (RFC 9180): the standard construction
10
10
  * behind TLS Encrypted Client Hello, MLS, and OHTTP that turns a recipient KEM
11
11
  * public key into an encapsulated key plus an AEAD-encrypting context. This is
12
12
  * the RFC 9180 base construction: the DHKEM suites P-256, P-521, X25519, and
@@ -358,7 +358,7 @@ var suites = {
358
358
 
359
359
  /**
360
360
  * @primitive pki.hpke.setupS
361
- * @signature pki.hpke.setupS(suiteIds, recipientPublicKey, opts?) -> { enc, context }
361
+ * @signature pki.hpke.setupS(suiteIds, recipientPublicKey, opts?) -> { enc, context, sharedSecret }
362
362
  * @since 0.2.2
363
363
  * @status stable
364
364
  * @spec RFC 9180