@blamejs/pki 0.6.28 → 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.
- package/CHANGELOG.md +25 -0
- package/README.md +1 -1
- package/lib/acme.js +10 -8
- package/lib/asn1-der.js +9 -7
- package/lib/attrcert-sign.js +8 -8
- package/lib/byte-reader.js +1 -1
- package/lib/byte-writer.js +1 -1
- package/lib/cmc-verify.js +4 -4
- package/lib/cmp-build.js +9 -5
- package/lib/cmp-session.js +9 -4
- package/lib/cms-verify.js +22 -17
- package/lib/composite-kem.js +2 -2
- package/lib/constants.js +1 -0
- package/lib/crl-sign.js +5 -5
- package/lib/crmf-sign.js +3 -3
- package/lib/csr-sign.js +2 -2
- package/lib/ct.js +3 -3
- package/lib/est.js +34 -22
- package/lib/framework-error.js +2 -2
- package/lib/guard-identifier.js +18 -1
- package/lib/hpke.js +2 -2
- package/lib/http-transport.js +82 -10
- package/lib/inspect.js +1 -1
- package/lib/jose.js +1 -1
- package/lib/key.js +7 -7
- package/lib/lint.js +1 -1
- package/lib/merkle.js +2 -6
- package/lib/mime.js +2 -2
- package/lib/ocsp.js +6 -6
- package/lib/oid.js +1 -1
- package/lib/path-validate.js +13 -13
- package/lib/pkcs12-build.js +4 -4
- package/lib/rfc3339.js +2 -2
- package/lib/scep.js +3 -15
- package/lib/schema-all.js +1 -1
- package/lib/schema-attrcert.js +1 -1
- package/lib/schema-cmc.js +2 -2
- package/lib/schema-cmp.js +8 -9
- package/lib/schema-cms.js +3 -3
- package/lib/schema-crmf.js +3 -3
- package/lib/schema-csr.js +1 -1
- package/lib/schema-csrattrs.js +1 -1
- package/lib/schema-engine.js +4 -4
- package/lib/schema-ocsp.js +1 -1
- package/lib/schema-pkcs12.js +2 -2
- package/lib/schema-pkcs8.js +2 -2
- package/lib/schema-smime.js +1 -1
- package/lib/schema-tsp.js +6 -6
- package/lib/schema-x509.js +2 -2
- package/lib/shbs.js +3 -4
- package/lib/sign-scheme.js +1 -1
- package/lib/sigstore.js +2 -2
- package/lib/smime.js +16 -16
- package/lib/tls-cert-compress.js +7 -7
- package/lib/trust.js +5 -5
- package/lib/tsp-sign.js +8 -6
- package/lib/webauthn.js +23 -19
- package/lib/webcrypto.js +3 -3
- package/lib/x509-sign.js +5 -5
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/lint.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @nav Tooling
|
|
7
7
|
* @title Lint
|
|
8
8
|
* @fullname Certificate linting against CA/Browser Forum requirements
|
|
9
|
-
* @intro The certificate LINTING engine
|
|
9
|
+
* @intro The certificate LINTING engine, the zlint / pkilint of JavaScript. It walks an
|
|
10
10
|
* ALREADY-PARSED certificate (from `pki.schema.x509.parse`, whose extension values it
|
|
11
11
|
* decodes with the shared RFC 5280 decoders) and emits graded, advisory FINDINGS: each
|
|
12
12
|
* with a stable id, a severity (`fatal` > `error` > `warn` > `notice` > `pass`), a source,
|
package/lib/merkle.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* @intro
|
|
13
13
|
* RFC 6962 (Certificate Transparency) / RFC 9162 (CT 2.0) Merkle-tree hash
|
|
14
|
-
* and proof-verification core
|
|
14
|
+
* and proof-verification core: the load-bearing primitive a static-CT
|
|
15
15
|
* client, a Merkle-Tree-Certificates relying party, and a sigstore / Rekor
|
|
16
16
|
* inclusion check all compose. Every verb is strict verification over
|
|
17
17
|
* SHA-256: zero new crypto.
|
|
@@ -234,11 +234,7 @@ function verifyInclusion(opts) {
|
|
|
234
234
|
* `merkle/no-consistency-claim`. RFC 6962 sec. 2.1.2 defines the proof for
|
|
235
235
|
* `0 < oldSize < newSize`: the empty tree is a prefix of every tree by
|
|
236
236
|
* definition, so there is no proof to check and nothing at all binds `newRoot`.
|
|
237
|
-
*
|
|
238
|
-
* been proven, and a monitor written `if (!verifyConsistency(...)) alarm()` would
|
|
239
|
-
* take that silence for evidence. A caller with no prior tree has an inclusion
|
|
240
|
-
* question about the new one, or should start from a checkpoint it already
|
|
241
|
-
* trusts. Two empty trees are still answered:
|
|
237
|
+
* Two empty trees are still answered:
|
|
242
238
|
* that is the degenerate identity case, and both roots must be `emptyRootHash()`.
|
|
243
239
|
*
|
|
244
240
|
* A malformed input throws a typed `merkle/*` error: `oldSize > newSize`, a
|
package/lib/mime.js
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
"use strict";
|
|
4
4
|
/**
|
|
5
5
|
* @internal
|
|
6
|
-
* lib/mime.js
|
|
6
|
+
* lib/mime.js: a minimal MIME entity framer + canonicalizer, the message-layer engine primitive
|
|
7
7
|
* under pki.smime (RFC 8551 S/MIME) and any future MIME-carrying feature. It parses an entity into
|
|
8
8
|
* its headers + body, canonicalizes a text entity to the RFC 8551 sec. 3.1.1 form (CRLF line endings),
|
|
9
9
|
* splits a multipart body on its boundary, and builds an entity/multipart back. There is NO crypto
|
|
10
|
-
* here
|
|
10
|
+
* here. The CMS layer signs/verifies the canonical bytes this module produces.
|
|
11
11
|
*
|
|
12
12
|
* The load-bearing rule is canonicalization: the detached signature over a multipart/signed first part
|
|
13
13
|
* is computed over that part's canonical MIME form, so the signer and verifier MUST share one
|
package/lib/ocsp.js
CHANGED
|
@@ -352,14 +352,14 @@ function _certStatusNode(status, opts) {
|
|
|
352
352
|
|
|
353
353
|
/**
|
|
354
354
|
* @primitive pki.ocsp.buildErrorResponse
|
|
355
|
-
* @signature pki.ocsp.buildErrorResponse(status) -> Buffer
|
|
355
|
+
* @signature pki.ocsp.buildErrorResponse(status) -> Buffer
|
|
356
356
|
* @since 0.2.22
|
|
357
357
|
* @status stable
|
|
358
358
|
* @spec RFC 6960
|
|
359
359
|
* @related pki.ocsp.sign
|
|
360
360
|
*
|
|
361
|
-
* Build an UNSIGNED error OCSPResponse
|
|
362
|
-
* `sigRequired` / `unauthorized
|
|
361
|
+
* Build an UNSIGNED error OCSPResponse, one of `malformedRequest` / `internalError` / `tryLater` /
|
|
362
|
+
* `sigRequired` / `unauthorized`, carrying only the responseStatus and no responseBytes (RFC 6960
|
|
363
363
|
* sec. 2.3: an error message conveys no certificate status and is not signed).
|
|
364
364
|
*
|
|
365
365
|
* @example
|
|
@@ -374,7 +374,7 @@ function buildErrorResponse(status) {
|
|
|
374
374
|
|
|
375
375
|
/**
|
|
376
376
|
* @primitive pki.ocsp.verify
|
|
377
|
-
* @signature pki.ocsp.verify(response, opts) -> Promise<{ status, responderAuthorized, signatureValid, thisUpdate, nextUpdate, revocationReason?, revocationTime?, nonceMatched?, reason }>
|
|
377
|
+
* @signature pki.ocsp.verify(response, opts) -> Promise<{ status, responderAuthorized, signatureValid, matched, thisUpdate, nextUpdate, revocationReason?, revocationTime?, nonceMatched?, reason }>
|
|
378
378
|
* @since 0.2.22
|
|
379
379
|
* @status stable
|
|
380
380
|
* @spec RFC 6960, RFC 9654, RFC 5019
|
|
@@ -524,9 +524,9 @@ function _signerVerdict(parsed, found, failReason) {
|
|
|
524
524
|
* request carried (or opts.certs supplied), including intermediates that do not sign and so are absent
|
|
525
525
|
* from `signerCerts`: the responder passes it as the `opts.candidates` pool to `pki.path.build`, which
|
|
526
526
|
* discovers and validates the ordered path from a `signerCerts` entry (leaf) up to a trust anchor.
|
|
527
|
-
* The responder then confirms that certificate is authorized to sign the request
|
|
527
|
+
* The responder then confirms that certificate is authorized to sign the request: its `keyUsage`,
|
|
528
528
|
* where present, must assert `digitalSignature` (RFC 5280 sec. 4.2.1.3, since the certificate signed
|
|
529
|
-
* the request)
|
|
529
|
+
* the request). It also compares the certificate's subject to the `requestorName` it expects. The decoded
|
|
530
530
|
* `requestList`, `requestExtensions` and `version` are
|
|
531
531
|
* returned so the CertIDs being asked about need no re-parse.
|
|
532
532
|
*
|
package/lib/oid.js
CHANGED
|
@@ -446,7 +446,7 @@ function register(dotted, n) {
|
|
|
446
446
|
*
|
|
447
447
|
* Register a whole OID family in one call. `base` is the shared arc prefix
|
|
448
448
|
* (the starting variable a class of OIDs has in common) and `members` maps
|
|
449
|
-
* each name to its trailing arc
|
|
449
|
+
* each name to its trailing arc: a number, or a short arc array for a
|
|
450
450
|
* multi-level leaf. Each full OID is derived as `base` followed by the leaf,
|
|
451
451
|
* so a family is declared as its hierarchy and no full path is re-spelled.
|
|
452
452
|
* This is the primitive the built-in seed set itself is built from.
|
package/lib/path-validate.js
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
* @intro
|
|
11
11
|
* RFC 5280 6 certification-path validation as a pure, re-entrant algorithm
|
|
12
12
|
* over already-parsed certificates. `pki.path.validate(path, opts)` runs the
|
|
13
|
-
* 6.1 state machine
|
|
13
|
+
* 6.1 state machine (signature chaining, validity windows, name chaining,
|
|
14
14
|
* basic constraints and path length, key usage, name constraints, and the
|
|
15
|
-
* certificate-policy tree
|
|
15
|
+
* certificate-policy tree) and returns a structured verdict with a per-check
|
|
16
16
|
* reason code for every step. Validity-window enforcement is always on, with
|
|
17
17
|
* the check date an explicit input; the trust anchor is an input, never one of
|
|
18
18
|
* the validated certificates, and no input object is mutated.
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
* Revocation is a pluggable hook: `pki.path.crlChecker(crls)` ships a CRL
|
|
21
21
|
* consultation built on `pki.schema.crl.parse`; an OCSP checker satisfies the
|
|
22
22
|
* same interface. Signature verification derives its algorithm from the
|
|
23
|
-
* certificate and the issuer key
|
|
23
|
+
* certificate and the issuer key, never from a value the message controls,
|
|
24
24
|
* and fails closed on an unknown critical extension, an undetermined
|
|
25
25
|
* revocation status, or any structural fault.
|
|
26
26
|
*
|
|
27
27
|
* @card
|
|
28
|
-
* RFC 5280 6 certification-path validation
|
|
28
|
+
* RFC 5280 6 certification-path validation: run the 6.1 state machine over
|
|
29
29
|
* an ordered path and a trust anchor for a structured, fail-closed verdict
|
|
30
30
|
* with per-check reason codes. Pure and re-entrant.
|
|
31
31
|
*/
|
|
@@ -836,7 +836,7 @@ function validateCriticalExtensionStructure(cert) {
|
|
|
836
836
|
* inputs (`initialExplicitPolicy`,
|
|
837
837
|
* `initialAnyPolicyInhibit`, `initialPolicyMappingInhibit`,
|
|
838
838
|
* `userInitialPolicySet`, and `initialPermittedSubtrees` /
|
|
839
|
-
* `initialExcludedSubtrees
|
|
839
|
+
* `initialExcludedSubtrees`: arrays of `{ tag, base }` where `tag` is the
|
|
840
840
|
* GeneralName tag number and `base` that form's constraint value), an
|
|
841
841
|
* optional `requiredEku` (key purposes the target's extendedKeyUsage must
|
|
842
842
|
* assert, given as registered OID names or dotted OID strings; an absent
|
|
@@ -846,9 +846,9 @@ function validateCriticalExtensionStructure(cert) {
|
|
|
846
846
|
* are validated at the entry point. A mis-shaped value throws `path/bad-input`,
|
|
847
847
|
* so it cannot silently go unapplied. Returns `{ valid, revocationChecked, anchorConstraints,
|
|
848
848
|
* path, results, workingPublicKey, workingPublicKeyAlgorithm,
|
|
849
|
-
* workingPublicKeyParameters, validPolicyTree }` where `results[i].checks`
|
|
849
|
+
* workingPublicKeyParameters, validPolicyTree, userConstrainedPolicySet }` where `results[i].checks`
|
|
850
850
|
* carries a per-check reason code (`path/*`) for every step. Pure and
|
|
851
|
-
* re-entrant
|
|
851
|
+
* re-entrant: no input object is mutated. An empty path or a missing anchor
|
|
852
852
|
* throws a typed `PathError`.
|
|
853
853
|
*
|
|
854
854
|
* `valid` alone cannot say whether revocation was ever established, so
|
|
@@ -1365,7 +1365,7 @@ function selectDelta(candidates) {
|
|
|
1365
1365
|
* (`thisUpdate`/`nextUpdate`), and reports `{ status: "good"|"revoked"|
|
|
1366
1366
|
* "unknown" }`. A partitioned/sharded CRL (a critical IDP naming a
|
|
1367
1367
|
* distribution point) establishes "good" when it corresponds to one of the
|
|
1368
|
-
* certificate's own cRLDistributionPoints
|
|
1368
|
+
* certificate's own cRLDistributionPoints: at least one identically-encoded
|
|
1369
1369
|
* name in common (RFC 5280 sec. 6.3.3). Reason-sharded CRLs ACCUMULATE: each
|
|
1370
1370
|
* corresponding CRL contributes its interim reason mask (sec. 6.3.3(d)) and the
|
|
1371
1371
|
* certificate is "good" once the shards together cover all eight revocation
|
|
@@ -1713,21 +1713,21 @@ function ocspChecker(responses) {
|
|
|
1713
1713
|
* directly, or a CA-issued delegate bearing both id-kp-OCSPSigning and
|
|
1714
1714
|
* id-pkix-ocsp-nocheck and passing the full out-of-path certificate gates),
|
|
1715
1715
|
* verifies the response signature over `tbsResponseDataBytes`, and checks
|
|
1716
|
-
* currency (`thisUpdate`/`nextUpdate`)
|
|
1716
|
+
* currency (`thisUpdate`/`nextUpdate`). There is no weaker second OCSP verify
|
|
1717
1717
|
* path. It is fail-closed and never throws on an unauthorized, stale, or
|
|
1718
1718
|
* unverifiable response: those yield `{ status: "unknown" }` with the granular
|
|
1719
1719
|
* `responderAuthorized`/`signatureValid`/`matched` flags and a `reason`; a
|
|
1720
1720
|
* `revoked` status surfaces its `revocationReason`. Setting `opts.historicalMode`
|
|
1721
1721
|
* treats a revocation whose `revocationTime` is strictly after `time` as not-yet-
|
|
1722
|
-
* revoked (`good`)
|
|
1722
|
+
* revoked (`good`): for validating a signature as of a past `time`, before the
|
|
1723
1723
|
* certificate was later revoked; the responder certificate is still validated at
|
|
1724
1724
|
* `time` either way. `time` must be a valid `Date`. A malformed response's parse
|
|
1725
1725
|
* fault surfaces as the parser's typed `ocsp/*` / `asn1/*` error.
|
|
1726
1726
|
*
|
|
1727
1727
|
* The response is its DER bytes, a PEM string, or an unmodified
|
|
1728
1728
|
* `pki.schema.ocsp.parseResponse` result. A REBUILT parsed response is refused. A
|
|
1729
|
-
* signature check has three parts
|
|
1730
|
-
* and the bytes it covers
|
|
1729
|
+
* signature check has three parts (the signature, the algorithm that verifies it,
|
|
1730
|
+
* and the bytes it covers) and on a parsed object all three are separate properties:
|
|
1731
1731
|
* a genuine CA signature over a certificate that CA issued, relabeled, verifies as a
|
|
1732
1732
|
* ResponseData signature for a response that never existed. The parser marks what it
|
|
1733
1733
|
* returns, so those three are known to have been derived together from one byte
|
|
@@ -2285,7 +2285,7 @@ async function _fetchAiaIssuers(current, aia) {
|
|
|
2285
2285
|
* from a certificate's Authority Information Access `caIssuers` URL (RFC 5280 sec. 4.2.2.1) over
|
|
2286
2286
|
* `pki.transport`: the fetch triggers only on a pool miss, every fetched certificate is UNTRUSTED pool material
|
|
2287
2287
|
* that still flows through `validate` when validation is on (never a trust anchor), and the whole surface is
|
|
2288
|
-
* SSRF/amplification bounded
|
|
2288
|
+
* SSRF/amplification bounded: https-only, a total fetch budget (a SILENT cap, never a throw that denies a
|
|
2289
2289
|
* buildable path), a per-cert URL cap, a build-wide URL dedupe, a response size + certificate-count cap, and no
|
|
2290
2290
|
* redirect following; every fetch fault is a silent skip. `aiaFetches` reports how many network GETs the build
|
|
2291
2291
|
* performed (`0` when `fetchAia` is off). NOTE: with `opts.validate:false` (pure-builder mode) a fetched cert is
|
package/lib/pkcs12-build.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @title PKCS#12
|
|
8
8
|
* @fullname PKCS#12 keystores (.p12 and .pfx): build and open
|
|
9
9
|
* @intro The PKCS#12 (.p12 / .pfx) producing side (RFC 7292, RFC 9579). `pki.pkcs12.build` assembles a
|
|
10
|
-
* password-integrity PFX
|
|
10
|
+
* password-integrity PFX: key, certificate, CRL, and secret bags (shrouded keys and cert safes encrypted
|
|
11
11
|
* under RFC 8018 PBES2) wrapped in an AuthenticatedSafe, protected by either a classic Appendix B HMAC or
|
|
12
12
|
* an RFC 9579 PBMAC1 (PBKDF2 + HMAC) MAC, over AES-128/192/256-CBC and SHA-256/384/512. Every password is
|
|
13
13
|
* encoded the PKCS#12 way (BMPString + NULL, Appendix B.1), so a file it emits opens in OpenSSL and NSS.
|
|
@@ -427,7 +427,7 @@ function _normalizeSpec(spec, opts, form) {
|
|
|
427
427
|
*
|
|
428
428
|
* @opts
|
|
429
429
|
* - `password` -- the shared privacy + integrity password (string / Buffer / Uint8Array).
|
|
430
|
-
* - `mac` -- `false` for a MAC-less store, or `{ algorithm: 'hmac'(default)|'pbmac1', hash: 'sha256'(default)|'sha1'|'sha384'|'sha512', salt?, iterations? }`. `keyLength` is a `pbmac1` field: the classic Appendix B derivation produces a key at the hash's own output length, and naming one under `hmac` is refused.
|
|
430
|
+
* - `mac` -- `false` for a MAC-less store, or `{ algorithm: 'hmac'(default)|'pbmac1', hash: 'sha256'(default)|'sha1'|'sha384'|'sha512', salt?, iterations?, password? }`. `password` overrides the shared integrity password for the MAC. `keyLength` is a `pbmac1` field: the classic Appendix B derivation produces a key at the hash's own output length, and naming one under `hmac` is refused.
|
|
431
431
|
* - `integrity` -- `{ mode: 'public-key', signer: { cert, key, digestAlgorithm?, pss? } | signers: [ ... ], sid?, signingTime?, certificates? }` for public-key integrity (a CMS SignedData authSafe over any `pki.cms.sign` signer algorithm, no MacData). Combining it with a truthy `mac` is rejected.
|
|
432
432
|
* - `recipientCerts` -- (public-key privacy convenience) `[certDer|PEM, ...]`; the convenience-form cert + key are placed in one recipient-enveloped safe (a plaintext keyBag). For the full form, set per-`safeContents` `recipients: [{ cert }, ...]` -- CERTIFICATE recipients only (RSA-OAEP / ECDH / X25519 / X448 / ML-KEM, dispatched off the cert key); a password or KEK recipient is not public-key privacy and is rejected -- with an optional `contentEncryptionAlgorithm` (`aes-128|192|256-cbc`, default 256; GCM/AEAD rejected). `encrypt` (password) and `recipients` (public-key) on the same safe is rejected; privacy is independent of integrity.
|
|
433
433
|
* - `pem` (boolean) -- return a PEM `PKCS12` string instead of DER.
|
|
@@ -534,7 +534,7 @@ async function _build(spec, opts) {
|
|
|
534
534
|
* a byte range the object carries, and the parser's mark is what says that range and the store it describes
|
|
535
535
|
* came from one place. `Object.assign`, spread and a JSON round-trip drop the mark. The password is BMPString+NULL encoded (RFC 7292 App. B.1), the MAC is
|
|
536
536
|
* recomputed over the store's exact AuthenticatedSafe byte range (`macedBytes`) using the store's own MAC
|
|
537
|
-
* parameters
|
|
537
|
+
* parameters, the classic Appendix B (ID=3) HMAC or the RFC 9579 PBMAC1, and constant-time-compared to
|
|
538
538
|
* the stored MAC value. The verdict's `valid` is the password match, and `macAlgorithm` (`hmac` or `pbmac1`),
|
|
539
539
|
* `macAlgorithmName` (the digest / scheme, e.g. `sha1`, `sha256`), and `iterationCount` name the integrity
|
|
540
540
|
* algorithm the store used, so a caller can reject a legacy SHA-1 MAC by inspecting them rather than
|
|
@@ -617,7 +617,7 @@ function _capWork(iterations, salt, opts, keyLength, hardCap) {
|
|
|
617
617
|
* SignedData signature, per RFC 7292 sec. 4 / 5.1, so no bag from a store whose integrity check fails is trusted),
|
|
618
618
|
* then decrypt every PBES2 privacy safe and pkcs8ShroudedKeyBag with the password, and every id-envelopedData
|
|
619
619
|
* (public-key privacy) safe with `opts.recipientKey` (RFC 7292 sec. 3.1, via `pki.cms.decrypt`), returning a
|
|
620
|
-
* structured bundle `{ integrityMode, macVerified, signers, keys, certs, crls, secrets }` with each private key as PKCS#8
|
|
620
|
+
* structured bundle `{ valid, integrityMode, macVerified, signers, keys, certs, crls, secrets }` with each private key as PKCS#8
|
|
621
621
|
* `PrivateKeyInfo` DER (re-validated), each certificate / CRL / secret as raw DER, all carrying their
|
|
622
622
|
* `friendlyName` / `localKeyId` for pairing. `pfx` is the store's DER `Buffer`, a PEM string, or an
|
|
623
623
|
* unmodified `pki.schema.pkcs12.parse` result; a rebuilt parsed store is refused, since the bytes whose
|
package/lib/rfc3339.js
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"use strict";
|
|
4
4
|
/**
|
|
5
5
|
* @internal
|
|
6
|
-
* lib/rfc3339.js
|
|
6
|
+
* lib/rfc3339.js: RFC 3339 date-time parsing + validation, a fail-closed engine primitive shared by
|
|
7
7
|
* pki.acme (a boolean field-validator over server-supplied JSON) and pki.ct (parse a CT log-list
|
|
8
8
|
* timestamp / temporal-interval bound to a comparable Date). Beyond the grammar it enforces CALENDAR
|
|
9
|
-
* validity
|
|
9
|
+
* validity: a syntactically well-formed but impossible instant (month 13, February 30, hour 25, a
|
|
10
10
|
* :60 leap second, a +25:00 offset) is rejected, so a downstream expiry / window comparison never runs
|
|
11
11
|
* on a value JS `Date` would silently roll over or `Date.parse` would NaN. Like the byte-reader / guard
|
|
12
12
|
* family, `parse` takes the caller's `(code, message) -> error` factory so every consumer keeps its own
|
package/lib/scep.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* issued certificate) in two nested CMS layers: an inner EnvelopedData
|
|
15
15
|
* (`pkcsPKIEnvelope`) that encrypts the messageData to the recipient, and an
|
|
16
16
|
* outer SignedData that signs it under a set of authenticated transaction
|
|
17
|
-
* attributes
|
|
17
|
+
* attributes: messageType, transactionID, pkiStatus, failInfo, and the
|
|
18
18
|
* sender/recipient nonces (RFC 8894 sec. 3). `pki.scep.build` assembles a
|
|
19
19
|
* request pkiMessage (PKCSReq, RenewalReq, CertPoll, GetCert, or GetCRL) or a
|
|
20
20
|
* CA-side CertRep response; `pki.scep.parse` verifies the
|
|
@@ -520,7 +520,7 @@ async function parse(bytes, opts) {
|
|
|
520
520
|
var messageType = MESSAGE_TYPE_BY_CODE[messageTypeCode];
|
|
521
521
|
if (messageType == null) throw _err("scep/bad-message-type", "unknown messageType " + JSON.stringify(messageTypeCode) + " (RFC 8894 sec. 3.2.1.2)");
|
|
522
522
|
if (_PARSE_SUPPORTED[messageType] !== 1) {
|
|
523
|
-
throw _err("scep/unsupported-message-type", "pki.scep.parse reads
|
|
523
|
+
throw _err("scep/unsupported-message-type", "pki.scep.parse reads " + Object.keys(_PARSE_SUPPORTED).join(", ") + "; " + messageType + " is not read in this release");
|
|
524
524
|
}
|
|
525
525
|
var out = {
|
|
526
526
|
signatureValid: true, signerAuthenticated: signerAuthenticated, signerCert: signer.cert,
|
|
@@ -717,19 +717,7 @@ function _drive(method, url, body, headers, opts, transport, budgets) {
|
|
|
717
717
|
}
|
|
718
718
|
return step(url);
|
|
719
719
|
}
|
|
720
|
-
function
|
|
721
|
-
function _snapshotProxy(p) {
|
|
722
|
-
if (p == null || typeof p !== "object" || Array.isArray(p)) return p;
|
|
723
|
-
var out = Object.assign({}, p);
|
|
724
|
-
if (p.auth != null && typeof p.auth === "object" && !Array.isArray(p.auth)) out.auth = Object.assign({}, p.auth);
|
|
725
|
-
if (p.tls != null && typeof p.tls === "object" && !Array.isArray(p.tls)) {
|
|
726
|
-
out.tls = Object.assign({}, p.tls);
|
|
727
|
-
var a = p.tls.anchors;
|
|
728
|
-
if (Array.isArray(a)) out.tls.anchors = a.map(_copyAnchor);
|
|
729
|
-
else if (a != null) out.tls.anchors = _copyAnchor(a);
|
|
730
|
-
}
|
|
731
|
-
return out;
|
|
732
|
-
}
|
|
720
|
+
function _snapshotProxy(p) { return httpTransport.snapshotProxy(p); }
|
|
733
721
|
function _client(method, url, body, headers, opts) {
|
|
734
722
|
var transport = opts.transport || httpTransport.https({ E: _err, errPrefix: "scep" });
|
|
735
723
|
var budgets = {
|
package/lib/schema-all.js
CHANGED
|
@@ -153,7 +153,7 @@ var FORMATS = [
|
|
|
153
153
|
* The names of every registered format, in detection order.
|
|
154
154
|
*
|
|
155
155
|
* @example
|
|
156
|
-
* pki.schema.all(); // -> ["cms", "tsp", "crmf", "cmp", "ocsp-request", "ocsp-response", "pkcs12", "pkcs8", "csr", "attrcert", "attrcert-v1", "crl", "x509"]
|
|
156
|
+
* pki.schema.all(); // -> ["cms", "tsp", "crmf", "cmp", "csrattrs", "ocsp-request", "ocsp-response", "pkcs12", "pkcs8", "csr", "attrcert", "attrcert-v1", "crl", "x509"]
|
|
157
157
|
*/
|
|
158
158
|
function all() { return FORMATS.map(function (f) { return f.name; }); }
|
|
159
159
|
|
package/lib/schema-attrcert.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* @intro
|
|
12
12
|
* X.509 Attribute Certificate handling per RFC 5755. An attribute certificate
|
|
13
13
|
* binds a holder to a set of privilege attributes (role, group, clearance)
|
|
14
|
-
* without carrying a public key
|
|
14
|
+
* without carrying a public key, the authorization counterpart to an identity
|
|
15
15
|
* certificate. `parse` decodes a v2 `AttributeCertificate` into its holder,
|
|
16
16
|
* issuer, validity window (real `Date`s), attributes, and extensions, reusing
|
|
17
17
|
* the shared signed-envelope so the raw `tbsBytes` (the exact signed region) and
|
package/lib/schema-cmc.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* RFC 5272 CMC message-layer decoding, as updated by RFC 6402. A Full PKI
|
|
13
13
|
* Request (`PKIData`) and a Full PKI Response (`PKIResponse`) both ride inside
|
|
14
14
|
* a CMS SignedData (or AuthenticatedData) as the encapsulated content, named by
|
|
15
|
-
* the eContentType `id-cct-PKIData` / `id-cct-PKIResponse
|
|
15
|
+
* the eContentType `id-cct-PKIData` / `id-cct-PKIResponse`, so `parse` peels
|
|
16
16
|
* the CMS layer, dispatches on that content type, and decodes the message.
|
|
17
17
|
*
|
|
18
18
|
* Every body part carries a `BodyPartID`, and the identifier MUST be unique
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* unrecognized control is data, not a fault, because the rule that a server
|
|
23
23
|
* fails an unrecognized control binds the server, not the client reading a
|
|
24
24
|
* response. The status controls (`CMCStatusInfo` v1 and `CMCStatusInfoV2`) are
|
|
25
|
-
* collected in wire order
|
|
25
|
+
* collected in wire order. A response may carry several verdicts, and the
|
|
26
26
|
* ABSENCE of one means success.
|
|
27
27
|
*
|
|
28
28
|
* The `reqSequence` byte range is surfaced exactly as it appeared on the wire,
|
package/lib/schema-cmp.js
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
* CRMF parser; response, revocation, confirmation, error, general-message,
|
|
23
23
|
* and polling arms decode structurally (an encrypted certificate's
|
|
24
24
|
* EnvelopedData decodes via the CMS parser); every other defined arm is
|
|
25
|
-
* recognized and surfaced raw
|
|
25
|
+
* recognized and surfaced raw; `nested` messages are never auto-recursed.
|
|
26
26
|
* Protection is surfaced, not verified: the exact `headerBytes` and
|
|
27
27
|
* `bodyBytes` wire slices are exposed so an external verifier reconstructs
|
|
28
28
|
* the virtual ProtectedPart `SEQUENCE { header, body }` and checks the MAC
|
|
@@ -725,7 +725,7 @@ var readName = _valueParser("Name", pkix.name(NS));
|
|
|
725
725
|
* Parse a DER `Buffer` or a PEM string into a structured PKIMessage:
|
|
726
726
|
* `{ header, headerBytes, body, bodyBytes, protection, extraCerts }`.
|
|
727
727
|
* `header` carries `pvno` (1..3), `sender` / `recipient` (validated
|
|
728
|
-
* GeneralNames
|
|
728
|
+
* GeneralNames, the anonymous NULL-DN form included), and the optional
|
|
729
729
|
* `messageTime`, `protectionAlg`, `senderKID` / `recipKID`,
|
|
730
730
|
* `transactionID`, `senderNonce` / `recipNonce`, `freeText`, and
|
|
731
731
|
* `generalInfo` (recognized id-it types value-checked: implicitConfirm is
|
|
@@ -734,14 +734,14 @@ var readName = _valueParser("Name", pkix.name(NS));
|
|
|
734
734
|
* (`ir` / `cr` / `kur` / `krr` / `ccr`) decode via the CRMF parser;
|
|
735
735
|
* `ip` / `cp` / `kup` / `ccp` decode to `{ caPubs, response }` (an encrypted
|
|
736
736
|
* certificate's EnvelopedData decodes via the CMS parser; the deprecated
|
|
737
|
-
* EncryptedValue arm and `caPubs` surface raw
|
|
737
|
+
* EncryptedValue arm and `caPubs` surface raw; the parser confers no
|
|
738
738
|
* trust); `krp` decodes to `{ status, newSigCert, caCerts, keyPairHist }`;
|
|
739
739
|
* `rr` / `rp`, `genm` / `genp`, `error`, `certConf` (an empty
|
|
740
740
|
* confirmation is the legal reject-all), and `pollReq` / `pollRep` decode
|
|
741
|
-
* structurally; `pkiconf` decodes to `null`; every other defined arm
|
|
742
|
-
* `p10cr` (feed `body.bytes` to
|
|
743
|
-
* challenge-response and announcement arms,
|
|
744
|
-
* auto-recursed)
|
|
741
|
+
* structurally; `pkiconf` decodes to `null`; every other defined arm
|
|
742
|
+
* surfaces raw with `decoded` absent: `p10cr` (feed `body.bytes` to
|
|
743
|
+
* `pki.schema.csr.parse`), the challenge-response and announcement arms,
|
|
744
|
+
* and `nested` (never auto-recursed). `certReqId` values
|
|
745
745
|
* are BigInt and accept the protocol's -1 sentinel.
|
|
746
746
|
*
|
|
747
747
|
* Protection is surfaced, not verified: `protection` carries the raw,
|
|
@@ -785,8 +785,7 @@ var parse = pkix.makeParser({
|
|
|
785
785
|
* @related pki.schema.cmp.parse
|
|
786
786
|
*
|
|
787
787
|
* Extract the DER bytes from a PEM block (default label `CMP`). CMP is
|
|
788
|
-
* wire-DER over HTTP (RFC 9811)
|
|
789
|
-
* messages that transit text channels.
|
|
788
|
+
* wire-DER over HTTP (RFC 9811).
|
|
790
789
|
*
|
|
791
790
|
* @example
|
|
792
791
|
* var pair = await pki.key.generate("Ed25519");
|
package/lib/schema-cms.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @intro
|
|
12
12
|
* CMS handling per RFC 5652 (sec. 3 ContentInfo envelope). `parse` turns a DER or PEM
|
|
13
|
-
* (`CMS`) message into a structured object and is an OID-dispatch envelope
|
|
13
|
+
* (`CMS`) message into a structured object and is an OID-dispatch envelope:
|
|
14
14
|
* ContentInfo reads its `contentType` and structurally decodes SignedData (sec. 5),
|
|
15
15
|
* EnvelopedData (sec. 6, with all five RecipientInfo kinds: key-transport,
|
|
16
16
|
* key-agreement per RFC 5753, KEK, password, and other, including the RFC 9629
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
* parse but an out-of-set element does. DER-only, fail-closed.
|
|
39
39
|
*
|
|
40
40
|
* @card
|
|
41
|
-
* Parse DER / PEM CMS (RFC 5652 / 5083 / 9629) into structured, validated fields
|
|
42
|
-
*
|
|
41
|
+
* Parse DER / PEM CMS (RFC 5652 / 5083 / 9629) into structured, validated fields:
|
|
42
|
+
* signed, enveloped, encrypted, authenticated, and auth-enveloped content;
|
|
43
43
|
* raw attribute bytes for external verification; certificates/CRLs kept raw,
|
|
44
44
|
* fail-closed.
|
|
45
45
|
*/
|
package/lib/schema-crmf.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @intro
|
|
12
12
|
* Certificate Request Message Format handling per RFC 4211. `parse` decodes a
|
|
13
|
-
* `CertReqMessages
|
|
13
|
+
* `CertReqMessages`, the request body CMP and EST enrollment carry, into an
|
|
14
14
|
* array of messages, each with its `CertRequest` (certReqId, a `CertTemplate`
|
|
15
15
|
* of the requested certificate fields, and any registration controls), an
|
|
16
16
|
* optional proof-of-possession, and optional registration info.
|
|
@@ -327,7 +327,7 @@ var CERT_REQ_MESSAGES = schema.seqOf(CERT_REQ_MSG, {
|
|
|
327
327
|
* surfaced. `popo` is
|
|
328
328
|
* `null`, `{ type: "raVerified" }`, `{ type: "signature", poposkInput,
|
|
329
329
|
* algorithmIdentifier, signature }`, or `{ type: "keyEncipherment" |
|
|
330
|
-
* "keyAgreement", method, bytes }` (where `method` is the POPOPrivKey alternative
|
|
330
|
+
* "keyAgreement", method, bytes }` (where `method` is the POPOPrivKey alternative:
|
|
331
331
|
* `thisMessage` / `subsequentMessage` / `dhMAC` / `agreeMAC` / `encryptedKey`, each
|
|
332
332
|
* structurally validated, the `encryptedKey` EnvelopedData included). When present, `poposkInput` is
|
|
333
333
|
* `{ bytes, signedBytes, publicKey }`, where `bytes` is the raw wire `[0]` TLV,
|
|
@@ -385,7 +385,7 @@ function pemDecode(text, label) { return pkix.pemDecode(text, label || null, Pem
|
|
|
385
385
|
* @related pki.schema.crmf.pemDecode
|
|
386
386
|
*
|
|
387
387
|
* Wrap DER bytes in a PEM envelope. RFC 4211 registers no RFC 7468 label, so
|
|
388
|
-
* `label` is REQUIRED
|
|
388
|
+
* `label` is REQUIRED: the operator names the envelope explicitly (mirroring
|
|
389
389
|
* `pemDecode`, which accepts any label). Omitting it throws `pem/bad-label`.
|
|
390
390
|
*
|
|
391
391
|
* @example
|
package/lib/schema-csr.js
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* A CSR is self-signed only in the sense that the requester proves possession of
|
|
22
22
|
* the private key; unlike a certificate or CRL there is no inner signature
|
|
23
23
|
* algorithm to agree with, the subject MAY be empty, and the attribute set has
|
|
24
|
-
* no uniqueness constraint
|
|
24
|
+
* no uniqueness constraint: the parser deliberately omits those three
|
|
25
25
|
* certificate/CRL guards.
|
|
26
26
|
*
|
|
27
27
|
* @card
|
package/lib/schema-csrattrs.js
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* and `id-aa-certificationRequestInfoTemplate` -> a fully-decoded `template`.
|
|
25
25
|
*
|
|
26
26
|
* Structure is strict-DER throughout, but UNKNOWN OIDs and attribute types
|
|
27
|
-
* are TOLERATED
|
|
27
|
+
* are TOLERATED: surfaced raw, never a parse fault ("the client MUST ignore
|
|
28
28
|
* any OID or attribute it does not recognize", RFC 8951 sec. 4.5.2). The
|
|
29
29
|
* RFC 9908 semantic MUSTs that ARE enforced fail closed with a typed
|
|
30
30
|
* `csrattrs/*` code: at most one `id-ExtensionReq` attribute, its values a SET
|
package/lib/schema-engine.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* @order 60
|
|
10
10
|
*
|
|
11
11
|
* @intro
|
|
12
|
-
* L2 of the ASN.1 stack
|
|
12
|
+
* L2 of the ASN.1 stack: a declarative structure-schema engine. A schema is
|
|
13
13
|
* plain data (`{kind, ...}` descriptors built by the combinators here) and
|
|
14
14
|
* `walk(schema, node, ctx)` interprets it against a decoded DER node. The
|
|
15
15
|
* engine is where every cross-cutting structural rule lives ONCE: the shape
|
|
@@ -179,7 +179,7 @@ function implicitSeqOf(tag, item, opts) {
|
|
|
179
179
|
* Interpret a declarative schema against a decoded DER node, enforcing the
|
|
180
180
|
* schema's structural rules (shape assertion, arity, optional / context-tagged
|
|
181
181
|
* fields in increasing tag order, SET-OF uniqueness) and returning the built
|
|
182
|
-
* value
|
|
182
|
+
* value, or the match tree (`{ node, fields | items }`, with the build output
|
|
183
183
|
* on `.result`) for a structure with no build fn. `ctx = { E, prefix, oid }`
|
|
184
184
|
* supplies the typed-error constructor, the error-code family prefix, and the
|
|
185
185
|
* OID registry a build fn resolves names through.
|
|
@@ -464,8 +464,8 @@ function _encodeChoice(schema, value, ctx) {
|
|
|
464
464
|
* @related pki.schema.engine.walk, pki.asn1.decode
|
|
465
465
|
*
|
|
466
466
|
* Decode a fresh DER (or, with `ber: true`, BER) blob carried inside an
|
|
467
|
-
* already-decoded value
|
|
468
|
-
* structure
|
|
467
|
+
* already-decoded value (an OCTET STRING whose content is itself an encoded
|
|
468
|
+
* structure) and walk it against a schema. A codec failure is wrapped in the
|
|
469
469
|
* caller's typed `code`; a schema rejection keeps its own code. This is the
|
|
470
470
|
* one named form of the re-decode idiom, so the caps that a fresh
|
|
471
471
|
* `pki.asn1.decode` would restart from zero can be carried across re-decode
|
package/lib/schema-ocsp.js
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
*
|
|
30
30
|
* @card
|
|
31
31
|
* Parse DER / PEM OCSP requests and responses (RFC 6960) into structured,
|
|
32
|
-
* validated fields
|
|
32
|
+
* validated fields: per-certificate status, responder identity, raw tbs bytes for
|
|
33
33
|
* external verification, certificates kept raw, fail-closed.
|
|
34
34
|
*/
|
|
35
35
|
|
package/lib/schema-pkcs12.js
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
* MAC-less store surfaces `integrityMode: "none"` for the caller's policy
|
|
28
28
|
* to judge. RFC 7292
|
|
29
29
|
* sec. 4.1 encodes content in BER, so parsing this one format accepts exactly
|
|
30
|
-
* two BER shapes
|
|
30
|
+
* two BER shapes (indefinite lengths and constructed OCTET STRINGs)
|
|
31
31
|
* anywhere in the store; every other strictness verdict, and every other
|
|
32
32
|
* format, stays strict DER, fail-closed.
|
|
33
33
|
*
|
|
@@ -406,7 +406,7 @@ function _buildBag(rec, state, ctx) {
|
|
|
406
406
|
* Parse a DER / BER `Buffer` or a PEM string into a structured PFX:
|
|
407
407
|
* `{ version, integrityMode, mac, macedBytes, authSafeSigned, safeBags,
|
|
408
408
|
* encryptedSafes }`. `integrityMode` is `"password"` (id-data authSafe with
|
|
409
|
-
* MacData
|
|
409
|
+
* MacData: `mac` carries `{ kind, hashOid, hashName, hashParameters,
|
|
410
410
|
* pbmac1, macValue, macSalt, iterations }`, where `kind` distinguishes the
|
|
411
411
|
* RFC 9579 PBMAC1 arm; for PBMAC1 the required parameters are validated and
|
|
412
412
|
* decoded onto `pbmac1` (`{ kdf: { salt, iterationCount, keyLength, prfOid,
|
package/lib/schema-pkcs8.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
*
|
|
20
20
|
* A PKCS#8 key is a container, not a signed structure: it has no signature, no
|
|
21
21
|
* distinguished name, and no to-be-signed region. The private-key OCTET STRING
|
|
22
|
-
* content is kept raw
|
|
22
|
+
* content is kept raw: the algorithm-specific inner key (an RSAPrivateKey, an
|
|
23
23
|
* ECPrivateKey, a CurvePrivateKey) is decoded by the caller using the surfaced
|
|
24
24
|
* algorithm OID, so an unknown or future key type never fails the parse. An
|
|
25
25
|
* `ENCRYPTED PRIVATE KEY` (EncryptedPrivateKeyInfo, RFC 5958 sec. 3) is recognized
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
*
|
|
29
29
|
* @card
|
|
30
30
|
* Parse DER / PEM PKCS#8 private keys (RFC 5208 / 5958) into structured,
|
|
31
|
-
* validated fields
|
|
31
|
+
* validated fields: algorithm, raw key bytes, attributes, optional public key,
|
|
32
32
|
* fail-closed. Encrypted keys are recognized, not decrypted.
|
|
33
33
|
*/
|
|
34
34
|
|
package/lib/schema-smime.js
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
*
|
|
38
38
|
* @card
|
|
39
39
|
* Decode RFC 5035 ESS SigningCertificate / SigningCertificateV2 and RFC 8551
|
|
40
|
-
* SMIMECapabilities signed-attribute values
|
|
40
|
+
* SMIMECapabilities signed-attribute values: cert-hash binding, validated
|
|
41
41
|
* issuer GeneralNames, ordered capability list, OID-dispatched, fail-closed.
|
|
42
42
|
*/
|
|
43
43
|
|
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
|
|
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
|
|
283
|
-
* encapsulates
|
|
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
|
|
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)
|
|
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
|
|
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
|
package/lib/schema-x509.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @intro
|
|
14
14
|
* X.509 certificate handling per RFC 5280. The seed surface is
|
|
15
|
-
* `parse
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
package/lib/sign-scheme.js
CHANGED
|
@@ -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];
|