| 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 |