[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [Git][tpo/applications/mullvad-browser][mullvad-browser-115.15.0esr-13.5-1] Bug 1760806 - WebCrypto: ECDH and ECDSA JWK import to check that the crv in...



Title: GitLab

ma1 pushed to branch mullvad-browser-115.15.0esr-13.5-1 at The Tor Project / Applications / Mullvad Browser

Commits:

  • 7d80ca6a
    by Anna Weine at 2024-08-31T12:30:55+08:00
    Bug 1760806 - WebCrypto: ECDH and ECDSA JWK import to check that the crv in params and crv in alg are the same r=keeler
    
    https://treeherder.mozilla.org/jobs?repo=try&revision=ed7936b105dea8e588650feb6baf26a50a6439fc
    
    Differential Revision: https://phabricator.services.mozilla.com/D217273
    

4 changed files:

Changes:

  • dom/crypto/WebCryptoTask.cpp
    ... ... @@ -1777,7 +1777,8 @@ class ImportEcKeyTask : public ImportKeyTask {
    1777 1777
           return;
    
    1778 1778
         }
    
    1779 1779
     
    
    1780
    -    if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW)) {
    
    1780
    +    if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_RAW) ||
    
    1781
    +        mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK)) {
    
    1781 1782
           RootedDictionary<EcKeyImportParams> params(aCx);
    
    1782 1783
           mEarlyRv = Coerce(aCx, params, aAlgorithm);
    
    1783 1784
           if (NS_FAILED(mEarlyRv) || !params.mNamedCurve.WasPassed()) {
    
    ... ... @@ -1882,11 +1883,21 @@ class ImportEcKeyTask : public ImportKeyTask {
    1882 1883
           return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
    
    1883 1884
         }
    
    1884 1885
     
    
    1885
    -    // Extract 'crv' parameter from JWKs.
    
    1886
    +    // Checking the 'crv' consistency
    
    1886 1887
         if (mFormat.EqualsLiteral(WEBCRYPTO_KEY_FORMAT_JWK)) {
    
    1887
    -      if (!NormalizeToken(mJwk.mCrv.Value(), mNamedCurve)) {
    
    1888
    +      // the curve stated in 'crv field'
    
    1889
    +      nsString namedCurveFromCrv;
    
    1890
    +      if (!NormalizeToken(mJwk.mCrv.Value(), namedCurveFromCrv)) {
    
    1888 1891
             return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
    
    1889 1892
           }
    
    1893
    +
    
    1894
    +      // https://w3c.github.io/webcrypto/#ecdh-operations
    
    1895
    +      // https://w3c.github.io/webcrypto/#ecdsa-operations
    
    1896
    +      // If namedCurve is not equal to the namedCurve member of
    
    1897
    +      // normalizedAlgorithm (mNamedCurve in our case), throw a DataError.
    
    1898
    +      if (!mNamedCurve.Equals(namedCurveFromCrv)) {
    
    1899
    +        return NS_ERROR_DOM_DATA_ERR;
    
    1900
    +      }
    
    1890 1901
         }
    
    1891 1902
         return NS_OK;
    
    1892 1903
       }
    

  • dom/crypto/test/test-vectors.js
    ... ... @@ -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",
    

  • dom/crypto/test/test_WebCrypto_ECDH.html
    ... ... @@ -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;
    
    ... ... @@ -391,6 +404,28 @@ TestArray.addTest(
    391 404
       }
    
    392 405
     );
    
    393 406
     
    
    407
    +// -----------------------------------------------------------------------------
    
    408
    +TestArray.addTest(
    
    409
    +  "Derive an HKDF key from two ECDH keys and derive an HMAC key from that",
    
    410
    +  function() {
    
    411
    +    var that = this;
    
    412
    +    var alg = { name: "ECDH", namedCurve: "P-256" };
    
    413
    +
    
    414
    +    async function doTest() {
    
    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, []);
    
    417
    +      let ecdhAlg = { name: "ECDH", public: pubKey };
    
    418
    +      let hkdfAlg = { name: "HKDF", hash: "SHA-256", salt: new Uint8Array(), info: new Uint8Array() };
    
    419
    +      let hkdfKey = await crypto.subtle.deriveKey(ecdhAlg, privKey, hkdfAlg, false, ["deriveKey"]);
    
    420
    +      let hmacAlg = { name: "HMAC", hash: "SHA-256" };
    
    421
    +      let hmacKey = await crypto.subtle.deriveKey(hkdfAlg, hkdfKey, hmacAlg, false, ["sign"]);
    
    422
    +      return crypto.subtle.sign("HMAC", hmacKey, new Uint8Array());
    
    423
    +    }
    
    424
    +    const expected = util.hex2abv("acf62832fa93469824cd997593bc963b28a68e6f73f4516bbe51b35942fe9811");
    
    425
    +    doTest().then(memcmp_complete(that, expected), error(that));
    
    426
    +  }
    
    427
    +);
    
    428
    +
    
    394 429
     // -----------------------------------------------------------------------------
    
    395 430
     TestArray.addTest(
    
    396 431
       "SPKI import/export of public ECDH keys (P-256)",
    
    ... ... @@ -433,7 +468,7 @@ TestArray.addTest(
    433 468
       "SPKI/JWK import ECDH keys (P-256) and derive a known secret",
    
    434 469
       function() {
    
    435 470
         var that = this;
    
    436
    -    var alg = { name: "ECDH" };
    
    471
    +    var alg = { name: "ECDH", namedCurve: "P-256" };
    
    437 472
     
    
    438 473
         var pubKey, privKey;
    
    439 474
         function setPub(x) { pubKey = x; }
    

  • dom/crypto/test/test_WebCrypto_ECDSA.html
    ... ... @@ -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",
    

  • _______________________________________________
    tor-commits mailing list
    tor-commits@xxxxxxxxxxxxxxxxxxxx
    https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits