| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "webcrypto_impl.h" | 5 #include "webcrypto_impl.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "content/public/renderer/content_renderer_client.h" | 11 #include "content/public/renderer/content_renderer_client.h" |
| 12 #include "content/renderer/renderer_webkitplatformsupport_impl.h" | 12 #include "content/renderer/renderer_webkitplatformsupport_impl.h" |
| 13 #include "content/renderer/webcrypto/webcrypto_impl.h" | 13 #include "content/renderer/webcrypto/webcrypto_impl.h" |
| 14 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
| 15 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" | 15 #include "third_party/WebKit/public/platform/WebArrayBuffer.h" |
| 16 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" | 16 #include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
| 17 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 17 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 WebKit::WebCryptoKey NullKey() { |
| 22 // TODO(eroman): Expose this in Blink instead. |
| 23 return WebKit::WebCryptoKey::create(NULL, WebKit::WebCryptoKeyTypeSecret, |
| 24 false, |
| 25 WebKit::WebCryptoAlgorithm::createNull(), |
| 26 0); |
| 27 } |
| 28 |
| 21 std::vector<uint8> HexStringToBytes(const std::string& hex) { | 29 std::vector<uint8> HexStringToBytes(const std::string& hex) { |
| 22 std::vector<uint8> bytes; | 30 std::vector<uint8> bytes; |
| 23 base::HexStringToBytes(hex, &bytes); | 31 base::HexStringToBytes(hex, &bytes); |
| 24 return bytes; | 32 return bytes; |
| 25 } | 33 } |
| 26 | 34 |
| 27 void ExpectArrayBufferMatchesHex(const std::string& expected_hex, | 35 void ExpectArrayBufferMatchesHex(const std::string& expected_hex, |
| 28 const WebKit::WebArrayBuffer& array_buffer) { | 36 const WebKit::WebArrayBuffer& array_buffer) { |
| 29 EXPECT_STRCASEEQ( | 37 EXPECT_STRCASEEQ( |
| 30 expected_hex.c_str(), | 38 expected_hex.c_str(), |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 } // namespace | 88 } // namespace |
| 81 | 89 |
| 82 namespace content { | 90 namespace content { |
| 83 | 91 |
| 84 class WebCryptoImplTest : public testing::Test { | 92 class WebCryptoImplTest : public testing::Test { |
| 85 protected: | 93 protected: |
| 86 WebKit::WebCryptoKey ImportSecretKeyFromRawHexString( | 94 WebKit::WebCryptoKey ImportSecretKeyFromRawHexString( |
| 87 const std::string& key_hex, | 95 const std::string& key_hex, |
| 88 const WebKit::WebCryptoAlgorithm& algorithm, | 96 const WebKit::WebCryptoAlgorithm& algorithm, |
| 89 WebKit::WebCryptoKeyUsageMask usage) { | 97 WebKit::WebCryptoKeyUsageMask usage) { |
| 90 WebKit::WebCryptoKeyType type; | |
| 91 scoped_ptr<WebKit::WebCryptoKeyHandle> handle; | |
| 92 | |
| 93 std::vector<uint8> key_raw = HexStringToBytes(key_hex); | 98 std::vector<uint8> key_raw = HexStringToBytes(key_hex); |
| 94 | 99 |
| 100 WebKit::WebCryptoKey key = NullKey(); |
| 101 bool extractable = true; |
| 95 EXPECT_TRUE(crypto_.ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw, | 102 EXPECT_TRUE(crypto_.ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw, |
| 96 Start(key_raw), | 103 Start(key_raw), |
| 97 key_raw.size(), | 104 key_raw.size(), |
| 98 algorithm, | 105 algorithm, |
| 106 extractable, |
| 99 usage, | 107 usage, |
| 100 &handle, | 108 &key)); |
| 101 &type)); | |
| 102 | 109 |
| 103 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, type); | 110 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); |
| 104 EXPECT_TRUE(handle.get()); | 111 EXPECT_TRUE(key.handle()); |
| 105 | 112 return key; |
| 106 return WebKit::WebCryptoKey::create( | |
| 107 handle.release(), type, false, algorithm, usage); | |
| 108 } | 113 } |
| 109 | 114 |
| 110 // Forwarding methods to gain access to protected methods of | 115 // Forwarding methods to gain access to protected methods of |
| 111 // WebCryptoImpl. | 116 // WebCryptoImpl. |
| 112 | 117 |
| 113 bool DigestInternal( | 118 bool DigestInternal( |
| 114 const WebKit::WebCryptoAlgorithm& algorithm, | 119 const WebKit::WebCryptoAlgorithm& algorithm, |
| 115 const std::vector<uint8>& data, | 120 const std::vector<uint8>& data, |
| 116 WebKit::WebArrayBuffer* buffer) { | 121 WebKit::WebArrayBuffer* buffer) { |
| 117 return crypto_.DigestInternal(algorithm, Start(data), data.size(), buffer); | 122 return crypto_.DigestInternal(algorithm, Start(data), data.size(), buffer); |
| 118 } | 123 } |
| 119 | 124 |
| 120 bool GenerateKeyInternal( | 125 bool GenerateKeyInternal( |
| 121 const WebKit::WebCryptoAlgorithm& algorithm, | 126 const WebKit::WebCryptoAlgorithm& algorithm, |
| 122 scoped_ptr<WebKit::WebCryptoKeyHandle>* handle, | 127 WebKit::WebCryptoKey* key) { |
| 123 WebKit::WebCryptoKeyType* type) { | 128 bool extractable = true; |
| 124 return crypto_.GenerateKeyInternal(algorithm, handle, type); | 129 WebKit::WebCryptoKeyUsageMask usage_mask = 0; |
| 130 return crypto_.GenerateKeyInternal(algorithm, extractable, usage_mask, key); |
| 125 } | 131 } |
| 126 | 132 |
| 127 bool ImportKeyInternal( | 133 bool ImportKeyInternal( |
| 128 WebKit::WebCryptoKeyFormat format, | 134 WebKit::WebCryptoKeyFormat format, |
| 129 const std::vector<uint8>& key_data, | 135 const std::vector<uint8>& key_data, |
| 130 const WebKit::WebCryptoAlgorithm& algorithm, | 136 const WebKit::WebCryptoAlgorithm& algorithm, |
| 131 WebKit::WebCryptoKeyUsageMask usage_mask, | 137 WebKit::WebCryptoKeyUsageMask usage_mask, |
| 132 scoped_ptr<WebKit::WebCryptoKeyHandle>* handle, | 138 WebKit::WebCryptoKey* key) { |
| 133 WebKit::WebCryptoKeyType* type) { | 139 bool extractable = true; |
| 134 return crypto_.ImportKeyInternal(format, | 140 return crypto_.ImportKeyInternal(format, |
| 135 Start(key_data), | 141 Start(key_data), |
| 136 key_data.size(), | 142 key_data.size(), |
| 137 algorithm, | 143 algorithm, |
| 144 extractable, |
| 138 usage_mask, | 145 usage_mask, |
| 139 handle, | 146 key); |
| 140 type); | |
| 141 } | 147 } |
| 142 | 148 |
| 143 bool SignInternal( | 149 bool SignInternal( |
| 144 const WebKit::WebCryptoAlgorithm& algorithm, | 150 const WebKit::WebCryptoAlgorithm& algorithm, |
| 145 const WebKit::WebCryptoKey& key, | 151 const WebKit::WebCryptoKey& key, |
| 146 const std::vector<uint8>& data, | 152 const std::vector<uint8>& data, |
| 147 WebKit::WebArrayBuffer* buffer) { | 153 WebKit::WebArrayBuffer* buffer) { |
| 148 return crypto_.SignInternal( | 154 return crypto_.SignInternal( |
| 149 algorithm, key, Start(data), data.size(), buffer); | 155 algorithm, key, Start(data), data.size(), buffer); |
| 150 } | 156 } |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 unsigned input_len = INT_MAX - 3; | 471 unsigned input_len = INT_MAX - 3; |
| 466 | 472 |
| 467 EXPECT_FALSE(EncryptInternal( | 473 EXPECT_FALSE(EncryptInternal( |
| 468 CreateAesCbcAlgorithm(iv), key, input, input_len, &output)); | 474 CreateAesCbcAlgorithm(iv), key, input, input_len, &output)); |
| 469 EXPECT_FALSE(DecryptInternal( | 475 EXPECT_FALSE(DecryptInternal( |
| 470 CreateAesCbcAlgorithm(iv), key, input, input_len, &output)); | 476 CreateAesCbcAlgorithm(iv), key, input, input_len, &output)); |
| 471 } | 477 } |
| 472 | 478 |
| 473 // Fail importing the key (too few bytes specified) | 479 // Fail importing the key (too few bytes specified) |
| 474 { | 480 { |
| 475 WebKit::WebCryptoKeyType type; | |
| 476 scoped_ptr<WebKit::WebCryptoKeyHandle> handle; | |
| 477 | |
| 478 std::vector<uint8> key_raw(1); | 481 std::vector<uint8> key_raw(1); |
| 479 std::vector<uint8> iv(16); | 482 std::vector<uint8> iv(16); |
| 480 | 483 |
| 484 WebKit::WebCryptoKey key = NullKey(); |
| 481 EXPECT_FALSE(ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw, | 485 EXPECT_FALSE(ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw, |
| 482 key_raw, | 486 key_raw, |
| 483 CreateAesCbcAlgorithm(iv), | 487 CreateAesCbcAlgorithm(iv), |
| 484 WebKit::WebCryptoKeyUsageDecrypt, | 488 WebKit::WebCryptoKeyUsageDecrypt, |
| 485 &handle, | 489 &key)); |
| 486 &type)); | |
| 487 } | 490 } |
| 488 } | 491 } |
| 489 | 492 |
| 493 |
| 490 TEST_F(WebCryptoImplTest, AesCbcSampleSets) { | 494 TEST_F(WebCryptoImplTest, AesCbcSampleSets) { |
| 491 struct TestCase { | 495 struct TestCase { |
| 492 const char* key; | 496 const char* key; |
| 493 const char* iv; | 497 const char* iv; |
| 494 const char* plain_text; | 498 const char* plain_text; |
| 495 const char* cipher_text; | 499 const char* cipher_text; |
| 496 }; | 500 }; |
| 497 | 501 |
| 498 TestCase kTests[] = { | 502 TestCase kTests[] = { |
| 499 // F.2.1 (CBC-AES128.Encrypt) | 503 // F.2.1 (CBC-AES128.Encrypt) |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 cipher_text.size() - 3, | 619 cipher_text.size() - 3, |
| 616 &output)); | 620 &output)); |
| 617 } | 621 } |
| 618 } | 622 } |
| 619 } | 623 } |
| 620 | 624 |
| 621 // TODO (padolph): Add test to verify generated symmetric keys appear random. | 625 // TODO (padolph): Add test to verify generated symmetric keys appear random. |
| 622 | 626 |
| 623 | 627 |
| 624 TEST_F(WebCryptoImplTest, GenerateKeyAes) { | 628 TEST_F(WebCryptoImplTest, GenerateKeyAes) { |
| 625 scoped_ptr<WebKit::WebCryptoKeyHandle> result; | 629 WebKit::WebCryptoKey key = NullKey(); |
| 626 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic; | 630 ASSERT_TRUE(GenerateKeyInternal(CreateAesCbcAlgorithm(128), &key)); |
| 627 ASSERT_TRUE(GenerateKeyInternal(CreateAesCbcAlgorithm(128), &result, &type)); | 631 EXPECT_TRUE(key.handle()); |
| 628 EXPECT_TRUE(result); | 632 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); |
| 629 EXPECT_EQ(type, WebKit::WebCryptoKeyTypeSecret); | |
| 630 } | 633 } |
| 631 | 634 |
| 632 TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) { | 635 TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) { |
| 633 scoped_ptr<WebKit::WebCryptoKeyHandle> result; | 636 WebKit::WebCryptoKey key = NullKey(); |
| 634 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic; | 637 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(0), &key)); |
| 635 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(0), &result, &type)); | 638 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(129), &key)); |
| 636 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(129), &result, &type)); | |
| 637 } | 639 } |
| 638 | 640 |
| 639 TEST_F(WebCryptoImplTest, GenerateKeyHmac) { | 641 TEST_F(WebCryptoImplTest, GenerateKeyHmac) { |
| 640 scoped_ptr<WebKit::WebCryptoKeyHandle> result; | 642 WebKit::WebCryptoKey key = NullKey(); |
| 641 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic; | |
| 642 WebKit::WebCryptoAlgorithm algorithm = | 643 WebKit::WebCryptoAlgorithm algorithm = |
| 643 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 128); | 644 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 128); |
| 644 ASSERT_TRUE(GenerateKeyInternal(algorithm, &result, &type)); | 645 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key)); |
| 645 EXPECT_TRUE(result); | 646 EXPECT_TRUE(key.handle()); |
| 646 EXPECT_EQ(type, WebKit::WebCryptoKeyTypeSecret); | 647 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); |
| 647 } | 648 } |
| 648 | 649 |
| 649 TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) { | 650 TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) { |
| 650 scoped_ptr<WebKit::WebCryptoKeyHandle> result; | 651 WebKit::WebCryptoKey key = NullKey(); |
| 651 WebKit::WebCryptoKeyType type = WebKit::WebCryptoKeyTypePublic; | |
| 652 WebKit::WebCryptoAlgorithm algorithm = | 652 WebKit::WebCryptoAlgorithm algorithm = |
| 653 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 0); | 653 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 0); |
| 654 ASSERT_TRUE(GenerateKeyInternal(algorithm, &result, &type)); | 654 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key)); |
| 655 EXPECT_TRUE(result); | 655 EXPECT_TRUE(key.handle()); |
| 656 EXPECT_EQ(type, WebKit::WebCryptoKeyTypeSecret); | 656 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); |
| 657 } |
| 658 |
| 659 TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) { |
| 660 WebKit::WebCryptoKey key = NullKey(); |
| 661 |
| 662 // This fails because the algorithm is null. |
| 663 EXPECT_FALSE(ImportKeyInternal( |
| 664 WebKit::WebCryptoKeyFormatRaw, |
| 665 HexStringToBytes("00000000000000000000"), |
| 666 WebKit::WebCryptoAlgorithm::createNull(), |
| 667 WebKit::WebCryptoKeyUsageSign, |
| 668 &key)); |
| 657 } | 669 } |
| 658 | 670 |
| 659 } // namespace content | 671 } // namespace content |
| OLD | NEW |