Chromium Code Reviews| 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 "content/child/webcrypto/shared_crypto.h" | 5 #include "content/child/webcrypto/shared_crypto.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 44 ASSERT_EQ(expected.ToString(), (code).ToString()) | 44 ASSERT_EQ(expected.ToString(), (code).ToString()) |
| 45 #define EXPECT_STATUS_SUCCESS(code) EXPECT_STATUS(Status::Success(), code) | 45 #define EXPECT_STATUS_SUCCESS(code) EXPECT_STATUS(Status::Success(), code) |
| 46 #define ASSERT_STATUS_SUCCESS(code) ASSERT_STATUS(Status::Success(), code) | 46 #define ASSERT_STATUS_SUCCESS(code) ASSERT_STATUS(Status::Success(), code) |
| 47 | 47 |
| 48 namespace content { | 48 namespace content { |
| 49 | 49 |
| 50 namespace webcrypto { | 50 namespace webcrypto { |
| 51 | 51 |
| 52 namespace { | 52 namespace { |
| 53 | 53 |
| 54 // TODO(eroman): For Linux builds using system NSS, AES-GCM support is a | |
| 55 // runtime dependency. Test it by trying to import a key. | |
| 56 // TODO(padolph): Consider caching the result of the import key test. | |
| 57 bool SupportsAesGcm() { | |
| 58 std::vector<uint8> key_raw(16, 0); | |
| 59 | |
| 60 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | |
| 61 Status status = ImportKey(blink::WebCryptoKeyFormatRaw, | |
| 62 CryptoData(key_raw), | |
| 63 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm), | |
| 64 true, | |
| 65 blink::WebCryptoKeyUsageEncrypt, | |
| 66 &key); | |
| 67 | |
| 68 if (status.IsError()) | |
| 69 EXPECT_EQ(Status::ErrorUnsupported().ToString(), status.ToString()); | |
|
eroman
2014/03/13 22:31:13
[optional] update this to use EXPECT_STATUS()
padolph
2014/03/13 22:39:34
Done.
| |
| 70 return status.IsSuccess(); | |
| 71 } | |
| 72 | |
| 54 blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm( | 73 blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm( |
| 55 blink::WebCryptoAlgorithmId algorithm_id, | 74 blink::WebCryptoAlgorithmId algorithm_id, |
| 56 unsigned int modulus_length, | 75 unsigned int modulus_length, |
| 57 const std::vector<uint8>& public_exponent) { | 76 const std::vector<uint8>& public_exponent) { |
| 58 DCHECK_EQ(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, algorithm_id); | 77 DCHECK_EQ(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, algorithm_id); |
| 59 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 78 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
| 60 algorithm_id, | 79 algorithm_id, |
| 61 new blink::WebCryptoRsaKeyGenParams( | 80 new blink::WebCryptoRsaKeyGenParams( |
| 62 modulus_length, | 81 modulus_length, |
| 63 webcrypto::Uint8VectorStart(public_exponent), | 82 webcrypto::Uint8VectorStart(public_exponent), |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 86 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 105 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
| 87 blink::WebCryptoAlgorithmIdAesCbc, | 106 blink::WebCryptoAlgorithmIdAesCbc, |
| 88 new blink::WebCryptoAesCbcParams(Uint8VectorStart(iv), iv.size())); | 107 new blink::WebCryptoAesCbcParams(Uint8VectorStart(iv), iv.size())); |
| 89 } | 108 } |
| 90 | 109 |
| 91 // Creates and AES-GCM algorithm. | 110 // Creates and AES-GCM algorithm. |
| 92 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm( | 111 blink::WebCryptoAlgorithm CreateAesGcmAlgorithm( |
| 93 const std::vector<uint8>& iv, | 112 const std::vector<uint8>& iv, |
| 94 const std::vector<uint8>& additional_data, | 113 const std::vector<uint8>& additional_data, |
| 95 unsigned int tag_length_bits) { | 114 unsigned int tag_length_bits) { |
| 115 DCHECK(SupportsAesGcm()); | |
|
eroman
2014/03/13 22:31:13
Instead of DCHECK() please use EXPECT_TRUE(). DCHE
padolph
2014/03/13 22:39:34
Done.
| |
| 96 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 116 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
| 97 blink::WebCryptoAlgorithmIdAesGcm, | 117 blink::WebCryptoAlgorithmIdAesGcm, |
| 98 new blink::WebCryptoAesGcmParams(Uint8VectorStart(iv), | 118 new blink::WebCryptoAesGcmParams(Uint8VectorStart(iv), |
| 99 iv.size(), | 119 iv.size(), |
| 100 true, | 120 true, |
| 101 Uint8VectorStart(additional_data), | 121 Uint8VectorStart(additional_data), |
| 102 additional_data.size(), | 122 additional_data.size(), |
| 103 true, | 123 true, |
| 104 tag_length_bits)); | 124 tag_length_bits)); |
| 105 } | 125 } |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 336 } | 356 } |
| 337 | 357 |
| 338 blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm( | 358 blink::WebCryptoAlgorithm CreateAesCbcKeyGenAlgorithm( |
| 339 unsigned short key_length_bits) { | 359 unsigned short key_length_bits) { |
| 340 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesCbc, | 360 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesCbc, |
| 341 key_length_bits); | 361 key_length_bits); |
| 342 } | 362 } |
| 343 | 363 |
| 344 blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm( | 364 blink::WebCryptoAlgorithm CreateAesGcmKeyGenAlgorithm( |
| 345 unsigned short key_length_bits) { | 365 unsigned short key_length_bits) { |
| 366 DCHECK(SupportsAesGcm()); | |
|
eroman
2014/03/13 22:31:13
ditto
padolph
2014/03/13 22:39:34
Done.
| |
| 346 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesGcm, | 367 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesGcm, |
| 347 key_length_bits); | 368 key_length_bits); |
| 348 } | 369 } |
| 349 | 370 |
| 350 blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm( | 371 blink::WebCryptoAlgorithm CreateAesKwKeyGenAlgorithm( |
| 351 unsigned short key_length_bits) { | 372 unsigned short key_length_bits) { |
| 352 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesKw, | 373 return CreateAesKeyGenAlgorithm(blink::WebCryptoAlgorithmIdAesKw, |
| 353 key_length_bits); | 374 key_length_bits); |
| 354 } | 375 } |
| 355 | 376 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 443 usage_mask, | 464 usage_mask, |
| 444 private_key)); | 465 private_key)); |
| 445 EXPECT_FALSE(private_key->isNull()); | 466 EXPECT_FALSE(private_key->isNull()); |
| 446 EXPECT_TRUE(private_key->handle()); | 467 EXPECT_TRUE(private_key->handle()); |
| 447 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key->type()); | 468 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key->type()); |
| 448 EXPECT_EQ(algorithm.id(), private_key->algorithm().id()); | 469 EXPECT_EQ(algorithm.id(), private_key->algorithm().id()); |
| 449 EXPECT_EQ(extractable, extractable); | 470 EXPECT_EQ(extractable, extractable); |
| 450 EXPECT_EQ(usage_mask, private_key->usages()); | 471 EXPECT_EQ(usage_mask, private_key->usages()); |
| 451 } | 472 } |
| 452 | 473 |
| 453 // TODO(eroman): For Linux builds using system NSS, AES-GCM support is a | |
| 454 // runtime dependency. Test it by trying to import a key. | |
| 455 bool SupportsAesGcm() { | |
| 456 std::vector<uint8> key_raw(16, 0); | |
| 457 | |
| 458 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | |
| 459 Status status = ImportKey(blink::WebCryptoKeyFormatRaw, | |
| 460 CryptoData(key_raw), | |
| 461 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesGcm), | |
| 462 true, | |
| 463 blink::WebCryptoKeyUsageEncrypt, | |
| 464 &key); | |
| 465 | |
| 466 if (status.IsError()) | |
| 467 EXPECT_EQ(Status::ErrorUnsupported().ToString(), status.ToString()); | |
| 468 return status.IsSuccess(); | |
| 469 } | |
| 470 | |
| 471 Status AesGcmEncrypt(const blink::WebCryptoKey& key, | 474 Status AesGcmEncrypt(const blink::WebCryptoKey& key, |
| 472 const std::vector<uint8>& iv, | 475 const std::vector<uint8>& iv, |
| 473 const std::vector<uint8>& additional_data, | 476 const std::vector<uint8>& additional_data, |
| 474 unsigned int tag_length_bits, | 477 unsigned int tag_length_bits, |
| 475 const std::vector<uint8>& plain_text, | 478 const std::vector<uint8>& plain_text, |
| 476 std::vector<uint8>* cipher_text, | 479 std::vector<uint8>* cipher_text, |
| 477 std::vector<uint8>* authentication_tag) { | 480 std::vector<uint8>* authentication_tag) { |
| 481 DCHECK(SupportsAesGcm()); | |
| 478 blink::WebCryptoAlgorithm algorithm = | 482 blink::WebCryptoAlgorithm algorithm = |
| 479 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); | 483 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); |
| 480 | 484 |
| 481 blink::WebArrayBuffer output; | 485 blink::WebArrayBuffer output; |
| 482 Status status = Encrypt(algorithm, key, CryptoData(plain_text), &output); | 486 Status status = Encrypt(algorithm, key, CryptoData(plain_text), &output); |
| 483 if (status.IsError()) | 487 if (status.IsError()) |
| 484 return status; | 488 return status; |
| 485 | 489 |
| 486 if (output.byteLength() * 8 < tag_length_bits) { | 490 if (output.byteLength() * 8 < tag_length_bits) { |
| 487 EXPECT_TRUE(false); | 491 EXPECT_TRUE(false); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 499 return Status::Success(); | 503 return Status::Success(); |
| 500 } | 504 } |
| 501 | 505 |
| 502 Status AesGcmDecrypt(const blink::WebCryptoKey& key, | 506 Status AesGcmDecrypt(const blink::WebCryptoKey& key, |
| 503 const std::vector<uint8>& iv, | 507 const std::vector<uint8>& iv, |
| 504 const std::vector<uint8>& additional_data, | 508 const std::vector<uint8>& additional_data, |
| 505 unsigned int tag_length_bits, | 509 unsigned int tag_length_bits, |
| 506 const std::vector<uint8>& cipher_text, | 510 const std::vector<uint8>& cipher_text, |
| 507 const std::vector<uint8>& authentication_tag, | 511 const std::vector<uint8>& authentication_tag, |
| 508 blink::WebArrayBuffer* plain_text) { | 512 blink::WebArrayBuffer* plain_text) { |
| 513 DCHECK(SupportsAesGcm()); | |
| 509 blink::WebCryptoAlgorithm algorithm = | 514 blink::WebCryptoAlgorithm algorithm = |
| 510 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); | 515 CreateAesGcmAlgorithm(iv, additional_data, tag_length_bits); |
| 511 | 516 |
| 512 // Join cipher text and authentication tag. | 517 // Join cipher text and authentication tag. |
| 513 std::vector<uint8> cipher_text_with_tag; | 518 std::vector<uint8> cipher_text_with_tag; |
| 514 cipher_text_with_tag.reserve(cipher_text.size() + authentication_tag.size()); | 519 cipher_text_with_tag.reserve(cipher_text.size() + authentication_tag.size()); |
| 515 cipher_text_with_tag.insert( | 520 cipher_text_with_tag.insert( |
| 516 cipher_text_with_tag.end(), cipher_text.begin(), cipher_text.end()); | 521 cipher_text_with_tag.end(), cipher_text.begin(), cipher_text.end()); |
| 517 cipher_text_with_tag.insert(cipher_text_with_tag.end(), | 522 cipher_text_with_tag.insert(cipher_text_with_tag.end(), |
| 518 authentication_tag.begin(), | 523 authentication_tag.begin(), |
| 519 authentication_tag.end()); | 524 authentication_tag.end()); |
| 520 | 525 |
| 521 return Decrypt(algorithm, key, CryptoData(cipher_text_with_tag), plain_text); | 526 return Decrypt(algorithm, key, CryptoData(cipher_text_with_tag), plain_text); |
| 522 } | 527 } |
| 523 | 528 |
| 524 Status ImportKeyJwkFromDict(const base::DictionaryValue& dict, | 529 Status ImportKeyJwkFromDict(const base::DictionaryValue& dict, |
| 525 const blink::WebCryptoAlgorithm& algorithm, | 530 const blink::WebCryptoAlgorithm& algorithm, |
| 526 bool extractable, | 531 bool extractable, |
| 527 blink::WebCryptoKeyUsageMask usage_mask, | 532 blink::WebCryptoKeyUsageMask usage_mask, |
| 528 blink::WebCryptoKey* key) { | 533 blink::WebCryptoKey* key) { |
| 529 return ImportKeyJwk(CryptoData(MakeJsonVector(dict)), | 534 return ImportKeyJwk(CryptoData(MakeJsonVector(dict)), |
| 530 algorithm, | 535 algorithm, |
| 531 extractable, | 536 extractable, |
| 532 usage_mask, | 537 usage_mask, |
| 533 key); | 538 key); |
| 534 } | 539 } |
| 535 | 540 |
| 536 } // namespace | 541 } // namespace |
| 537 | 542 |
| 543 TEST_F(SharedCryptoTest, CheckAesGcm) { | |
| 544 if (!SupportsAesGcm()) { | |
| 545 LOG(WARNING) << "AES GCM not supported on this platform, so some tests " | |
| 546 "will be skipped. Consider upgrading local NSS libraries"; | |
| 547 return; | |
| 548 } | |
| 549 } | |
| 550 | |
| 538 TEST_F(SharedCryptoTest, StatusToString) { | 551 TEST_F(SharedCryptoTest, StatusToString) { |
| 539 EXPECT_EQ("Success", Status::Success().ToString()); | 552 EXPECT_EQ("Success", Status::Success().ToString()); |
| 540 EXPECT_EQ("", Status::Error().ToString()); | 553 EXPECT_EQ("", Status::Error().ToString()); |
| 541 EXPECT_EQ("The requested operation is unsupported", | 554 EXPECT_EQ("The requested operation is unsupported", |
| 542 Status::ErrorUnsupported().ToString()); | 555 Status::ErrorUnsupported().ToString()); |
| 543 EXPECT_EQ("The required JWK property \"kty\" was missing", | 556 EXPECT_EQ("The required JWK property \"kty\" was missing", |
| 544 Status::ErrorJwkPropertyMissing("kty").ToString()); | 557 Status::ErrorJwkPropertyMissing("kty").ToString()); |
| 545 EXPECT_EQ("The JWK property \"kty\" must be a string", | 558 EXPECT_EQ("The JWK property \"kty\" must be a string", |
| 546 Status::ErrorJwkPropertyWrongType("kty", "string").ToString()); | 559 Status::ErrorJwkPropertyWrongType("kty", "string").ToString()); |
| 547 EXPECT_EQ("The JWK property \"n\" could not be base64 decoded", | 560 EXPECT_EQ("The JWK property \"n\" could not be base64 decoded", |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 807 } | 820 } |
| 808 } | 821 } |
| 809 | 822 |
| 810 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAes)) { | 823 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAes)) { |
| 811 // Check key generation for each of AES-CBC, AES-GCM, and AES-KW, and for each | 824 // Check key generation for each of AES-CBC, AES-GCM, and AES-KW, and for each |
| 812 // allowed key length. | 825 // allowed key length. |
| 813 std::vector<blink::WebCryptoAlgorithm> algorithm; | 826 std::vector<blink::WebCryptoAlgorithm> algorithm; |
| 814 const unsigned short kKeyLength[] = {128, 192, 256}; | 827 const unsigned short kKeyLength[] = {128, 192, 256}; |
| 815 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLength); ++i) { | 828 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLength); ++i) { |
| 816 algorithm.push_back(CreateAesCbcKeyGenAlgorithm(kKeyLength[i])); | 829 algorithm.push_back(CreateAesCbcKeyGenAlgorithm(kKeyLength[i])); |
| 817 algorithm.push_back(CreateAesGcmKeyGenAlgorithm(kKeyLength[i])); | |
| 818 algorithm.push_back(CreateAesKwKeyGenAlgorithm(kKeyLength[i])); | 830 algorithm.push_back(CreateAesKwKeyGenAlgorithm(kKeyLength[i])); |
| 831 if (SupportsAesGcm()) | |
|
eroman
2014/03/13 22:31:13
Interesting. So generating AES-GCM key works witho
padolph
2014/03/13 22:39:34
Yes, appears so. Strange.
| |
| 832 algorithm.push_back(CreateAesGcmKeyGenAlgorithm(kKeyLength[i])); | |
| 819 } | 833 } |
| 820 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 834 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 821 std::vector<blink::WebArrayBuffer> keys; | 835 std::vector<blink::WebArrayBuffer> keys; |
| 822 blink::WebArrayBuffer key_bytes; | 836 blink::WebArrayBuffer key_bytes; |
| 823 for (size_t i = 0; i < algorithm.size(); ++i) { | 837 for (size_t i = 0; i < algorithm.size(); ++i) { |
| 824 SCOPED_TRACE(i); | 838 SCOPED_TRACE(i); |
| 825 // Generate a small sample of keys. | 839 // Generate a small sample of keys. |
| 826 keys.clear(); | 840 keys.clear(); |
| 827 for (int j = 0; j < 16; ++j) { | 841 for (int j = 0; j < 16; ++j) { |
| 828 ASSERT_STATUS_SUCCESS(GenerateSecretKey(algorithm[i], true, 0, &key)); | 842 ASSERT_STATUS_SUCCESS(GenerateSecretKey(algorithm[i], true, 0, &key)); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 843 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAesBadLength)) { | 857 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyAesBadLength)) { |
| 844 const unsigned short kKeyLen[] = {0, 127, 257}; | 858 const unsigned short kKeyLen[] = {0, 127, 257}; |
| 845 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 859 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 846 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLen); ++i) { | 860 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kKeyLen); ++i) { |
| 847 SCOPED_TRACE(i); | 861 SCOPED_TRACE(i); |
| 848 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), | 862 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), |
| 849 GenerateSecretKey( | 863 GenerateSecretKey( |
| 850 CreateAesCbcKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); | 864 CreateAesCbcKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); |
| 851 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), | 865 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), |
| 852 GenerateSecretKey( | 866 GenerateSecretKey( |
| 853 CreateAesGcmKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); | |
| 854 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), | |
| 855 GenerateSecretKey( | |
| 856 CreateAesKwKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); | 867 CreateAesKwKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); |
| 868 if (SupportsAesGcm()) { | |
| 869 EXPECT_STATUS(Status::ErrorGenerateKeyLength(), | |
| 870 GenerateSecretKey( | |
| 871 CreateAesGcmKeyGenAlgorithm(kKeyLen[i]), true, 0, &key)); | |
| 872 } | |
| 857 } | 873 } |
| 858 } | 874 } |
| 859 | 875 |
| 860 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyHmac)) { | 876 TEST_F(SharedCryptoTest, MAYBE(GenerateKeyHmac)) { |
| 861 // Generate a small sample of HMAC keys. | 877 // Generate a small sample of HMAC keys. |
| 862 std::vector<blink::WebArrayBuffer> keys; | 878 std::vector<blink::WebArrayBuffer> keys; |
| 863 for (int i = 0; i < 16; ++i) { | 879 for (int i = 0; i < 16; ++i) { |
| 864 blink::WebArrayBuffer key_bytes; | 880 blink::WebArrayBuffer key_bytes; |
| 865 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 881 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 866 blink::WebCryptoAlgorithm algorithm = | 882 blink::WebCryptoAlgorithm algorithm = |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 912 EXPECT_STATUS(Status::ErrorMissingAlgorithmImportRawKey(), | 928 EXPECT_STATUS(Status::ErrorMissingAlgorithmImportRawKey(), |
| 913 ImportKey(blink::WebCryptoKeyFormatRaw, | 929 ImportKey(blink::WebCryptoKeyFormatRaw, |
| 914 CryptoData(HexStringToBytes("00000000000000000000")), | 930 CryptoData(HexStringToBytes("00000000000000000000")), |
| 915 blink::WebCryptoAlgorithm::createNull(), | 931 blink::WebCryptoAlgorithm::createNull(), |
| 916 true, | 932 true, |
| 917 blink::WebCryptoKeyUsageEncrypt, | 933 blink::WebCryptoKeyUsageEncrypt, |
| 918 &key)); | 934 &key)); |
| 919 } | 935 } |
| 920 | 936 |
| 921 TEST_F(SharedCryptoTest, ImportJwkFailures) { | 937 TEST_F(SharedCryptoTest, ImportJwkFailures) { |
| 922 | |
| 923 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 938 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 924 blink::WebCryptoAlgorithm algorithm = | 939 blink::WebCryptoAlgorithm algorithm = |
| 925 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | 940 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
| 926 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; | 941 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; |
| 927 | 942 |
| 928 // Baseline pass: each test below breaks a single item, so we start with a | 943 // Baseline pass: each test below breaks a single item, so we start with a |
| 929 // passing case to make sure each failure is caused by the isolated break. | 944 // passing case to make sure each failure is caused by the isolated break. |
| 930 // Each breaking subtest below resets the dictionary to this passing case when | 945 // Each breaking subtest below resets the dictionary to this passing case when |
| 931 // complete. | 946 // complete. |
| 932 base::DictionaryValue dict; | 947 base::DictionaryValue dict; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 998 RestoreJwkOctDictionary(&dict); | 1013 RestoreJwkOctDictionary(&dict); |
| 999 | 1014 |
| 1000 // Fail on invalid extractable (wrong type). | 1015 // Fail on invalid extractable (wrong type). |
| 1001 dict.SetInteger("extractable", 0); | 1016 dict.SetInteger("extractable", 0); |
| 1002 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("extractable", "boolean"), | 1017 EXPECT_STATUS(Status::ErrorJwkPropertyWrongType("extractable", "boolean"), |
| 1003 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1018 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 1004 RestoreJwkOctDictionary(&dict); | 1019 RestoreJwkOctDictionary(&dict); |
| 1005 } | 1020 } |
| 1006 | 1021 |
| 1007 TEST_F(SharedCryptoTest, ImportJwkOctFailures) { | 1022 TEST_F(SharedCryptoTest, ImportJwkOctFailures) { |
| 1008 | |
| 1009 base::DictionaryValue dict; | 1023 base::DictionaryValue dict; |
| 1010 RestoreJwkOctDictionary(&dict); | 1024 RestoreJwkOctDictionary(&dict); |
| 1011 blink::WebCryptoAlgorithm algorithm = | 1025 blink::WebCryptoAlgorithm algorithm = |
| 1012 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); | 1026 CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc); |
| 1013 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; | 1027 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; |
| 1014 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1028 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 1015 | 1029 |
| 1016 // Baseline pass. | 1030 // Baseline pass. |
| 1017 EXPECT_STATUS_SUCCESS( | 1031 EXPECT_STATUS_SUCCESS( |
| 1018 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1032 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1050 | 1064 |
| 1051 // Fail on k actual length (192 bits) inconsistent with the embedded JWK alg | 1065 // Fail on k actual length (192 bits) inconsistent with the embedded JWK alg |
| 1052 // value (128) for an AES key. | 1066 // value (128) for an AES key. |
| 1053 dict.SetString("k", "dGhpcyAgaXMgIDI0ICBieXRlcyBsb25n"); | 1067 dict.SetString("k", "dGhpcyAgaXMgIDI0ICBieXRlcyBsb25n"); |
| 1054 EXPECT_STATUS(Status::ErrorJwkIncorrectKeyLength(), | 1068 EXPECT_STATUS(Status::ErrorJwkIncorrectKeyLength(), |
| 1055 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1069 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 1056 RestoreJwkOctDictionary(&dict); | 1070 RestoreJwkOctDictionary(&dict); |
| 1057 } | 1071 } |
| 1058 | 1072 |
| 1059 TEST_F(SharedCryptoTest, MAYBE(ImportJwkRsaFailures)) { | 1073 TEST_F(SharedCryptoTest, MAYBE(ImportJwkRsaFailures)) { |
| 1060 | |
| 1061 base::DictionaryValue dict; | 1074 base::DictionaryValue dict; |
| 1062 RestoreJwkRsaDictionary(&dict); | 1075 RestoreJwkRsaDictionary(&dict); |
| 1063 blink::WebCryptoAlgorithm algorithm = | 1076 blink::WebCryptoAlgorithm algorithm = |
| 1064 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); | 1077 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
| 1065 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; | 1078 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageEncrypt; |
| 1066 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1079 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 1067 | 1080 |
| 1068 // An RSA public key JWK _must_ have an "n" (modulus) and an "e" (exponent) | 1081 // An RSA public key JWK _must_ have an "n" (modulus) and an "e" (exponent) |
| 1069 // entry, while an RSA private key must have those plus at least a "d" | 1082 // entry, while an RSA private key must have those plus at least a "d" |
| 1070 // (private exponent) entry. | 1083 // (private exponent) entry. |
| 1071 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18, | 1084 // See http://tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-18, |
| 1072 // section 6.3. | 1085 // section 6.3. |
| 1073 | 1086 |
| 1074 // Baseline pass. | 1087 // Baseline pass. |
| 1075 EXPECT_STATUS_SUCCESS( | 1088 EXPECT_STATUS_SUCCESS( |
| 1076 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1089 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 1077 EXPECT_EQ(algorithm.id(), key.algorithm().id()); | 1090 EXPECT_EQ(algorithm.id(), key.algorithm().id()); |
| 1078 EXPECT_FALSE(key.extractable()); | 1091 EXPECT_FALSE(key.extractable()); |
| 1079 EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages()); | 1092 EXPECT_EQ(blink::WebCryptoKeyUsageEncrypt, key.usages()); |
| 1080 EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type()); | 1093 EXPECT_EQ(blink::WebCryptoKeyTypePublic, key.type()); |
| 1081 | 1094 |
| 1082 // The following are specific failure cases for when kty = "RSA". | 1095 // The following are specific failure cases for when kty = "RSA". |
| 1083 | 1096 |
| 1084 // Fail if either "n" or "e" is not present or malformed. | 1097 // Fail if either "n" or "e" is not present or malformed. |
| 1085 const std::string kKtyParmName[] = {"n", "e"}; | 1098 const std::string kKtyParmName[] = {"n", "e"}; |
| 1086 for (size_t idx = 0; idx < ARRAYSIZE_UNSAFE(kKtyParmName); ++idx) { | 1099 for (size_t idx = 0; idx < ARRAYSIZE_UNSAFE(kKtyParmName); ++idx) { |
| 1087 | |
| 1088 // Fail on missing parameter. | 1100 // Fail on missing parameter. |
| 1089 dict.Remove(kKtyParmName[idx], NULL); | 1101 dict.Remove(kKtyParmName[idx], NULL); |
| 1090 EXPECT_STATUS_ERROR( | 1102 EXPECT_STATUS_ERROR( |
| 1091 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1103 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| 1092 RestoreJwkRsaDictionary(&dict); | 1104 RestoreJwkRsaDictionary(&dict); |
| 1093 | 1105 |
| 1094 // Fail on bad b64 parameter encoding. | 1106 // Fail on bad b64 parameter encoding. |
| 1095 dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0"); | 1107 dict.SetString(kKtyParmName[idx], "Qk3f0DsytU8lfza2au #$% Htaw2xpop9yTuH0"); |
| 1096 EXPECT_STATUS_ERROR( | 1108 EXPECT_STATUS_ERROR( |
| 1097 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); | 1109 ImportKeyJwkFromDict(dict, algorithm, false, usage_mask, &key)); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1226 ImportKeyJwk( | 1238 ImportKeyJwk( |
| 1227 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); | 1239 CryptoData(json_vec), algorithm, extractable, usage_mask, &key)); |
| 1228 | 1240 |
| 1229 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, | 1241 // TODO(padolph): kty vs alg consistency tests: Depending on the kty value, |
| 1230 // only certain alg values are permitted. For example, when kty = "RSA" alg | 1242 // only certain alg values are permitted. For example, when kty = "RSA" alg |
| 1231 // must be of the RSA family, or when kty = "oct" alg must be symmetric | 1243 // must be of the RSA family, or when kty = "oct" alg must be symmetric |
| 1232 // algorithm. | 1244 // algorithm. |
| 1233 } | 1245 } |
| 1234 | 1246 |
| 1235 TEST_F(SharedCryptoTest, MAYBE(ImportJwkHappy)) { | 1247 TEST_F(SharedCryptoTest, MAYBE(ImportJwkHappy)) { |
| 1236 | |
| 1237 // This test verifies the happy path of JWK import, including the application | 1248 // This test verifies the happy path of JWK import, including the application |
| 1238 // of the imported key material. | 1249 // of the imported key material. |
| 1239 | 1250 |
| 1240 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); | 1251 blink::WebCryptoKey key = blink::WebCryptoKey::createNull(); |
| 1241 bool extractable = false; | 1252 bool extractable = false; |
| 1242 blink::WebCryptoAlgorithm algorithm = | 1253 blink::WebCryptoAlgorithm algorithm = |
| 1243 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); | 1254 CreateHmacImportAlgorithm(blink::WebCryptoAlgorithmIdSha256); |
| 1244 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; | 1255 blink::WebCryptoKeyUsageMask usage_mask = blink::WebCryptoKeyUsageSign; |
| 1245 | 1256 |
| 1246 // Import a symmetric key JWK and HMAC-SHA256 sign() | 1257 // Import a symmetric key JWK and HMAC-SHA256 sign() |
| (...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2472 wrapping_algorithm, | 2483 wrapping_algorithm, |
| 2473 key_algorithm, | 2484 key_algorithm, |
| 2474 true, | 2485 true, |
| 2475 blink::WebCryptoKeyUsageSign, | 2486 blink::WebCryptoKeyUsageSign, |
| 2476 &unwrapped_key)); | 2487 &unwrapped_key)); |
| 2477 } | 2488 } |
| 2478 | 2489 |
| 2479 } // namespace webcrypto | 2490 } // namespace webcrypto |
| 2480 | 2491 |
| 2481 } // namespace content | 2492 } // namespace content |
| OLD | NEW |