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