@blamejs/pki 0.8.55 → 0.8.56
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 +66 -0
- package/lib/acme.js +2 -2
- package/lib/asn1-der.js +17 -5
- package/lib/attrcert-verify.js +1 -1
- package/lib/cmc-verify.js +1 -1
- package/lib/cmp-session.js +2 -2
- package/lib/cmp-verify.js +2 -2
- package/lib/cms-decrypt.js +4 -1
- package/lib/cms-encrypt.js +4 -1
- package/lib/cms-sign.js +26 -12
- package/lib/cms-verify.js +1 -1
- package/lib/composite-kem.js +30 -12
- package/lib/composite-sig.js +42 -23
- package/lib/constants.js +7 -2
- package/lib/crl-verify.js +1 -1
- package/lib/crmf-sign.js +72 -43
- package/lib/crmf-verify.js +1 -1
- package/lib/csr-verify.js +1 -1
- package/lib/ct.js +2 -2
- package/lib/edwards-point.js +1 -1
- package/lib/est.js +3 -3
- package/lib/guard-async.js +22 -1
- package/lib/guard-bytes.js +6 -3
- package/lib/guard-identifier.js +1 -1
- package/lib/guard-intrinsic.js +474 -0
- package/lib/http-digest.js +146 -62
- package/lib/http-transport.js +82 -17
- package/lib/identity-match.js +2 -2
- package/lib/merkle.js +2 -2
- package/lib/ocsp-request-verify.js +1 -1
- package/lib/ocsp.js +46 -22
- package/lib/path-validate.js +169 -76
- package/lib/pbes2.js +14 -7
- package/lib/schema-attrcert.js +2 -2
- package/lib/schema-cmc.js +2 -2
- package/lib/schema-cmp.js +2 -2
- package/lib/schema-cms.js +2 -2
- package/lib/schema-crmf.js +2 -2
- package/lib/schema-csr.js +2 -2
- package/lib/schema-pkix.js +3 -3
- package/lib/schema-x509.js +2 -2
- package/lib/sigstore.js +1 -1
- package/lib/tlog.js +7 -4
- package/lib/trust.js +187 -104
- package/lib/tsp-sign.js +1 -1
- package/lib/webauthn-mds.js +257 -121
- package/lib/webauthn.js +327 -164
- package/lib/webcrypto.js +10 -3
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/ocsp.js
CHANGED
|
@@ -40,7 +40,6 @@ var _promiseResolve = _ocspIntrinsic.uncurry(_ocspIntrinsic.promiseResolve);
|
|
|
40
40
|
var _promiseReject = _ocspIntrinsic.uncurry(_ocspIntrinsic.promiseReject);
|
|
41
41
|
/** @internal The CertID hashes bind a response to the certificate it answers for, and they are awaited
|
|
42
42
|
* as a pair, so a replaced `all` decides what that pair contains. */
|
|
43
|
-
var _promiseAll = _ocspIntrinsic.uncurry(_ocspIntrinsic.promiseAll);
|
|
44
43
|
var oid = require("./oid");
|
|
45
44
|
var x509 = require("./schema-x509");
|
|
46
45
|
var ocspSchema = require("./schema-ocsp");
|
|
@@ -77,7 +76,12 @@ var ENTRY_EXTENSION_CRITICALITY = crlSchema.entryExtensionCriticality(oid);
|
|
|
77
76
|
var CERTIFICATE_HOLD = REASON_CODE.certificateHold, REMOVE_FROM_CRL = REASON_CODE.removeFromCRL;
|
|
78
77
|
var OID_REASON_CODE = O("reasonCode");
|
|
79
78
|
|
|
80
|
-
|
|
79
|
+
/** @internal Continued through the capture. Every CertID in a request and the key hash a responder
|
|
80
|
+
* names itself by come out of this step, so a replacement settling it names another certificate's
|
|
81
|
+
* identity, or another responder's key, in bytes that are then signed. */
|
|
82
|
+
function _digest(wcHash, buf) {
|
|
83
|
+
return _ocspIntrinsic.chain(subtle.digest(wcHash, buf), function (h) { return Buffer.from(h); });
|
|
84
|
+
}
|
|
81
85
|
function _certOf(arg, what) {
|
|
82
86
|
var label = what || "a certificate";
|
|
83
87
|
return guard.parsed.acceptDerived(arg, "certificate", function (bytes) {
|
|
@@ -115,10 +119,14 @@ var REQUESTER_NONCE_FLOOR = 32, RESPONDER_NONCE_FLOOR = 1;
|
|
|
115
119
|
function _buildCertID(cert, issuer, hashName) {
|
|
116
120
|
var wc = HASH_WC[guard.text.keyOf(hashName)];
|
|
117
121
|
if (!wc) throw _err("ocsp/bad-input", "unsupported CertID hashAlgorithm " + guard.text.showValue(hashName) + " (sha1 / sha256 / sha384 / sha512)");
|
|
118
|
-
|
|
122
|
+
/** @internal The two hashes are awaited through the aggregate that consults nothing replaceable.
|
|
123
|
+
* The static form reads `resolve` off the constructor at each call, and these two digests ARE the
|
|
124
|
+
* CertID a responder answers about, so a replacement answering for either names another
|
|
125
|
+
* certificate's identity in the request. */
|
|
126
|
+
return _ocspIntrinsic.chain(_ocspIntrinsic.allOf([
|
|
119
127
|
_digest(wc, issuer.subject.bytes),
|
|
120
128
|
_digest(wc, _keyValue(issuer.subjectPublicKeyInfo.bytes)),
|
|
121
|
-
])
|
|
129
|
+
]), function (hashes) {
|
|
122
130
|
var hashAlgId = hashName === "sha1" ? b.sequence([b.oid(O(hashName)), b.nullValue()]) : b.sequence([b.oid(O(hashName))]);
|
|
123
131
|
return b.sequence([
|
|
124
132
|
hashAlgId,
|
|
@@ -204,13 +212,15 @@ function _buildRequest(query, opts) {
|
|
|
204
212
|
requestorNameDer = signerCert.subject.bytes;
|
|
205
213
|
}
|
|
206
214
|
|
|
207
|
-
|
|
215
|
+
/** @internal Each query's CertID is awaited through the aggregate that consults nothing
|
|
216
|
+
* replaceable, for the reason at `_buildCertID`. */
|
|
217
|
+
var builtRequests = _ocspIntrinsic.allOf(_ocspIntrinsic.mapList(queries, function (q) {
|
|
208
218
|
if (!q || typeof q !== "object") throw _err("ocsp/bad-input", "each query must be { cert, issuer }");
|
|
209
219
|
guard.identifier.assertKnownKeys(q, _QUERY_KEYS, _err, "ocsp/bad-input", "unknown query field (a query is { cert, issuer, singleRequestExtensions? }): ");
|
|
210
220
|
if (q.cert == null || q.issuer == null) throw _err("ocsp/bad-input", "each query must be { cert, issuer }");
|
|
211
221
|
var cert = _certOf(q.cert, "the query certificate");
|
|
212
222
|
var issuer = _certOf(q.issuer, "the issuer certificate");
|
|
213
|
-
return _buildCertID(cert, issuer, hashName)
|
|
223
|
+
return _ocspIntrinsic.chain(_buildCertID(cert, issuer, hashName), function (certID) {
|
|
214
224
|
var reqChildren = [certID];
|
|
215
225
|
if (q.singleRequestExtensions != null) {
|
|
216
226
|
/** @internal Read through the same door the sibling lists in this module use, so a value that is
|
|
@@ -225,7 +235,8 @@ function _buildRequest(query, opts) {
|
|
|
225
235
|
}
|
|
226
236
|
return b.sequence(reqChildren);
|
|
227
237
|
});
|
|
228
|
-
}))
|
|
238
|
+
}));
|
|
239
|
+
return _ocspIntrinsic.chain(builtRequests, function (requests) {
|
|
229
240
|
var tbsChildren = [];
|
|
230
241
|
if (requestorNameDer !== null) tbsChildren.push(b.explicit(1, b.contextConstructed(4, requestorNameDer)));
|
|
231
242
|
tbsChildren.push(b.sequence(requests));
|
|
@@ -239,10 +250,12 @@ function _buildRequest(query, opts) {
|
|
|
239
250
|
var tbsRequest = b.sequence(tbsChildren);
|
|
240
251
|
if (signerCert === null) return _emitReq(b.sequence([tbsRequest]), opts);
|
|
241
252
|
var scheme = signScheme.resolveSignScheme(signerCert, { combinedRsaSig: true }, true, _signE);
|
|
242
|
-
return signScheme.signOverTbs(scheme, opts.signer.key, tbsRequest, _signE)
|
|
253
|
+
return _ocspIntrinsic.chain(signScheme.signOverTbs(scheme, opts.signer.key, tbsRequest, _signE), function (sig) {
|
|
243
254
|
/** @internal The request is held to the same proof a certificate is: the signature verifies
|
|
244
|
-
* against the public key the certificate it carries declares.
|
|
245
|
-
|
|
255
|
+
* against the public key the certificate it carries declares. Both continuations are captured,
|
|
256
|
+
* since the inner one runs only after that proof has been made. */
|
|
257
|
+
var selfChecked = _promiseResolve(_Promise, _b.assertSignatureVerifies(tbsRequest, sig, signerCert.subjectPublicKeyInfo.bytes, scheme));
|
|
258
|
+
return _ocspIntrinsic.chain(selfChecked, function () {
|
|
246
259
|
var optionalSignature = b.sequence([scheme.sigAlgId, b.bitString(sig, 0), b.explicit(0, b.sequence([b.raw(signerCertDer)]))]);
|
|
247
260
|
return _emitReq(b.sequence([tbsRequest, b.explicit(0, optionalSignature)]), opts);
|
|
248
261
|
});
|
|
@@ -353,7 +366,8 @@ function _sign(responseData, responder, opts) {
|
|
|
353
366
|
try {
|
|
354
367
|
pending = _signResponse(responseData, responder, respCert, respCertDer, responderKey, opts);
|
|
355
368
|
} catch (e) { _wipeOwnedKey(); throw e; }
|
|
356
|
-
|
|
369
|
+
/** @internal Captured: this continuation is what wipes a key this verb owns, on either outcome. */
|
|
370
|
+
return _ocspIntrinsic.chain(pending, function (out) { _wipeOwnedKey(); return out; },
|
|
357
371
|
function (e) { _wipeOwnedKey(); throw e; });
|
|
358
372
|
}
|
|
359
373
|
|
|
@@ -361,10 +375,12 @@ function _signResponse(responseData, responder, respCert, respCertDer, responder
|
|
|
361
375
|
var responses = responseData.responses != null ? pkiBuild.reqDenseArray(responseData.responses, "responses", _err, "ocsp/bad-input") : [];
|
|
362
376
|
if (!responses.length) throw _err("ocsp/bad-input", "a response MUST include at least one SingleResponse (RFC 6960 sec. 4.2.1)");
|
|
363
377
|
|
|
364
|
-
return _responderID(responseData.responderID, respCert)
|
|
365
|
-
return
|
|
366
|
-
|
|
367
|
-
|
|
378
|
+
return _ocspIntrinsic.chain(_responderID(responseData.responderID, respCert), function (ridNode) {
|
|
379
|
+
return _ocspIntrinsic.chain(_ocspIntrinsic.allOf(_ocspIntrinsic.mapList(responses, function (r) {
|
|
380
|
+
return _buildSingleResponse(r, opts);
|
|
381
|
+
})), function (built) {
|
|
382
|
+
var srNodes = _ocspIntrinsic.mapList(built, function (x) { return x.node; });
|
|
383
|
+
var anyNonIssued = _ocspIntrinsic.some(built, function (x) { return x.nonIssued; });
|
|
368
384
|
/** @internal Sec. 2.2 and 4.4.8: a "revoked" answer for a non-issued certificate MUST carry the
|
|
369
385
|
* extended revoked definition in responseExtensions, so the shape itself places it there,
|
|
370
386
|
* and a caller declining it is refused rather than left with a response the section forbids. */
|
|
@@ -378,10 +394,12 @@ function _signResponse(responseData, responder, respCert, respCertDer, responder
|
|
|
378
394
|
if (respExts.length) rdChildren.push(b.explicit(1, b.sequence(respExts)));
|
|
379
395
|
var responseDataDer = b.sequence(rdChildren);
|
|
380
396
|
var scheme = signScheme.resolveSignScheme(respCert, { combinedRsaSig: true }, true, _signE);
|
|
381
|
-
return signScheme.signOverTbs(scheme, responderKey, responseDataDer, _signE)
|
|
397
|
+
return _ocspIntrinsic.chain(signScheme.signOverTbs(scheme, responderKey, responseDataDer, _signE), function (sig) {
|
|
382
398
|
/** @internal The response is held to the same proof a certificate is: the signature verifies
|
|
383
|
-
* against the public key the responder certificate declares.
|
|
384
|
-
|
|
399
|
+
* against the public key the responder certificate declares. Both continuations are captured,
|
|
400
|
+
* since the inner one runs only after that proof has been made. */
|
|
401
|
+
var selfChecked = _promiseResolve(_Promise, _b.assertSignatureVerifies(responseDataDer, sig, respCert.subjectPublicKeyInfo.bytes, scheme));
|
|
402
|
+
return _ocspIntrinsic.chain(selfChecked, function () {
|
|
385
403
|
var basicChildren = [responseDataDer, scheme.sigAlgId, b.bitString(sig, 0)];
|
|
386
404
|
if (opts.embedCert !== false) basicChildren.push(b.explicit(0, b.sequence([b.raw(respCertDer)])));
|
|
387
405
|
var responseBytes = b.sequence([b.oid(OID_OCSP_BASIC), b.octetString(b.sequence(basicChildren))]);
|
|
@@ -422,7 +440,10 @@ function _snapshotSignerKey(key, owned) {
|
|
|
422
440
|
|
|
423
441
|
function _responderID(rid, respCert) {
|
|
424
442
|
if (rid == null || rid === "byName") return _promiseResolve(_Promise, b.explicit(1, b.raw(respCert.subject.bytes)));
|
|
425
|
-
if (rid === "byKey")
|
|
443
|
+
if (rid === "byKey") {
|
|
444
|
+
return _ocspIntrinsic.chain(_digest("SHA-1", _keyValue(respCert.subjectPublicKeyInfo.bytes)),
|
|
445
|
+
function (kh) { return b.explicit(2, b.octetString(kh)); });
|
|
446
|
+
}
|
|
426
447
|
throw _err("ocsp/bad-input", "responderID must be \"byName\" or \"byKey\"");
|
|
427
448
|
}
|
|
428
449
|
function _buildSingleResponse(r, opts) {
|
|
@@ -438,7 +459,7 @@ function _buildSingleResponse(r, opts) {
|
|
|
438
459
|
* map into Promise.all, so a synchronous throw here would abort the map before Promise.all
|
|
439
460
|
* attached handlers, and an earlier entry's rejection would be orphaned: the caller catches
|
|
440
461
|
* sign()'s failure and the process still sees an unhandled rejection. */
|
|
441
|
-
return
|
|
462
|
+
return _ocspIntrinsic.chain(certIdP, function (certID) {
|
|
442
463
|
var thisUpdate = _asEncodableDate(r.thisUpdate, "thisUpdate") || new Date();
|
|
443
464
|
var nextUpdate = r.nextUpdate === null ? null : (_asEncodableDate(r.nextUpdate, "nextUpdate") || _defaultNextUpdate());
|
|
444
465
|
/** @internal RFC 6960 sec. 4.2.2.1 makes thisUpdate and nextUpdate a validity interval, and says
|
|
@@ -687,8 +708,11 @@ function verify(response, opts) {
|
|
|
687
708
|
try { reqNonce = guard.bytes.snapshotSource(reqNonce, OcspError, "ocsp/bad-input", "opts.requestNonce"); }
|
|
688
709
|
catch (e) { return _promiseReject(_Promise, e); }
|
|
689
710
|
}
|
|
690
|
-
|
|
691
|
-
|
|
711
|
+
/** @internal Captured: this continuation is where the response's status becomes the verdict a
|
|
712
|
+
* caller reads, so a settled value in place of it reports a status nothing evaluated. */
|
|
713
|
+
var evaluated = pathValidate.verifyOcspResponse(parsed, cert, issuerCert, time,
|
|
714
|
+
{ historicalMode: opts.historicalMode === true, requestNonce: reqNonce });
|
|
715
|
+
return _ocspIntrinsic.chain(evaluated, function (verdict) {
|
|
692
716
|
return guard.verdict.of(verdict, { valid: verdict.status === "good" });
|
|
693
717
|
});
|
|
694
718
|
}
|