| 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 #include "third_party/WebKit/public/platform/WebCryptoKey.h" |
| 18 | 19 |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 std::vector<uint8> HexStringToBytes(const std::string& hex) { | 22 std::vector<uint8> HexStringToBytes(const std::string& hex) { |
| 22 std::vector<uint8> bytes; | 23 std::vector<uint8> bytes; |
| 23 base::HexStringToBytes(hex, &bytes); | 24 base::HexStringToBytes(hex, &bytes); |
| 24 return bytes; | 25 return bytes; |
| 25 } | 26 } |
| 26 | 27 |
| 27 void ExpectArrayBufferMatchesHex(const std::string& expected_hex, | 28 void ExpectArrayBufferMatchesHex(const std::string& expected_hex, |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 new WebKit::WebCryptoAesCbcParams(Start(iv), iv.size())); | 71 new WebKit::WebCryptoAesCbcParams(Start(iv), iv.size())); |
| 71 } | 72 } |
| 72 | 73 |
| 73 WebKit::WebCryptoAlgorithm CreateAesCbcAlgorithm( | 74 WebKit::WebCryptoAlgorithm CreateAesCbcAlgorithm( |
| 74 unsigned short key_length_bits) { | 75 unsigned short key_length_bits) { |
| 75 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate( | 76 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate( |
| 76 WebKit::WebCryptoAlgorithmIdAesCbc, | 77 WebKit::WebCryptoAlgorithmIdAesCbc, |
| 77 new WebKit::WebCryptoAesKeyGenParams(key_length_bits)); | 78 new WebKit::WebCryptoAesKeyGenParams(key_length_bits)); |
| 78 } | 79 } |
| 79 | 80 |
| 81 WebKit::WebCryptoAlgorithm CreateRsaAlgorithm( |
| 82 WebKit::WebCryptoAlgorithmId algorithm_id, |
| 83 unsigned modulus_length, |
| 84 const std::vector<uint8>& public_exponent) { |
| 85 DCHECK(algorithm_id == WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || |
| 86 algorithm_id == WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 || |
| 87 algorithm_id == WebKit::WebCryptoAlgorithmIdRsaOaep); |
| 88 return WebKit::WebCryptoAlgorithm::adoptParamsAndCreate( |
| 89 algorithm_id, |
| 90 new WebKit::WebCryptoRsaKeyGenParams( |
| 91 modulus_length, Start(public_exponent), public_exponent.size())); |
| 92 } |
| 93 |
| 80 } // namespace | 94 } // namespace |
| 81 | 95 |
| 82 namespace content { | 96 namespace content { |
| 83 | 97 |
| 84 class WebCryptoImplTest : public testing::Test { | 98 class WebCryptoImplTest : public testing::Test { |
| 85 protected: | 99 protected: |
| 86 WebKit::WebCryptoKey ImportSecretKeyFromRawHexString( | 100 WebKit::WebCryptoKey ImportSecretKeyFromRawHexString( |
| 87 const std::string& key_hex, | 101 const std::string& key_hex, |
| 88 const WebKit::WebCryptoAlgorithm& algorithm, | 102 const WebKit::WebCryptoAlgorithm& algorithm, |
| 89 WebKit::WebCryptoKeyUsageMask usage) { | 103 WebKit::WebCryptoKeyUsageMask usage) { |
| 90 std::vector<uint8> key_raw = HexStringToBytes(key_hex); | 104 std::vector<uint8> key_raw = HexStringToBytes(key_hex); |
| 91 | 105 |
| 92 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); | 106 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); |
| 93 bool extractable = true; | 107 bool extractable = true; |
| 94 EXPECT_TRUE(crypto_.ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw, | 108 EXPECT_TRUE(crypto_.ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw, |
| 95 Start(key_raw), | 109 Start(key_raw), |
| 96 key_raw.size(), | 110 key_raw.size(), |
| 97 algorithm, | 111 algorithm, |
| 98 extractable, | 112 extractable, |
| 99 usage, | 113 usage, |
| 100 &key)); | 114 &key)); |
| 101 | 115 |
| 102 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); | 116 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 115 } | 129 } |
| 116 | 130 |
| 117 bool GenerateKeyInternal( | 131 bool GenerateKeyInternal( |
| 118 const WebKit::WebCryptoAlgorithm& algorithm, | 132 const WebKit::WebCryptoAlgorithm& algorithm, |
| 119 WebKit::WebCryptoKey* key) { | 133 WebKit::WebCryptoKey* key) { |
| 120 bool extractable = true; | 134 bool extractable = true; |
| 121 WebKit::WebCryptoKeyUsageMask usage_mask = 0; | 135 WebKit::WebCryptoKeyUsageMask usage_mask = 0; |
| 122 return crypto_.GenerateKeyInternal(algorithm, extractable, usage_mask, key); | 136 return crypto_.GenerateKeyInternal(algorithm, extractable, usage_mask, key); |
| 123 } | 137 } |
| 124 | 138 |
| 139 bool GenerateKeyPairInternal( |
| 140 const WebKit::WebCryptoAlgorithm& algorithm, |
| 141 bool extractable, |
| 142 WebKit::WebCryptoKeyUsageMask usage_mask, |
| 143 WebKit::WebCryptoKey* public_key, |
| 144 WebKit::WebCryptoKey* private_key) { |
| 145 return crypto_.GenerateKeyPairInternal( |
| 146 algorithm, extractable, usage_mask, public_key, private_key); |
| 147 } |
| 148 |
| 125 bool ImportKeyInternal( | 149 bool ImportKeyInternal( |
| 126 WebKit::WebCryptoKeyFormat format, | 150 WebKit::WebCryptoKeyFormat format, |
| 127 const std::vector<uint8>& key_data, | 151 const std::vector<uint8>& key_data, |
| 128 const WebKit::WebCryptoAlgorithm& algorithm, | 152 const WebKit::WebCryptoAlgorithm& algorithm, |
| 129 WebKit::WebCryptoKeyUsageMask usage_mask, | 153 WebKit::WebCryptoKeyUsageMask usage_mask, |
| 130 WebKit::WebCryptoKey* key) { | 154 WebKit::WebCryptoKey* key) { |
| 131 bool extractable = true; | 155 bool extractable = true; |
| 132 return crypto_.ImportKeyInternal(format, | 156 return crypto_.ImportKeyInternal(format, |
| 133 Start(key_data), | 157 Start(key_data), |
| 134 key_data.size(), | 158 key_data.size(), |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 CreateAesCbcAlgorithm(iv), key, input, input_len, &output)); | 490 CreateAesCbcAlgorithm(iv), key, input, input_len, &output)); |
| 467 EXPECT_FALSE(DecryptInternal( | 491 EXPECT_FALSE(DecryptInternal( |
| 468 CreateAesCbcAlgorithm(iv), key, input, input_len, &output)); | 492 CreateAesCbcAlgorithm(iv), key, input, input_len, &output)); |
| 469 } | 493 } |
| 470 | 494 |
| 471 // Fail importing the key (too few bytes specified) | 495 // Fail importing the key (too few bytes specified) |
| 472 { | 496 { |
| 473 std::vector<uint8> key_raw(1); | 497 std::vector<uint8> key_raw(1); |
| 474 std::vector<uint8> iv(16); | 498 std::vector<uint8> iv(16); |
| 475 | 499 |
| 476 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); | 500 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); |
| 477 EXPECT_FALSE(ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw, | 501 EXPECT_FALSE(ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw, |
| 478 key_raw, | 502 key_raw, |
| 479 CreateAesCbcAlgorithm(iv), | 503 CreateAesCbcAlgorithm(iv), |
| 480 WebKit::WebCryptoKeyUsageDecrypt, | 504 WebKit::WebCryptoKeyUsageDecrypt, |
| 481 &key)); | 505 &key)); |
| 482 } | 506 } |
| 483 } | 507 } |
| 484 | 508 |
| 485 TEST_F(WebCryptoImplTest, AesCbcSampleSets) { | 509 TEST_F(WebCryptoImplTest, AesCbcSampleSets) { |
| 486 struct TestCase { | 510 struct TestCase { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 cipher_text.size() - 3, | 634 cipher_text.size() - 3, |
| 611 &output)); | 635 &output)); |
| 612 } | 636 } |
| 613 } | 637 } |
| 614 } | 638 } |
| 615 | 639 |
| 616 // TODO (padolph): Add test to verify generated symmetric keys appear random. | 640 // TODO (padolph): Add test to verify generated symmetric keys appear random. |
| 617 | 641 |
| 618 | 642 |
| 619 TEST_F(WebCryptoImplTest, GenerateKeyAes) { | 643 TEST_F(WebCryptoImplTest, GenerateKeyAes) { |
| 620 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); | 644 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); |
| 621 ASSERT_TRUE(GenerateKeyInternal(CreateAesCbcAlgorithm(128), &key)); | 645 ASSERT_TRUE(GenerateKeyInternal(CreateAesCbcAlgorithm(128), &key)); |
| 622 EXPECT_TRUE(key.handle()); | 646 EXPECT_TRUE(key.handle()); |
| 623 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); | 647 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); |
| 624 } | 648 } |
| 625 | 649 |
| 626 TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) { | 650 TEST_F(WebCryptoImplTest, GenerateKeyAesBadLength) { |
| 627 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); | 651 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); |
| 628 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(0), &key)); | 652 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(0), &key)); |
| 629 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(129), &key)); | 653 EXPECT_FALSE(GenerateKeyInternal(CreateAesCbcAlgorithm(129), &key)); |
| 630 } | 654 } |
| 631 | 655 |
| 632 TEST_F(WebCryptoImplTest, GenerateKeyHmac) { | 656 TEST_F(WebCryptoImplTest, GenerateKeyHmac) { |
| 633 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); | 657 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); |
| 634 WebKit::WebCryptoAlgorithm algorithm = | 658 WebKit::WebCryptoAlgorithm algorithm = |
| 635 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 128); | 659 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 128); |
| 636 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key)); | 660 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key)); |
| 637 EXPECT_TRUE(key.handle()); | 661 EXPECT_TRUE(key.handle()); |
| 638 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); | 662 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); |
| 639 } | 663 } |
| 640 | 664 |
| 641 TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) { | 665 TEST_F(WebCryptoImplTest, GenerateKeyHmacNoLength) { |
| 642 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); | 666 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); |
| 643 WebKit::WebCryptoAlgorithm algorithm = | 667 WebKit::WebCryptoAlgorithm algorithm = |
| 644 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 0); | 668 CreateHmacKeyAlgorithm(WebKit::WebCryptoAlgorithmIdSha1, 0); |
| 645 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key)); | 669 ASSERT_TRUE(GenerateKeyInternal(algorithm, &key)); |
| 646 EXPECT_TRUE(key.handle()); | 670 EXPECT_TRUE(key.handle()); |
| 647 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); | 671 EXPECT_EQ(WebKit::WebCryptoKeyTypeSecret, key.type()); |
| 648 } | 672 } |
| 649 | 673 |
| 650 TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) { | 674 TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) { |
| 651 WebKit::WebCryptoKey key = WebCryptoImpl::NullKey(); | 675 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); |
| 652 | 676 |
| 653 // This fails because the algorithm is null. | 677 // This fails because the algorithm is null. |
| 654 EXPECT_FALSE(ImportKeyInternal( | 678 EXPECT_FALSE(ImportKeyInternal( |
| 655 WebKit::WebCryptoKeyFormatRaw, | 679 WebKit::WebCryptoKeyFormatRaw, |
| 656 HexStringToBytes("00000000000000000000"), | 680 HexStringToBytes("00000000000000000000"), |
| 657 WebKit::WebCryptoAlgorithm::createNull(), | 681 WebKit::WebCryptoAlgorithm::createNull(), |
| 658 WebKit::WebCryptoKeyUsageSign, | 682 WebKit::WebCryptoKeyUsageSign, |
| 659 &key)); | 683 &key)); |
| 660 } | 684 } |
| 661 | 685 |
| 686 #if !defined(USE_OPENSSL) |
| 687 |
| 688 TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) { |
| 689 |
| 690 // Note: using unrealistic short key lengths here to avoid bogging down tests. |
| 691 |
| 692 // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation. |
| 693 const unsigned modulus_length = 256; |
| 694 const std::vector<uint8> public_exponent = HexStringToBytes("010001"); |
| 695 WebKit::WebCryptoAlgorithm algorithm = |
| 696 CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
| 697 modulus_length, |
| 698 public_exponent); |
| 699 const bool extractable = false; |
| 700 const WebKit::WebCryptoKeyUsageMask usage_mask = 0; |
| 701 WebKit::WebCryptoKey public_key = WebKit::WebCryptoKey::createNull(); |
| 702 WebKit::WebCryptoKey private_key = WebKit::WebCryptoKey::createNull(); |
| 703 EXPECT_TRUE(GenerateKeyPairInternal( |
| 704 algorithm, extractable, usage_mask, &public_key, &private_key)); |
| 705 EXPECT_FALSE(public_key.isNull()); |
| 706 EXPECT_FALSE(private_key.isNull()); |
| 707 EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type()); |
| 708 EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type()); |
| 709 EXPECT_EQ(extractable, public_key.extractable()); |
| 710 EXPECT_EQ(extractable, private_key.extractable()); |
| 711 EXPECT_EQ(usage_mask, public_key.usages()); |
| 712 EXPECT_EQ(usage_mask, private_key.usages()); |
| 713 |
| 714 // Fail with bad modulus. |
| 715 algorithm = CreateRsaAlgorithm( |
| 716 WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, 0, public_exponent); |
| 717 EXPECT_FALSE(GenerateKeyPairInternal( |
| 718 algorithm, extractable, usage_mask, &public_key, &private_key)); |
| 719 |
| 720 // Fail with bad exponent: larger than unsigned long. |
| 721 unsigned exponent_length = sizeof(unsigned long) + 1; |
| 722 const std::vector<uint8> long_exponent(exponent_length, 0x01); |
| 723 algorithm = CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
| 724 modulus_length, |
| 725 long_exponent); |
| 726 EXPECT_FALSE(GenerateKeyPairInternal( |
| 727 algorithm, extractable, usage_mask, &public_key, &private_key)); |
| 728 |
| 729 // Fail with bad exponent: empty. |
| 730 const std::vector<uint8> empty_exponent; |
| 731 algorithm = CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
| 732 modulus_length, |
| 733 empty_exponent); |
| 734 EXPECT_FALSE(GenerateKeyPairInternal( |
| 735 algorithm, extractable, usage_mask, &public_key, &private_key)); |
| 736 |
| 737 // Fail with bad exponent: all zeros. |
| 738 std::vector<uint8> exponent_with_leading_zeros(15, 0x00); |
| 739 algorithm = CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
| 740 modulus_length, |
| 741 exponent_with_leading_zeros); |
| 742 EXPECT_FALSE(GenerateKeyPairInternal( |
| 743 algorithm, extractable, usage_mask, &public_key, &private_key)); |
| 744 |
| 745 // Key generation success using exponent with leading zeros. |
| 746 exponent_with_leading_zeros.insert(exponent_with_leading_zeros.end(), |
| 747 public_exponent.begin(), |
| 748 public_exponent.end()); |
| 749 algorithm = CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
| 750 modulus_length, |
| 751 exponent_with_leading_zeros); |
| 752 EXPECT_TRUE(GenerateKeyPairInternal( |
| 753 algorithm, extractable, usage_mask, &public_key, &private_key)); |
| 754 EXPECT_FALSE(public_key.isNull()); |
| 755 EXPECT_FALSE(private_key.isNull()); |
| 756 EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type()); |
| 757 EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type()); |
| 758 EXPECT_EQ(extractable, public_key.extractable()); |
| 759 EXPECT_EQ(extractable, private_key.extractable()); |
| 760 EXPECT_EQ(usage_mask, public_key.usages()); |
| 761 EXPECT_EQ(usage_mask, private_key.usages()); |
| 762 |
| 763 // Successful WebCryptoAlgorithmIdRsaOaep key generation. |
| 764 algorithm = CreateRsaAlgorithm( |
| 765 WebKit::WebCryptoAlgorithmIdRsaOaep, modulus_length, public_exponent); |
| 766 EXPECT_TRUE(GenerateKeyPairInternal( |
| 767 algorithm, extractable, usage_mask, &public_key, &private_key)); |
| 768 EXPECT_FALSE(public_key.isNull()); |
| 769 EXPECT_FALSE(private_key.isNull()); |
| 770 EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type()); |
| 771 EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type()); |
| 772 EXPECT_EQ(extractable, public_key.extractable()); |
| 773 EXPECT_EQ(extractable, private_key.extractable()); |
| 774 EXPECT_EQ(usage_mask, public_key.usages()); |
| 775 EXPECT_EQ(usage_mask, private_key.usages()); |
| 776 |
| 777 // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation. |
| 778 algorithm = CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, |
| 779 modulus_length, |
| 780 public_exponent); |
| 781 EXPECT_TRUE(GenerateKeyPairInternal( |
| 782 algorithm, extractable, usage_mask, &public_key, &private_key)); |
| 783 EXPECT_FALSE(public_key.isNull()); |
| 784 EXPECT_FALSE(private_key.isNull()); |
| 785 EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type()); |
| 786 EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type()); |
| 787 EXPECT_EQ(extractable, public_key.extractable()); |
| 788 EXPECT_EQ(extractable, private_key.extractable()); |
| 789 EXPECT_EQ(usage_mask, public_key.usages()); |
| 790 EXPECT_EQ(usage_mask, private_key.usages()); |
| 791 } |
| 792 |
| 793 #endif // #if !defined(USE_OPENSSL) |
| 794 |
| 662 } // namespace content | 795 } // namespace content |
| OLD | NEW |