@blamejs/pki 0.8.2 → 0.8.4
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 +41 -0
- package/lib/guard-limits.js +48 -1
- package/lib/guard-parsed.js +4 -4
- package/lib/schema-all.js +29 -18
- package/lib/schema-attrcert.js +52 -35
- package/lib/schema-c509.js +92 -46
- package/lib/schema-cmc.js +75 -36
- package/lib/schema-cmp.js +14 -9
- package/lib/schema-cms.js +45 -29
- package/lib/schema-crl.js +17 -12
- package/lib/schema-crmf.js +17 -7
- package/lib/schema-csr.js +6 -1
- package/lib/schema-csrattrs.js +14 -7
- package/lib/schema-engine.js +65 -2
- package/lib/schema-ocsp.js +29 -18
- package/lib/schema-pkcs12.js +21 -12
- package/lib/schema-pkcs8.js +21 -4
- package/lib/schema-pkix.js +183 -10
- package/lib/schema-smime.js +12 -2
- package/lib/schema-tsp.js +54 -9
- package/lib/schema-x509.js +6 -1
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/schema-tsp.js
CHANGED
|
@@ -46,6 +46,8 @@ var PemError = frameworkError.PemError;
|
|
|
46
46
|
|
|
47
47
|
var NS = pkix.makeNS("tsp", TspError, oid);
|
|
48
48
|
|
|
49
|
+
var _TOKEN_PARSE_OPTS = pkix.parseOpts({ ErrorClass: TspError, prefix: "tsp", what: "the timeStampToken" });
|
|
50
|
+
|
|
49
51
|
var ALGORITHM_IDENTIFIER = pkix.algorithmIdentifier(NS);
|
|
50
52
|
var EXTENSION = pkix.extension(NS);
|
|
51
53
|
|
|
@@ -202,7 +204,7 @@ var TIME_STAMP_RESP = schema.seq([
|
|
|
202
204
|
schema.optional("timeStampToken", schema.any(), { whenUniversal: [TAGS.SEQUENCE] }),
|
|
203
205
|
], {
|
|
204
206
|
assert: "sequence", arity: { min: 1 }, code: "tsp/bad-response", what: "TimeStampResp",
|
|
205
|
-
build: function (m) {
|
|
207
|
+
build: function (m, ctx) {
|
|
206
208
|
var status = m.fields.status.value.result;
|
|
207
209
|
var present = m.fields.timeStampToken.present;
|
|
208
210
|
var granted = status.status === 0 || status.status === 1;
|
|
@@ -213,7 +215,9 @@ var TIME_STAMP_RESP = schema.seq([
|
|
|
213
215
|
status: status.status,
|
|
214
216
|
statusString: status.statusString,
|
|
215
217
|
failInfo: status.failInfo,
|
|
216
|
-
|
|
218
|
+
/** @internal The token is a second parse of bytes carried inside this one, so it takes the
|
|
219
|
+
* caps this door was given rather than the built-in ceilings. */
|
|
220
|
+
timeStampToken: present ? parseToken(m.fields.timeStampToken.value.bytes, ctx ? ctx.caps : undefined) : null,
|
|
217
221
|
};
|
|
218
222
|
},
|
|
219
223
|
});
|
|
@@ -250,7 +254,7 @@ var TIME_STAMP_REQ = schema.seq([
|
|
|
250
254
|
|
|
251
255
|
/**
|
|
252
256
|
* @primitive pki.schema.tsp.parseRequest
|
|
253
|
-
* @signature pki.schema.tsp.parseRequest(input) -> timeStampReq
|
|
257
|
+
* @signature pki.schema.tsp.parseRequest(input, caps?) -> timeStampReq
|
|
254
258
|
* @since 0.2.19
|
|
255
259
|
* @status stable
|
|
256
260
|
* @spec RFC 3161
|
|
@@ -268,12 +272,17 @@ var TIME_STAMP_REQ = schema.seq([
|
|
|
268
272
|
* var req = pki.schema.tsp.parseRequest(der);
|
|
269
273
|
* req.certReq; // -> boolean
|
|
270
274
|
* req.messageImprint.hashedMessage; // -> Buffer (the raw digest)
|
|
275
|
+
* @opts
|
|
276
|
+
* - `maxBytes` / `maxDepth` / `maxItems` (number) -- decode caps for this parse. Each
|
|
277
|
+
* defaults to the matching `pki.C.LIMITS` figure and may only be set lower; a value
|
|
278
|
+
* above it, or an option outside this set, is refused. A parse that exceeds one is
|
|
279
|
+
* refused with the `/too-large` code of this format.
|
|
271
280
|
*/
|
|
272
281
|
var parseRequest = pkix.makeParser({ pemLabel: null, PemError: PemError, ErrorClass: TspError, prefix: "tsp", what: "TimeStampReq", topSchema: TIME_STAMP_REQ, ns: NS });
|
|
273
282
|
|
|
274
283
|
/**
|
|
275
284
|
* @primitive pki.schema.tsp.parseTstInfo
|
|
276
|
-
* @signature pki.schema.tsp.parseTstInfo(input) -> tstInfo
|
|
285
|
+
* @signature pki.schema.tsp.parseTstInfo(input, caps?) -> tstInfo
|
|
277
286
|
* @since 0.1.13
|
|
278
287
|
* @status stable
|
|
279
288
|
* @spec RFC 3161
|
|
@@ -299,12 +308,17 @@ var parseRequest = pkix.makeParser({ pemLabel: null, PemError: PemError, ErrorCl
|
|
|
299
308
|
* var tst = pki.schema.tsp.parseTstInfo(der);
|
|
300
309
|
* tst.genTime; // -> Date
|
|
301
310
|
* tst.messageImprint.hashedMessage; // -> Buffer (the raw digest)
|
|
311
|
+
* @opts
|
|
312
|
+
* - `maxBytes` / `maxDepth` / `maxItems` (number) -- decode caps for this parse. Each
|
|
313
|
+
* defaults to the matching `pki.C.LIMITS` figure and may only be set lower; a value
|
|
314
|
+
* above it, or an option outside this set, is refused. A parse that exceeds one is
|
|
315
|
+
* refused with the `/too-large` code of this format.
|
|
302
316
|
*/
|
|
303
317
|
var parseTstInfo = pkix.makeParser({ pemLabel: null, PemError: PemError, ErrorClass: TspError, prefix: "tsp", what: "TSTInfo", topSchema: TST_INFO, ns: NS });
|
|
304
318
|
|
|
305
319
|
/**
|
|
306
320
|
* @primitive pki.schema.tsp.parse
|
|
307
|
-
* @signature pki.schema.tsp.parse(input) -> timeStampResp
|
|
321
|
+
* @signature pki.schema.tsp.parse(input, caps?) -> timeStampResp
|
|
308
322
|
* @since 0.1.13
|
|
309
323
|
* @status stable
|
|
310
324
|
* @spec RFC 3161
|
|
@@ -329,12 +343,17 @@ var parseTstInfo = pkix.makeParser({ pemLabel: null, PemError: PemError, ErrorCl
|
|
|
329
343
|
* var res = pki.schema.tsp.parse(der);
|
|
330
344
|
* res.status; // -> 0 (granted)
|
|
331
345
|
* res.timeStampToken.tstInfo.genTime; // -> Date (a granted token is decoded)
|
|
346
|
+
* @opts
|
|
347
|
+
* - `maxBytes` / `maxDepth` / `maxItems` (number) -- decode caps for this parse. Each
|
|
348
|
+
* defaults to the matching `pki.C.LIMITS` figure and may only be set lower; a value
|
|
349
|
+
* above it, or an option outside this set, is refused. A parse that exceeds one is
|
|
350
|
+
* refused with the `/too-large` code of this format.
|
|
332
351
|
*/
|
|
333
352
|
var parse = pkix.makeParser({ pemLabel: null, PemError: PemError, ErrorClass: TspError, prefix: "tsp", what: "TimeStampResp", topSchema: TIME_STAMP_RESP, ns: NS });
|
|
334
353
|
|
|
335
354
|
/**
|
|
336
355
|
* @primitive pki.schema.tsp.parseToken
|
|
337
|
-
* @signature pki.schema.tsp.parseToken(input) -> tstInfo
|
|
356
|
+
* @signature pki.schema.tsp.parseToken(input, caps?) -> tstInfo
|
|
338
357
|
* @since 0.1.13
|
|
339
358
|
* @status stable
|
|
340
359
|
* @spec RFC 3161, RFC 5652
|
|
@@ -364,13 +383,28 @@ var parse = pkix.makeParser({ pemLabel: null, PemError: PemError, ErrorClass: Ts
|
|
|
364
383
|
* var token = pki.schema.tsp.parseToken(tokenDer);
|
|
365
384
|
* token.tstInfo.genTime; // -> Date
|
|
366
385
|
* token.signerInfo.sid; // -> the TSA signer identifier
|
|
386
|
+
* @opts
|
|
387
|
+
* - `maxBytes` / `maxDepth` / `maxItems` (number) -- decode caps for this parse. Each
|
|
388
|
+
* defaults to the matching `pki.C.LIMITS` figure and may only be set lower; a value
|
|
389
|
+
* above it, or an option outside this set, is refused. A parse that exceeds one is
|
|
390
|
+
* refused with the `/too-large` code of this format.
|
|
367
391
|
*/
|
|
368
|
-
function parseToken(input) {
|
|
392
|
+
function parseToken(input, callerOpts) {
|
|
393
|
+
/** @internal The caller's options are this door's to answer for, so they are read here rather
|
|
394
|
+
* than inside the CMS parser: a complaint about an option must not come back wearing the
|
|
395
|
+
* delegate's verdict about the content. The snapshot travels onward, because handing the
|
|
396
|
+
* caller's own object to the CMS parser would read each cap a second time. */
|
|
397
|
+
var caps = pkix.parseCaps(callerOpts, _TOKEN_PARSE_OPTS);
|
|
369
398
|
var der = pkix.coerceToDer(input, { pemLabel: null, PemError: PemError, ErrorClass: TspError, prefix: "tsp" });
|
|
370
399
|
var signed;
|
|
371
|
-
try { signed = cms.parse(der); }
|
|
400
|
+
try { signed = cms.parse(der, caps); }
|
|
372
401
|
catch (e) {
|
|
373
402
|
if (e instanceof TspError) throw e;
|
|
403
|
+
/** @internal A resource refusal says the cap was too small, not that the token is malformed,
|
|
404
|
+
* so it keeps that meaning rather than becoming a statement about the bytes. */
|
|
405
|
+
if (e && typeof e.code === "string" && e.code.indexOf("/too-large") !== -1) {
|
|
406
|
+
throw new TspError("tsp/too-large", "the timeStampToken exceeds the decode budget for this parse: " + (e.message || ""), e);
|
|
407
|
+
}
|
|
374
408
|
throw new TspError("tsp/bad-token", "the timeStampToken did not decode as a CMS SignedData: " + ((e && e.message) || String(e)), e);
|
|
375
409
|
}
|
|
376
410
|
if (signed.contentTypeName !== "signedData") {
|
|
@@ -392,12 +426,23 @@ function parseToken(input) {
|
|
|
392
426
|
if (!hasSigningCert) {
|
|
393
427
|
throw new TspError("tsp/missing-signing-certificate", "a TimeStampToken signerInfo must carry a SigningCertificate or SigningCertificateV2 signed attribute (RFC 3161 sec. 2.4.2, RFC 5816)");
|
|
394
428
|
}
|
|
429
|
+
/** @internal The TSTInfo is decoded out of the eContent the CMS layer handed back, so it is a
|
|
430
|
+
* second decode and takes the caller's caps the way the carrier did. The latch is re-read
|
|
431
|
+
* below, because the catch here answers in this domain and would otherwise report a cap that
|
|
432
|
+
* was too small as a malformed TSTInfo. */
|
|
433
|
+
var nested = pkix.nestedContext(NS, caps);
|
|
395
434
|
var tstInfo;
|
|
396
|
-
try { tstInfo = schema.embeddedDer(TST_INFO, encap.eContent,
|
|
435
|
+
try { tstInfo = schema.embeddedDer(TST_INFO, encap.eContent, nested.ns, { code: "tsp/bad-der", what: "the encapsulated TSTInfo" }); }
|
|
397
436
|
catch (e) {
|
|
437
|
+
if (nested.budget.exhausted()) {
|
|
438
|
+
throw new TspError("tsp/too-large", "the timeStampToken exceeds the decode budget for this parse", e);
|
|
439
|
+
}
|
|
398
440
|
if (e instanceof TspError) throw e;
|
|
399
441
|
throw new TspError("tsp/bad-der", "the encapsulated TSTInfo did not decode: " + ((e && e.message) || String(e)), e);
|
|
400
442
|
}
|
|
443
|
+
if (nested.budget.exhausted()) {
|
|
444
|
+
throw new TspError("tsp/too-large", "the timeStampToken exceeds the decode budget for this parse");
|
|
445
|
+
}
|
|
401
446
|
return { tstInfo: tstInfo.result, eContent: encap.eContent, signerInfo: signed.signerInfos[0], certificates: signed.certificates };
|
|
402
447
|
}
|
|
403
448
|
|
package/lib/schema-x509.js
CHANGED
|
@@ -165,7 +165,7 @@ var CERTIFICATE = pkix.signedEnvelope(NS, CERTIFICATE_TBS, {
|
|
|
165
165
|
|
|
166
166
|
/**
|
|
167
167
|
* @primitive pki.schema.x509.parse
|
|
168
|
-
* @signature pki.schema.x509.parse(input) -> certificate
|
|
168
|
+
* @signature pki.schema.x509.parse(input, caps?) -> certificate
|
|
169
169
|
* @since 0.1.7
|
|
170
170
|
* @status stable
|
|
171
171
|
* @spec RFC 5280, X.509
|
|
@@ -194,6 +194,11 @@ var CERTIFICATE = pkix.signedEnvelope(NS, CERTIFICATE_TBS, {
|
|
|
194
194
|
* cert.subject.dn; // "CN=example.com, O=Example"
|
|
195
195
|
* cert.validity.notAfter; // Date
|
|
196
196
|
* cert.signatureAlgorithm.name; // "Ed25519" (the algorithm the issuer signed with)
|
|
197
|
+
* @opts
|
|
198
|
+
* - `maxBytes` / `maxDepth` / `maxItems` (number) -- decode caps for this parse. Each
|
|
199
|
+
* defaults to the matching `pki.C.LIMITS` figure and may only be set lower; a value
|
|
200
|
+
* above it, or an option outside this set, is refused. A parse that exceeds one is
|
|
201
|
+
* refused with the `/too-large` code of this format.
|
|
197
202
|
*/
|
|
198
203
|
var parse = pkix.makeRecordingParser({ pemLabel: "CERTIFICATE", PemError: PemError, ErrorClass: CertificateError, prefix: "x509", what: "certificate", topSchema: CERTIFICATE, ns: NS }, "certificate");
|
|
199
204
|
|
package/package.json
CHANGED
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:
|
|
5
|
+
"serialNumber": "urn:uuid:ca3c695a-64b2-4346-9529-6a6c719eb6bb",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-09-
|
|
8
|
+
"timestamp": "2026-09-20T06:26:19.862Z",
|
|
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.
|
|
22
|
+
"bom-ref": "@blamejs/pki@0.8.4",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "pki",
|
|
25
|
-
"version": "0.8.
|
|
25
|
+
"version": "0.8.4",
|
|
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.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/pki@0.8.4",
|
|
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.
|
|
57
|
+
"ref": "@blamejs/pki@0.8.4",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|