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 <algorithm> |
7 #include <string> | 8 #include <string> |
8 #include <vector> | 9 #include <vector> |
9 | 10 |
10 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "base/memory/ref_counted.h" | 13 #include "base/memory/ref_counted.h" |
13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
14 #include "content/public/renderer/content_renderer_client.h" | 15 #include "content/public/renderer/content_renderer_client.h" |
15 #include "content/renderer/renderer_webkitplatformsupport_impl.h" | 16 #include "content/renderer/renderer_webkitplatformsupport_impl.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 } | 75 } |
75 | 76 |
76 blink::WebCryptoAlgorithm CreateAesCbcAlgorithm( | 77 blink::WebCryptoAlgorithm CreateAesCbcAlgorithm( |
77 unsigned short key_length_bits) { // NOLINT | 78 unsigned short key_length_bits) { // NOLINT |
78 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 79 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
79 blink::WebCryptoAlgorithmIdAesCbc, | 80 blink::WebCryptoAlgorithmIdAesCbc, |
80 new blink::WebCryptoAesKeyGenParams(key_length_bits)); | 81 new blink::WebCryptoAesKeyGenParams(key_length_bits)); |
81 } | 82 } |
82 | 83 |
83 #if !defined(USE_OPENSSL) | 84 #if !defined(USE_OPENSSL) |
84 blink::WebCryptoAlgorithm CreateRsaAlgorithm( | 85 |
| 86 blink::WebCryptoAlgorithm CreateRsaKeyGenAlgorithm( |
85 blink::WebCryptoAlgorithmId algorithm_id, | 87 blink::WebCryptoAlgorithmId algorithm_id, |
86 unsigned modulus_length, | 88 unsigned modulus_length, |
87 const std::vector<uint8>& public_exponent) { | 89 const std::vector<uint8>& public_exponent) { |
88 DCHECK(algorithm_id == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || | 90 DCHECK(algorithm_id == blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5 || |
89 algorithm_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 || | 91 algorithm_id == blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 || |
90 algorithm_id == blink::WebCryptoAlgorithmIdRsaOaep); | 92 algorithm_id == blink::WebCryptoAlgorithmIdRsaOaep); |
91 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 93 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
92 algorithm_id, | 94 algorithm_id, |
93 new blink::WebCryptoRsaKeyGenParams( | 95 new blink::WebCryptoRsaKeyGenParams( |
94 modulus_length, Start(public_exponent), public_exponent.size())); | 96 modulus_length, Start(public_exponent), public_exponent.size())); |
95 } | 97 } |
96 #endif // !defined(USE_OPENSSL) | 98 |
| 99 #endif // #if !defined(USE_OPENSSL) |
97 | 100 |
98 } // namespace | 101 } // namespace |
99 | 102 |
100 namespace content { | 103 namespace content { |
101 | 104 |
102 class WebCryptoImplTest : public testing::Test { | 105 class WebCryptoImplTest : public testing::Test { |
103 protected: | 106 protected: |
104 blink::WebCryptoKey ImportSecretKeyFromRawHexString( | 107 blink::WebCryptoKey ImportSecretKeyFromRawHexString( |
105 const std::string& key_hex, | 108 const std::string& key_hex, |
106 const blink::WebCryptoAlgorithm& algorithm, | 109 const blink::WebCryptoAlgorithm& algorithm, |
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 // TODO(padolph): Use the imported key for a Known Answer Test (KAT). | 875 // TODO(padolph): Use the imported key for a Known Answer Test (KAT). |
873 } | 876 } |
874 | 877 |
875 TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) { | 878 TEST_F(WebCryptoImplTest, GenerateKeyPairRsa) { |
876 // Note: using unrealistic short key lengths here to avoid bogging down tests. | 879 // Note: using unrealistic short key lengths here to avoid bogging down tests. |
877 | 880 |
878 // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation. | 881 // Successful WebCryptoAlgorithmIdRsaEsPkcs1v1_5 key generation. |
879 const unsigned modulus_length = 256; | 882 const unsigned modulus_length = 256; |
880 const std::vector<uint8> public_exponent = HexStringToBytes("010001"); | 883 const std::vector<uint8> public_exponent = HexStringToBytes("010001"); |
881 blink::WebCryptoAlgorithm algorithm = | 884 blink::WebCryptoAlgorithm algorithm = |
882 CreateRsaAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, | 885 CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
883 modulus_length, | 886 modulus_length, |
884 public_exponent); | 887 public_exponent); |
885 bool extractable = true; | 888 bool extractable = true; |
886 const blink::WebCryptoKeyUsageMask usage_mask = 0; | 889 const blink::WebCryptoKeyUsageMask usage_mask = 0; |
887 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); | 890 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
888 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); | 891 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
889 EXPECT_TRUE(GenerateKeyPairInternal( | 892 EXPECT_TRUE(GenerateKeyPairInternal( |
890 algorithm, extractable, usage_mask, &public_key, &private_key)); | 893 algorithm, extractable, usage_mask, &public_key, &private_key)); |
891 EXPECT_FALSE(public_key.isNull()); | 894 EXPECT_FALSE(public_key.isNull()); |
892 EXPECT_FALSE(private_key.isNull()); | 895 EXPECT_FALSE(private_key.isNull()); |
893 EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type()); | 896 EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type()); |
894 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type()); | 897 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type()); |
895 EXPECT_EQ(extractable, public_key.extractable()); | 898 EXPECT_EQ(extractable, public_key.extractable()); |
896 EXPECT_EQ(extractable, private_key.extractable()); | 899 EXPECT_EQ(extractable, private_key.extractable()); |
897 EXPECT_EQ(usage_mask, public_key.usages()); | 900 EXPECT_EQ(usage_mask, public_key.usages()); |
898 EXPECT_EQ(usage_mask, private_key.usages()); | 901 EXPECT_EQ(usage_mask, private_key.usages()); |
899 | 902 |
900 // Fail with bad modulus. | 903 // Fail with bad modulus. |
901 algorithm = CreateRsaAlgorithm( | 904 algorithm = CreateRsaKeyGenAlgorithm( |
902 blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, 0, public_exponent); | 905 blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, 0, public_exponent); |
903 EXPECT_FALSE(GenerateKeyPairInternal( | 906 EXPECT_FALSE(GenerateKeyPairInternal( |
904 algorithm, extractable, usage_mask, &public_key, &private_key)); | 907 algorithm, extractable, usage_mask, &public_key, &private_key)); |
905 | 908 |
906 // Fail with bad exponent: larger than unsigned long. | 909 // Fail with bad exponent: larger than unsigned long. |
907 unsigned exponent_length = sizeof(unsigned long) + 1; // NOLINT | 910 unsigned exponent_length = sizeof(unsigned long) + 1; // NOLINT |
908 const std::vector<uint8> long_exponent(exponent_length, 0x01); | 911 const std::vector<uint8> long_exponent(exponent_length, 0x01); |
909 algorithm = CreateRsaAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, | 912 algorithm = CreateRsaKeyGenAlgorithm( |
910 modulus_length, | 913 blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, modulus_length, long_exponent); |
911 long_exponent); | |
912 EXPECT_FALSE(GenerateKeyPairInternal( | 914 EXPECT_FALSE(GenerateKeyPairInternal( |
913 algorithm, extractable, usage_mask, &public_key, &private_key)); | 915 algorithm, extractable, usage_mask, &public_key, &private_key)); |
914 | 916 |
915 // Fail with bad exponent: empty. | 917 // Fail with bad exponent: empty. |
916 const std::vector<uint8> empty_exponent; | 918 const std::vector<uint8> empty_exponent; |
917 algorithm = CreateRsaAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, | 919 algorithm = |
918 modulus_length, | 920 CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
919 empty_exponent); | 921 modulus_length, |
| 922 empty_exponent); |
920 EXPECT_FALSE(GenerateKeyPairInternal( | 923 EXPECT_FALSE(GenerateKeyPairInternal( |
921 algorithm, extractable, usage_mask, &public_key, &private_key)); | 924 algorithm, extractable, usage_mask, &public_key, &private_key)); |
922 | 925 |
923 // Fail with bad exponent: all zeros. | 926 // Fail with bad exponent: all zeros. |
924 std::vector<uint8> exponent_with_leading_zeros(15, 0x00); | 927 std::vector<uint8> exponent_with_leading_zeros(15, 0x00); |
925 algorithm = CreateRsaAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, | 928 algorithm = |
926 modulus_length, | 929 CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
927 exponent_with_leading_zeros); | 930 modulus_length, |
| 931 exponent_with_leading_zeros); |
928 EXPECT_FALSE(GenerateKeyPairInternal( | 932 EXPECT_FALSE(GenerateKeyPairInternal( |
929 algorithm, extractable, usage_mask, &public_key, &private_key)); | 933 algorithm, extractable, usage_mask, &public_key, &private_key)); |
930 | 934 |
931 // Key generation success using exponent with leading zeros. | 935 // Key generation success using exponent with leading zeros. |
932 exponent_with_leading_zeros.insert(exponent_with_leading_zeros.end(), | 936 exponent_with_leading_zeros.insert(exponent_with_leading_zeros.end(), |
933 public_exponent.begin(), | 937 public_exponent.begin(), |
934 public_exponent.end()); | 938 public_exponent.end()); |
935 algorithm = CreateRsaAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, | 939 algorithm = |
936 modulus_length, | 940 CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
937 exponent_with_leading_zeros); | 941 modulus_length, |
| 942 exponent_with_leading_zeros); |
938 EXPECT_TRUE(GenerateKeyPairInternal( | 943 EXPECT_TRUE(GenerateKeyPairInternal( |
939 algorithm, extractable, usage_mask, &public_key, &private_key)); | 944 algorithm, extractable, usage_mask, &public_key, &private_key)); |
940 EXPECT_FALSE(public_key.isNull()); | 945 EXPECT_FALSE(public_key.isNull()); |
941 EXPECT_FALSE(private_key.isNull()); | 946 EXPECT_FALSE(private_key.isNull()); |
942 EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type()); | 947 EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type()); |
943 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type()); | 948 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type()); |
944 EXPECT_EQ(extractable, public_key.extractable()); | 949 EXPECT_EQ(extractable, public_key.extractable()); |
945 EXPECT_EQ(extractable, private_key.extractable()); | 950 EXPECT_EQ(extractable, private_key.extractable()); |
946 EXPECT_EQ(usage_mask, public_key.usages()); | 951 EXPECT_EQ(usage_mask, public_key.usages()); |
947 EXPECT_EQ(usage_mask, private_key.usages()); | 952 EXPECT_EQ(usage_mask, private_key.usages()); |
948 | 953 |
949 // Successful WebCryptoAlgorithmIdRsaOaep key generation. | 954 // Successful WebCryptoAlgorithmIdRsaOaep key generation. |
950 algorithm = CreateRsaAlgorithm( | 955 algorithm = CreateRsaKeyGenAlgorithm( |
951 blink::WebCryptoAlgorithmIdRsaOaep, modulus_length, public_exponent); | 956 blink::WebCryptoAlgorithmIdRsaOaep, modulus_length, public_exponent); |
952 EXPECT_TRUE(GenerateKeyPairInternal( | 957 EXPECT_TRUE(GenerateKeyPairInternal( |
953 algorithm, extractable, usage_mask, &public_key, &private_key)); | 958 algorithm, extractable, usage_mask, &public_key, &private_key)); |
954 EXPECT_FALSE(public_key.isNull()); | 959 EXPECT_FALSE(public_key.isNull()); |
955 EXPECT_FALSE(private_key.isNull()); | 960 EXPECT_FALSE(private_key.isNull()); |
956 EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type()); | 961 EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type()); |
957 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type()); | 962 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type()); |
958 EXPECT_EQ(extractable, public_key.extractable()); | 963 EXPECT_EQ(extractable, public_key.extractable()); |
959 EXPECT_EQ(extractable, private_key.extractable()); | 964 EXPECT_EQ(extractable, private_key.extractable()); |
960 EXPECT_EQ(usage_mask, public_key.usages()); | 965 EXPECT_EQ(usage_mask, public_key.usages()); |
961 EXPECT_EQ(usage_mask, private_key.usages()); | 966 EXPECT_EQ(usage_mask, private_key.usages()); |
962 | 967 |
963 // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation. | 968 // Successful WebCryptoAlgorithmIdRsaSsaPkcs1v1_5 key generation. |
964 algorithm = CreateRsaAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, | 969 algorithm = |
965 modulus_length, | 970 CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5, |
966 public_exponent); | 971 modulus_length, |
| 972 public_exponent); |
967 EXPECT_TRUE(GenerateKeyPairInternal( | 973 EXPECT_TRUE(GenerateKeyPairInternal( |
968 algorithm, extractable, usage_mask, &public_key, &private_key)); | 974 algorithm, extractable, usage_mask, &public_key, &private_key)); |
969 EXPECT_FALSE(public_key.isNull()); | 975 EXPECT_FALSE(public_key.isNull()); |
970 EXPECT_FALSE(private_key.isNull()); | 976 EXPECT_FALSE(private_key.isNull()); |
971 EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type()); | 977 EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key.type()); |
972 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type()); | 978 EXPECT_EQ(blink::WebCryptoKeyTypePrivate, private_key.type()); |
973 EXPECT_EQ(extractable, public_key.extractable()); | 979 EXPECT_EQ(extractable, public_key.extractable()); |
974 EXPECT_EQ(extractable, private_key.extractable()); | 980 EXPECT_EQ(extractable, private_key.extractable()); |
975 EXPECT_EQ(usage_mask, public_key.usages()); | 981 EXPECT_EQ(usage_mask, public_key.usages()); |
976 EXPECT_EQ(usage_mask, private_key.usages()); | 982 EXPECT_EQ(usage_mask, private_key.usages()); |
977 | 983 |
978 // Fail SPKI export of private key. This is an ExportKey test, but do it here | 984 // Fail SPKI export of private key. This is an ExportKey test, but do it here |
979 // since it is expensive to generate an RSA key pair and we already have a | 985 // since it is expensive to generate an RSA key pair and we already have a |
980 // private key here. | 986 // private key here. |
981 blink::WebArrayBuffer output; | 987 blink::WebArrayBuffer output; |
982 EXPECT_FALSE( | 988 EXPECT_FALSE( |
983 ExportKeyInternal(blink::WebCryptoKeyFormatSpki, private_key, &output)); | 989 ExportKeyInternal(blink::WebCryptoKeyFormatSpki, private_key, &output)); |
984 } | 990 } |
985 | 991 |
| 992 TEST_F(WebCryptoImplTest, RsaEsRoundTrip) { |
| 993 // Note: using unrealistic short key length here to avoid bogging down tests. |
| 994 |
| 995 // Create a key pair. |
| 996 const unsigned kModulusLength = 256; |
| 997 blink::WebCryptoAlgorithm algorithm = |
| 998 CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
| 999 kModulusLength, |
| 1000 HexStringToBytes("010001")); |
| 1001 const blink::WebCryptoKeyUsageMask usage_mask = |
| 1002 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt; |
| 1003 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| 1004 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| 1005 EXPECT_TRUE(GenerateKeyPairInternal( |
| 1006 algorithm, false, usage_mask, &public_key, &private_key)); |
| 1007 EXPECT_FALSE(public_key.isNull()); |
| 1008 EXPECT_FALSE(private_key.isNull()); |
| 1009 |
| 1010 // Make a maximum-length data message. RSAES can operate on messages up to |
| 1011 // length of k - 11 bytes, where k is the octet length of the RSA modulus. |
| 1012 const unsigned kMaxMsgSizeBytes = kModulusLength / 8 - 11; |
| 1013 // There are two hex chars for each byte. |
| 1014 const unsigned kMsgHexSize = kMaxMsgSizeBytes * 2; |
| 1015 char max_data_hex[kMsgHexSize+1]; |
| 1016 std::fill(&max_data_hex[0], &max_data_hex[0] + kMsgHexSize, 'a'); |
| 1017 max_data_hex[kMsgHexSize] = '\0'; |
| 1018 |
| 1019 // Verify encrypt / decrypt round trip on a few messages. Note that RSA |
| 1020 // encryption does not support empty input. |
| 1021 algorithm = CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
| 1022 const char* const kTestDataHex[] = { |
| 1023 "ff", |
| 1024 "0102030405060708090a0b0c0d0e0f", |
| 1025 max_data_hex |
| 1026 }; |
| 1027 blink::WebArrayBuffer encrypted_data; |
| 1028 blink::WebArrayBuffer decrypted_data; |
| 1029 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestDataHex); ++i) { |
| 1030 SCOPED_TRACE(i); |
| 1031 ASSERT_TRUE(EncryptInternal( |
| 1032 algorithm, |
| 1033 public_key, |
| 1034 HexStringToBytes(kTestDataHex[i]), |
| 1035 &encrypted_data)); |
| 1036 EXPECT_EQ(kModulusLength/8, encrypted_data.byteLength()); |
| 1037 ASSERT_TRUE(DecryptInternal( |
| 1038 algorithm, |
| 1039 private_key, |
| 1040 reinterpret_cast<const unsigned char*>(encrypted_data.data()), |
| 1041 encrypted_data.byteLength(), |
| 1042 &decrypted_data)); |
| 1043 ExpectArrayBufferMatchesHex(kTestDataHex[i], decrypted_data); |
| 1044 } |
| 1045 } |
| 1046 |
| 1047 TEST_F(WebCryptoImplTest, RsaEsKnownAnswer) { |
| 1048 // Because the random data in PKCS1.5 padding makes the encryption output non- |
| 1049 // deterministic, we cannot easily do a typical known-answer test for RSA |
| 1050 // encryption / decryption. Instead we will take a known-good encrypted |
| 1051 // message, decrypt it, re-encrypt it, then decrypt again, verifying that the |
| 1052 // original known cleartext is the result. |
| 1053 |
| 1054 // The RSA public and private keys used for this test are produced by the |
| 1055 // openssl command line: |
| 1056 // % openssl genrsa -out pair.pem 1024 |
| 1057 // % openssl rsa -in pair.pem -out spki.der -outform DER -pubout |
| 1058 // % openssl pkcs8 -topk8 -inform PEM -outform DER -in pair.pem -out |
| 1059 // pkcs8.der -nocrypt |
| 1060 // % xxd -p spki.der |
| 1061 // % xxd -p pkcs8.der |
| 1062 const std::string rsa_spki_der_hex = |
| 1063 "30819f300d06092a864886f70d010101050003818d0030818902818100a8" |
| 1064 "d30894b93f376f7822229bfd2483e50da944c4ab803ca31979e0f47e70bf" |
| 1065 "683c687c6b3e80f280a237cea3643fd1f7f10f7cc664dbc2ecd45be53e1c" |
| 1066 "9b15a53c37dbdad846c0f8340c472abc7821e4aa7df185867bf38228ac3e" |
| 1067 "cc1d97d3c8b57e21ea6ba57b2bc3814a436e910ee8ab64a0b7743a927e94" |
| 1068 "4d3420401f7dd50203010001"; |
| 1069 const std::string rsa_pkcs8_der_hex = |
| 1070 "30820276020100300d06092a864886f70d0101010500048202603082025c" |
| 1071 "02010002818100a8d30894b93f376f7822229bfd2483e50da944c4ab803c" |
| 1072 "a31979e0f47e70bf683c687c6b3e80f280a237cea3643fd1f7f10f7cc664" |
| 1073 "dbc2ecd45be53e1c9b15a53c37dbdad846c0f8340c472abc7821e4aa7df1" |
| 1074 "85867bf38228ac3ecc1d97d3c8b57e21ea6ba57b2bc3814a436e910ee8ab" |
| 1075 "64a0b7743a927e944d3420401f7dd5020301000102818100896cdffb50a0" |
| 1076 "691bd00ad9696933243a7c5861a64684e8d74b91aed0d76c28234da9303e" |
| 1077 "8c6ea2f89b141a9d5ea9a4ddd3d8eb9503dcf05ba0b1fd76060b281e3ae4" |
| 1078 "b9d497fb5519bdf1127db8ad412d6a722686c78df3e3002acca960c6b2a2" |
| 1079 "42a83ace5410693c03ce3d74cb9c9a7bacc8e271812920d1f53fee9312ef" |
| 1080 "4eb1024100d09c14418ce92af7cc62f7cdc79836d8c6e3d0d33e7229cc11" |
| 1081 "d732cbac75aa4c56c92e409a3ccbe75d4ce63ac5adca33080690782c6371" |
| 1082 "e3628134c3534ca603024100cf2d3206f6deea2f39b70351c51f85436200" |
| 1083 "5aa8f643e49e22486736d536e040dc30a2b4f9be3ab212a88d1891280874" |
| 1084 "b9a170cdeb22eaf61c27c4b082c7d1470240638411a5b3b307ec6e744802" |
| 1085 "c2d4ba556f8bfe72c7b76e790b89bd91ac13f5c9b51d04138d80b3450c1d" |
| 1086 "4337865601bf96748b36c8f627be719f71ac3c70b441024065ce92cfe34e" |
| 1087 "a58bf173a2b8f3024b4d5282540ac581957db3e11a7f528535ec098808dc" |
| 1088 "a0013ffcb3b88a25716757c86c540e07d2ad8502cdd129118822c30f0240" |
| 1089 "420a4983040e9db46eb29f1315a0d7b41cf60428f7460fce748e9a1a7d22" |
| 1090 "d7390fa328948e7e9d1724401374e99d45eb41474781201378a4330e8e80" |
| 1091 "8ce63551"; |
| 1092 |
| 1093 // Similarly, the cleartext and public key encrypted ciphertext for this test |
| 1094 // are also produced by openssl. Note that since we are using a 1024-bit key, |
| 1095 // the cleartext size must be less than or equal to 117 bytes (modulusLength / |
| 1096 // 8 - 11). |
| 1097 // % openssl rand -out cleartext.bin 64 |
| 1098 // % openssl rsautl -encrypt -inkey spki.der -keyform DER -pubin -in |
| 1099 // cleartext.bin -out ciphertext.bin |
| 1100 // % xxd -p cleartext.bin |
| 1101 // % xxd -p ciphertext.bin |
| 1102 const std::string cleartext_hex = |
| 1103 "ec358ed141c45d7e03d4c6338aebad718e8bcbbf8f8ee6f8d9f4b9ef06d8" |
| 1104 "84739a398c6bcbc688418b2ff64761dc0ccd40e7d52bed03e06946d0957a" |
| 1105 "eef9e822"; |
| 1106 const std::string ciphertext_hex = |
| 1107 "6106441c2b7a4b1a16260ed1ae4fe6135247345dc8e674754bbda6588c6c" |
| 1108 "0d95a3d4d26bb34cdbcbe327723e80343bd7a15cd4c91c3a44e6cb9c6cd6" |
| 1109 "7ad2e8bf41523188d9b36dc364a838642dcbc2c25e85dfb2106ba47578ca" |
| 1110 "3bbf8915055aea4fa7c3cbfdfbcc163f04c234fb6d847f39bab9612ecbee" |
| 1111 "04626e945c3ccf42"; |
| 1112 |
| 1113 // Import the public key. |
| 1114 const blink::WebCryptoAlgorithm algorithm = |
| 1115 CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
| 1116 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| 1117 ASSERT_TRUE(ImportKeyInternal( |
| 1118 blink::WebCryptoKeyFormatSpki, |
| 1119 HexStringToBytes(rsa_spki_der_hex), |
| 1120 algorithm, |
| 1121 true, |
| 1122 blink::WebCryptoKeyUsageEncrypt, |
| 1123 &public_key)); |
| 1124 EXPECT_FALSE(public_key.isNull()); |
| 1125 EXPECT_TRUE(public_key.handle()); |
| 1126 |
| 1127 // Import the private key. |
| 1128 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| 1129 ASSERT_TRUE(ImportKeyInternal( |
| 1130 blink::WebCryptoKeyFormatPkcs8, |
| 1131 HexStringToBytes(rsa_pkcs8_der_hex), |
| 1132 algorithm, |
| 1133 true, |
| 1134 blink::WebCryptoKeyUsageDecrypt, |
| 1135 &private_key)); |
| 1136 EXPECT_FALSE(private_key.isNull()); |
| 1137 EXPECT_TRUE(private_key.handle()); |
| 1138 |
| 1139 // Decrypt the known-good ciphertext with the private key. As a check we must |
| 1140 // get the known original cleartext. |
| 1141 blink::WebArrayBuffer decrypted_data; |
| 1142 ASSERT_TRUE(DecryptInternal( |
| 1143 algorithm, |
| 1144 private_key, |
| 1145 HexStringToBytes(ciphertext_hex), |
| 1146 &decrypted_data)); |
| 1147 EXPECT_FALSE(decrypted_data.isNull()); |
| 1148 ExpectArrayBufferMatchesHex(cleartext_hex, decrypted_data); |
| 1149 |
| 1150 // Encrypt this decrypted data with the public key. |
| 1151 blink::WebArrayBuffer encrypted_data; |
| 1152 ASSERT_TRUE(EncryptInternal( |
| 1153 algorithm, |
| 1154 public_key, |
| 1155 reinterpret_cast<const unsigned char*>(decrypted_data.data()), |
| 1156 decrypted_data.byteLength(), |
| 1157 &encrypted_data)); |
| 1158 EXPECT_EQ(128u, encrypted_data.byteLength()); |
| 1159 |
| 1160 // Finally, decrypt the newly encrypted result with the private key, and |
| 1161 // compare to the known original cleartext. |
| 1162 decrypted_data.reset(); |
| 1163 ASSERT_TRUE(DecryptInternal( |
| 1164 algorithm, |
| 1165 private_key, |
| 1166 reinterpret_cast<const unsigned char*>(encrypted_data.data()), |
| 1167 encrypted_data.byteLength(), |
| 1168 &decrypted_data)); |
| 1169 EXPECT_FALSE(decrypted_data.isNull()); |
| 1170 ExpectArrayBufferMatchesHex(cleartext_hex, decrypted_data); |
| 1171 } |
| 1172 |
| 1173 TEST_F(WebCryptoImplTest, RsaEsFailures) { |
| 1174 // Note: using unrealistic short key length here to avoid bogging down tests. |
| 1175 |
| 1176 // Create a key pair. |
| 1177 const unsigned kModulusLength = 256; |
| 1178 blink::WebCryptoAlgorithm algorithm = |
| 1179 CreateRsaKeyGenAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5, |
| 1180 kModulusLength, |
| 1181 HexStringToBytes("010001")); |
| 1182 const blink::WebCryptoKeyUsageMask usage_mask = |
| 1183 blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageDecrypt; |
| 1184 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull(); |
| 1185 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull(); |
| 1186 EXPECT_TRUE(GenerateKeyPairInternal( |
| 1187 algorithm, false, usage_mask, &public_key, &private_key)); |
| 1188 EXPECT_FALSE(public_key.isNull()); |
| 1189 EXPECT_FALSE(private_key.isNull()); |
| 1190 |
| 1191 // Fail encrypt with a private key. |
| 1192 algorithm = CreateAlgorithm(blink::WebCryptoAlgorithmIdRsaEsPkcs1v1_5); |
| 1193 blink::WebArrayBuffer encrypted_data; |
| 1194 const std::string message_hex_str("0102030405060708090a0b0c0d0e0f"); |
| 1195 const std::vector<uint8> message_hex(HexStringToBytes(message_hex_str)); |
| 1196 EXPECT_FALSE( |
| 1197 EncryptInternal(algorithm, private_key, message_hex, &encrypted_data)); |
| 1198 |
| 1199 // Fail encrypt with empty message. |
| 1200 EXPECT_FALSE(EncryptInternal( |
| 1201 algorithm, public_key, std::vector<uint8>(), &encrypted_data)); |
| 1202 |
| 1203 // Fail encrypt with message too large. RSAES can operate on messages up to |
| 1204 // length of k - 11 bytes, where k is the octet length of the RSA modulus. |
| 1205 const unsigned kMaxMsgSizeBytes = kModulusLength / 8 - 11; |
| 1206 EXPECT_FALSE(EncryptInternal(algorithm, |
| 1207 public_key, |
| 1208 std::vector<uint8>(kMaxMsgSizeBytes + 1, '0'), |
| 1209 &encrypted_data)); |
| 1210 |
| 1211 // Generate encrypted data. |
| 1212 EXPECT_TRUE( |
| 1213 EncryptInternal(algorithm, public_key, message_hex, &encrypted_data)); |
| 1214 |
| 1215 // Fail decrypt with a public key. |
| 1216 blink::WebArrayBuffer decrypted_data; |
| 1217 EXPECT_FALSE(DecryptInternal( |
| 1218 algorithm, |
| 1219 public_key, |
| 1220 reinterpret_cast<const unsigned char*>(encrypted_data.data()), |
| 1221 encrypted_data.byteLength(), |
| 1222 &decrypted_data)); |
| 1223 |
| 1224 // Corrupt encrypted data; ensure decrypt fails because padding was disrupted. |
| 1225 std::vector<uint8> corrupted_data( |
| 1226 static_cast<uint8*>(encrypted_data.data()), |
| 1227 static_cast<uint8*>(encrypted_data.data()) + encrypted_data.byteLength()); |
| 1228 corrupted_data[corrupted_data.size() / 2] ^= 0x01; |
| 1229 EXPECT_FALSE( |
| 1230 DecryptInternal(algorithm, private_key, corrupted_data, &decrypted_data)); |
| 1231 |
| 1232 // TODO(padolph): Are there other specific data corruption scenarios to |
| 1233 // consider? |
| 1234 |
| 1235 // Do a successful decrypt with good data just for confirmation. |
| 1236 EXPECT_TRUE(DecryptInternal( |
| 1237 algorithm, |
| 1238 private_key, |
| 1239 reinterpret_cast<const unsigned char*>(encrypted_data.data()), |
| 1240 encrypted_data.byteLength(), |
| 1241 &decrypted_data)); |
| 1242 ExpectArrayBufferMatchesHex(message_hex_str, decrypted_data); |
| 1243 } |
| 1244 |
986 #endif // #if !defined(USE_OPENSSL) | 1245 #endif // #if !defined(USE_OPENSSL) |
987 | 1246 |
988 } // namespace content | 1247 } // namespace content |
OLD | NEW |