Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: content/renderer/webcrypto/webcrypto_impl_unittest.cc

Issue 75653002: [webcrypto] Add RSAES-PKCS1-v1_5 encrypt and decrypt for NSS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: restored #ifdef to make android build succeed Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/renderer/webcrypto/webcrypto_impl_nss.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « content/renderer/webcrypto/webcrypto_impl_nss.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698