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 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1193 RestoreJwkRsaDictionary(&dict); | 1156 RestoreJwkRsaDictionary(&dict); |
1194 | 1157 |
1195 // Fail on empty parameter. | 1158 // Fail on empty parameter. |
1196 dict.SetString(kKtyParmName[idx], ""); | 1159 dict.SetString(kKtyParmName[idx], ""); |
1197 EXPECT_EQ(Status::ErrorJwkEmptyBigInteger(kKtyParmName[idx]), | 1160 EXPECT_EQ(Status::ErrorJwkEmptyBigInteger(kKtyParmName[idx]), |
1198 ImportKeyJwkFromDict(dict, algorithm, false, usages, &key)); | 1161 ImportKeyJwkFromDict(dict, algorithm, false, usages, &key)); |
1199 RestoreJwkRsaDictionary(&dict); | 1162 RestoreJwkRsaDictionary(&dict); |
1200 } | 1163 } |
1201 } | 1164 } |
1202 | 1165 |
1166 // Reads a key format string as used in bad_rsa_keys.json, and converts to a | |
1167 // WebCryptoKeyFormat. | |
1168 blink::WebCryptoKeyFormat GetKeyFormat(const base::DictionaryValue* test) { | |
Ryan Sleevi
2014/10/24 23:00:57
Need a better variable name here? |test| isn't qui
eroman
2014/10/27 23:35:18
Renamed the functions to:
GetKeyFormatForTestCase
| |
1169 std::string format; | |
1170 EXPECT_TRUE(test->GetString("format", &format)); | |
1171 if (format == "jwk") | |
1172 return blink::WebCryptoKeyFormatJwk; | |
1173 else if (format == "pkcs8") | |
1174 return blink::WebCryptoKeyFormatPkcs8; | |
1175 else if (format == "spki") | |
1176 return blink::WebCryptoKeyFormatSpki; | |
1177 | |
1178 EXPECT_TRUE(false) << "Unrecognized key format: " << format; | |
1179 return blink::WebCryptoKeyFormatRaw; | |
1180 } | |
1181 | |
1182 // Extracts the key data bytes from |test|, as it appears in bad_rsa_keys.json. | |
1183 std::vector<uint8_t> GetKeyData(const base::DictionaryValue* test, | |
1184 blink::WebCryptoKeyFormat key_format) { | |
1185 if (key_format == blink::WebCryptoKeyFormatJwk) { | |
1186 const base::DictionaryValue* json; | |
1187 EXPECT_TRUE(test->GetDictionary("data", &json)); | |
1188 return MakeJsonVector(*json); | |
1189 } | |
1190 return GetBytesFromHexString(test, "data"); | |
1191 } | |
1192 | |
1193 // Imports invalid JWK/SPKI/PKCS8 data and verifies that it fails as expected. | |
1194 TEST(WebCryptoRsaSsaTest, ImportInvalidKeyData) { | |
1195 if (!SupportsRsaPrivateKeyImport()) | |
1196 return; | |
1197 | |
1198 scoped_ptr<base::ListValue> tests; | |
1199 ASSERT_TRUE(ReadJsonTestFileToList("bad_rsa_keys.json", &tests)); | |
1200 | |
1201 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { | |
1202 SCOPED_TRACE(test_index); | |
1203 | |
1204 const base::DictionaryValue* test; | |
1205 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); | |
1206 | |
1207 blink::WebCryptoKeyFormat key_format = GetKeyFormat(test); | |
1208 std::vector<uint8_t> key_data = GetKeyData(test, key_format); | |
1209 std::string test_error; | |
1210 ASSERT_TRUE(test->GetString("error", &test_error)); | |
1211 | |
1212 blink::WebCryptoKey key; | |
1213 Status status = ImportKey(key_format, | |
1214 CryptoData(key_data), | |
1215 CreateRsaHashedImportAlgorithm( | |
1216 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | |
1217 blink::WebCryptoAlgorithmIdSha256), | |
1218 true, | |
1219 0, | |
1220 &key); | |
1221 EXPECT_EQ(test_error, StatusToString(status)); | |
1222 } | |
1223 } | |
1224 | |
1203 } // namespace | 1225 } // namespace |
1204 | 1226 |
1205 } // namespace webcrypto | 1227 } // namespace webcrypto |
1206 | 1228 |
1207 } // namespace content | 1229 } // namespace content |
OLD | NEW |