| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/logging.h" | 5 #include "base/logging.h" |
| 6 #include "base/stl_util.h" | 6 #include "base/stl_util.h" |
| 7 #include "content/child/webcrypto/algorithm_dispatch.h" | 7 #include "content/child/webcrypto/algorithm_dispatch.h" |
| 8 #include "content/child/webcrypto/crypto_data.h" | 8 #include "content/child/webcrypto/crypto_data.h" |
| 9 #include "content/child/webcrypto/status.h" | 9 #include "content/child/webcrypto/status.h" |
| 10 #include "content/child/webcrypto/test/test_helpers.h" | 10 #include "content/child/webcrypto/test/test_helpers.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 EXPECT_TRUE(key.handle()); | 51 EXPECT_TRUE(key.handle()); |
| 52 EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type()); | 52 EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type()); |
| 53 EXPECT_TRUE(key.extractable()); | 53 EXPECT_TRUE(key.extractable()); |
| 54 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); | 54 EXPECT_EQ(blink::WebCryptoKeyUsageVerify, key.usages()); |
| 55 EXPECT_EQ(kModulusLengthBits, | 55 EXPECT_EQ(kModulusLengthBits, |
| 56 key.algorithm().rsaHashedParams()->modulusLengthBits()); | 56 key.algorithm().rsaHashedParams()->modulusLengthBits()); |
| 57 EXPECT_BYTES_EQ_HEX( | 57 EXPECT_BYTES_EQ_HEX( |
| 58 "010001", | 58 "010001", |
| 59 CryptoData(key.algorithm().rsaHashedParams()->publicExponent())); | 59 CryptoData(key.algorithm().rsaHashedParams()->publicExponent())); |
| 60 | 60 |
| 61 // Failing case: Empty SPKI data | |
| 62 EXPECT_EQ( | |
| 63 Status::ErrorImportEmptyKeyData(), | |
| 64 ImportKey(blink::WebCryptoKeyFormatSpki, | |
| 65 CryptoData(std::vector<uint8_t>()), | |
| 66 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5), | |
| 67 true, | |
| 68 blink::WebCryptoKeyUsageVerify, | |
| 69 &key)); | |
| 70 | |
| 71 // Failing case: Bad DER encoding. | |
| 72 EXPECT_EQ( | |
| 73 Status::DataError(), | |
| 74 ImportKey(blink::WebCryptoKeyFormatSpki, | |
| 75 CryptoData(HexStringToBytes("618333c4cb")), | |
| 76 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5), | |
| 77 true, | |
| 78 blink::WebCryptoKeyUsageVerify, | |
| 79 &key)); | |
| 80 | |
| 81 // Failing case: Import RSA key but provide an inconsistent input algorithm. | 61 // Failing case: Import RSA key but provide an inconsistent input algorithm. |
| 82 EXPECT_EQ(Status::ErrorUnsupportedImportKeyFormat(), | 62 EXPECT_EQ(Status::ErrorUnsupportedImportKeyFormat(), |
| 83 ImportKey(blink::WebCryptoKeyFormatSpki, | 63 ImportKey(blink::WebCryptoKeyFormatSpki, |
| 84 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), | 64 CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)), |
| 85 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), | 65 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
| 86 true, | 66 true, |
| 87 blink::WebCryptoKeyUsageEncrypt, | 67 blink::WebCryptoKeyUsageEncrypt, |
| 88 &key)); | 68 &key)); |
| 89 | 69 |
| 90 // Passing case: Export a previously imported RSA public key in SPKI format | 70 // Passing case: Export a previously imported RSA public key in SPKI format |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 key.algorithm().rsaHashedParams()->modulusLengthBits()); | 127 key.algorithm().rsaHashedParams()->modulusLengthBits()); |
| 148 EXPECT_BYTES_EQ_HEX( | 128 EXPECT_BYTES_EQ_HEX( |
| 149 "010001", | 129 "010001", |
| 150 CryptoData(key.algorithm().rsaHashedParams()->publicExponent())); | 130 CryptoData(key.algorithm().rsaHashedParams()->publicExponent())); |
| 151 | 131 |
| 152 std::vector<uint8_t> exported_key; | 132 std::vector<uint8_t> exported_key; |
| 153 ASSERT_EQ(Status::Success(), | 133 ASSERT_EQ(Status::Success(), |
| 154 ExportKey(blink::WebCryptoKeyFormatPkcs8, key, &exported_key)); | 134 ExportKey(blink::WebCryptoKeyFormatPkcs8, key, &exported_key)); |
| 155 EXPECT_BYTES_EQ_HEX(kPrivateKeyPkcs8DerHex, exported_key); | 135 EXPECT_BYTES_EQ_HEX(kPrivateKeyPkcs8DerHex, exported_key); |
| 156 | 136 |
| 157 // Failing case: Empty PKCS#8 data | |
| 158 EXPECT_EQ(Status::ErrorImportEmptyKeyData(), | |
| 159 ImportKey(blink::WebCryptoKeyFormatPkcs8, | |
| 160 CryptoData(std::vector<uint8_t>()), | |
| 161 CreateRsaHashedImportAlgorithm( | |
| 162 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | |
| 163 blink::WebCryptoAlgorithmIdSha1), | |
| 164 true, | |
| 165 blink::WebCryptoKeyUsageSign, | |
| 166 &key)); | |
| 167 | |
| 168 // Failing case: Bad DER encoding. | |
| 169 EXPECT_EQ( | |
| 170 Status::DataError(), | |
| 171 ImportKey(blink::WebCryptoKeyFormatPkcs8, | |
| 172 CryptoData(HexStringToBytes("618333c4cb")), | |
| 173 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5), | |
| 174 true, | |
| 175 blink::WebCryptoKeyUsageSign, | |
| 176 &key)); | |
| 177 | |
| 178 // Failing case: Import RSA key but provide an inconsistent input algorithm | 137 // Failing case: Import RSA key but provide an inconsistent input algorithm |
| 179 // and usage. Several issues here: | 138 // and usage. Several issues here: |
| 180 // * AES-CBC doesn't support PKCS8 key format | 139 // * AES-CBC doesn't support PKCS8 key format |
| 181 // * AES-CBC doesn't support "sign" usage | 140 // * AES-CBC doesn't support "sign" usage |
| 182 EXPECT_EQ(Status::ErrorUnsupportedImportKeyFormat(), | 141 EXPECT_EQ(Status::ErrorUnsupportedImportKeyFormat(), |
| 183 ImportKey(blink::WebCryptoKeyFormatPkcs8, | 142 ImportKey(blink::WebCryptoKeyFormatPkcs8, |
| 184 CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)), | 143 CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)), |
| 185 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), | 144 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
| 186 true, | 145 true, |
| 187 blink::WebCryptoKeyUsageSign, | 146 blink::WebCryptoKeyUsageSign, |
| 188 &key)); | 147 &key)); |
| 189 } | 148 } |
| 190 | 149 |
| 191 // Tests importing of PKCS8 data that does not define a valid RSA key. | 150 // Tests importing of PKCS8 data that does not define a valid RSA key. |
| 151 // TODO(eroman): Move to bad_rsa_keys.json |
| 192 TEST(WebCryptoRsaSsaTest, ImportInvalidPkcs8) { | 152 TEST(WebCryptoRsaSsaTest, ImportInvalidPkcs8) { |
| 193 if (!SupportsRsaPrivateKeyImport()) | 153 if (!SupportsRsaPrivateKeyImport()) |
| 194 return; | 154 return; |
| 195 | 155 |
| 196 // kPrivateKeyPkcs8DerHex defines an RSA private key in PKCS8 format, whose | 156 // kPrivateKeyPkcs8DerHex defines an RSA private key in PKCS8 format, whose |
| 197 // parameters appear at the following offsets: | 157 // parameters appear at the following offsets: |
| 198 // | 158 // |
| 199 // n: (offset=36, len=129) | 159 // n: (offset=36, len=129) |
| 200 // e: (offset=167, len=3) | 160 // e: (offset=167, len=3) |
| 201 // d: (offset=173, len=128) | 161 // d: (offset=173, len=128) |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 424 &key2)); | 384 &key2)); |
| 425 } | 385 } |
| 426 | 386 |
| 427 // Import a JWK RSA private key with some optional parameters missing (q, dp, | 387 // Import a JWK RSA private key with some optional parameters missing (q, dp, |
| 428 // dq, qi). | 388 // dq, qi). |
| 429 // | 389 // |
| 430 // The only optional parameter included is "p". | 390 // The only optional parameter included is "p". |
| 431 // | 391 // |
| 432 // This fails because JWA says that producers must include either ALL optional | 392 // This fails because JWA says that producers must include either ALL optional |
| 433 // parameters or NONE. | 393 // parameters or NONE. |
| 394 // TODO(eroman): Move to bad_rsa_keys.json |
| 434 TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkMissingOptionalParams) { | 395 TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkMissingOptionalParams) { |
| 435 blink::WebCryptoKey key; | 396 blink::WebCryptoKey key; |
| 436 | 397 |
| 437 base::DictionaryValue dict; | 398 base::DictionaryValue dict; |
| 438 dict.SetString("kty", "RSA"); | 399 dict.SetString("kty", "RSA"); |
| 439 dict.SetString("alg", "RS1"); | 400 dict.SetString("alg", "RS1"); |
| 440 | 401 |
| 441 dict.SetString( | 402 dict.SetString( |
| 442 "n", | 403 "n", |
| 443 "pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_" | 404 "pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 464 blink::WebCryptoKeyUsageSign, | 425 blink::WebCryptoKeyUsageSign, |
| 465 &key)); | 426 &key)); |
| 466 } | 427 } |
| 467 | 428 |
| 468 // Import a JWK RSA private key, without any of the optional parameters. | 429 // Import a JWK RSA private key, without any of the optional parameters. |
| 469 // | 430 // |
| 470 // According to JWA, such keys are valid, but applications SHOULD | 431 // According to JWA, such keys are valid, but applications SHOULD |
| 471 // include all the parameters when sending, and recipients MAY | 432 // include all the parameters when sending, and recipients MAY |
| 472 // accept them, but are not required to. Chromium's WebCrypto does | 433 // accept them, but are not required to. Chromium's WebCrypto does |
| 473 // not allow such degenerate keys. | 434 // not allow such degenerate keys. |
| 435 // TODO(eroman): Move to bad_rsa_keys.json |
| 474 TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkIncorrectOptionalEmpty) { | 436 TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkIncorrectOptionalEmpty) { |
| 475 if (!SupportsRsaPrivateKeyImport()) | 437 if (!SupportsRsaPrivateKeyImport()) |
| 476 return; | 438 return; |
| 477 | 439 |
| 478 blink::WebCryptoKey key; | 440 blink::WebCryptoKey key; |
| 479 | 441 |
| 480 base::DictionaryValue dict; | 442 base::DictionaryValue dict; |
| 481 dict.SetString("kty", "RSA"); | 443 dict.SetString("kty", "RSA"); |
| 482 dict.SetString("alg", "RS1"); | 444 dict.SetString("alg", "RS1"); |
| 483 | 445 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 497 ImportKeyJwkFromDict(dict, | 459 ImportKeyJwkFromDict(dict, |
| 498 CreateRsaHashedImportAlgorithm( | 460 CreateRsaHashedImportAlgorithm( |
| 499 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | 461 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, |
| 500 blink::WebCryptoAlgorithmIdSha1), | 462 blink::WebCryptoAlgorithmIdSha1), |
| 501 true, | 463 true, |
| 502 blink::WebCryptoKeyUsageSign, | 464 blink::WebCryptoKeyUsageSign, |
| 503 &key)); | 465 &key)); |
| 504 } | 466 } |
| 505 | 467 |
| 506 // Tries importing a public RSA key whose exponent contains leading zeros. | 468 // Tries importing a public RSA key whose exponent contains leading zeros. |
| 469 // TODO(eroman): Move to bad_rsa_keys.json |
| 507 TEST(WebCryptoRsaSsaTest, ImportJwkRsaNonMinimalExponent) { | 470 TEST(WebCryptoRsaSsaTest, ImportJwkRsaNonMinimalExponent) { |
| 508 base::DictionaryValue dict; | 471 base::DictionaryValue dict; |
| 509 | 472 |
| 510 dict.SetString("kty", "RSA"); | 473 dict.SetString("kty", "RSA"); |
| 511 dict.SetString("e", "AAEAAQ"); // 00 01 00 01 | 474 dict.SetString("e", "AAEAAQ"); // 00 01 00 01 |
| 512 dict.SetString( | 475 dict.SetString( |
| 513 "n", | 476 "n", |
| 514 "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk" | 477 "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk" |
| 515 "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm" | 478 "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm" |
| 516 "e7PUJHYW1PW6ENTP0ibeiNOfFvs"); | 479 "e7PUJHYW1PW6ENTP0ibeiNOfFvs"); |
| (...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1219 ImportKey(blink::WebCryptoKeyFormatJwk, | 1182 ImportKey(blink::WebCryptoKeyFormatJwk, |
| 1220 bad_data, | 1183 bad_data, |
| 1221 CreateRsaHashedImportAlgorithm( | 1184 CreateRsaHashedImportAlgorithm( |
| 1222 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | 1185 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, |
| 1223 blink::WebCryptoAlgorithmIdSha256), | 1186 blink::WebCryptoAlgorithmIdSha256), |
| 1224 true, | 1187 true, |
| 1225 blink::WebCryptoKeyUsageVerify | blink::WebCryptoKeyUsageSign, | 1188 blink::WebCryptoKeyUsageVerify | blink::WebCryptoKeyUsageSign, |
| 1226 &key)); | 1189 &key)); |
| 1227 } | 1190 } |
| 1228 | 1191 |
| 1192 // Reads a key format string as used in bad_rsa_keys.json, and converts to a |
| 1193 // WebCryptoKeyFormat. |
| 1194 blink::WebCryptoKeyFormat GetKeyFormatForTestCase( |
| 1195 const base::DictionaryValue* test) { |
| 1196 std::string format; |
| 1197 EXPECT_TRUE(test->GetString("format", &format)); |
| 1198 if (format == "jwk") |
| 1199 return blink::WebCryptoKeyFormatJwk; |
| 1200 else if (format == "pkcs8") |
| 1201 return blink::WebCryptoKeyFormatPkcs8; |
| 1202 else if (format == "spki") |
| 1203 return blink::WebCryptoKeyFormatSpki; |
| 1204 |
| 1205 EXPECT_TRUE(false) << "Unrecognized key format: " << format; |
| 1206 return blink::WebCryptoKeyFormatRaw; |
| 1207 } |
| 1208 |
| 1209 // Extracts the key data bytes from |test|, as it appears in bad_rsa_keys.json. |
| 1210 std::vector<uint8_t> GetKeyDataForTestCase( |
| 1211 const base::DictionaryValue* test, |
| 1212 blink::WebCryptoKeyFormat key_format) { |
| 1213 if (key_format == blink::WebCryptoKeyFormatJwk) { |
| 1214 const base::DictionaryValue* json; |
| 1215 EXPECT_TRUE(test->GetDictionary("data", &json)); |
| 1216 return MakeJsonVector(*json); |
| 1217 } |
| 1218 return GetBytesFromHexString(test, "data"); |
| 1219 } |
| 1220 |
| 1221 // Imports invalid JWK/SPKI/PKCS8 data and verifies that it fails as expected. |
| 1222 TEST(WebCryptoRsaSsaTest, ImportInvalidKeyData) { |
| 1223 if (!SupportsRsaPrivateKeyImport()) |
| 1224 return; |
| 1225 |
| 1226 scoped_ptr<base::ListValue> tests; |
| 1227 ASSERT_TRUE(ReadJsonTestFileToList("bad_rsa_keys.json", &tests)); |
| 1228 |
| 1229 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { |
| 1230 SCOPED_TRACE(test_index); |
| 1231 |
| 1232 const base::DictionaryValue* test; |
| 1233 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); |
| 1234 |
| 1235 blink::WebCryptoKeyFormat key_format = GetKeyFormatForTestCase(test); |
| 1236 std::vector<uint8_t> key_data = GetKeyDataForTestCase(test, key_format); |
| 1237 std::string test_error; |
| 1238 ASSERT_TRUE(test->GetString("error", &test_error)); |
| 1239 |
| 1240 blink::WebCryptoKey key; |
| 1241 Status status = ImportKey(key_format, CryptoData(key_data), |
| 1242 CreateRsaHashedImportAlgorithm( |
| 1243 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, |
| 1244 blink::WebCryptoAlgorithmIdSha256), |
| 1245 true, 0, &key); |
| 1246 EXPECT_EQ(test_error, StatusToString(status)); |
| 1247 } |
| 1248 } |
| 1249 |
| 1229 } // namespace | 1250 } // namespace |
| 1230 | 1251 |
| 1231 } // namespace webcrypto | 1252 } // namespace webcrypto |
| 1232 | 1253 |
| 1233 } // namespace content | 1254 } // namespace content |
| OLD | NEW |