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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 // * AES-CBC doesn't support "sign" usage | 140 // * AES-CBC doesn't support "sign" usage |
141 EXPECT_EQ(Status::ErrorUnsupportedImportKeyFormat(), | 141 EXPECT_EQ(Status::ErrorUnsupportedImportKeyFormat(), |
142 ImportKey(blink::WebCryptoKeyFormatPkcs8, | 142 ImportKey(blink::WebCryptoKeyFormatPkcs8, |
143 CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)), | 143 CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)), |
144 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), | 144 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc), |
145 true, | 145 true, |
146 blink::WebCryptoKeyUsageSign, | 146 blink::WebCryptoKeyUsageSign, |
147 &key)); | 147 &key)); |
148 } | 148 } |
149 | 149 |
150 // Tests importing of PKCS8 data that does not define a valid RSA key. | |
151 // TODO(eroman): Move to bad_rsa_keys.json | |
152 TEST(WebCryptoRsaSsaTest, ImportInvalidPkcs8) { | |
153 if (!SupportsRsaPrivateKeyImport()) | |
154 return; | |
155 | |
156 // kPrivateKeyPkcs8DerHex defines an RSA private key in PKCS8 format, whose | |
157 // parameters appear at the following offsets: | |
158 // | |
159 // n: (offset=36, len=129) | |
160 // e: (offset=167, len=3) | |
161 // d: (offset=173, len=128) | |
162 // p: (offset=303, len=65) | |
163 // q: (offset=370, len=65) | |
164 // dp: (offset=437, len=64) | |
165 // dq; (offset=503, len=64) | |
166 // qi: (offset=569, len=64) | |
167 | |
168 // Do several tests, each of which invert a single byte within the input. | |
169 const unsigned int kOffsetsToCorrupt[] = { | |
170 50, // inside n | |
171 168, // inside e | |
172 175, // inside d | |
173 333, // inside p | |
174 373, // inside q | |
175 450, // inside dp | |
176 550, // inside dq | |
177 600, // inside qi | |
178 }; | |
179 | |
180 for (size_t test_index = 0; test_index < arraysize(kOffsetsToCorrupt); | |
181 ++test_index) { | |
182 SCOPED_TRACE(test_index); | |
183 | |
184 unsigned int i = kOffsetsToCorrupt[test_index]; | |
185 std::vector<uint8_t> corrupted_data = | |
186 HexStringToBytes(kPrivateKeyPkcs8DerHex); | |
187 corrupted_data[i] = ~corrupted_data[i]; | |
188 | |
189 blink::WebCryptoKey key; | |
190 EXPECT_EQ(Status::DataError(), | |
191 ImportKey(blink::WebCryptoKeyFormatPkcs8, | |
192 CryptoData(corrupted_data), | |
193 CreateRsaHashedImportAlgorithm( | |
194 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | |
195 blink::WebCryptoAlgorithmIdSha1), | |
196 true, | |
197 blink::WebCryptoKeyUsageSign, | |
198 &key)); | |
199 } | |
200 } | |
201 | |
202 // Tests JWK import and export by doing a roundtrip key conversion and ensuring | 150 // Tests JWK import and export by doing a roundtrip key conversion and ensuring |
203 // it was lossless: | 151 // it was lossless: |
204 // | 152 // |
205 // PKCS8 --> JWK --> PKCS8 | 153 // PKCS8 --> JWK --> PKCS8 |
206 TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkToPkcs8RoundTrip) { | 154 TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkToPkcs8RoundTrip) { |
207 if (!SupportsRsaPrivateKeyImport()) | 155 if (!SupportsRsaPrivateKeyImport()) |
208 return; | 156 return; |
209 | 157 |
210 blink::WebCryptoKey key; | 158 blink::WebCryptoKey key; |
211 ASSERT_EQ(Status::Success(), | 159 ASSERT_EQ(Status::Success(), |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 ASSERT_EQ(Status::OperationError(), | 325 ASSERT_EQ(Status::OperationError(), |
378 ImportKeyJwkFromDict(*key2_jwk, | 326 ImportKeyJwkFromDict(*key2_jwk, |
379 CreateRsaHashedImportAlgorithm( | 327 CreateRsaHashedImportAlgorithm( |
380 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | 328 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, |
381 blink::WebCryptoAlgorithmIdSha256), | 329 blink::WebCryptoAlgorithmIdSha256), |
382 true, | 330 true, |
383 blink::WebCryptoKeyUsageSign, | 331 blink::WebCryptoKeyUsageSign, |
384 &key2)); | 332 &key2)); |
385 } | 333 } |
386 | 334 |
387 // Import a JWK RSA private key with some optional parameters missing (q, dp, | |
388 // dq, qi). | |
389 // | |
390 // The only optional parameter included is "p". | |
391 // | |
392 // This fails because JWA says that producers must include either ALL optional | |
393 // parameters or NONE. | |
394 // TODO(eroman): Move to bad_rsa_keys.json | |
395 TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkMissingOptionalParams) { | |
396 blink::WebCryptoKey key; | |
397 | |
398 base::DictionaryValue dict; | |
399 dict.SetString("kty", "RSA"); | |
400 dict.SetString("alg", "RS1"); | |
401 | |
402 dict.SetString( | |
403 "n", | |
404 "pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_" | |
405 "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_" | |
406 "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc"); | |
407 dict.SetString("e", "AQAB"); | |
408 dict.SetString( | |
409 "d", | |
410 "M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-" | |
411 "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ" | |
412 "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU"); | |
413 | |
414 dict.SetString("p", | |
415 "5-" | |
416 "iUJyCod1Fyc6NWBT6iobwMlKpy1VxuhilrLfyWeUjApyy8zKfqyzVwbgmh31W" | |
417 "hU1vZs8w0Fgs7bc0-2o5kQw"); | |
418 | |
419 ASSERT_EQ(Status::ErrorJwkPropertyMissing("q"), | |
420 ImportKeyJwkFromDict(dict, | |
421 CreateRsaHashedImportAlgorithm( | |
422 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | |
423 blink::WebCryptoAlgorithmIdSha1), | |
424 true, | |
425 blink::WebCryptoKeyUsageSign, | |
426 &key)); | |
427 } | |
428 | |
429 // Import a JWK RSA private key, without any of the optional parameters. | |
430 // | |
431 // According to JWA, such keys are valid, but applications SHOULD | |
432 // include all the parameters when sending, and recipients MAY | |
433 // accept them, but are not required to. Chromium's WebCrypto does | |
434 // not allow such degenerate keys. | |
435 // TODO(eroman): Move to bad_rsa_keys.json | |
436 TEST(WebCryptoRsaSsaTest, ImportRsaPrivateKeyJwkIncorrectOptionalEmpty) { | |
437 if (!SupportsRsaPrivateKeyImport()) | |
438 return; | |
439 | |
440 blink::WebCryptoKey key; | |
441 | |
442 base::DictionaryValue dict; | |
443 dict.SetString("kty", "RSA"); | |
444 dict.SetString("alg", "RS1"); | |
445 | |
446 dict.SetString( | |
447 "n", | |
448 "pW5KDnAQF1iaUYfcfqhB0Vby7A42rVKkTf6x5h962ZHYxRBW_-2xYrTA8oOhKoijlN_" | |
449 "1JqtykcuzB86r_OCx39XNlQgJbVsri2311nHvY3fAkhyyPCcKcOJZjm_4nRnxBazC0_" | |
450 "DLNfKSgOE4a29kxO8i4eHyDQzoz_siSb2aITc"); | |
451 dict.SetString("e", "AQAB"); | |
452 dict.SetString( | |
453 "d", | |
454 "M6UEKpCyfU9UUcqbu9C0R3GhAa-IQ0Cu-YhfKku-" | |
455 "kuiUpySsPFaMj5eFOtB8AmbIxqPKCSnx6PESMYhEKfxNmuVf7olqEM5wfD7X5zTkRyejlXRQ" | |
456 "GlMmgxCcKrrKuig8MbS9L1PD7jfjUs7jT55QO9gMBiKtecbc7og1R8ajsyU"); | |
457 | |
458 ASSERT_EQ(Status::ErrorJwkPropertyMissing("p"), | |
459 ImportKeyJwkFromDict(dict, | |
460 CreateRsaHashedImportAlgorithm( | |
461 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | |
462 blink::WebCryptoAlgorithmIdSha1), | |
463 true, | |
464 blink::WebCryptoKeyUsageSign, | |
465 &key)); | |
466 } | |
467 | |
468 // Tries importing a public RSA key whose exponent contains leading zeros. | |
469 // TODO(eroman): Move to bad_rsa_keys.json | |
470 TEST(WebCryptoRsaSsaTest, ImportJwkRsaNonMinimalExponent) { | |
471 base::DictionaryValue dict; | |
472 | |
473 dict.SetString("kty", "RSA"); | |
474 dict.SetString("e", "AAEAAQ"); // 00 01 00 01 | |
475 dict.SetString( | |
476 "n", | |
477 "qLOyhK-OtQs4cDSoYPFGxJGfMYdjzWxVmMiuSBGh4KvEx-CwgtaTpef87Wdc9GaFEncsDLxk" | |
478 "p0LGxjD1M8jMcvYq6DPEC_JYQumEu3i9v5fAEH1VvbZi9cTg-rmEXLUUjvc5LdOq_5OuHmtm" | |
479 "e7PUJHYW1PW6ENTP0ibeiNOfFvs"); | |
480 | |
481 blink::WebCryptoKey key; | |
482 | |
483 EXPECT_EQ(Status::ErrorJwkBigIntegerHasLeadingZero("e"), | |
484 ImportKeyJwkFromDict(dict, | |
485 CreateRsaHashedImportAlgorithm( | |
486 blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | |
487 blink::WebCryptoAlgorithmIdSha256), | |
488 false, | |
489 blink::WebCryptoKeyUsageVerify, | |
490 &key)); | |
491 } | |
492 | |
493 TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) { | 335 TEST(WebCryptoRsaSsaTest, GenerateKeyPairRsa) { |
494 // Note: using unrealistic short key lengths here to avoid bogging down tests. | 336 // Note: using unrealistic short key lengths here to avoid bogging down tests. |
495 | 337 |
496 // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation (sha256) | 338 // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation (sha256) |
497 const unsigned int modulus_length = 256; | 339 const unsigned int modulus_length = 256; |
498 const std::vector<uint8_t> public_exponent = HexStringToBytes("010001"); | 340 const std::vector<uint8_t> public_exponent = HexStringToBytes("010001"); |
499 blink::WebCryptoAlgorithm algorithm = | 341 blink::WebCryptoAlgorithm algorithm = |
500 CreateRsaHashedKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | 342 CreateRsaHashedKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, |
501 blink::WebCryptoAlgorithmIdSha256, | 343 blink::WebCryptoAlgorithmIdSha256, |
502 modulus_length, | 344 modulus_length, |
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1245 true, 0, &key); | 1087 true, 0, &key); |
1246 EXPECT_EQ(test_error, StatusToString(status)); | 1088 EXPECT_EQ(test_error, StatusToString(status)); |
1247 } | 1089 } |
1248 } | 1090 } |
1249 | 1091 |
1250 } // namespace | 1092 } // namespace |
1251 | 1093 |
1252 } // namespace webcrypto | 1094 } // namespace webcrypto |
1253 | 1095 |
1254 } // namespace content | 1096 } // namespace content |
OLD | NEW |