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 |