Chromium Code Reviews| 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 "content/renderer/webcrypto/webcrypto_impl.h" | 5 #include "content/renderer/webcrypto/webcrypto_impl.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 146 WebKit::WebCryptoKey* public_key, | 146 WebKit::WebCryptoKey* public_key, |
| 147 WebKit::WebCryptoKey* private_key) { | 147 WebKit::WebCryptoKey* private_key) { |
| 148 return crypto_.GenerateKeyPairInternal( | 148 return crypto_.GenerateKeyPairInternal( |
| 149 algorithm, extractable, usage_mask, public_key, private_key); | 149 algorithm, extractable, usage_mask, public_key, private_key); |
| 150 } | 150 } |
| 151 | 151 |
| 152 bool ImportKeyInternal( | 152 bool ImportKeyInternal( |
| 153 WebKit::WebCryptoKeyFormat format, | 153 WebKit::WebCryptoKeyFormat format, |
| 154 const std::vector<uint8>& key_data, | 154 const std::vector<uint8>& key_data, |
| 155 const WebKit::WebCryptoAlgorithm& algorithm, | 155 const WebKit::WebCryptoAlgorithm& algorithm, |
| 156 bool extractable, | |
| 156 WebKit::WebCryptoKeyUsageMask usage_mask, | 157 WebKit::WebCryptoKeyUsageMask usage_mask, |
| 157 WebKit::WebCryptoKey* key) { | 158 WebKit::WebCryptoKey* key) { |
| 158 bool extractable = true; | |
| 159 return crypto_.ImportKeyInternal(format, | 159 return crypto_.ImportKeyInternal(format, |
| 160 Start(key_data), | 160 Start(key_data), |
| 161 key_data.size(), | 161 key_data.size(), |
| 162 algorithm, | 162 algorithm, |
| 163 extractable, | 163 extractable, |
| 164 usage_mask, | 164 usage_mask, |
| 165 key); | 165 key); |
| 166 } | 166 } |
| 167 | 167 |
| 168 bool ExportKeyInternal( | |
| 169 WebKit::WebCryptoKeyFormat format, | |
| 170 const WebKit::WebCryptoKey& key, | |
| 171 WebKit::WebArrayBuffer* buffer) { | |
| 172 return crypto_.ExportKeyInternal( | |
| 173 format, key, buffer); | |
|
eroman
2013/11/06 23:48:40
this should fit on one line.
padolph
2013/11/07 00:23:50
Done.
| |
| 174 } | |
| 175 | |
| 168 bool SignInternal( | 176 bool SignInternal( |
| 169 const WebKit::WebCryptoAlgorithm& algorithm, | 177 const WebKit::WebCryptoAlgorithm& algorithm, |
| 170 const WebKit::WebCryptoKey& key, | 178 const WebKit::WebCryptoKey& key, |
| 171 const std::vector<uint8>& data, | 179 const std::vector<uint8>& data, |
| 172 WebKit::WebArrayBuffer* buffer) { | 180 WebKit::WebArrayBuffer* buffer) { |
| 173 return crypto_.SignInternal( | 181 return crypto_.SignInternal( |
| 174 algorithm, key, Start(data), data.size(), buffer); | 182 algorithm, key, Start(data), data.size(), buffer); |
| 175 } | 183 } |
| 176 | 184 |
| 177 bool VerifySignatureInternal( | 185 bool VerifySignatureInternal( |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 | 505 |
| 498 // Fail importing the key (too few bytes specified) | 506 // Fail importing the key (too few bytes specified) |
| 499 { | 507 { |
| 500 std::vector<uint8> key_raw(1); | 508 std::vector<uint8> key_raw(1); |
| 501 std::vector<uint8> iv(16); | 509 std::vector<uint8> iv(16); |
| 502 | 510 |
| 503 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); | 511 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); |
| 504 EXPECT_FALSE(ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw, | 512 EXPECT_FALSE(ImportKeyInternal(WebKit::WebCryptoKeyFormatRaw, |
| 505 key_raw, | 513 key_raw, |
| 506 CreateAesCbcAlgorithm(iv), | 514 CreateAesCbcAlgorithm(iv), |
| 515 true, | |
| 507 WebKit::WebCryptoKeyUsageDecrypt, | 516 WebKit::WebCryptoKeyUsageDecrypt, |
| 508 &key)); | 517 &key)); |
| 509 } | 518 } |
| 519 | |
| 520 // Fail exporting the key in SPKI format (SPKI export not allowed for secret | |
| 521 // keys) | |
| 522 EXPECT_FALSE(ExportKeyInternal(WebKit::WebCryptoKeyFormatSpki, key, &output)); | |
| 510 } | 523 } |
| 511 | 524 |
| 512 TEST_F(WebCryptoImplTest, AesCbcSampleSets) { | 525 TEST_F(WebCryptoImplTest, AesCbcSampleSets) { |
| 513 struct TestCase { | 526 struct TestCase { |
| 514 const char* key; | 527 const char* key; |
| 515 const char* iv; | 528 const char* iv; |
| 516 const char* plain_text; | 529 const char* plain_text; |
| 517 const char* cipher_text; | 530 const char* cipher_text; |
| 518 }; | 531 }; |
| 519 | 532 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 675 } | 688 } |
| 676 | 689 |
| 677 TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) { | 690 TEST_F(WebCryptoImplTest, ImportSecretKeyNoAlgorithm) { |
| 678 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); | 691 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); |
| 679 | 692 |
| 680 // This fails because the algorithm is null. | 693 // This fails because the algorithm is null. |
| 681 EXPECT_FALSE(ImportKeyInternal( | 694 EXPECT_FALSE(ImportKeyInternal( |
| 682 WebKit::WebCryptoKeyFormatRaw, | 695 WebKit::WebCryptoKeyFormatRaw, |
| 683 HexStringToBytes("00000000000000000000"), | 696 HexStringToBytes("00000000000000000000"), |
| 684 WebKit::WebCryptoAlgorithm::createNull(), | 697 WebKit::WebCryptoAlgorithm::createNull(), |
| 698 true, | |
| 685 WebKit::WebCryptoKeyUsageSign, | 699 WebKit::WebCryptoKeyUsageSign, |
| 686 &key)); | 700 &key)); |
| 687 } | 701 } |
| 688 | 702 |
| 689 #if !defined(USE_OPENSSL) | 703 #if !defined(USE_OPENSSL) |
| 690 | 704 |
| 705 TEST_F(WebCryptoImplTest, ImportExportSpki) { | |
| 706 // openssl genrsa -out pair.pem 2048 | |
| 707 // openssl rsa -in pair.pem -out pubkey.der -outform DER -pubout | |
| 708 // xxd -p pubkey.der | |
| 709 const std::string hex_rsa_spki_der = | |
| 710 "30820122300d06092a864886f70d01010105000382010f003082010a0282" | |
| 711 "010100f19e40f94e3780858701577a571cca000cb9795db89ddf8e98ab0e" | |
| 712 "5eecfa47516cb08dc591cae5ab7fa43d6db402e95991d4a2de52e7cd3a66" | |
| 713 "4f58284be2eb4675d5a849a2582c585d2b3c6c225a8f2c53a0414d5dbd06" | |
| 714 "172371cefdf953e9ec3000fc9ad000743023f74e82d12aa93917a2c9b832" | |
| 715 "696085ee0711154cf98a6d098f44cee00ea3b7584236503a5483ba8b6792" | |
| 716 "fee588d1a8f4a0618333c4cb3447d760b43d5a0d9ed6ef79763df670cd8b" | |
| 717 "5eb869a20833f1e3e6d8b88240a5d4335c73fd20487f2a7d112af8692357" | |
| 718 "6425e44a273e5ad2e93d6b50a28e65f9e133958e4f0c7d12e0adc90fedd4" | |
| 719 "f6b6848e7b6900666642a08b520a6534a35d4f0203010001"; | |
| 720 | |
| 721 // Passing case: Import a valid RSA key in SPKI format. | |
| 722 WebKit::WebCryptoKey key = WebKit::WebCryptoKey::createNull(); | |
| 723 ASSERT_TRUE(ImportKeyInternal( | |
| 724 WebKit::WebCryptoKeyFormatSpki, | |
| 725 HexStringToBytes(hex_rsa_spki_der), | |
| 726 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), | |
| 727 true, | |
| 728 WebKit::WebCryptoKeyUsageEncrypt, | |
| 729 &key)); | |
| 730 EXPECT_TRUE(key.handle()); | |
| 731 EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, key.type()); | |
| 732 EXPECT_TRUE(key.extractable()); | |
| 733 EXPECT_EQ(WebKit::WebCryptoKeyUsageEncrypt, key.usages()); | |
| 734 | |
| 735 // Failing case: Import RSA key with NULL input algorithm. This is not | |
| 736 // allowed because the SPKI ASN.1 format for RSA keys is not specific enough | |
| 737 // to map to a Web Crypto algorithm. | |
| 738 EXPECT_FALSE(ImportKeyInternal( | |
| 739 WebKit::WebCryptoKeyFormatSpki, | |
| 740 HexStringToBytes(hex_rsa_spki_der), | |
| 741 WebKit::WebCryptoAlgorithm::createNull(), | |
| 742 true, | |
| 743 WebKit::WebCryptoKeyUsageEncrypt, | |
| 744 &key)); | |
| 745 | |
| 746 // Failing case: Bad DER encoding. | |
| 747 EXPECT_FALSE(ImportKeyInternal( | |
| 748 WebKit::WebCryptoKeyFormatSpki, | |
| 749 HexStringToBytes("618333c4cb"), | |
| 750 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), | |
| 751 true, | |
| 752 WebKit::WebCryptoKeyUsageEncrypt, | |
| 753 &key)); | |
| 754 | |
| 755 // Failing case: Import RSA key but provide an inconsistent input algorithm. | |
| 756 EXPECT_FALSE(ImportKeyInternal( | |
| 757 WebKit::WebCryptoKeyFormatSpki, | |
| 758 HexStringToBytes(hex_rsa_spki_der), | |
| 759 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdAesCbc), | |
| 760 true, | |
| 761 WebKit::WebCryptoKeyUsageEncrypt, | |
| 762 &key)); | |
| 763 | |
| 764 // Passing case: Export a previously imported RSA public key in SPKI format | |
| 765 // and compare to original data. | |
| 766 WebKit::WebArrayBuffer output; | |
| 767 ASSERT_TRUE(ExportKeyInternal(WebKit::WebCryptoKeyFormatSpki, key, &output)); | |
| 768 ExpectArrayBufferMatchesHex(hex_rsa_spki_der, output); | |
| 769 | |
| 770 // Failing case: Try to export a non-extractable key | |
| 771 ASSERT_TRUE(ImportKeyInternal( | |
| 772 WebKit::WebCryptoKeyFormatSpki, | |
| 773 HexStringToBytes(hex_rsa_spki_der), | |
| 774 CreateAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5), | |
| 775 false, | |
| 776 WebKit::WebCryptoKeyUsageEncrypt, | |
| 777 &key)); | |
| 778 EXPECT_TRUE(key.handle()); | |
| 779 EXPECT_FALSE(key.extractable()); | |
| 780 EXPECT_FALSE(ExportKeyInternal(WebKit::WebCryptoKeyFormatSpki, key, &output)); | |
| 781 | |
| 782 // TODO(padolph): Import a RSA SPKI key and verify it works with an operation. | |
| 783 } | |
| 784 | |
| 691 TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) { | 785 TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) { |
| 692 // Note: using unrealistic short key lengths here to avoid bogging down tests. | 786 // Note: using unrealistic short key lengths here to avoid bogging down tests. |
| 693 | 787 |
| 694 // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation. | 788 // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation. |
| 695 const unsigned modulus_length = 256; | 789 const unsigned modulus_length = 256; |
| 696 const std::vector<uint8> public_exponent = HexStringToBytes("010001"); | 790 const std::vector<uint8> public_exponent = HexStringToBytes("010001"); |
| 697 WebKit::WebCryptoAlgorithm algorithm = | 791 WebKit::WebCryptoAlgorithm algorithm = |
| 698 CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, | 792 CreateRsaAlgorithm(WebKit::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
| 699 modulus_length, | 793 modulus_length, |
| 700 public_exponent); | 794 public_exponent); |
| 701 bool extractable = false; | 795 bool extractable = true; |
| 702 const WebKit::WebCryptoKeyUsageMask usage_mask = 0; | 796 const WebKit::WebCryptoKeyUsageMask usage_mask = 0; |
| 703 WebKit::WebCryptoKey public_key = WebKit::WebCryptoKey::createNull(); | 797 WebKit::WebCryptoKey public_key = WebKit::WebCryptoKey::createNull(); |
| 704 WebKit::WebCryptoKey private_key = WebKit::WebCryptoKey::createNull(); | 798 WebKit::WebCryptoKey private_key = WebKit::WebCryptoKey::createNull(); |
| 705 EXPECT_TRUE(GenerateKeyPairInternal( | 799 EXPECT_TRUE(GenerateKeyPairInternal( |
| 706 algorithm, extractable, usage_mask, &public_key, &private_key)); | 800 algorithm, extractable, usage_mask, &public_key, &private_key)); |
| 707 EXPECT_FALSE(public_key.isNull()); | 801 EXPECT_FALSE(public_key.isNull()); |
| 708 EXPECT_FALSE(private_key.isNull()); | 802 EXPECT_FALSE(private_key.isNull()); |
| 709 EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type()); | 803 EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type()); |
| 710 EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type()); | 804 EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type()); |
| 711 EXPECT_EQ(extractable, public_key.extractable()); | 805 EXPECT_EQ(extractable, public_key.extractable()); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 783 EXPECT_TRUE(GenerateKeyPairInternal( | 877 EXPECT_TRUE(GenerateKeyPairInternal( |
| 784 algorithm, extractable, usage_mask, &public_key, &private_key)); | 878 algorithm, extractable, usage_mask, &public_key, &private_key)); |
| 785 EXPECT_FALSE(public_key.isNull()); | 879 EXPECT_FALSE(public_key.isNull()); |
| 786 EXPECT_FALSE(private_key.isNull()); | 880 EXPECT_FALSE(private_key.isNull()); |
| 787 EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type()); | 881 EXPECT_EQ(WebKit::WebCryptoKeyTypePublic, public_key.type()); |
| 788 EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type()); | 882 EXPECT_EQ(WebKit::WebCryptoKeyTypePrivate, private_key.type()); |
| 789 EXPECT_EQ(extractable, public_key.extractable()); | 883 EXPECT_EQ(extractable, public_key.extractable()); |
| 790 EXPECT_EQ(extractable, private_key.extractable()); | 884 EXPECT_EQ(extractable, private_key.extractable()); |
| 791 EXPECT_EQ(usage_mask, public_key.usages()); | 885 EXPECT_EQ(usage_mask, public_key.usages()); |
| 792 EXPECT_EQ(usage_mask, private_key.usages()); | 886 EXPECT_EQ(usage_mask, private_key.usages()); |
| 887 | |
| 888 // Fail SPKI export of private key. This is an ExportKey test, but do it here | |
| 889 // since it is expensive to generate an RSA key pair and we already have a | |
| 890 // private key here. | |
| 891 WebKit::WebArrayBuffer output; | |
| 892 EXPECT_FALSE( | |
| 893 ExportKeyInternal(WebKit::WebCryptoKeyFormatSpki, private_key, &output)); | |
| 793 } | 894 } |
| 794 | 895 |
| 795 #endif // #if !defined(USE_OPENSSL) | 896 #endif // #if !defined(USE_OPENSSL) |
| 796 | 897 |
| 797 } // namespace content | 898 } // namespace content |
| OLD | NEW |