@blamejs/pki 0.6.29 → 0.6.31

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 (60) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +1 -1
  3. package/lib/acme.js +8 -7
  4. package/lib/asn1-der.js +9 -7
  5. package/lib/attrcert-sign.js +8 -8
  6. package/lib/byte-reader.js +1 -1
  7. package/lib/byte-writer.js +1 -1
  8. package/lib/cmc-verify.js +4 -4
  9. package/lib/cmp-build.js +3 -3
  10. package/lib/cmp-session.js +3 -3
  11. package/lib/cmp-verify.js +2 -1
  12. package/lib/cms-verify.js +22 -17
  13. package/lib/composite-kem.js +2 -2
  14. package/lib/crl-sign.js +5 -5
  15. package/lib/crmf-sign.js +3 -3
  16. package/lib/csr-sign.js +2 -2
  17. package/lib/ct.js +3 -3
  18. package/lib/est.js +40 -8
  19. package/lib/framework-error.js +2 -2
  20. package/lib/hpke.js +2 -2
  21. package/lib/http-transport.js +61 -14
  22. package/lib/inspect.js +1 -1
  23. package/lib/jose.js +1 -1
  24. package/lib/key.js +7 -7
  25. package/lib/lint.js +1 -1
  26. package/lib/merkle.js +2 -6
  27. package/lib/mime.js +2 -2
  28. package/lib/ocsp.js +6 -6
  29. package/lib/oid.js +1 -1
  30. package/lib/path-validate.js +13 -13
  31. package/lib/pkcs12-build.js +4 -4
  32. package/lib/rfc3339.js +2 -2
  33. package/lib/scep.js +2 -2
  34. package/lib/schema-all.js +1 -1
  35. package/lib/schema-attrcert.js +1 -1
  36. package/lib/schema-cmc.js +2 -2
  37. package/lib/schema-cmp.js +8 -9
  38. package/lib/schema-cms.js +3 -3
  39. package/lib/schema-crmf.js +3 -3
  40. package/lib/schema-csr.js +1 -1
  41. package/lib/schema-csrattrs.js +1 -1
  42. package/lib/schema-engine.js +4 -4
  43. package/lib/schema-ocsp.js +1 -1
  44. package/lib/schema-pkcs12.js +2 -2
  45. package/lib/schema-pkcs8.js +2 -2
  46. package/lib/schema-smime.js +1 -1
  47. package/lib/schema-tsp.js +6 -6
  48. package/lib/schema-x509.js +2 -2
  49. package/lib/shbs.js +3 -4
  50. package/lib/sign-scheme.js +1 -1
  51. package/lib/sigstore.js +2 -2
  52. package/lib/smime.js +16 -16
  53. package/lib/tls-cert-compress.js +7 -7
  54. package/lib/trust.js +5 -5
  55. package/lib/tsp-sign.js +8 -6
  56. package/lib/webauthn.js +23 -19
  57. package/lib/webcrypto.js +3 -3
  58. package/lib/x509-sign.js +5 -5
  59. package/package.json +1 -1
  60. package/sbom.cdx.json +6 -6
package/lib/webauthn.js CHANGED
@@ -17,7 +17,7 @@
17
17
  * `pki.path.validate` is the caller's step: this module verifies the statement, not
18
18
  * the certificate chain. A verifier, not a ceremony client: the relying party
19
19
  * supplies the clientDataHash + any trust anchors; this module never touches a
20
- * socket. Fail-closed -- every malformed shape or failed check throws a typed
20
+ * socket. Fail-closed: every malformed shape or failed check throws a typed
21
21
  * `WebauthnError`, never a partial verdict.
22
22
  * @spec W3C WebAuthn Level 3 sec. 6.5 / 8, RFC 9052 (COSE)
23
23
  * @card Verify a WebAuthn / passkey attestation (packed / tpm / android-key / apple / fido-u2f / none).
@@ -119,8 +119,8 @@ function _decodeCoseKey(node) {
119
119
  * @spec RFC 9052, W3C WebAuthn Level 3 sec. 6.5.1
120
120
  * @related pki.webauthn.verify, pki.webauthn.verifyAssertion
121
121
  *
122
- * Decode a bare COSE_Key -- the credential public key a relying party stored at
123
- * registration -- back into the object `verifyAssertion` takes. `pki.webauthn.verify`
122
+ * Decode a bare COSE_Key, the credential public key a relying party stored at
123
+ * registration, back into the object `verifyAssertion` takes. `pki.webauthn.verify`
124
124
  * returns that object, but the durable form is bytes: the object carries `Buffer`
125
125
  * values, so a JSON round trip through a datastore yields
126
126
  * `{"type":"Buffer","data":[...]}` in place of the object that went in, and existing
@@ -279,7 +279,7 @@ function _findExt(cert, oidName) {
279
279
  * authData}`) and its authenticatorData, fail-closed. `authData` carries the decoded
280
280
  * rpIdHash / flags / signCount and, when the AT flag is set, the attestedCredentialData
281
281
  * (aaguid, credentialId, and the decoded COSE `credentialPublicKey`). `authDataBytes`
282
- * is the raw authenticatorData -- the exact bytes an attestation signature covers.
282
+ * is the raw authenticatorData, the exact bytes an attestation signature covers.
283
283
  * A malformed object throws `webauthn/bad-attestation-object`.
284
284
  *
285
285
  * @example
@@ -820,7 +820,7 @@ function _checkAndroidKeyDescription(cert, clientDataHash) {
820
820
  * The verdict field is `attestationVerified`, and the name is the point: a sound
821
821
  * attestation statement is not the same claim as an acceptable registration. The
822
822
  * statement says nothing about which relying party asked for it, or whether a user
823
- * was present -- so an attestation naming another origin's RP ID, with user presence
823
+ * was present, so an attestation naming another origin's RP ID, with user presence
824
824
  * clear, is perfectly sound and must not be registered. Supply `expectedRpId`,
825
825
  * `requireUserPresence`, `requireUserVerification` and `allowedAlgorithms` and those
826
826
  * are checked here; `bindingChecked` reports which ran, so a check that passed can be
@@ -834,18 +834,18 @@ function _checkAndroidKeyDescription(cert, clientDataHash) {
834
834
  * The verdict also carries what a relying party must STORE to run a later login:
835
835
  * `credentialId`, `credentialPublicKey` and the initial `signCount`. The credential key
836
836
  * comes back in both forms: the decoded object, and `credentialPublicKeyBytes`, which is
837
- * what a credential row should hold -- the object carries `Buffer` values, so a JSON round
837
+ * what a credential row should hold. The object carries `Buffer` values, so a JSON round
838
838
  * trip through a datastore returns `{"type":"Buffer","data":[...]}` in place of the object
839
839
  * that went in. `pki.webauthn.parseCoseKey` reads those bytes back, and
840
840
  * `verifyAssertion` accepts either form.
841
841
  *
842
- * @intro This verifies the attestation STATEMENT -- the signature and the format's
842
+ * @intro This verifies the attestation STATEMENT: the signature and the format's
843
843
  * structural bindings (the x5c leaf key == credential key, the apple nonce, the tpm
844
844
  * certInfo Name/extraData, the android KeyDescription, the fido-u2f verificationData).
845
845
  * Chaining the returned `trustPath` (the x5c certificates in `pki.path.validate`
846
- * order -- anchor-adjacent first, leaf last) to a trusted root is a separate step,
846
+ * order: anchor-adjacent first, leaf last) to a trusted root is a separate step,
847
847
  * and there are three ways to take it. Pass `opts.metadata`, a
848
- * `pki.webauthn.verifyMetadataBlob` result -- and the authenticator's registered
848
+ * `pki.webauthn.verifyMetadataBlob` result. The authenticator's registered
849
849
  * attestation roots are resolved from its own identifier and the trust path is
850
850
  * required to reach one, so an unlisted or revoked model is refused and never
851
851
  * reported as verified. Pass `opts.rootCertificates` and the path is required to
@@ -858,7 +858,7 @@ function _checkAndroidKeyDescription(cert, clientDataHash) {
858
858
  * roots are a stronger claim than a static pin and its status reports can
859
859
  * disqualify a model those roots would still accept. `anchoredTo` reports which
860
860
  * route ran, naming every route that contributed and joining them with `+` when more
861
- * than one did -- `"metadata"`, `"rootCertificates"`, and `"safetyNetRoots"` for the
861
+ * than one did: `"metadata"`, `"rootCertificates"`, and `"safetyNetRoots"` for the
862
862
  * android-safetynet chain, which anchors through the roots that format requires whether
863
863
  * or not either other route was asked for. It is `null` only when nothing anchored the
864
864
  * path. On the mixed metadata/pinned-root route `metadata` still carries the
@@ -1091,14 +1091,14 @@ void constants;
1091
1091
  * @spec FIDO Metadata Service v3.0 sec. 3.1, RFC 7515
1092
1092
  * @related pki.webauthn.verify, pki.webauthn.metadataFor
1093
1093
  *
1094
- * Verify a FIDO Metadata Service BLOB -- the signed catalogue of every registered
1095
- * authenticator model, its attestation roots, and its certification status, and
1094
+ * Verify a FIDO Metadata Service BLOB (the signed catalogue of every registered
1095
+ * authenticator model, its attestation roots, and its certification status), and
1096
1096
  * return its entries indexed by aaguid for lookup. `blob` is caller-supplied bytes or
1097
1097
  * a string; retrieval is out of scope, so this never touches the network.
1098
1098
  *
1099
1099
  * The BLOB is a JWS. Its signature is checked under the certificate in its own header,
1100
1100
  * that chain is validated to one of `opts.rootCertificates`, and only THEN is the
1101
- * payload read -- a BLOB that does not verify never reaches the JSON parser. `no` must
1101
+ * payload read. A BLOB that does not verify never reaches the JSON parser. `no` must
1102
1102
  * exceed `opts.previousNo` (rollback) and `nextUpdate` must not have passed
1103
1103
  * (freshness). Every failure is a typed `webauthn/metadata-*` throw, never a partial
1104
1104
  * result.
@@ -1224,7 +1224,7 @@ var CLIENT_DATA_TYPE = Object.assign(Object.create(null), { "webauthn.create": 1
1224
1224
  * @defends webauthn-ceremony-confusion (CWE-345)
1225
1225
  * @related pki.webauthn.verify, pki.webauthn.verifyAssertion
1226
1226
  *
1227
- * Decode the `clientDataJSON` a ceremony returns -- the half of a WebAuthn response
1227
+ * Decode the `clientDataJSON` a ceremony returns, the half of a WebAuthn response
1228
1228
  * the signature covers by digest but that no signature check ever looks inside.
1229
1229
  * Parsed through the shared fail-closed JSON guard (bounded bytes and depth,
1230
1230
  * fatal UTF-8, duplicate members refused, no prototype pollution), because these
@@ -1233,7 +1233,7 @@ var CLIENT_DATA_TYPE = Object.assign(Object.create(null), { "webauthn.create": 1
1233
1233
  * value; `type`, `origin`, `crossOrigin` and `topOrigin` come back as they were.
1234
1234
  *
1235
1235
  * Supply `expectedType`, `expectedChallenge`, `expectedOrigin` and
1236
- * `expectedTopOrigin` and each is checked here -- the challenge in constant time
1236
+ * `expectedTopOrigin` and each is checked here: the challenge in constant time
1237
1237
  * and by full value, the origins whole and case-sensitively. `checked`
1238
1238
  * reports which ran, so a check that passed is distinguishable from one that never
1239
1239
  * happened. `expectedType` is worth setting on every call: the ceremony a response
@@ -1418,7 +1418,7 @@ var _ASSERT_OPTS = Object.assign(Object.create(null), {
1418
1418
  *
1419
1419
  * Verify an authentication assertion's signature: the authenticator signs
1420
1420
  * `authenticatorData || SHA-256(clientDataJSON)` as raw bytes with the credential
1421
- * key registered earlier -- no COSE_Sign1 wrapper, so a COSE message verifier is
1421
+ * key registered earlier: no COSE_Sign1 wrapper, so a COSE message verifier is
1422
1422
  * the wrong tool and fails on structure before it ever reaches the signature. An
1423
1423
  * ES256 assertion signature is an ASN.1 DER `SEQUENCE { r, s }`, converted here
1424
1424
  * with the same order-aware reader the attestation path uses, so an r or s outside
@@ -1428,10 +1428,13 @@ var _ASSERT_OPTS = Object.assign(Object.create(null), {
1428
1428
  * registered credential key produced this response. What makes the response
1429
1429
  * ACCEPTABLE is the sec. 7.2 binding, and the caller owns most of it. Supply
1430
1430
  * `expectedRpId`, `requireUserPresence`, `requireUserVerification` and
1431
- * `allowedAlgorithms` and they are checked here -- `bindingChecked` reports which
1431
+ * `allowedAlgorithms` and they are checked here. `bindingChecked` reports which
1432
1432
  * ones ran, so a check that passed is distinguishable from one that never
1433
- * happened. The CHALLENGE and the ORIGIN stay with the caller: both live in
1434
- * clientDataJSON and are compared against state only the relying party has.
1433
+ * happened. Supply `expectedChallenge`, `expectedOrigin`, or `expectedTopOrigin`
1434
+ * together with `clientDataJSON` and the challenge and origin are checked here
1435
+ * against it; omit them and they stay with the caller to compare against the
1436
+ * clientDataJSON this call surfaces. Passing them with only `clientDataHash`
1437
+ * throws, because there is no clientDataJSON to check them against.
1435
1438
  *
1436
1439
  * Pass `previousSignCount` (the value stored at registration or the last login) and
1437
1440
  * the sec. 7.2 step 21 counter rule is applied: a counter that fails to advance is
@@ -1447,6 +1450,7 @@ var _ASSERT_OPTS = Object.assign(Object.create(null), {
1447
1450
  * credentialPublicKey -- the stored COSE key (as parseAttestationObject surfaced it)
1448
1451
  * previousSignCount -- the stored counter, enabling the sec. 7.2 step 21 rule
1449
1452
  * expectedRpId, requireUserPresence, requireUserVerification, allowedAlgorithms: the bindings above
1453
+ * expectedChallenge, expectedOrigin, expectedTopOrigin -- checked against clientDataJSON when supplied (needs clientDataJSON, not clientDataHash)
1450
1454
  *
1451
1455
  * @example
1452
1456
  * // requires: `assertion` -- credential.response from navigator.credentials.get();
package/lib/webcrypto.js CHANGED
@@ -20,7 +20,7 @@
20
20
  * Unlike the browser's built-in `crypto.subtle`, this engine is
21
21
  * **PQC-first without being PQC-only**: the FIPS 204 ML-DSA and FIPS
22
22
  * 205 SLH-DSA signature suites sit alongside the full classical set PKI
23
- * still runs on -- RSASSA-PKCS1-v1_5, RSA-PSS, RSA-OAEP, ECDSA, ECDH,
23
+ * still runs on: RSASSA-PKCS1-v1_5, RSA-PSS, RSA-OAEP, ECDSA, ECDH,
24
24
  * Ed25519 / Ed448, AES-GCM / CBC / KW, HMAC, HKDF, PBKDF2, the SHA family
25
25
  * (including legacy SHA-1 for old certificates and signatures), and the
26
26
  * SHAKE128 / SHAKE256 extendable-output functions as message digests.
@@ -193,8 +193,8 @@ var SECRET_KEY_NAMES = intrinsic.assign(intrinsic.create(null), { "AES-GCM": tru
193
193
  *
194
194
  * Opaque handle to key material, matching the W3C `CryptoKey` shape:
195
195
  * `{ type, extractable, algorithm, usages }`. The underlying
196
- * `node:crypto` KeyObject is non-enumerable and never serialized --
197
- * extract material only through `subtle.exportKey`, and only when the key
196
+ * `node:crypto` KeyObject is non-enumerable and never serialized.
197
+ * Extract material only through `subtle.exportKey`, and only when the key
198
198
  * was created `extractable`. Instances are produced by
199
199
  * `subtle.generateKey` / `subtle.importKey`; the constructor is rarely
200
200
  * called directly.
package/lib/x509-sign.js CHANGED
@@ -195,13 +195,13 @@ function _hasCriticalSan(extSpec) {
195
195
  * @defends forged-certificate-issuance (CWE-347)
196
196
  * @related pki.schema.x509.parse, pki.path.validate, pki.cms.sign
197
197
  *
198
- * Build, sign, and DER-encode an X.509 certificate. `spec` describes the certificate to issue --
198
+ * Build, sign, and DER-encode an X.509 certificate. `spec` describes the certificate to issue:
199
199
  * `subject` (a string CN, an array of RDNs, or raw Name DER), `subjectPublicKey` (the SPKI DER of the
200
200
  * key being certified), `notBefore` / `notAfter` (`Date`s), an optional `serialNumber`, and an optional
201
201
  * `extensions` object. `issuer` is the signing side: `{ key }` alone issues a self-signed certificate
202
202
  * (issuer = subject, signed with the subject's own key); `{ name, publicKey, key }` or `{ cert, key }`
203
- * issues a CA-signed one. The signing key `key` is a WebCrypto `CryptoKey` -- a `pki.key.generate`
204
- * private key passed directly, without exporting -- or a PKCS#8 private key as DER (`Buffer`) or PEM
203
+ * issues a CA-signed one. The signing key `key` is a WebCrypto `CryptoKey` (a `pki.key.generate`
204
+ * private key passed directly, without exporting) or a PKCS#8 private key as DER (`Buffer`) or PEM
205
205
  * (`string`); a public or secret CryptoKey, or a `node:crypto` KeyObject, is refused. A `subjectAltName`
206
206
  * (or any `GeneralName`) entry may be a form object (`{ dNSName: "..." }`) or a bare string classified
207
207
  * fail-closed into its form (`"host.example"`, `"a@b.example"`, `"10.0.0.1"`, `"https://host.example/"`).
@@ -213,8 +213,8 @@ function _hasCriticalSan(extSpec) {
213
213
  * (positive, <= 20 octets), the validity UTCTime/GeneralizedTime cutover, the DER DEFAULT omissions
214
214
  * (v1 tag, `critical=FALSE`, `cA=FALSE`), and the CA cross-field rules (keyCertSign and
215
215
  * pathLenConstraint require cA=TRUE) are all enforced; a violation throws a typed `CertificateError`.
216
- * Where the spec carries raw DER -- a `Name` Buffer, a pre-encoded `Extension`, an issuer `publicKey`
217
- * SPKI -- a structural fault throws `CertificateError`, while a malformed leaf inside those bytes
216
+ * Where the spec carries raw DER (a `Name` Buffer, a pre-encoded `Extension`, an issuer `publicKey`
217
+ * SPKI), a structural fault throws `CertificateError`, while a malformed leaf inside those bytes
218
218
  * throws `Asn1Error`, the same two-error contract the parsers present.
219
219
  *
220
220
  * @opts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/pki",
3
- "version": "0.6.29",
3
+ "version": "0.6.31",
4
4
  "description": "Pure-JavaScript PKI toolkit that owns its stack — X.509, ASN.1/DER, CMS, PQC-first.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",
package/sbom.cdx.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.5",
5
- "serialNumber": "urn:uuid:e72c9e5f-07a6-48ad-bf71-a361b1470bef",
5
+ "serialNumber": "urn:uuid:692adf4f-5fb7-41cd-94f6-da6509e828d9",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-09-03T05:34:38.589Z",
8
+ "timestamp": "2026-09-04T15:47:45.151Z",
9
9
  "lifecycles": [
10
10
  {
11
11
  "phase": "build"
@@ -19,14 +19,14 @@
19
19
  }
20
20
  ],
21
21
  "component": {
22
- "bom-ref": "@blamejs/pki@0.6.29",
22
+ "bom-ref": "@blamejs/pki@0.6.31",
23
23
  "type": "application",
24
24
  "name": "pki",
25
- "version": "0.6.29",
25
+ "version": "0.6.31",
26
26
  "scope": "required",
27
27
  "author": "blamejs contributors",
28
28
  "description": "Pure-JavaScript PKI toolkit that owns its stack — X.509, ASN.1/DER, CMS, PQC-first.",
29
- "purl": "pkg:npm/%40blamejs/pki@0.6.29",
29
+ "purl": "pkg:npm/%40blamejs/pki@0.6.31",
30
30
  "properties": [],
31
31
  "externalReferences": [
32
32
  {
@@ -54,7 +54,7 @@
54
54
  "components": [],
55
55
  "dependencies": [
56
56
  {
57
- "ref": "@blamejs/pki@0.6.29",
57
+ "ref": "@blamejs/pki@0.6.31",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]