@blamejs/pki 0.8.12 → 0.8.15

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.
@@ -0,0 +1,278 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (c) blamejs contributors
3
+ "use strict";
4
+ /**
5
+ * @module pki.trustanchor
6
+ * @nav Trust
7
+ * @title Trust anchor lists
8
+ * @order 178
9
+ * @slug trustanchor-build
10
+ *
11
+ * @intro
12
+ * Write the RFC 5914 `TrustAnchorList` a root program publishes: each anchor
13
+ * as a certificate, as a bare `TBSCertificate`, or as a `TrustAnchorInfo`
14
+ * carrying the name it is known by and the constraints a relying party
15
+ * applies to paths beneath it. Every anchor is held to the same rules
16
+ * `pki.schema.trustanchor.parse` holds one to, and the result round-trips
17
+ * through that parser before it is returned.
18
+ *
19
+ * @card
20
+ * Build RFC 5914 trust anchor lists: the anchor carries its own policies,
21
+ * name constraints and path length.
22
+ */
23
+
24
+ var asn1 = require("./asn1-der");
25
+ var schema = require("./schema-engine");
26
+ var pkix = require("./schema-pkix");
27
+ var trustanchor = require("./schema-trustanchor");
28
+ var x509 = require("./schema-x509");
29
+ var pkiBuild = require("./pki-build");
30
+ var oid = require("./oid");
31
+ var frameworkError = require("./framework-error");
32
+ var intrinsic = require("./guard-intrinsic");
33
+ var guard = require("./guard-all");
34
+
35
+ var TrustAnchorError = frameworkError.TrustAnchorError;
36
+ var b = asn1.build;
37
+
38
+ function _err(code, message, cause) { return new TrustAnchorError(code, message, cause); }
39
+ function O(n) { return oid.byName(n); }
40
+
41
+ var NS = pkix.makeNS("trustanchor", TrustAnchorError, oid);
42
+ var NAME_SCHEMA = pkix.name(NS);
43
+ var SPKI_SCHEMA = pkix.spki(NS);
44
+ var _b = pkiBuild.makeBuilder({ ErrorClass: TrustAnchorError, prefix: "trustanchor", O: O, NS: NS,
45
+ NAME_SCHEMA: NAME_SCHEMA, SPKI_SCHEMA: SPKI_SCHEMA, EXT_DECODERS: {} });
46
+
47
+ var CERT_EXT_DECODERS = pkix.certExtensionDecoders(NS).byOid;
48
+ var OID_NAME_CONSTRAINTS = oid.byName("nameConstraints");
49
+
50
+ var _ANCHOR_KEYS = intrinsic.assign(intrinsic.create(null), { certificate: 1, tbsCert: 1, taInfo: 1 });
51
+ var _INFO_KEYS = intrinsic.assign(intrinsic.create(null), {
52
+ pubKey: 1, keyId: 1, taTitle: 1, certPath: 1, exts: 1, taTitleLangTag: 1 });
53
+ var _CERT_PATH_KEYS = intrinsic.assign(intrinsic.create(null), {
54
+ taName: 1, certificate: 1, policySet: 1, policyFlags: 1, nameConstr: 1, pathLenConstraint: 1 });
55
+ var _FLAG_KEYS = intrinsic.assign(intrinsic.create(null), {
56
+ inhibitPolicyMapping: 1, requireExplicitPolicy: 1, inhibitAnyPolicy: 1 });
57
+ var _BUILD_KEYS = intrinsic.assign(intrinsic.create(null), { anchors: 1, pem: 1 });
58
+
59
+ /** @internal The shape check comes first, so every nested record reports a typed refusal naming
60
+ * the field instead of a native TypeError from the first property read below it. */
61
+ function _known(obj, allowed, what) {
62
+ guard.identifier.assertPlainRecord(obj, _err, "trustanchor/bad-input", what);
63
+ guard.identifier.assertKnownKeys(obj, allowed, _err, "trustanchor/bad-input", "unknown " + what + " field ");
64
+ }
65
+
66
+ function _policySetDer(list) {
67
+ if (!intrinsic.isArray(list) || list.length === 0) {
68
+ throw _err("trustanchor/bad-input", "certPath.policySet must be a non-empty array of policy identifiers");
69
+ }
70
+ return b.sequence(intrinsic.map(list, function (p) {
71
+ if (typeof p !== "string" || !oid.isDottedDecimal(p)) {
72
+ throw _err("trustanchor/bad-input", "certPath.policySet entries must be dotted-decimal policy identifiers");
73
+ }
74
+ /** @internal RFC 5914 sec. 2 forbids the qualifiers, so there is no place to put one and a
75
+ * caller cannot supply one: the element is the identifier alone. */
76
+ return b.sequence([b.oid(p)]);
77
+ }));
78
+ }
79
+
80
+ var FLAG_BITS = trustanchor.policyFlagBits;
81
+ function _policyFlagsDer(flags) {
82
+ _known(flags, _FLAG_KEYS, "certPath.policyFlags");
83
+ var bits = [];
84
+ for (var i = 0; i < FLAG_BITS.length; i++) {
85
+ var v = flags[FLAG_BITS[i]];
86
+ if (v === undefined || v === false) continue;
87
+ if (v !== true) throw _err("trustanchor/bad-input", "certPath.policyFlags." + FLAG_BITS[i] + " must be a boolean");
88
+ guard.list.append(bits, i);
89
+ }
90
+ if (bits.length === 0) return null;
91
+ return b.implicit(2, b.namedBitString(bits));
92
+ }
93
+
94
+ function _certPathDer(spec) {
95
+ _known(spec, _CERT_PATH_KEYS, "certPath");
96
+ var nameDer = _b.encodeName(spec.taName);
97
+ if (_b.isEmptyName(nameDer)) {
98
+ throw _err("trustanchor/bad-input", "certPath.taName must be a non-empty distinguished name (RFC 5914 sec. 2)");
99
+ }
100
+ var kids = [b.raw(nameDer)];
101
+ /** @internal The RFC 5914 module is IMPLICIT TAGS, so a context tag REPLACES the member's own
102
+ * universal tag rather than wrapping it. `b.implicit` re-tags the value it is given; only the
103
+ * three members the module writes EXPLICIT beside get a wrapper. */
104
+ if (spec.certificate !== undefined) {
105
+ guard.list.append(kids, b.implicit(0, _b.reqDer(spec.certificate, "certPath.certificate")));
106
+ }
107
+ var hasPolicySet = spec.policySet !== undefined;
108
+ if (hasPolicySet) guard.list.append(kids, b.implicit(1, _policySetDer(spec.policySet)));
109
+ if (spec.policyFlags !== undefined) {
110
+ if (!spec.policyFlags || typeof spec.policyFlags !== "object") {
111
+ throw _err("trustanchor/bad-input", "certPath.policyFlags must be an object of boolean flags");
112
+ }
113
+ /** @internal RFC 5914 sec. 2: "This bit MUST be set to FALSE if policySet is absent." Refused
114
+ * here as well as at the parse, so the builder cannot emit what the parser would reject. */
115
+ if (spec.policyFlags.requireExplicitPolicy === true && !hasPolicySet) {
116
+ throw _err("trustanchor/bad-input", "certPath.policyFlags.requireExplicitPolicy requires a policySet (RFC 5914 sec. 2)");
117
+ }
118
+ var flagsDer = _policyFlagsDer(spec.policyFlags);
119
+ if (flagsDer !== null) guard.list.append(kids,flagsDer);
120
+ }
121
+ if (spec.nameConstr !== undefined) {
122
+ var ncDer = _b.reqDer(spec.nameConstr, "certPath.nameConstr");
123
+ try { CERT_EXT_DECODERS[OID_NAME_CONSTRAINTS](ncDer); }
124
+ catch (e) { throw _err("trustanchor/bad-input", "certPath.nameConstr is not a well-formed NameConstraints (RFC 5280 sec. 4.2.1.10)", e); }
125
+ guard.list.append(kids, b.implicit(3, ncDer));
126
+ }
127
+ if (spec.pathLenConstraint !== undefined) {
128
+ var n = spec.pathLenConstraint;
129
+ if (!intrinsic.isInteger(n) || n < 0) {
130
+ throw _err("trustanchor/bad-input", "certPath.pathLenConstraint must be a non-negative integer (INTEGER (0..MAX), RFC 5914 sec. 2)");
131
+ }
132
+ guard.list.append(kids,b.implicit(4, b.integer(intrinsic.BigInt(n))));
133
+ }
134
+ return b.sequence(kids);
135
+ }
136
+
137
+ function _taInfoDer(spec) {
138
+ _known(spec, _INFO_KEYS, "taInfo");
139
+ /** @internal The version is the DEFAULT v1 and DER omits it, so it is not a field a caller sets
140
+ * and there is exactly one encoding of a v1 anchor. */
141
+ var spki = _b.reqDer(spec.pubKey, "taInfo.pubKey");
142
+ _b.assertValidSpki(spki, "taInfo.pubKey");
143
+ var keyId = guard.bytes.snapshotSource(spec.keyId, TrustAnchorError, "trustanchor/bad-input", "taInfo.keyId");
144
+ if (keyId.length === 0) throw _err("trustanchor/bad-input", "taInfo.keyId must not be empty");
145
+ var kids = [b.raw(spki), b.octetString(keyId)];
146
+ if (spec.taTitle !== undefined) {
147
+ /** @internal Counted the way the reader counts, in characters rather than UTF-16 code units,
148
+ * so the writer admits exactly the titles the reader does. */
149
+ if (typeof spec.taTitle !== "string") {
150
+ throw _err("trustanchor/bad-input", "taInfo.taTitle must be a string");
151
+ }
152
+ var titleLen = trustanchor.titleChars(spec.taTitle);
153
+ if (titleLen < 1 || titleLen > 64) {
154
+ throw _err("trustanchor/bad-input", "taInfo.taTitle must be 1 to 64 characters (SIZE (1..64), RFC 5914 sec. 2), got " + titleLen);
155
+ }
156
+ guard.list.append(kids,b.utf8(spec.taTitle));
157
+ }
158
+ if (spec.certPath !== undefined) guard.list.append(kids,_certPathDer(spec.certPath));
159
+ if (spec.exts !== undefined) {
160
+ if (!intrinsic.isArray(spec.exts) || spec.exts.length === 0) {
161
+ throw _err("trustanchor/bad-input", "taInfo.exts must be a non-empty array of pre-encoded Extension DER");
162
+ }
163
+ var extDers = intrinsic.map(spec.exts, function (e, i) {
164
+ var der = _b.reqDer(e, "taInfo.exts[" + i + "]");
165
+ var extnId;
166
+ try { extnId = asn1.read.oid(asn1.decode(der).children[0]); }
167
+ catch (err) { throw _err("trustanchor/bad-input", "taInfo.exts[" + i + "] is not a well-formed Extension", err); }
168
+ /** @internal RFC 5914 sec. 3 names four extension types that MUST NOT appear here. The parser
169
+ * ignores one that does, as the RFC says to; the builder refuses to write one, so this
170
+ * toolkit never produces an anchor carrying a constraint nothing will read. */
171
+ if (trustanchor.excludedExtensionOids[extnId] === true) {
172
+ throw _err("trustanchor/bad-input", "taInfo.exts must not carry " + (oid.name(extnId) || extnId) +
173
+ ", which RFC 5914 sec. 3 excludes and a reader ignores; state it in certPath instead");
174
+ }
175
+ return b.raw(der);
176
+ });
177
+ guard.list.append(kids,b.explicit(1, b.sequence(extDers)));
178
+ }
179
+ if (spec.taTitleLangTag !== undefined) {
180
+ /** @internal The type carries no SIZE constraint, so the reader accepts an empty language tag
181
+ * and this refuses to write one: an empty tag names no language, and the field exists to say
182
+ * which language the title is in. The docstring states it, since the module does not. */
183
+ if (typeof spec.taTitleLangTag !== "string" || spec.taTitleLangTag.length === 0) {
184
+ throw _err("trustanchor/bad-input", "taInfo.taTitleLangTag must be a non-empty string; an empty one names no language");
185
+ }
186
+ /** @internal `[2] UTF8String` with no EXPLICIT beside it in the module, so the context tag
187
+ * replaces the UTF8String tag rather than wrapping it. */
188
+ guard.list.append(kids, b.implicit(2, b.utf8(spec.taTitleLangTag)));
189
+ }
190
+ return b.sequence(kids);
191
+ }
192
+
193
+ function _anchorDer(spec, i) {
194
+ if (!spec || typeof spec !== "object" || intrinsic.isArray(spec)) {
195
+ throw _err("trustanchor/bad-input", "anchors[" + i + "] must be an object naming exactly one of certificate, tbsCert or taInfo");
196
+ }
197
+ _known(spec, _ANCHOR_KEYS, "anchors[" + i + "]");
198
+ var named = [];
199
+ intrinsic.forEach(["certificate", "tbsCert", "taInfo"], function (k) {
200
+ if (spec[k] !== undefined) guard.list.append(named, k);
201
+ });
202
+ if (named.length !== 1) {
203
+ throw _err("trustanchor/bad-input", "anchors[" + i + "] must name exactly one of certificate, tbsCert or taInfo, got " +
204
+ (named.length === 0 ? "none" : intrinsic.join(named, " and ")));
205
+ }
206
+ if (named[0] === "certificate") return b.raw(_b.reqDer(spec.certificate, "anchors[" + i + "].certificate"));
207
+ if (named[0] === "tbsCert") return b.explicit(1, b.raw(_b.reqDer(spec.tbsCert, "anchors[" + i + "].tbsCert")));
208
+ return b.explicit(2, _taInfoDer(spec.taInfo));
209
+ }
210
+
211
+ /**
212
+ * @primitive pki.trustanchor.build
213
+ * @signature pki.trustanchor.build(spec, opts?) -> Buffer | string
214
+ * @since 0.8.13
215
+ * @status stable
216
+ * @spec RFC 5914
217
+ * @related pki.schema.trustanchor.parse, pki.trust.parseTrustAnchorList
218
+ *
219
+ * Build an RFC 5914 `TrustAnchorList`, the structure a root program publishes. `spec.anchors` is a
220
+ * non-empty array, each entry naming exactly one of `certificate` (pre-encoded Certificate DER),
221
+ * `tbsCert` (pre-encoded TBSCertificate DER) or `taInfo`.
222
+ *
223
+ * A `taInfo` entry is `{ pubKey, keyId, taTitle?, certPath?, exts?, taTitleLangTag? }`, where
224
+ * `pubKey` is SubjectPublicKeyInfo DER and `keyId` the key identifier bytes. `certPath` carries the
225
+ * constraints: `taName` (a distinguished name string or an array of relative names), `certificate`,
226
+ * `policySet` (an array of policy identifiers), `policyFlags`
227
+ * (`{ inhibitPolicyMapping, requireExplicitPolicy, inhibitAnyPolicy }`), `nameConstr` (pre-encoded
228
+ * NameConstraints DER) and `pathLenConstraint`.
229
+ *
230
+ * Every rule the parser enforces is enforced here, so this toolkit does not emit an anchor it would
231
+ * refuse to read: an empty `taName`, a `requireExplicitPolicy` with no `policySet`, a negative
232
+ * `pathLenConstraint`, and an `exts` entry naming one of the four extension types RFC 5914
233
+ * section 3 excludes. The result round-trips through `pki.schema.trustanchor.parse` before it is
234
+ * returned.
235
+ *
236
+ * The version is not a field a caller sets: v1 is the ASN.1 DEFAULT and DER omits it, so every v1
237
+ * anchor has one encoding.
238
+ *
239
+ * Two refusals are stricter than the module, on the principle that what this
240
+ * writes is what an operator publishes: `taTitleLangTag` may not be the empty string, which
241
+ * names no language, and `exts` may not carry one of the four extension types RFC 5914 section 3
242
+ * excludes, which a reader is told to ignore and which `certPath` states properly.
243
+ *
244
+ * @opts
245
+ * - `pem` (boolean) -- return a PEM `TRUST ANCHOR LIST` string instead of DER.
246
+ * @example
247
+ * var pair = await pki.key.generate("Ed25519");
248
+ * var der = pki.trustanchor.build({ anchors: [{ taInfo: {
249
+ * pubKey: await pki.key.export(pair.publicKey),
250
+ * keyId: Buffer.alloc(20, 1),
251
+ * taTitle: "Example Root CA",
252
+ * certPath: { taName: "CN=Example Root", pathLenConstraint: 2 } } }] });
253
+ * pki.schema.trustanchor.parse(der).anchors[0].taInfo.certPath.pathLenConstraint; // -> 2
254
+ */
255
+ function build(spec, opts) {
256
+ if (!spec || typeof spec !== "object" || intrinsic.isArray(spec)) {
257
+ throw _err("trustanchor/bad-input", "build expects a { anchors } specification object");
258
+ }
259
+ _known(spec, _BUILD_KEYS, "build");
260
+ var checked = guard.identifier.optionsObject(opts, _err, "trustanchor/bad-input", "pki.trustanchor.build options");
261
+ guard.identifier.assertKnownKeys(checked, intrinsic.assign(intrinsic.create(null), { pem: 1 }),
262
+ _err, "trustanchor/bad-input", "unknown pki.trustanchor.build option ");
263
+ if (!intrinsic.isArray(spec.anchors) || spec.anchors.length === 0) {
264
+ throw _err("trustanchor/bad-input", "build: anchors must be a non-empty array (TrustAnchorList is SIZE (1..MAX))");
265
+ }
266
+ var der = b.sequence(intrinsic.map(spec.anchors, function (a, i) { return _anchorDer(a, i); }));
267
+ /** @internal The reader reads the writer's output back before it is returned, so a shape the two
268
+ * disagree about fails the build instead of reaching an operator. */
269
+ try { trustanchor.parse(der); }
270
+ catch (e) { throw _err("trustanchor/bad-input", "the built trust anchor list does not parse: " + guard.text.describeThrown(e), e); }
271
+ if (checked.pem === true) return trustanchor.pemEncode(der);
272
+ return der;
273
+ }
274
+
275
+ void schema;
276
+ void x509;
277
+
278
+ module.exports = { build: build };
@@ -122,7 +122,7 @@ function normalizeObjectAttributePolicy(policy, E, code) {
122
122
  var explicit = policy.objectAttributes;
123
123
  if (explicit !== undefined) {
124
124
  if (!explicit || typeof explicit !== "object" || Array.isArray(explicit)) throw new E(code, "opts.tpmPolicy.objectAttributes must be an object");
125
- Object.keys(explicit).forEach(function (n) {
125
+ guard.identifier.optionNames(explicit).forEach(function (n) {
126
126
  if (TPMA_OBJECT_BITS[n] === undefined) throw new E(code, "opts.tpmPolicy.objectAttributes has an unknown attribute " + JSON.stringify(n));
127
127
  if (typeof explicit[n] !== "boolean") throw new E(code, "opts.tpmPolicy.objectAttributes." + n + " must be a boolean");
128
128
  want[n] = explicit[n];
@@ -440,7 +440,7 @@ function metadataAnchors(entry, opts) {
440
440
  opts = opts || {};
441
441
  if (typeof opts !== "object" || Array.isArray(opts)) throw _err("webauthn/bad-input", "metadataAnchors opts must be an object");
442
442
  guard.identifier.assertKnownKeys(opts, _ANCHOR_OPTS, _err, "webauthn/bad-input", "metadataAnchors opts has an unknown key ");
443
- opts = Object.assign({}, opts);
443
+ opts = guard.identifier.ownOptions(opts);
444
444
  if (opts.time !== undefined) guard.time.assertValid(opts.time, _err, "webauthn/bad-input", "opts.time");
445
445
  if (opts.metadata !== undefined) {
446
446
  if (!isVerifiedResult(opts.metadata)) {
package/lib/webauthn.js CHANGED
@@ -906,7 +906,7 @@ function verify(attestationObject, clientDataHash, opts) {
906
906
  try {
907
907
  if (!_isPlainObject(opts)) throw _err("webauthn/bad-input", "opts must be an object");
908
908
  guard.identifier.assertKnownKeys(opts, _VERIFY_OPTS, _err, "webauthn/bad-input", "opts has an unknown key ");
909
- opts = Object.assign({}, opts);
909
+ opts = guard.identifier.ownOptions(opts);
910
910
  if (opts.time !== undefined) guard.time.assertValid(opts.time, _err, "webauthn/bad-input", "opts.time");
911
911
  _FORMAT_SCOPED_BOOLEAN_OPTS.forEach(function (k) {
912
912
  if (opts[k] !== undefined && typeof opts[k] !== "boolean") throw _err("webauthn/bad-input", "opts." + k + " must be a boolean");
@@ -957,10 +957,9 @@ function verify(attestationObject, clientDataHash, opts) {
957
957
  var bindingChecked, vopts;
958
958
  try {
959
959
  bindingChecked = _applyBindings(att.authData, att.authData.credentialPublicKey, opts);
960
- vopts = Object.assign({}, opts, {
961
- rootCertificates: _snapshotRoots(opts.rootCertificates),
962
- safetyNetRoots: _snapshotRoots(opts.safetyNetRoots),
963
- });
960
+ vopts = guard.identifier.ownOptions(opts);
961
+ vopts.rootCertificates = _snapshotRoots(opts.rootCertificates);
962
+ vopts.safetyNetRoots = _snapshotRoots(opts.safetyNetRoots);
964
963
  } catch (e) { return Promise.reject(e); }
965
964
  return Promise.resolve().then(function () { return verifier(att, clientDataHash, vopts); })
966
965
  .then(function (res) {
@@ -1478,8 +1477,7 @@ var _ASSERT_OPTS = Object.assign(Object.create(null), {
1478
1477
  function _snapshotAssertion(input) {
1479
1478
  if (!_isPlainObject(input)) throw _err("webauthn/bad-input", "pki.webauthn.verifyAssertion takes an options object");
1480
1479
  guard.identifier.assertKnownKeys(input, _ASSERT_OPTS, _err, "webauthn/bad-input", "verifyAssertion input has an unknown key ");
1481
- var out = intrinsic.create(null), k;
1482
- for (k in input) { if (_hasOwn(input, k)) out[k] = input[k]; }
1480
+ var out = guard.identifier.ownOptions(input);
1483
1481
  ["authenticatorData", "clientDataJSON", "clientDataHash", "signature", "expectedChallenge"].forEach(function (f) {
1484
1482
  if (_isBufferSource(out[f])) out[f] = guard.bytes.snapshotSource(out[f], WebauthnError, "webauthn/bad-input", f);
1485
1483
  });
@@ -1487,9 +1485,10 @@ function _snapshotAssertion(input) {
1487
1485
  out.credentialPublicKey = guard.bytes.snapshotSource(out.credentialPublicKey, WebauthnError,
1488
1486
  "webauthn/bad-input", "credentialPublicKey");
1489
1487
  } else if (_isPlainObject(out.credentialPublicKey)) {
1490
- var key = intrinsic.create(null), kk;
1491
- for (kk in out.credentialPublicKey) {
1492
- if (!_hasOwn(out.credentialPublicKey, kk)) continue;
1488
+ var key = intrinsic.create(null);
1489
+ var coseNames = guard.identifier.optionNames(out.credentialPublicKey);
1490
+ for (var ci = 0; ci < coseNames.length; ci++) {
1491
+ var kk = coseNames[ci];
1493
1492
  var v;
1494
1493
  try { v = out.credentialPublicKey[kk]; }
1495
1494
  catch (e) { throw _err("webauthn/bad-cose-key", "credentialPublicKey." + kk + " could not be read", e); }
package/lib/webcrypto.js CHANGED
@@ -116,8 +116,7 @@ function _normalizeAlg(algorithm, who) {
116
116
  if (!alg || typeof alg.name !== "string") {
117
117
  throw new WebCryptoError("webcrypto/syntax", (who || "operation") + ": algorithm must be a string or an object with a name");
118
118
  }
119
- var out = intrinsic.create(null);
120
- for (var k in alg) { if (_hasOwn(alg, k)) out[k] = alg[k]; }
119
+ var out = guard.identifier.ownOptions(alg);
121
120
  out.name = _toUpperCase(alg.name);
122
121
  return out;
123
122
  }
@@ -1030,7 +1029,8 @@ function _algFromImport(name, alg, keyObject) {
1030
1029
  function _curveFromKey(ko) {
1031
1030
  try {
1032
1031
  var jwk = ko.export({ format: "jwk" });
1033
- for (var k in CURVE_NODE) { if (jwk.crv === k) return k; }
1032
+ var curves = guard.identifier.optionNames(CURVE_NODE);
1033
+ for (var k = 0; k < curves.length; k++) { if (jwk.crv === curves[k]) return curves[k]; }
1034
1034
  }
1035
1035
  catch (_e) { }
1036
1036
  return undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/pki",
3
- "version": "0.8.12",
3
+ "version": "0.8.15",
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:d763f0be-c3b6-4191-bd7e-120bc1818e88",
5
+ "serialNumber": "urn:uuid:fd715296-3209-4fc3-85ee-b6af7fbfdd1c",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-09-23T23:26:25.918Z",
8
+ "timestamp": "2026-09-24T03:48:38.286Z",
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.8.12",
22
+ "bom-ref": "@blamejs/pki@0.8.15",
23
23
  "type": "application",
24
24
  "name": "pki",
25
- "version": "0.8.12",
25
+ "version": "0.8.15",
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.8.12",
29
+ "purl": "pkg:npm/%40blamejs/pki@0.8.15",
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.8.12",
57
+ "ref": "@blamejs/pki@0.8.15",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]