ma1 pushed to branch base-browser-128.2.0esr-14.0-1 at The Tor Project / Applications / Tor Browser
Commits:
-
62e7b72b
by Anna Weine at 2024-08-31T12:40:33+08:00
4 changed files:
- dom/crypto/WebCryptoTask.cpp
- dom/crypto/test/test-vectors.js
- dom/crypto/test/test_WebCrypto_ECDH.html
- dom/crypto/test/test_WebCrypto_ECDSA.html
Changes:
| ... | ... | @@ -1802,7 +1802,8 @@ class ImportEcKeyTask : public ImportKeyTask { |
| 1802 | 1802 | return;
|
| 1803 | 1803 | }
|
| 1804 | 1804 | |
| 1805 | - if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW)) {
|
|
| 1805 | + if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW) ||
|
|
| 1806 | + mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK)) {
|
|
| 1806 | 1807 | RootedDictionary<EcKeyImportParams> params(aCx);
|
| 1807 | 1808 | mEarlyRv = Coerce(aCx, params, aAlgorithm);
|
| 1808 | 1809 | if (NS_FAILED(mEarlyRv) || !params.mNamedCurve.WasPassed()) {
|
| ... | ... | @@ -1907,11 +1908,21 @@ class ImportEcKeyTask : public ImportKeyTask { |
| 1907 | 1908 | return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
| 1908 | 1909 | }
|
| 1909 | 1910 | |
| 1910 | - // Extract 'crv' parameter from JWKs.
|
|
| 1911 | + // Checking the 'crv' consistency
|
|
| 1911 | 1912 | if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK)) {
|
| 1912 | - if (!NormalizeToken(mJwk.mCrv.Value(), mNamedCurve)) {
|
|
| 1913 | + // the curve stated in 'crv field'
|
|
| 1914 | + nsString namedCurveFromCrv;
|
|
| 1915 | + if (!NormalizeToken(mJwk.mCrv.Value(), namedCurveFromCrv)) {
|
|
| 1913 | 1916 | return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
| 1914 | 1917 | }
|
| 1918 | + |
|
| 1919 | + // https://w3c.github.io/webcrypto/#ecdh-operations
|
|
| 1920 | + // https://w3c.github.io/webcrypto/#ecdsa-operations
|
|
| 1921 | + // If namedCurve is not equal to the namedCurve member of
|
|
| 1922 | + // normalizedAlgorithm (mNamedCurve in our case), throw a DataError.
|
|
| 1923 | + if (!mNamedCurve.Equals(namedCurveFromCrv)) {
|
|
| 1924 | + return NS_ERROR_DOM_DATA_ERR;
|
|
| 1925 | + }
|
|
| 1915 | 1926 | }
|
| 1916 | 1927 | return NS_OK;
|
| 1917 | 1928 | }
|
| ... | ... | @@ -901,6 +901,13 @@ let tv = { |
| 901 | 901 | y: "9M8HWzlAXdHxresJAQftz7K0ljc52HZ54wVssFV9Ct8",
|
| 902 | 902 | },
|
| 903 | 903 | |
| 904 | + jwk_different_crv: {
|
|
| 905 | + kty: "EC",
|
|
| 906 | + crv: "P-521",
|
|
| 907 | + x: "XOe4bjsyZgQD5jcS7wmY3q4QJ_rsPBvp92-TTf61jpg",
|
|
| 908 | + y: "9M8HWzlAXdHxresJAQftz7K0ljc52HZ54wVssFV9Ct8",
|
|
| 909 | + },
|
|
| 910 | + |
|
| 904 | 911 | // The crv parameter is missing.
|
| 905 | 912 | jwk_missing_crv: {
|
| 906 | 913 | kty: "EC",
|
| ... | ... | @@ -1017,6 +1024,18 @@ let tv = { |
| 1017 | 1024 | },
|
| 1018 | 1025 | },
|
| 1019 | 1026 | |
| 1027 | + // An ECDSA key in JWK format, which an "crv" field doesn't match the alg's crv.
|
|
| 1028 | + ecdsa_jwk_crv_mismatch: {
|
|
| 1029 | + pub_jwk: {
|
|
| 1030 | + kty: "EC",
|
|
| 1031 | + crv: "P-256",
|
|
| 1032 | + alg: "ECDSA",
|
|
| 1033 | + |
|
| 1034 | + x: "XOe4bjsyZgQD5jcS7wmY3q4QJ_rsPBvp92-TTf61jpg",
|
|
| 1035 | + y: "9M8HWzlAXdHxresJAQftz7K0ljc52HZ54wVssFV9Ct8",
|
|
| 1036 | + },
|
|
| 1037 | + },
|
|
| 1038 | + |
|
| 1020 | 1039 | ecdsa_bad: {
|
| 1021 | 1040 | pub_jwk: {
|
| 1022 | 1041 | kty: "EC",
|
| ... | ... | @@ -152,12 +152,24 @@ TestArray.addTest( |
| 152 | 152 | }
|
| 153 | 153 | );
|
| 154 | 154 | |
| 155 | +// -----------------------------------------------------------------------------
|
|
| 156 | +TestArray.addTest(
|
|
| 157 | + "Verify that ECDH import fails with a key with a mismatched 'crv' field",
|
|
| 158 | + function() {
|
|
| 159 | + var that = this;
|
|
| 160 | + var alg = { name: "ECDH", namedCurve: "P-521"};
|
|
| 161 | + |
|
| 162 | + crypto.subtle.importKey("jwk", tv.ecdsa_jwk_crv_mismatch.pub_jwk, alg, true, ["verify"])
|
|
| 163 | + .then(error(that), complete(that));
|
|
| 164 | + }
|
|
| 165 | +);
|
|
| 166 | + |
|
| 155 | 167 | // -----------------------------------------------------------------------------
|
| 156 | 168 | TestArray.addTest(
|
| 157 | 169 | "JWK import an ECDH public and private key and derive bits (P-256)",
|
| 158 | 170 | function() {
|
| 159 | 171 | var that = this;
|
| 160 | - var alg = { name: "ECDH" };
|
|
| 172 | + var alg = { name: "ECDH", namedCurve: "P-256" };
|
|
| 161 | 173 | |
| 162 | 174 | var pubKey, privKey;
|
| 163 | 175 | function setPub(x) { pubKey = x; }
|
| ... | ... | @@ -182,7 +194,7 @@ TestArray.addTest( |
| 182 | 194 | "JWK import an ECDH public and private key and derive bits (P-384)",
|
| 183 | 195 | function() {
|
| 184 | 196 | var that = this;
|
| 185 | - var alg = { name: "ECDH" };
|
|
| 197 | + var alg = { name: "ECDH", namedCurve: "P-384"};
|
|
| 186 | 198 | |
| 187 | 199 | var pubKey, privKey;
|
| 188 | 200 | function setPub(x) { pubKey = x; }
|
| ... | ... | @@ -207,7 +219,7 @@ TestArray.addTest( |
| 207 | 219 | "JWK import an ECDH public and private key and derive bits (P-521)",
|
| 208 | 220 | function() {
|
| 209 | 221 | var that = this;
|
| 210 | - var alg = { name: "ECDH" };
|
|
| 222 | + var alg = { name: "ECDH", namedCurve : "P-521" };
|
|
| 211 | 223 | |
| 212 | 224 | var pubKey, privKey;
|
| 213 | 225 | function setPub(x) { pubKey = x; }
|
| ... | ... | @@ -232,7 +244,7 @@ TestArray.addTest( |
| 232 | 244 | "JWK import/export roundtrip with ECDH (P-256)",
|
| 233 | 245 | function() {
|
| 234 | 246 | var that = this;
|
| 235 | - var alg = { name: "ECDH" };
|
|
| 247 | + var alg = { name: "ECDH", namedCurve : "P-256" };
|
|
| 236 | 248 | |
| 237 | 249 | var pubKey, privKey;
|
| 238 | 250 | function setPub(x) { pubKey = x; }
|
| ... | ... | @@ -277,7 +289,7 @@ TestArray.addTest( |
| 277 | 289 | "PKCS8 import/export roundtrip with ECDH (P-256)",
|
| 278 | 290 | function() {
|
| 279 | 291 | var that = this;
|
| 280 | - var alg = { name: "ECDH", namedCurve: "P-256" };
|
|
| 292 | + var alg = { name: "ECDH", namedCurve: "P-256" };
|
|
| 281 | 293 | |
| 282 | 294 | function doExportPriv(x) {
|
| 283 | 295 | return crypto.subtle.exportKey("pkcs8", x);
|
| ... | ... | @@ -296,7 +308,7 @@ TestArray.addTest( |
| 296 | 308 | "Test that importing bad JWKs fails",
|
| 297 | 309 | function() {
|
| 298 | 310 | var that = this;
|
| 299 | - var alg = { name: "ECDH" };
|
|
| 311 | + var alg = { name: "ECDH", namedCurve: "P-256" };
|
|
| 300 | 312 | var tvs = tv.ecdh_p256_negative;
|
| 301 | 313 | |
| 302 | 314 | function doTryImport(jwk) {
|
| ... | ... | @@ -306,6 +318,7 @@ TestArray.addTest( |
| 306 | 318 | }
|
| 307 | 319 | |
| 308 | 320 | doTryImport(tvs.jwk_bad_crv)()
|
| 321 | + .then(error(that), doTryImport(tvs.jwk_different_crv))
|
|
| 309 | 322 | .then(error(that), doTryImport(tvs.jwk_missing_crv))
|
| 310 | 323 | .then(error(that), doTryImport(tvs.jwk_missing_x))
|
| 311 | 324 | .then(error(that), doTryImport(tvs.jwk_missing_y))
|
| ... | ... | @@ -349,7 +362,7 @@ TestArray.addTest( |
| 349 | 362 | "Derive an HMAC key from two ECDH keys and test sign/verify",
|
| 350 | 363 | function() {
|
| 351 | 364 | var that = this;
|
| 352 | - var alg = { name: "ECDH" };
|
|
| 365 | + var alg = { name: "ECDH", namedCurve: "P-521" };
|
|
| 353 | 366 | var algDerived = { name: "HMAC", hash: {name: "SHA-1"} };
|
| 354 | 367 | |
| 355 | 368 | var pubKey, privKey;
|
| ... | ... | @@ -396,10 +409,11 @@ TestArray.addTest( |
| 396 | 409 | "Derive an HKDF key from two ECDH keys and derive an HMAC key from that",
|
| 397 | 410 | function() {
|
| 398 | 411 | var that = this;
|
| 412 | + var alg = { name: "ECDH", namedCurve: "P-256" };
|
|
| 399 | 413 | |
| 400 | 414 | async function doTest() {
|
| 401 | - let privKey = await crypto.subtle.importKey("jwk", tv.ecdh_p256.jwk_priv, "ECDH", false, ["deriveKey"]);
|
|
| 402 | - let pubKey = await crypto.subtle.importKey("jwk", tv.ecdh_p256.jwk_pub, "ECDH", false, []);
|
|
| 415 | + let privKey = await crypto.subtle.importKey("jwk", tv.ecdh_p256.jwk_priv, alg, false, ["deriveKey"]);
|
|
| 416 | + let pubKey = await crypto.subtle.importKey("jwk", tv.ecdh_p256.jwk_pub, alg, false, []);
|
|
| 403 | 417 | let ecdhAlg = { name: "ECDH", public: pubKey };
|
| 404 | 418 | let hkdfAlg = { name: "HKDF", hash: "SHA-256", salt: new Uint8Array(), info: new Uint8Array() };
|
| 405 | 419 | let hkdfKey = await crypto.subtle.deriveKey(ecdhAlg, privKey, hkdfAlg, false, ["deriveKey"]);
|
| ... | ... | @@ -454,7 +468,7 @@ TestArray.addTest( |
| 454 | 468 | "SPKI/JWK import ECDH keys (P-256) and derive a known secret",
|
| 455 | 469 | function() {
|
| 456 | 470 | var that = this;
|
| 457 | - var alg = { name: "ECDH" };
|
|
| 471 | + var alg = { name: "ECDH", namedCurve: "P-256" };
|
|
| 458 | 472 | |
| 459 | 473 | var pubKey, privKey;
|
| 460 | 474 | function setPub(x) { pubKey = x; }
|
| ... | ... | @@ -91,7 +91,7 @@ TestArray.addTest( |
| 91 | 91 | "ECDSA JWK import and reject a known-bad signature",
|
| 92 | 92 | function() {
|
| 93 | 93 | var that = this;
|
| 94 | - var alg = { name: "ECDSA", namedCurve: "P-256", hash: "SHA-256" };
|
|
| 94 | + var alg = { name: "ECDSA", namedCurve: "P-521", hash: "SHA-512" };
|
|
| 95 | 95 | |
| 96 | 96 | function doVerify(x) {
|
| 97 | 97 | return crypto.subtle.verify(alg, x, tv.ecdsa_verify.sig_tampered,
|
| ... | ... | @@ -141,6 +141,18 @@ TestArray.addTest( |
| 141 | 141 | }
|
| 142 | 142 | );
|
| 143 | 143 | |
| 144 | +// -----------------------------------------------------------------------------
|
|
| 145 | +TestArray.addTest(
|
|
| 146 | + "Verify that ECDSA import fails with a key with a mismatched 'crv' field",
|
|
| 147 | + function() {
|
|
| 148 | + var that = this;
|
|
| 149 | + var alg = { name: "ECDSA", namedCurve: "P-521", hash: "SHA-512" };
|
|
| 150 | + |
|
| 151 | + crypto.subtle.importKey("jwk", tv.ecdsa_jwk_crv_mismatch.pub_jwk, alg, true, ["verify"])
|
|
| 152 | + .then(error(that), complete(that));
|
|
| 153 | + }
|
|
| 154 | +);
|
|
| 155 | + |
|
| 144 | 156 | // -----------------------------------------------------------------------------
|
| 145 | 157 | TestArray.addTest(
|
| 146 | 158 | "Verify that ECDSA import fails with a known-bad public key",
|