@blamejs/pki 0.4.14 → 0.5.0
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 +61 -0
- package/MIGRATING.md +2 -2
- package/README.md +142 -137
- package/index.js +4 -0
- package/lib/acme.js +73 -1
- package/lib/asn1-der.js +2 -0
- package/lib/attrcert-sign.js +4 -0
- package/lib/cbor-det.js +32 -16
- package/lib/cmc-build.js +880 -0
- package/lib/cmc-verify.js +657 -0
- package/lib/cmp-build.js +8 -7
- package/lib/cmp-verify.js +11 -1
- package/lib/cms-sign.js +170 -8
- package/lib/cms-verify.js +80 -14
- package/lib/crl-sign.js +22 -0
- package/lib/crmf-sign.js +5 -2
- package/lib/csr-sign.js +3 -0
- package/lib/ct.js +72 -0
- package/lib/est.js +828 -32
- package/lib/framework-error.js +13 -0
- package/lib/guard-bytes.js +37 -1
- package/lib/guard-range.js +23 -1
- package/lib/http-transport.js +9 -3
- package/lib/inspect.js +28 -5
- package/lib/jose.js +15 -0
- package/lib/lint.js +4 -0
- package/lib/merkle.js +5 -5
- package/lib/ocsp.js +139 -11
- package/lib/oid.js +69 -1
- package/lib/path-validate.js +438 -100
- package/lib/pkcs12-build.js +12 -0
- package/lib/schema-all.js +19 -1
- package/lib/schema-attrcert.js +27 -0
- package/lib/schema-c509.js +6 -0
- package/lib/schema-cmc.js +791 -0
- package/lib/schema-cmp.js +25 -0
- package/lib/schema-cms.js +17 -1
- package/lib/schema-crl.js +23 -1
- package/lib/schema-crmf.js +13 -0
- package/lib/schema-csr.js +11 -0
- package/lib/schema-csrattrs.js +6 -0
- package/lib/schema-engine.js +6 -2
- package/lib/schema-ocsp.js +41 -0
- package/lib/schema-pkcs12.js +16 -0
- package/lib/schema-pkcs8.js +8 -0
- package/lib/schema-pkix.js +6 -0
- package/lib/schema-smime.js +4 -4
- package/lib/schema-tsp.js +32 -1
- package/lib/schema-x509.js +14 -1
- package/lib/shbs.js +12 -4
- package/lib/sigstore.js +4 -0
- package/lib/smime.js +28 -7
- package/lib/tls-cert-compress.js +15 -3
- package/lib/trust.js +27 -4
- package/lib/tsp-sign.js +41 -6
- package/lib/vendor/README.md +19 -19
- package/lib/webauthn.js +895 -26
- package/lib/x509-sign.js +3 -0
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/ct.js
CHANGED
|
@@ -173,6 +173,19 @@ function _parseSct(r, sctLen) {
|
|
|
173
173
|
* `TypeError`.
|
|
174
174
|
*
|
|
175
175
|
* @example
|
|
176
|
+
* // a certificate with an embedded SCT list, as a log would return it
|
|
177
|
+
* var log = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
|
|
178
|
+
* var kp = await pki.key.generate("Ed25519");
|
|
179
|
+
* var leaf = await pki.x509.sign({ subject: "example.org", subjectPublicKey: await pki.key.export(kp.publicKey),
|
|
180
|
+
* notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") },
|
|
181
|
+
* { key: await pki.key.export(kp.privateKey) });
|
|
182
|
+
* var sct = await pki.ct.signSct({ entryType: 0, leafCert: leaf }, await pki.key.export(log.privateKey));
|
|
183
|
+
* var sctExt = pki.asn1.build.sequence([pki.asn1.build.oid(pki.oid.byName("signedCertificateTimestampList")),
|
|
184
|
+
* pki.asn1.build.octetString(pki.ct.encodeSctList([sct]))]);
|
|
185
|
+
* var pem = await pki.x509.sign({ subject: "example.org", subjectPublicKey: await pki.key.export(kp.publicKey),
|
|
186
|
+
* notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z"),
|
|
187
|
+
* extensions: [sctExt] }, { key: await pki.key.export(kp.privateKey) }, { pem: true });
|
|
188
|
+
*
|
|
176
189
|
* var cert = pki.schema.x509.parse(pem);
|
|
177
190
|
* var sctOid = pki.oid.byName("signedCertificateTimestampList");
|
|
178
191
|
* var ext = (cert.extensions || []).find(function (e) { return e.oid === sctOid; });
|
|
@@ -252,6 +265,13 @@ function _u24Bytes(n) {
|
|
|
252
265
|
* extensions exceed their RFC 6962 3.2 wire ranges (uint64 / opaque<0..2^16-1>).
|
|
253
266
|
*
|
|
254
267
|
* @example
|
|
268
|
+
* var log = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
|
|
269
|
+
* var kp = await pki.key.generate("Ed25519");
|
|
270
|
+
* var der = await pki.x509.sign({ subject: "example.org", subjectPublicKey: await pki.key.export(kp.publicKey),
|
|
271
|
+
* notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") },
|
|
272
|
+
* { key: await pki.key.export(kp.privateKey) });
|
|
273
|
+
* var sctExtValue = pki.ct.encodeSctList([
|
|
274
|
+
* await pki.ct.signSct({ entryType: 0, leafCert: der }, await pki.key.export(log.privateKey))]);
|
|
255
275
|
* var sct = pki.ct.parseSctList(sctExtValue).scts[0];
|
|
256
276
|
* var preimage = pki.ct.reconstructSignedData({ entryType: 0, leafCert: der }, sct);
|
|
257
277
|
* // hash `preimage` + verify against the log's public key at the verify layer
|
|
@@ -367,9 +387,17 @@ function _spkiAlg(spki) {
|
|
|
367
387
|
* entry/SCT, an unusable log key, or an unsupported hash/signature algorithm.
|
|
368
388
|
*
|
|
369
389
|
* @example
|
|
390
|
+
* var log = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
|
|
391
|
+
* var kp = await pki.key.generate("Ed25519");
|
|
392
|
+
* var certDer = await pki.x509.sign({ subject: "example.org", subjectPublicKey: await pki.key.export(kp.publicKey),
|
|
393
|
+
* notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") },
|
|
394
|
+
* { key: await pki.key.export(kp.privateKey) });
|
|
395
|
+
* var sctExtValue = pki.ct.encodeSctList([
|
|
396
|
+
* await pki.ct.signSct({ entryType: 0, leafCert: certDer }, await pki.key.export(log.privateKey))]);
|
|
370
397
|
* var sct = pki.ct.parseSctList(sctExtValue).scts[0];
|
|
371
398
|
* // Resolve the CT log's DER SubjectPublicKeyInfo from a trusted log list, keyed by log id.
|
|
372
399
|
* var logKeysByLogId = {}; // { sct.logIdHex: <SPKI Buffer>, ... }
|
|
400
|
+
* logKeysByLogId[sct.logIdHex] = await pki.key.export(log.publicKey);
|
|
373
401
|
* var logKey = logKeysByLogId[sct.logIdHex];
|
|
374
402
|
* var ok = await pki.ct.verifySct({ entryType: 0, leafCert: certDer }, sct, logKey);
|
|
375
403
|
*/
|
|
@@ -480,6 +508,13 @@ function _encodeSctBody(sct) {
|
|
|
480
508
|
* `ct/bad-input`, `ct/too-large`, `ct/too-many-scts`) on malformed input.
|
|
481
509
|
*
|
|
482
510
|
* @example
|
|
511
|
+
* var log = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
|
|
512
|
+
* var kp = await pki.key.generate("Ed25519");
|
|
513
|
+
* var der = await pki.x509.sign({ subject: "example.org", subjectPublicKey: await pki.key.export(kp.publicKey),
|
|
514
|
+
* notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") },
|
|
515
|
+
* { key: await pki.key.export(kp.privateKey) });
|
|
516
|
+
* var sctExtValue = pki.ct.encodeSctList([
|
|
517
|
+
* await pki.ct.signSct({ entryType: 0, leafCert: der }, await pki.key.export(log.privateKey))]);
|
|
483
518
|
* var list = pki.ct.parseSctList(sctExtValue);
|
|
484
519
|
* var reEncoded = pki.ct.encodeSctList(list.all); // byte-identical to sctExtValue
|
|
485
520
|
*/
|
|
@@ -549,6 +584,12 @@ function _logKeyMaterial(logKey) {
|
|
|
549
584
|
* @opts extensions raw `CtExtensions` bytes (opaque<0..2^16-1>). Default empty.
|
|
550
585
|
* @opts logId assert the derived LogID equals this 32-byte value (fail closed on mismatch).
|
|
551
586
|
* @example
|
|
587
|
+
* var log = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
|
|
588
|
+
* var signerKeyPkcs8 = await pki.key.export(log.privateKey);
|
|
589
|
+
* var kp = await pki.key.generate("Ed25519");
|
|
590
|
+
* var der = await pki.x509.sign({ subject: "example.org", subjectPublicKey: await pki.key.export(kp.publicKey),
|
|
591
|
+
* notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") },
|
|
592
|
+
* { key: await pki.key.export(kp.privateKey) });
|
|
552
593
|
* var sct = await pki.ct.signSct({ entryType: 0, leafCert: der }, signerKeyPkcs8);
|
|
553
594
|
* var ext = pki.ct.encodeSctList([sct]);
|
|
554
595
|
*/
|
|
@@ -688,6 +729,14 @@ function _logsAgree(a, b) {
|
|
|
688
729
|
* leniently, never a throw). Every malformed / oversized / mis-bound input is a typed `CtError`.
|
|
689
730
|
*
|
|
690
731
|
* @example
|
|
732
|
+
* // the v3 log-list JSON shape, as published by a CT log-list operator
|
|
733
|
+
* var log = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
|
|
734
|
+
* var logSpki = await pki.key.export(log.publicKey);
|
|
735
|
+
* var logId = Buffer.from(await pki.webcrypto.subtle.digest("SHA-256", logSpki));
|
|
736
|
+
* var logListJsonBytes = Buffer.from(JSON.stringify({ operators: [{ name: "Example Operator", logs: [{
|
|
737
|
+
* description: "Example Log", log_id: logId.toString("base64"), key: logSpki.toString("base64"),
|
|
738
|
+
* url: "https://ct.example/log/", mmd: 86400,
|
|
739
|
+
* state: { usable: { timestamp: "2026-01-01T00:00:00Z" } } }] }] }), "utf8");
|
|
691
740
|
* var logList = pki.ct.parseLogList(logListJsonBytes);
|
|
692
741
|
* logList.logs[0].trusted; // was the first log trusted (usable/qualified/readonly)?
|
|
693
742
|
*/
|
|
@@ -770,6 +819,20 @@ function _resolveNotAfter(entry, opts) {
|
|
|
770
819
|
*
|
|
771
820
|
* @opts certNotAfter A `Date` -- the covered certificate's notAfter for the temporal-interval gate (required for a precert entry).
|
|
772
821
|
* @example
|
|
822
|
+
* var log = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
|
|
823
|
+
* var logSpki = await pki.key.export(log.publicKey);
|
|
824
|
+
* var kp = await pki.key.generate("Ed25519");
|
|
825
|
+
* var leafCert = await pki.x509.sign({ subject: "example.org", subjectPublicKey: await pki.key.export(kp.publicKey),
|
|
826
|
+
* notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") },
|
|
827
|
+
* { key: await pki.key.export(kp.privateKey) });
|
|
828
|
+
* var sctEntry = { entryType: 0, leafCert: leafCert };
|
|
829
|
+
* var embeddedSct = pki.ct.parseSctList(pki.ct.encodeSctList([
|
|
830
|
+
* await pki.ct.signSct(sctEntry, await pki.key.export(log.privateKey))])).scts[0];
|
|
831
|
+
* var logId = Buffer.from(await pki.webcrypto.subtle.digest("SHA-256", logSpki));
|
|
832
|
+
* var logList = pki.ct.parseLogList(Buffer.from(JSON.stringify({ operators: [{ name: "Example Operator", logs: [{
|
|
833
|
+
* description: "Example Log", log_id: logId.toString("base64"), key: logSpki.toString("base64"),
|
|
834
|
+
* url: "https://ct.example/log/", mmd: 86400,
|
|
835
|
+
* state: { usable: { timestamp: "2026-01-01T00:00:00Z" } } }] }] }), "utf8"));
|
|
773
836
|
* var ok = await pki.ct.verifySctWithLogList(sctEntry, embeddedSct, logList);
|
|
774
837
|
*/
|
|
775
838
|
async function verifySctWithLogList(entry, sct, logList, opts) {
|
|
@@ -818,6 +881,15 @@ async function verifySctWithLogList(entry, sct, logList, opts) {
|
|
|
818
881
|
* evaluation failure is `ct/verify-error`. Offline: the caller fetches and pins; the toolkit only verifies.
|
|
819
882
|
*
|
|
820
883
|
* @example
|
|
884
|
+
* var b = pki.asn1.build;
|
|
885
|
+
* var signer = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
|
|
886
|
+
* var googleSignerSpki = await pki.key.export(signer.publicKey);
|
|
887
|
+
* var logListJsonBytes = Buffer.from(JSON.stringify({ operators: [] }), "utf8");
|
|
888
|
+
* // the published signature is DER SEQUENCE(r, s); WebCrypto emits the raw r||s pair
|
|
889
|
+
* var raw = Buffer.from(await pki.webcrypto.subtle.sign({ name: "ECDSA", hash: "SHA-256" },
|
|
890
|
+
* signer.privateKey, logListJsonBytes));
|
|
891
|
+
* var logListSig = b.sequence([b.integer(BigInt("0x" + raw.subarray(0, raw.length / 2).toString("hex"))),
|
|
892
|
+
* b.integer(BigInt("0x" + raw.subarray(raw.length / 2).toString("hex")))]);
|
|
821
893
|
* var ok = await pki.ct.verifyLogListSignature(logListJsonBytes, logListSig, googleSignerSpki);
|
|
822
894
|
*/
|
|
823
895
|
async function verifyLogListSignature(json, signature, publicKey) {
|