@blamejs/pki 0.8.60 → 0.9.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 +48 -0
- package/README.md +7 -0
- package/index.js +55 -26
- package/lib/acme.js +5 -5
- package/lib/asn1-der.js +1 -1
- package/lib/attrcert-sign.js +2 -2
- package/lib/cbor-det.js +4 -1
- package/lib/cmc-build.js +15 -10
- package/lib/cmp-build.js +5 -5
- package/lib/cmp-session.js +6 -3
- package/lib/cmp-verify.js +1 -1
- package/lib/cms-compress.js +5 -2
- package/lib/cms-decrypt.js +17 -17
- package/lib/cms-digest.js +2 -3
- package/lib/cms-encrypt.js +17 -18
- package/lib/cms-sign.js +2 -2
- package/lib/composite-kem.js +28 -29
- package/lib/crl-sign.js +3 -3
- package/lib/crmf-sign.js +12 -18
- package/lib/csr-sign.js +1 -1
- package/lib/ct.js +25 -22
- package/lib/est.js +12 -12
- package/lib/framework-error.js +1 -1
- package/lib/guard-bytes.js +1 -1
- package/lib/guard-crypto.js +506 -14
- package/lib/guard-limits.js +3 -2
- package/lib/guard-secret.js +3 -2
- package/lib/hpke.js +26 -26
- package/lib/http-digest.js +5 -7
- package/lib/http-retry-after.js +4 -1
- package/lib/http-transport.js +6 -6
- package/lib/inspect.js +9 -4
- package/lib/jose.js +3 -3
- package/lib/key.js +41 -29
- package/lib/merkle.js +4 -4
- package/lib/ocsp.js +3 -4
- package/lib/path-validate.js +3 -3
- package/lib/pbes2.js +14 -11
- package/lib/pkcs12-build.js +10 -11
- package/lib/pki-build.js +3 -3
- package/lib/scep.js +8 -9
- package/lib/schema-engine.js +12 -12
- package/lib/schema-pkix.js +12 -12
- package/lib/schema-tsp.js +3 -3
- package/lib/shbs.js +3 -6
- package/lib/sign-scheme.js +4 -4
- package/lib/sigstore.js +10 -10
- package/lib/smime.js +12 -9
- package/lib/tlog.js +5 -4
- package/lib/tls-cert-compress.js +3 -3
- package/lib/tsp-sign.js +6 -6
- package/lib/tuf.js +6 -5
- package/lib/validator-cose.js +2 -2
- package/lib/webauthn-mds.js +4 -8
- package/lib/webauthn.js +5 -12
- package/lib/webcrypto.js +61 -46
- package/lib/x509-sign.js +3 -3
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/smime.js
CHANGED
|
@@ -33,6 +33,10 @@
|
|
|
33
33
|
* algorithm-agnostic.
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
|
+
/** @internal The record constructor, captured at load, for the reason the same capture in
|
|
37
|
+
* `lib/inspect.js` gives: requiring the guard-intrinsic captures arms the module whole, which counts
|
|
38
|
+
* 176 live runtime reads here. */
|
|
39
|
+
var _create = Object.create;
|
|
36
40
|
var frameworkError = require("./framework-error.js");
|
|
37
41
|
var mime = require("./mime.js");
|
|
38
42
|
var cms = require("./cms-verify.js");
|
|
@@ -48,7 +52,6 @@ var _push = guard.list.append;
|
|
|
48
52
|
var pkiBuild = require("./pki-build.js");
|
|
49
53
|
var C = require("./constants.js");
|
|
50
54
|
var nodeUtil = require("util");
|
|
51
|
-
var nodeCrypto = require("crypto");
|
|
52
55
|
|
|
53
56
|
var SmimeError = frameworkError.SmimeError;
|
|
54
57
|
|
|
@@ -591,7 +594,7 @@ function _micalgOf(p7Der) {
|
|
|
591
594
|
return out.length ? out.sort().join(",") : null;
|
|
592
595
|
}
|
|
593
596
|
|
|
594
|
-
function _boundary() { return "----=_pki_smime_" +
|
|
597
|
+
function _boundary() { return "----=_pki_smime_" + guard.crypto.randomBytes(18).toString("hex"); }
|
|
595
598
|
|
|
596
599
|
function _wrap64Crlf(s) {
|
|
597
600
|
var out = "";
|
|
@@ -655,7 +658,7 @@ function _base64Body(der) {
|
|
|
655
658
|
*/
|
|
656
659
|
async function sign(content, signers, opts) {
|
|
657
660
|
content = _fixedContent(content);
|
|
658
|
-
opts = opts ||
|
|
661
|
+
opts = opts || _create(null);
|
|
659
662
|
opts = _knownOpts(opts, SIGN_OPTS, "sign");
|
|
660
663
|
signers = _snapshotSignersFitForMail(signers);
|
|
661
664
|
var hp = opts.protectHeaders === true;
|
|
@@ -768,7 +771,7 @@ function _capped(msg) {
|
|
|
768
771
|
* if (res.valid) { res.content; res.signers[0].sid; }
|
|
769
772
|
*/
|
|
770
773
|
async function verify(message, opts) {
|
|
771
|
-
opts = opts ||
|
|
774
|
+
opts = opts || _create(null);
|
|
772
775
|
opts = _knownOpts(opts, VERIFY_OPTS, "verify");
|
|
773
776
|
var ent = mime.parse(message, SmimeError, "smime/bad-mime");
|
|
774
777
|
var ct = ent.contentType;
|
|
@@ -878,7 +881,7 @@ function _cmsEncryptOpts(opts) {
|
|
|
878
881
|
*/
|
|
879
882
|
async function encrypt(content, recipients, opts) {
|
|
880
883
|
content = _fixedContent(content);
|
|
881
|
-
opts = opts ||
|
|
884
|
+
opts = opts || _create(null);
|
|
882
885
|
opts = _knownOpts(opts, ENCRYPT_OPTS, "encrypt");
|
|
883
886
|
var hp = opts.protectHeaders === true;
|
|
884
887
|
var hpList = hp ? _hpHeaderList(opts.headers) : null;
|
|
@@ -935,7 +938,7 @@ async function encrypt(content, recipients, opts) {
|
|
|
935
938
|
* res.authenticated; // true here (an AEAD content cipher); false for an enveloped-only CBC message, which carries no integrity
|
|
936
939
|
*/
|
|
937
940
|
async function decrypt(message, keyMaterial, opts) {
|
|
938
|
-
opts = opts ||
|
|
941
|
+
opts = opts || _create(null);
|
|
939
942
|
opts = _knownOpts(opts, DECRYPT_OPTS, "decrypt");
|
|
940
943
|
var ent = mime.parse(message, SmimeError, "smime/bad-mime");
|
|
941
944
|
var ct = ent.contentType;
|
|
@@ -985,7 +988,7 @@ async function decrypt(message, keyMaterial, opts) {
|
|
|
985
988
|
*/
|
|
986
989
|
async function compress(content, opts) {
|
|
987
990
|
content = _fixedContent(content);
|
|
988
|
-
opts = opts ||
|
|
991
|
+
opts = opts || _create(null);
|
|
989
992
|
opts = _knownOpts(opts, COMPRESS_OPTS, "compress");
|
|
990
993
|
var entity = _entityBytes(content, opts);
|
|
991
994
|
var cOpts = {};
|
|
@@ -1019,7 +1022,7 @@ async function compress(content, opts) {
|
|
|
1019
1022
|
* res.content; // the recovered inner MIME entity
|
|
1020
1023
|
*/
|
|
1021
1024
|
async function decompress(message, opts) {
|
|
1022
|
-
opts = opts ||
|
|
1025
|
+
opts = opts || _create(null);
|
|
1023
1026
|
opts = _knownOpts(opts, DECOMPRESS_OPTS, "decompress");
|
|
1024
1027
|
var ent = mime.parse(message, SmimeError, "smime/bad-mime");
|
|
1025
1028
|
var ct = ent.contentType;
|
|
@@ -1065,7 +1068,7 @@ var CERTS_ONLY_OPTS = Object.assign(Object.create(null), { crls: 1 });
|
|
|
1065
1068
|
* var p7c = pki.smime.buildCertsOnly([leafDer]);
|
|
1066
1069
|
*/
|
|
1067
1070
|
function buildCertsOnly(certs, opts) {
|
|
1068
|
-
opts = opts ||
|
|
1071
|
+
opts = opts || _create(null);
|
|
1069
1072
|
opts = _knownOpts(opts, CERTS_ONLY_OPTS, "buildCertsOnly");
|
|
1070
1073
|
var der = _toBuf(cms.certsOnly(certs, { crls: opts.crls }));
|
|
1071
1074
|
return _capped(Buffer.concat([_pkcs7MimeHead("certs-only", "smime.p7c"), _base64Body(der), mime.CRLF]));
|
package/lib/tlog.js
CHANGED
|
@@ -299,12 +299,13 @@ function _resolveKey(keyName, publicKey) {
|
|
|
299
299
|
throw _err("tlog/bad-input", "publicKey must be the raw " + ED25519_RAW_BYTES +
|
|
300
300
|
" Ed25519 bytes or a SubjectPublicKeyInfo, got " + bytes.length + " bytes", e);
|
|
301
301
|
}
|
|
302
|
-
var type = key
|
|
302
|
+
var type = guard.crypto.keyType(key);
|
|
303
303
|
if (type === "ed25519") {
|
|
304
304
|
return _edKey(name, bytes, _subarray(bytes, bytes.length - ED25519_RAW_BYTES));
|
|
305
305
|
}
|
|
306
306
|
if (type === "ec") {
|
|
307
|
-
var
|
|
307
|
+
var keyDetails = guard.crypto.keyDetails(key);
|
|
308
|
+
var curve = keyDetails && keyDetails.namedCurve;
|
|
308
309
|
if (EC_CURVES[curve] !== 1) {
|
|
309
310
|
throw _err("tlog/bad-input", "a signed note names no key-ID derivation for the elliptic curve " +
|
|
310
311
|
guard.text.showValue(_stringOf(curve)));
|
|
@@ -670,7 +671,7 @@ function parseCheckpoint(input) {
|
|
|
670
671
|
*/
|
|
671
672
|
var _CHECKPOINT_OPTS = _assign(_create(null), { origin: 1 });
|
|
672
673
|
async function verifyCheckpoint(input, keys, opts) {
|
|
673
|
-
opts = opts ||
|
|
674
|
+
opts = opts || _create(null);
|
|
674
675
|
guard.identifier.assertKnownKeys(opts, _CHECKPOINT_OPTS, _err,
|
|
675
676
|
"tlog/bad-input", "unknown verifyCheckpoint option ");
|
|
676
677
|
/** @internal ONE read of the caller's input, shared by the decode and the verification below. Reading
|
|
@@ -1208,7 +1209,7 @@ async function _tilePath(lo, hi, m, size, unitAt) {
|
|
|
1208
1209
|
*/
|
|
1209
1210
|
var _INCLUSION_PROOF_KEYS = _assign(_create(null), { index: 1, size: 1, read: 1 });
|
|
1210
1211
|
async function inclusionProof(opts) {
|
|
1211
|
-
opts = opts ||
|
|
1212
|
+
opts = opts || _create(null);
|
|
1212
1213
|
guard.identifier.assertKnownKeys(opts, _INCLUSION_PROOF_KEYS, _err,
|
|
1213
1214
|
"tlog/bad-input", "unknown inclusionProof option ");
|
|
1214
1215
|
var size = guard.range.uint64(opts.size, _err, "tlog/bad-input", "size");
|
package/lib/tls-cert-compress.js
CHANGED
|
@@ -167,7 +167,7 @@ function _resolveAllowed(opts) {
|
|
|
167
167
|
* pki.schema.x509.parse(out.certificate.entries[0].certData).subject;
|
|
168
168
|
*/
|
|
169
169
|
function decompressCertificate(bytes, opts) {
|
|
170
|
-
opts = opts ||
|
|
170
|
+
opts = opts || intrinsic.create(null);
|
|
171
171
|
/** @internal Viewed, CAPPED, then COPIED, and only then are the options read. A view stays a window
|
|
172
172
|
* onto the caller's buffer, and `_resolveCap` reads `opts`, which is caller code when it is an
|
|
173
173
|
* accessor: a `maxOutputBytes` getter that wrote another valid message of the same length over the
|
|
@@ -262,7 +262,7 @@ function decompressCertificate(bytes, opts) {
|
|
|
262
262
|
* pki.schema.x509.parse(msg.entries[0].certData).subject;
|
|
263
263
|
*/
|
|
264
264
|
function parseCertificateMessage(bytes, opts) {
|
|
265
|
-
opts = opts ||
|
|
265
|
+
opts = opts || intrinsic.create(null);
|
|
266
266
|
var type = opts.certificateType === undefined ? "X509" : opts.certificateType;
|
|
267
267
|
if (type !== "X509" && type !== "RawPublicKey") {
|
|
268
268
|
throw _err("tls/bad-input", "opts.certificateType must be \"X509\" or \"RawPublicKey\"");
|
|
@@ -315,7 +315,7 @@ function parseCertificateMessage(bytes, opts) {
|
|
|
315
315
|
* wire.length < message.length; // true
|
|
316
316
|
*/
|
|
317
317
|
function compressCertificate(certificateMessage, opts) {
|
|
318
|
-
opts = opts ||
|
|
318
|
+
opts = opts || intrinsic.create(null);
|
|
319
319
|
/** @internal Copied, not viewed. `opts.algorithm` is read below, and reading an option is caller code
|
|
320
320
|
* when it is an accessor, so over a view it would run between the message being looked at and being
|
|
321
321
|
* compressed and replace what this verb compresses, after it had accepted the message it was handed.
|
package/lib/tsp-sign.js
CHANGED
|
@@ -155,7 +155,7 @@ var _SIGN_OPTS = intrinsic.assign(intrinsic.create(null), {
|
|
|
155
155
|
});
|
|
156
156
|
|
|
157
157
|
function _sign(messageImprint, tsa, opts) {
|
|
158
|
-
opts = opts ||
|
|
158
|
+
opts = opts || intrinsic.create(null);
|
|
159
159
|
if (messageImprint && typeof messageImprint === "object" && !Buffer.isBuffer(messageImprint)) {
|
|
160
160
|
guard.identifier.assertKnownKeys(messageImprint, _IMPRINT_KEYS, _err, "tsp/bad-input", function (k) {
|
|
161
161
|
return "unknown messageImprint field " + JSON.stringify(k) + " (the imprint is { hashAlgorithm, hashedMessage })";
|
|
@@ -169,7 +169,7 @@ function _sign(messageImprint, tsa, opts) {
|
|
|
169
169
|
" (the TSA is { cert, key }; a signing option belongs in the third argument)";
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
|
-
var mi = messageImprint ||
|
|
172
|
+
var mi = messageImprint || intrinsic.create(null);
|
|
173
173
|
if (!mi.hashAlgorithm || !NODE_DIGEST[guard.text.keyOf(mi.hashAlgorithm)]) throw _err("tsp/unsupported-algorithm", "messageImprint.hashAlgorithm must be a supported hash name");
|
|
174
174
|
if (!guard.bytes.isByteSource(mi.hashedMessage)) throw _err("tsp/bad-input", "messageImprint.hashedMessage must be a BufferSource");
|
|
175
175
|
var _signHmLen = guard.bytes.source(mi.hashedMessage, TspError, "tsp/bad-input", "messageImprint.hashedMessage").length;
|
|
@@ -292,10 +292,10 @@ function _assertImprint(mi) {
|
|
|
292
292
|
var _REQUEST_OPTS = intrinsic.assign(intrinsic.create(null), { reqPolicy: 1, nonce: 1, certReq: 1, extensions: 1, pem: 1 });
|
|
293
293
|
|
|
294
294
|
function request(messageImprint, opts) {
|
|
295
|
-
opts = opts ||
|
|
295
|
+
opts = opts || intrinsic.create(null);
|
|
296
296
|
if (typeof opts !== "object" || Buffer.isBuffer(opts)) throw _err("tsp/bad-input", "pki.tsp.request options must be an object");
|
|
297
297
|
guard.identifier.assertKnownKeys(opts, _REQUEST_OPTS, _err, "tsp/bad-input", "pki.tsp.request has an unknown option ");
|
|
298
|
-
var mi = messageImprint ||
|
|
298
|
+
var mi = messageImprint || intrinsic.create(null);
|
|
299
299
|
if (mi && typeof mi === "object" && !Buffer.isBuffer(mi)) {
|
|
300
300
|
guard.identifier.assertKnownKeys(mi, _IMPRINT_KEYS, _err, "tsp/bad-input", function (k) {
|
|
301
301
|
return "unknown messageImprint field " + JSON.stringify(k) +
|
|
@@ -379,7 +379,7 @@ function parseRequest(input) { return schemaTsp.parseRequest(input); }
|
|
|
379
379
|
var _RESPONSE_OPTS = intrinsic.assign(intrinsic.create(null), { status: 1, statusString: 1, failInfo: 1, pem: 1 });
|
|
380
380
|
|
|
381
381
|
function response(token, opts) {
|
|
382
|
-
opts = opts ||
|
|
382
|
+
opts = opts || intrinsic.create(null);
|
|
383
383
|
if (typeof opts !== "object" || Buffer.isBuffer(opts)) throw _err("tsp/bad-input", "pki.tsp.response options must be an object");
|
|
384
384
|
guard.identifier.assertKnownKeys(opts, _RESPONSE_OPTS, _err, "tsp/bad-input", "pki.tsp.response has an unknown option ");
|
|
385
385
|
var st = opts.status;
|
|
@@ -664,7 +664,7 @@ function _anyCritical(extensions) {
|
|
|
664
664
|
}
|
|
665
665
|
|
|
666
666
|
async function verify(token, data, opts) {
|
|
667
|
-
opts = opts ||
|
|
667
|
+
opts = opts || intrinsic.create(null);
|
|
668
668
|
if (typeof opts !== "object" || Buffer.isBuffer(opts)) throw _err("tsp/bad-input", "pki.tsp.verify options must be an object");
|
|
669
669
|
guard.identifier.assertKnownKeys(opts, _VERIFY_OPTS, _err, "tsp/bad-input",
|
|
670
670
|
"pki.tsp.verify has an unknown option (the anchor option is `trustAnchors`) ");
|
package/lib/tuf.js
CHANGED
|
@@ -798,12 +798,13 @@ function _declarationOf(key) {
|
|
|
798
798
|
function _checkedPublicKey(key, d) {
|
|
799
799
|
if (d.nodeType === "ed25519") return null;
|
|
800
800
|
var imported = _publicFromPem(key.keyval.public, "a " + key.keytype + " public key");
|
|
801
|
-
|
|
801
|
+
var importedType = guard.crypto.keyType(imported);
|
|
802
|
+
if (importedType !== d.nodeType) {
|
|
802
803
|
throw _err("tuf/bad-key", "the key declared as " + key.keytype + " holds a " +
|
|
803
|
-
guard.text.showValue(
|
|
804
|
+
guard.text.showValue(importedType) + " public key, so the signature would be checked " +
|
|
804
805
|
"under an algorithm the metadata does not name");
|
|
805
806
|
}
|
|
806
|
-
var details = imported
|
|
807
|
+
var details = guard.crypto.keyDetails(imported) || _create(null);
|
|
807
808
|
if (d.curve !== null && details.namedCurve !== d.curve) {
|
|
808
809
|
throw _err("tuf/bad-key", "the scheme " + key.scheme + " names the " + d.curve +
|
|
809
810
|
" curve; the key is on " + guard.text.showValue(details.namedCurve));
|
|
@@ -888,7 +889,7 @@ function _publicFromPem(pem, label) {
|
|
|
888
889
|
*/
|
|
889
890
|
var _VERIFY_KEYS = intrinsic.assign(_create(null), { metadata: 1, keys: 1, role: 1 });
|
|
890
891
|
async function verifySignatures(opts) {
|
|
891
|
-
opts = opts ||
|
|
892
|
+
opts = opts || _create(null);
|
|
892
893
|
guard.identifier.assertKnownKeys(opts, _VERIFY_KEYS, _err, "tuf/bad-input", "unknown verifySignatures option ");
|
|
893
894
|
/** @internal Every caller-owned input is taken ONCE, at the top, and everything below reads the copy.
|
|
894
895
|
* Validating the caller's object and then reading it again is two reads, and a member reached through an
|
|
@@ -1296,7 +1297,7 @@ function _asRoot(input, label) {
|
|
|
1296
1297
|
*/
|
|
1297
1298
|
var _UPDATE_KEYS = intrinsic.assign(_create(null), { trustedRoot: 1, candidates: 1, now: 1 });
|
|
1298
1299
|
async function updateRoot(opts) {
|
|
1299
|
-
opts = opts ||
|
|
1300
|
+
opts = opts || _create(null);
|
|
1300
1301
|
guard.identifier.assertKnownKeys(opts, _UPDATE_KEYS, _err, "tuf/bad-input", "unknown updateRoot option ");
|
|
1301
1302
|
/** @internal The instant is CAPTURED here, at the call, into a Date this function owns. A Date is
|
|
1302
1303
|
* mutable and the caller keeps theirs, and the freeze-attack check runs at the END, after a signature
|
package/lib/validator-cose.js
CHANGED
|
@@ -7,7 +7,7 @@ var cbor = require("./cbor-det");
|
|
|
7
7
|
var asn1 = require("./asn1-der");
|
|
8
8
|
var oid = require("./oid");
|
|
9
9
|
var edwardsPoint = require("./edwards-point");
|
|
10
|
-
var
|
|
10
|
+
var guard = require("./guard-all.js");
|
|
11
11
|
|
|
12
12
|
var EC2_CRV_LEN = Object.assign(Object.create(null), { 1: 32, 2: 48, 3: 66 });
|
|
13
13
|
var EC2_CRV_OID = Object.assign(Object.create(null), { 1: "prime256v1", 2: "secp384r1", 3: "secp521r1" });
|
|
@@ -114,7 +114,7 @@ function assertKeyMaterial(key, E, code, unsupportedCode) {
|
|
|
114
114
|
if (!prof) throw new E(unsupportedCode || code, "unsupported credential key algorithm " + key.alg);
|
|
115
115
|
if (prof.kty !== key.kty) throw bad("credential key algorithm " + key.alg + " is inconsistent with key type " + key.kty);
|
|
116
116
|
if (prof.crv != null && prof.crv !== key.crv) throw bad("credential key algorithm " + key.alg + " requires a different curve");
|
|
117
|
-
try {
|
|
117
|
+
try { guard.crypto.publicKey({ key: toSpki(key, E, code), format: "der", type: "spki" }); }
|
|
118
118
|
catch (e) { throw bad("the credential public key point is not valid for its curve", e); }
|
|
119
119
|
if (Number(key.kty) === 1 && !edwardsPoint.validate(key.x, key.crv)) throw bad("the OKP credential public key is not a valid, full-order Edwards point");
|
|
120
120
|
return key;
|
package/lib/webauthn-mds.js
CHANGED
|
@@ -26,12 +26,6 @@ var _charAt = intrinsic.uncurry(String.prototype.charAt);
|
|
|
26
26
|
var _strToLowerCase = intrinsic.toLowerCase;
|
|
27
27
|
var _strSlice = intrinsic.uncurry(String.prototype.slice);
|
|
28
28
|
var _strSplit = intrinsic.uncurry(String.prototype.split);
|
|
29
|
-
/** @internal The hash constructor and the methods of the object it returns. What a digest here
|
|
30
|
-
* produces is a metadata lookup key and the identity two certificates are told apart by, so a
|
|
31
|
-
* replaced constructor, update or digest decides which entry governs an attestation. */
|
|
32
|
-
var _createHash = _nodeCrypto.createHash;
|
|
33
|
-
var _hashUpdate = intrinsic.uncurry(_nodeCrypto.createHash("sha256").update);
|
|
34
|
-
var _hashDigest = intrinsic.uncurry(_nodeCrypto.createHash("sha256").digest);
|
|
35
29
|
var jose = require("./jose");
|
|
36
30
|
var rfc3339 = require("./rfc3339");
|
|
37
31
|
var constants = require("./constants");
|
|
@@ -324,7 +318,7 @@ function _verifyMetadataBlob(blob, opts) {
|
|
|
324
318
|
});
|
|
325
319
|
var leaf = chain[0];
|
|
326
320
|
_assertLeafSigns(leaf);
|
|
327
|
-
var leafAlg = (leaf.subjectPublicKeyInfo.algorithm ||
|
|
321
|
+
var leafAlg = (leaf.subjectPublicKeyInfo.algorithm || intrinsic.create(null)).name;
|
|
328
322
|
var leafSchemes = typeof leafAlg === "string" ? LEAF_SCHEMES_BY_SPKI_ALG[leafAlg] : undefined;
|
|
329
323
|
if (!leafSchemes || !leafSchemes[algRow.scheme]) {
|
|
330
324
|
throw _err("webauthn/unsupported-algorithm", "the metadata BLOB alg " + header.alg + " does not match the x5c leaf key type " + intrinsic.stringify(leafAlg));
|
|
@@ -702,7 +696,9 @@ function certKeyIdentifier(cert) {
|
|
|
702
696
|
if (!pk || !intrinsic.isBuffer(pk.bytes)) {
|
|
703
697
|
throw _err("webauthn/bad-input", "certKeyIdentifier expects a parsed certificate carrying a subject public key");
|
|
704
698
|
}
|
|
705
|
-
|
|
699
|
+
/** @internal A metadata lookup key, and the identity two certificates are told apart by, so
|
|
700
|
+
* whatever computes it decides which entry governs an attestation. */
|
|
701
|
+
return guard.crypto.digest("sha1", pk.bytes, { output: "hex" });
|
|
706
702
|
}
|
|
707
703
|
|
|
708
704
|
function metadataForKeyIdentifier(metadata, keyId) {
|
package/lib/webauthn.js
CHANGED
|
@@ -54,7 +54,6 @@ var _promiseResolve = intrinsic.uncurry(intrinsic.promiseResolve);
|
|
|
54
54
|
var _promiseReject = intrinsic.uncurry(intrinsic.promiseReject);
|
|
55
55
|
var jose = require("./jose");
|
|
56
56
|
var mds = require("./webauthn-mds");
|
|
57
|
-
var nodeCrypto = require("crypto");
|
|
58
57
|
|
|
59
58
|
var WebauthnError = frameworkError.WebauthnError;
|
|
60
59
|
function _err(code, message, cause) { return new WebauthnError(code, message, cause); }
|
|
@@ -76,16 +75,10 @@ var _subtleVerify = intrinsic.uncurry(subtle.verify);
|
|
|
76
75
|
* while the bytes handed in were never the credential's. */
|
|
77
76
|
var _subtleImportKey = intrinsic.uncurry(subtle.importKey);
|
|
78
77
|
|
|
79
|
-
/** @internal
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
|
|
83
|
-
function _sha(name, buf) {
|
|
84
|
-
var h = _createHash(name);
|
|
85
|
-
return _hashDigest(_hashUpdate(h, buf));
|
|
86
|
-
}
|
|
87
|
-
var _hashUpdate = intrinsic.uncurry(nodeCrypto.createHash("sha256").update);
|
|
88
|
-
var _hashDigest = intrinsic.uncurry(nodeCrypto.createHash("sha256").digest);
|
|
78
|
+
/** @internal Every attestation comparison in this module rests on a digest, so whatever computes one
|
|
79
|
+
* chooses what the comparison sees. The guard owns the hash construction and the methods of the
|
|
80
|
+
* object it returns. */
|
|
81
|
+
function _sha(name, buf) { return guard.crypto.digest(name, buf); }
|
|
89
82
|
/** @internal The comparison goes through the captured operation. This is what decides that an
|
|
90
83
|
* attestation statement's key is the credential's key, so a replacement answering zero makes a
|
|
91
84
|
* different key match. */
|
|
@@ -275,7 +268,7 @@ function _certKeyAlgNames(cose) {
|
|
|
275
268
|
return [];
|
|
276
269
|
}
|
|
277
270
|
function _assertCertKeyAlgorithm(cert, cose, E) {
|
|
278
|
-
var alg = (cert.subjectPublicKeyInfo && cert.subjectPublicKeyInfo.algorithm) ||
|
|
271
|
+
var alg = (cert.subjectPublicKeyInfo && cert.subjectPublicKeyInfo.algorithm) || intrinsic.create(null);
|
|
279
272
|
var want = _certKeyAlgNames(cose);
|
|
280
273
|
if (!want.length || intrinsic.indexOf(want, alg.name) < 0) {
|
|
281
274
|
throw E("webauthn/key-mismatch", "the attestation certificate carries a " + intrinsic.stringify(alg.name) +
|