@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.
Files changed (60) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/MIGRATING.md +2 -2
  3. package/README.md +142 -137
  4. package/index.js +4 -0
  5. package/lib/acme.js +73 -1
  6. package/lib/asn1-der.js +2 -0
  7. package/lib/attrcert-sign.js +4 -0
  8. package/lib/cbor-det.js +32 -16
  9. package/lib/cmc-build.js +880 -0
  10. package/lib/cmc-verify.js +657 -0
  11. package/lib/cmp-build.js +8 -7
  12. package/lib/cmp-verify.js +11 -1
  13. package/lib/cms-sign.js +170 -8
  14. package/lib/cms-verify.js +80 -14
  15. package/lib/crl-sign.js +22 -0
  16. package/lib/crmf-sign.js +5 -2
  17. package/lib/csr-sign.js +3 -0
  18. package/lib/ct.js +72 -0
  19. package/lib/est.js +828 -32
  20. package/lib/framework-error.js +13 -0
  21. package/lib/guard-bytes.js +37 -1
  22. package/lib/guard-range.js +23 -1
  23. package/lib/http-transport.js +9 -3
  24. package/lib/inspect.js +28 -5
  25. package/lib/jose.js +15 -0
  26. package/lib/lint.js +4 -0
  27. package/lib/merkle.js +5 -5
  28. package/lib/ocsp.js +139 -11
  29. package/lib/oid.js +69 -1
  30. package/lib/path-validate.js +438 -100
  31. package/lib/pkcs12-build.js +12 -0
  32. package/lib/schema-all.js +19 -1
  33. package/lib/schema-attrcert.js +27 -0
  34. package/lib/schema-c509.js +6 -0
  35. package/lib/schema-cmc.js +791 -0
  36. package/lib/schema-cmp.js +25 -0
  37. package/lib/schema-cms.js +17 -1
  38. package/lib/schema-crl.js +23 -1
  39. package/lib/schema-crmf.js +13 -0
  40. package/lib/schema-csr.js +11 -0
  41. package/lib/schema-csrattrs.js +6 -0
  42. package/lib/schema-engine.js +6 -2
  43. package/lib/schema-ocsp.js +41 -0
  44. package/lib/schema-pkcs12.js +16 -0
  45. package/lib/schema-pkcs8.js +8 -0
  46. package/lib/schema-pkix.js +6 -0
  47. package/lib/schema-smime.js +4 -4
  48. package/lib/schema-tsp.js +32 -1
  49. package/lib/schema-x509.js +14 -1
  50. package/lib/shbs.js +12 -4
  51. package/lib/sigstore.js +4 -0
  52. package/lib/smime.js +28 -7
  53. package/lib/tls-cert-compress.js +15 -3
  54. package/lib/trust.js +27 -4
  55. package/lib/tsp-sign.js +41 -6
  56. package/lib/vendor/README.md +19 -19
  57. package/lib/webauthn.js +895 -26
  58. package/lib/x509-sign.js +3 -0
  59. package/package.json +1 -1
  60. package/sbom.cdx.json +6 -6
package/index.js CHANGED
@@ -39,6 +39,7 @@ var ct = require("./lib/ct");
39
39
  var tls = require("./lib/tls-cert-compress");
40
40
  var cms = require("./lib/cms-verify");
41
41
  var smime = require("./lib/smime");
42
+ var cmc = require("./lib/cmc-verify");
42
43
  var tsp = require("./lib/tsp-sign");
43
44
  var ocsp = require("./lib/ocsp");
44
45
  var x509 = require("./lib/x509-sign");
@@ -93,6 +94,9 @@ module.exports = {
93
94
  tls: tls,
94
95
  cms: cms,
95
96
  smime: smime,
97
+ // `cmc` interprets an RFC 5272 Full PKI Response into one terminal verdict;
98
+ // `pki.schema.cmc` is the decoder underneath it.
99
+ cmc: cmc,
96
100
  tsp: tsp,
97
101
  ocsp: ocsp,
98
102
  // `x509` is the certificate-issuance producing side -- pki.x509.sign builds and
package/lib/acme.js CHANGED
@@ -416,6 +416,10 @@ function validateProblem(obj) {
416
416
  * `acme/*` fault; returns the object.
417
417
  *
418
418
  * @example
419
+ * var orderObj = { status: "pending", expires: "2026-02-01T00:00:00Z",
420
+ * identifiers: [{ type: "dns", value: "example.org" }],
421
+ * authorizations: ["https://ca.example/authz/1"],
422
+ * finalize: "https://ca.example/order/1/finalize" };
419
423
  * pki.acme.validate("order", orderObj).status; // -> "pending"
420
424
  */
421
425
  function validate(kind, obj) {
@@ -442,6 +446,10 @@ function validate(kind, obj) {
442
446
  * are proven mutually exclusive; a DER structure identifies as `"unknown"`.
443
447
  *
444
448
  * @example
449
+ * var orderObj = { status: "pending", expires: "2026-02-01T00:00:00Z",
450
+ * identifiers: [{ type: "dns", value: "example.org" }],
451
+ * authorizations: ["https://ca.example/authz/1"],
452
+ * finalize: "https://ca.example/order/1/finalize" };
445
453
  * pki.acme.identify(orderObj); // -> "order"
446
454
  */
447
455
  function identify(obj) {
@@ -484,6 +492,9 @@ async function _sha256(bytes) { return Buffer.from(await subtle.digest("SHA-256"
484
492
  * digest, so changing the account key changes the key authorization.
485
493
  *
486
494
  * @example
495
+ * var ec = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
496
+ * var accountJwk = await pki.webcrypto.subtle.exportKey("jwk", ec.publicKey);
497
+ * var token = "example-challenge-token-not-a-secret"; // the real one comes from the CA
487
498
  * await pki.acme.keyAuthorization(token, accountJwk); // -> "<token>.<thumbprint>"
488
499
  */
489
500
  async function keyAuthorization(token, accountJwk) {
@@ -505,6 +516,9 @@ async function keyAuthorization(token, accountJwk) {
505
516
  * authorization, no trailing newline). Validation reaches TCP port 80 over HTTP.
506
517
  *
507
518
  * @example
519
+ * var ec = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
520
+ * var accountJwk = await pki.webcrypto.subtle.exportKey("jwk", ec.publicKey);
521
+ * var token = "example-challenge-token-not-a-secret";
508
522
  * var c = await pki.acme.http01(token, accountJwk);
509
523
  * c.path; // -> "/.well-known/acme-challenge/<token>"
510
524
  */
@@ -526,6 +540,9 @@ async function http01(token, accountJwk) {
526
540
  * order) and the `value` `base64url(SHA-256(keyAuthorization))`.
527
541
  *
528
542
  * @example
543
+ * var ec = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
544
+ * var accountJwk = await pki.webcrypto.subtle.exportKey("jwk", ec.publicKey);
545
+ * var token = "example-challenge-token-not-a-secret";
529
546
  * var r = await pki.acme.dns01(token, accountJwk, "example.org");
530
547
  * r.name; // -> "_acme-challenge.example.org"
531
548
  */
@@ -559,6 +576,9 @@ var _extCtx = { E: function (c, m, cause) { return new AcmeError(c, m, cause); }
559
576
  * SHA-256(keyAuthorization) }`. Placed in the validation certificate.
560
577
  *
561
578
  * @example
579
+ * var ec = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
580
+ * var accountJwk = await pki.webcrypto.subtle.exportKey("jwk", ec.publicKey);
581
+ * var token = "example-challenge-token-not-a-secret";
562
582
  * var extDer = await pki.acme.tlsAlpn01Extension(token, accountJwk);
563
583
  */
564
584
  async function tlsAlpn01Extension(token, accountJwk) {
@@ -593,6 +613,19 @@ function _readAcmeIdentifier(extnValue) {
593
613
  * for an `ip` identifier (RFC 8738 sec. 6). Any deviation throws `acme/bad-tlsalpn`.
594
614
  *
595
615
  * @example
616
+ * var b = pki.asn1.build;
617
+ * var ec = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
618
+ * var accountJwk = await pki.webcrypto.subtle.exportKey("jwk", ec.publicKey);
619
+ * var token = "example-challenge-token-not-a-secret";
620
+ * // the validation certificate carries exactly two extensions: the critical
621
+ * // acmeIdentifier, and a single-entry SAN naming the identifier being validated
622
+ * var acmeExt = await pki.acme.tlsAlpn01Extension(token, accountJwk);
623
+ * var sanExt = b.sequence([b.oid("2.5.29.17"),
624
+ * b.octetString(b.sequence([b.contextPrimitive(2, Buffer.from("example.org", "ascii"))]))]);
625
+ * var kp = await pki.key.generate("Ed25519");
626
+ * var certDer = await pki.x509.sign({ subject: "example.org", subjectPublicKey: await pki.key.export(kp.publicKey),
627
+ * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z"),
628
+ * extensions: [acmeExt, sanExt] }, { key: await pki.key.export(kp.privateKey) });
596
629
  * await pki.acme.verifyTlsAlpn01(certDer, token, accountJwk, { type: "dns", value: "example.org" });
597
630
  */
598
631
  async function verifyTlsAlpn01(certDer, token, accountJwk, identifier) {
@@ -755,6 +788,10 @@ var _HMAC_HASH = { HS256: "SHA-256", HS384: "SHA-384", HS512: "SHA-512" };
755
788
  * (alg default `HS256`). The result is embedded as newAccount's `externalAccountBinding`.
756
789
  *
757
790
  * @example
791
+ * var ec = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
792
+ * var accountJwk = await pki.webcrypto.subtle.exportKey("jwk", ec.publicKey);
793
+ * var macKey = Buffer.alloc(32, 7); // the HMAC key the CA issued out of band
794
+ * var url = "https://ca.example/acme/new-acct";
758
795
  * var eab = await pki.acme.externalAccountBinding({ macKey, kid: "abc123", url, accountJwk });
759
796
  */
760
797
  async function externalAccountBinding(o) {
@@ -991,6 +1028,10 @@ async function finalize(o) {
991
1028
  * (payload default `{}`; pass a custom object for a future challenge type).
992
1029
  *
993
1030
  * @example
1031
+ * var ec = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
1032
+ * var key = ec.privateKey;
1033
+ * var nonce = "oFvnlFP1wIhRlYS2jTaXbA"; // from the CA's Replay-Nonce header
1034
+ * var kid = "https://ca.example/acct/1", challUrl = "https://ca.example/chall/1";
994
1035
  * await pki.acme.challengeResponse({ key, alg: "ES256", nonce, url: challUrl, kid });
995
1036
  */
996
1037
  function challengeResponse(o) {
@@ -1013,6 +1054,10 @@ function challengeResponse(o) {
1013
1054
  * the only client-settable status. `opts` = `{ key, alg, nonce, url, kid }`.
1014
1055
  *
1015
1056
  * @example
1057
+ * var ec = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
1058
+ * var key = ec.privateKey;
1059
+ * var nonce = "oFvnlFP1wIhRlYS2jTaXbA";
1060
+ * var kid = "https://ca.example/acct/1", authzUrl = "https://ca.example/authz/1";
1016
1061
  * await pki.acme.deactivate({ key, alg: "ES256", nonce, url: authzUrl, kid });
1017
1062
  */
1018
1063
  function deactivate(o) {
@@ -1035,6 +1080,14 @@ function deactivate(o) {
1035
1080
  * url, certificate (DER Buffer), reason?, kid? | jwk? }`.
1036
1081
  *
1037
1082
  * @example
1083
+ * var ec = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
1084
+ * var key = ec.privateKey;
1085
+ * var nonce = "oFvnlFP1wIhRlYS2jTaXbA";
1086
+ * var kid = "https://ca.example/acct/1", url = "https://ca.example/acme/revoke-cert";
1087
+ * var kp = await pki.key.generate("Ed25519");
1088
+ * var certDer = await pki.x509.sign({ subject: "example.org", subjectPublicKey: await pki.key.export(kp.publicKey),
1089
+ * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") },
1090
+ * { key: await pki.key.export(kp.privateKey) });
1038
1091
  * await pki.acme.revokeCert({ key, alg: "ES256", nonce, url, kid, certificate: certDer, reason: 1 });
1039
1092
  */
1040
1093
  function revokeCert(o) {
@@ -1071,6 +1124,14 @@ function revokeCert(o) {
1071
1124
  * private), newJwk (new public JWK), newAlg, nonce, url }`.
1072
1125
  *
1073
1126
  * @example
1127
+ * var subtle = pki.webcrypto.subtle;
1128
+ * var oldPair = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
1129
+ * var newPair = await pki.key.generate({ name: "ECDSA", namedCurve: "P-256" });
1130
+ * var oldKey = oldPair.privateKey, newKey = newPair.privateKey;
1131
+ * var oldJwk = await subtle.exportKey("jwk", oldPair.publicKey);
1132
+ * var newJwk = await subtle.exportKey("jwk", newPair.publicKey);
1133
+ * var nonce = "oFvnlFP1wIhRlYS2jTaXbA";
1134
+ * var kid = "https://ca.example/acct/1", url = "https://ca.example/acme/key-change";
1074
1135
  * await pki.acme.keyChange({ key: oldKey, alg: "ES256", kid, account: kid, oldKey: oldJwk, newKey, newJwk, newAlg: "ES256", nonce, url });
1075
1136
  */
1076
1137
  async function keyChange(o) {
@@ -1106,6 +1167,16 @@ async function keyChange(o) {
1106
1167
  * `acme/bad-certid` if the certificate lacks an AKI keyIdentifier.
1107
1168
  *
1108
1169
  * @example
1170
+ * // the certificate must carry an authorityKeyIdentifier -- ARI keys off it
1171
+ * var ca = await pki.key.generate("Ed25519");
1172
+ * var caKey = await pki.key.export(ca.privateKey);
1173
+ * var caDer = await pki.x509.sign({ subject: "Example CA", subjectPublicKey: await pki.key.export(ca.publicKey),
1174
+ * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z"),
1175
+ * extensions: { basicConstraints: { cA: true }, keyUsage: ["keyCertSign"], subjectKeyIdentifier: true } }, { key: caKey });
1176
+ * var kp = await pki.key.generate("Ed25519");
1177
+ * var certDer = await pki.x509.sign({ subject: "example.org", subjectPublicKey: await pki.key.export(kp.publicKey),
1178
+ * serialNumber: 0x87654321n, notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z"),
1179
+ * extensions: { authorityKeyIdentifier: true } }, { cert: caDer, key: caKey });
1109
1180
  * pki.acme.ariCertId(certDer); // -> "<b64u-aki>.<b64u-serial>"
1110
1181
  */
1111
1182
  function ariCertId(certDer) {
@@ -1132,7 +1203,8 @@ function ariCertId(certDer) {
1132
1203
  * non-alphabet rejected); anything but exactly two parts throws `acme/bad-certid`.
1133
1204
  *
1134
1205
  * @example
1135
- * pki.acme.parseAriCertId("<b64u-aki>.<b64u-serial>").serial; // -> Buffer
1206
+ * // the two halves are base64url(authorityKeyIdentifier) and base64url(serialNumber)
1207
+ * pki.acme.parseAriCertId("aYhfK4oaay8.AIdlQyE").serial; // -> Buffer 00 87 65 43 21
1136
1208
  */
1137
1209
  function parseAriCertId(certId) {
1138
1210
  if (!_isString(certId)) throw E("acme/bad-certid", "an ARI certID must be a string");
package/lib/asn1-der.js CHANGED
@@ -156,6 +156,7 @@ function _asBuffer(input, who) {
156
156
  * // constructed OCTET STRINGs (BER content regions)
157
157
  *
158
158
  * @example
159
+ * var der = pki.asn1.build.sequence([pki.asn1.build.integer(1n)]);
159
160
  * var node = pki.asn1.decode(der);
160
161
  * node.tagNumber === pki.asn1.TAGS.SEQUENCE;
161
162
  */
@@ -553,6 +554,7 @@ function readNullImplicit(node, tag) {
553
554
  * the minimal base-128 sub-identifier encoding DER requires.
554
555
  *
555
556
  * @example
557
+ * var node = pki.asn1.decode(pki.asn1.build.oid("2.5.4.3"));
556
558
  * pki.asn1.read.oid(node); // -> "2.5.4.3"
557
559
  */
558
560
  function readOid(node) {
@@ -440,6 +440,10 @@ function _buildExtensions(extSpec, aaSpki) {
440
440
  * - `pss` (boolean) -- sign an RSA key with RSASSA-PSS rather than PKCS#1 v1.5.
441
441
  * - `digestAlgorithm` (string) -- override the message digest where the algorithm permits a choice.
442
442
  * @example
443
+ * var pair = await pki.key.generate("Ed25519");
444
+ * var signerKeyPkcs8 = await pki.key.export(pair.privateKey);
445
+ * var signerCertDer = await pki.x509.sign({ subject: "Attribute Authority", subjectPublicKey: await pki.key.export(pair.publicKey),
446
+ * notBefore: new Date("2026-01-01T00:00:00Z"), notAfter: new Date("2036-01-01T00:00:00Z") }, { key: signerKeyPkcs8 });
443
447
  * var ac = await pki.attrcert.sign(
444
448
  * { holder: { entityName: { directoryName: "CN=Alice" } },
445
449
  * notBeforeTime: new Date("2026-01-01T00:00:00Z"), notAfterTime: new Date("2027-01-01T00:00:00Z"),
package/lib/cbor-det.js CHANGED
@@ -232,7 +232,7 @@ function _decodeItem(buf, start, limit, depth, maxD, rules, state) {
232
232
  * @primitive pki.cbor.decode
233
233
  * @signature pki.cbor.decode(bytes, opts?) -> node
234
234
  * @since 0.1.27
235
- * @status experimental
235
+ * @status stable
236
236
  * @spec RFC 8949 sec. 4.2 (core deterministic encoding)
237
237
  *
238
238
  * Decode one Deterministically Encoded CBOR item into a navigable node tree.
@@ -290,7 +290,7 @@ function _tagInner(node, tagNum, who) {
290
290
  * @primitive pki.cbor.read.uint
291
291
  * @signature pki.cbor.read.uint(node) -> 0n
292
292
  * @since 0.1.27
293
- * @status experimental
293
+ * @status stable
294
294
  * @spec RFC 8949 sec. 3.1 (major type 0)
295
295
  *
296
296
  * The unsigned integer value of a major-type-0 node, as a BigInt (uniform
@@ -298,6 +298,7 @@ function _tagInner(node, tagNum, who) {
298
298
  * `cbor/unexpected-major` on any other major type.
299
299
  *
300
300
  * @example
301
+ * var node = pki.cbor.decode(Buffer.from("00", "hex"));
301
302
  * pki.cbor.read.uint(node); // -> 0n
302
303
  */
303
304
  function readUint(node) {
@@ -309,13 +310,14 @@ function readUint(node) {
309
310
  * @primitive pki.cbor.read.nint
310
311
  * @signature pki.cbor.read.nint(node) -> -1n
311
312
  * @since 0.1.27
312
- * @status experimental
313
+ * @status stable
313
314
  * @spec RFC 8949 sec. 3.1 (major type 1)
314
315
  *
315
316
  * The negative integer value of a major-type-1 node, as a BigInt
316
317
  * (value = -1 - argument). Throws `cbor/unexpected-major` otherwise.
317
318
  *
318
319
  * @example
320
+ * var node = pki.cbor.decode(Buffer.from("20", "hex"));
319
321
  * pki.cbor.read.nint(node); // -> -1n
320
322
  */
321
323
  function readNint(node) {
@@ -327,13 +329,14 @@ function readNint(node) {
327
329
  * @primitive pki.cbor.read.int
328
330
  * @signature pki.cbor.read.int(node) -> -1n
329
331
  * @since 0.1.27
330
- * @status experimental
332
+ * @status stable
331
333
  * @spec RFC 8949 sec. 3.1 (major types 0 and 1)
332
334
  *
333
335
  * The signed integer value of a major-type-0 or -1 node, as a BigInt. Throws
334
336
  * `cbor/unexpected-major` on any other major type.
335
337
  *
336
338
  * @example
339
+ * var node = pki.cbor.decode(Buffer.from("20", "hex"));
337
340
  * pki.cbor.read.int(node); // -> -1n
338
341
  */
339
342
  function readInt(node) {
@@ -346,13 +349,14 @@ function readInt(node) {
346
349
  * @primitive pki.cbor.read.byteString
347
350
  * @signature pki.cbor.read.byteString(node) -> Buffer
348
351
  * @since 0.1.27
349
- * @status experimental
352
+ * @status stable
350
353
  * @spec RFC 8949 sec. 3.1 (major type 2)
351
354
  *
352
355
  * The zero-copy `Buffer` content of a major-type-2 byte string. Throws
353
356
  * `cbor/unexpected-major` otherwise.
354
357
  *
355
358
  * @example
359
+ * var node = pki.cbor.decode(Buffer.from("4401020304", "hex"));
356
360
  * pki.cbor.read.byteString(node); // -> <Buffer 01 02 03 04>
357
361
  */
358
362
  function readByteString(node) {
@@ -364,13 +368,14 @@ function readByteString(node) {
364
368
  * @primitive pki.cbor.read.textString
365
369
  * @signature pki.cbor.read.textString(node) -> "text"
366
370
  * @since 0.1.27
367
- * @status experimental
371
+ * @status stable
368
372
  * @spec RFC 8949 sec. 3.1 (major type 3)
369
373
  *
370
374
  * The string value of a major-type-3 text string (already validated as
371
375
  * well-formed UTF-8 at decode). Throws `cbor/unexpected-major` otherwise.
372
376
  *
373
377
  * @example
378
+ * var node = pki.cbor.decode(Buffer.from("6161", "hex"));
374
379
  * pki.cbor.read.textString(node); // -> "a"
375
380
  */
376
381
  function readTextString(node) {
@@ -382,13 +387,14 @@ function readTextString(node) {
382
387
  * @primitive pki.cbor.read.array
383
388
  * @signature pki.cbor.read.array(node) -> [node, ...]
384
389
  * @since 0.1.27
385
- * @status experimental
390
+ * @status stable
386
391
  * @spec RFC 8949 sec. 3.1 (major type 4)
387
392
  *
388
393
  * The element nodes of a major-type-4 array. Throws `cbor/unexpected-major`
389
394
  * otherwise.
390
395
  *
391
396
  * @example
397
+ * var node = pki.cbor.decode(Buffer.from("83010203", "hex"));
392
398
  * pki.cbor.read.array(node); // -> [node, node, node]
393
399
  */
394
400
  function readArray(node) {
@@ -400,7 +406,7 @@ function readArray(node) {
400
406
  * @primitive pki.cbor.read.map
401
407
  * @signature pki.cbor.read.map(node) -> [[keyNode, valueNode], ...]
402
408
  * @since 0.1.27
403
- * @status experimental
409
+ * @status stable
404
410
  * @spec RFC 8949 sec. 3.1 (major type 5)
405
411
  *
406
412
  * The ordered key/value node pairs of a major-type-5 map (ordering and
@@ -408,6 +414,7 @@ function readArray(node) {
408
414
  * otherwise.
409
415
  *
410
416
  * @example
417
+ * var node = pki.cbor.decode(Buffer.from("a1616101", "hex")); // {"a": 1}
411
418
  * pki.cbor.read.map(node); // -> [[keyNode, valueNode]]
412
419
  */
413
420
  function readMap(node) {
@@ -419,7 +426,7 @@ function readMap(node) {
419
426
  * @primitive pki.cbor.read.mapGet
420
427
  * @signature pki.cbor.read.mapGet(node, key) -> valueNode | null
421
428
  * @since 0.2.20
422
- * @status experimental
429
+ * @status stable
423
430
  * @spec RFC 8949 sec. 3.1 (major type 5)
424
431
  *
425
432
  * The value node of the map entry whose key equals `key` -- a text string
@@ -436,6 +443,8 @@ function readMap(node) {
436
443
  * a TypeError for a key that is neither a text string nor an integer.
437
444
  *
438
445
  * @example
446
+ * // a WebAuthn-shaped map: {3: -7, "fmt": "packed"} in deterministic key order
447
+ * var node = pki.cbor.decode(Buffer.from("a2032663666d74667061636b6564", "hex"));
439
448
  * pki.cbor.read.mapGet(node, "fmt"); // -> valueNode | null
440
449
  * pki.cbor.read.mapGet(node, 3); // a COSE alg label -> valueNode | null
441
450
  */
@@ -465,7 +474,7 @@ function readMapGet(node, key) {
465
474
  * @primitive pki.cbor.read.boolean
466
475
  * @signature pki.cbor.read.boolean(node) -> false
467
476
  * @since 0.1.27
468
- * @status experimental
477
+ * @status stable
469
478
  * @spec RFC 8949 sec. 3.3 (simple values 20 / 21)
470
479
  *
471
480
  * The boolean value of a simple-value node (false=20, true=21). Throws
@@ -473,6 +482,7 @@ function readMapGet(node, key) {
473
482
  * other simple value.
474
483
  *
475
484
  * @example
485
+ * var node = pki.cbor.decode(Buffer.from("f5", "hex"));
476
486
  * pki.cbor.read.boolean(node); // -> true
477
487
  */
478
488
  function readBoolean(node) {
@@ -486,13 +496,14 @@ function readBoolean(node) {
486
496
  * @primitive pki.cbor.read.nullValue
487
497
  * @signature pki.cbor.read.nullValue(node) -> null
488
498
  * @since 0.1.27
489
- * @status experimental
499
+ * @status stable
490
500
  * @spec RFC 8949 sec. 3.3 (simple value 22)
491
501
  *
492
502
  * `null` for a simple-value-22 node. Throws `cbor/unexpected-major` on a
493
503
  * non-simple node, `cbor/bad-simple` on any other simple value.
494
504
  *
495
505
  * @example
506
+ * var node = pki.cbor.decode(Buffer.from("f6", "hex"));
496
507
  * pki.cbor.read.nullValue(node); // -> null
497
508
  */
498
509
  function readNull(node) {
@@ -505,13 +516,14 @@ function readNull(node) {
505
516
  * @primitive pki.cbor.read.undefinedValue
506
517
  * @signature pki.cbor.read.undefinedValue(node) -> undefined
507
518
  * @since 0.1.27
508
- * @status experimental
519
+ * @status stable
509
520
  * @spec RFC 8949 sec. 3.3 (simple value 23)
510
521
  *
511
522
  * `undefined` for a simple-value-23 node. Throws `cbor/unexpected-major` on a
512
523
  * non-simple node, `cbor/bad-simple` on any other simple value.
513
524
  *
514
525
  * @example
526
+ * var node = pki.cbor.decode(Buffer.from("f7", "hex"));
515
527
  * pki.cbor.read.undefinedValue(node); // -> undefined
516
528
  */
517
529
  function readUndefined(node) {
@@ -524,7 +536,7 @@ function readUndefined(node) {
524
536
  * @primitive pki.cbor.read.float
525
537
  * @signature pki.cbor.read.float(node) -> 1.5
526
538
  * @since 0.1.27
527
- * @status experimental
539
+ * @status stable
528
540
  * @spec RFC 8949 sec. 3.1 (major type 7 floats)
529
541
  *
530
542
  * The JS number (double) of a half / single / double float node (the
@@ -533,6 +545,7 @@ function readUndefined(node) {
533
545
  * simple value that is not a float.
534
546
  *
535
547
  * @example
548
+ * var node = pki.cbor.decode(Buffer.from("f93e00", "hex")); // half-precision 1.5
536
549
  * pki.cbor.read.float(node); // -> 1.5
537
550
  */
538
551
  function readFloat(node) {
@@ -547,7 +560,7 @@ function readFloat(node) {
547
560
  * @primitive pki.cbor.read.biguint
548
561
  * @signature pki.cbor.read.biguint(node) -> 18446744073709551616n
549
562
  * @since 0.1.27
550
- * @status experimental
563
+ * @status stable
551
564
  * @spec RFC 8949 sec. 3.4.3 (tag 2 unsigned bignum)
552
565
  *
553
566
  * The BigInt value of a tag-2 unsigned bignum (a big-endian magnitude byte
@@ -557,6 +570,7 @@ function readFloat(node) {
557
570
  * (`cbor/bad-tag-content`); a wrong / absent tag throws `cbor/unexpected-tag`.
558
571
  *
559
572
  * @example
573
+ * var node = pki.cbor.decode(Buffer.from("c249010000000000000000", "hex"));
560
574
  * pki.cbor.read.biguint(node); // -> 18446744073709551616n
561
575
  */
562
576
  function readBiguint(node) {
@@ -575,7 +589,7 @@ function readBiguint(node) {
575
589
  * @primitive pki.cbor.read.time
576
590
  * @signature pki.cbor.read.time(node) -> Date
577
591
  * @since 0.1.27
578
- * @status experimental
592
+ * @status stable
579
593
  * @spec RFC 8949 sec. 3.4.2 (tag 1 epoch date/time)
580
594
  *
581
595
  * The `Date` of a tag-1 epoch time (seconds since 1970-01-01T00:00Z, integer).
@@ -583,6 +597,7 @@ function readBiguint(node) {
583
597
  * when tag 1 does not wrap an integer, `cbor/bad-time` on an out-of-range value.
584
598
  *
585
599
  * @example
600
+ * var node = pki.cbor.decode(Buffer.from("c11a514b67b0", "hex")); // tag 1, epoch seconds
586
601
  * pki.cbor.read.time(node); // -> Date 2013-03-21T20:04:00.000Z
587
602
  */
588
603
  function readTime(node) {
@@ -606,7 +621,7 @@ function readTime(node) {
606
621
  * @primitive pki.cbor.read.oid
607
622
  * @signature pki.cbor.read.oid(node) -> "2.5.4.3"
608
623
  * @since 0.1.27
609
- * @status experimental
624
+ * @status stable
610
625
  * @spec RFC 9090 (tag 111 CBOR OID)
611
626
  *
612
627
  * The dotted OID string of a tag-111 CBOR OID (a byte string carrying the BER
@@ -616,6 +631,7 @@ function readTime(node) {
616
631
  * `cbor/bad-tag-content` when tag 111 does not wrap a byte string.
617
632
  *
618
633
  * @example
634
+ * var node = pki.cbor.decode(Buffer.from("d86f43550403", "hex")); // tag 111 (RFC 9090)
619
635
  * pki.cbor.read.oid(node); // -> "2.5.4.3"
620
636
  */
621
637
  function readOid(node) {