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

Side by Side Diff: content/child/webcrypto/test/rsa_pss_unittest.cc

Issue 661653002: [webcrypto] Implement RSA-PSS using BoringSSL. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@refactor_rsassa
Patch Set: rebase onto master (corrected) Created 6 years, 2 months 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/child/webcrypto/platform_crypto.h ('k') | content/child/webcrypto/test/test_helpers.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/logging.h"
6 #include "base/stl_util.h"
7 #include "content/child/webcrypto/algorithm_dispatch.h"
8 #include "content/child/webcrypto/crypto_data.h"
9 #include "content/child/webcrypto/jwk.h"
10 #include "content/child/webcrypto/status.h"
11 #include "content/child/webcrypto/test/test_helpers.h"
12 #include "content/child/webcrypto/webcrypto_util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
15 #include "third_party/WebKit/public/platform/WebCryptoKey.h"
16 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
17
18 namespace content {
19
20 namespace webcrypto {
21
22 namespace {
23
24 bool SupportsRsaPss() {
25 #if defined(USE_OPENSSL)
26 return true;
27 #else
28 return false;
29 #endif
30 }
31
32 blink::WebCryptoAlgorithm CreateRsaPssAlgorithm(
33 unsigned int salt_length_bytes) {
34 return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
35 blink::WebCryptoAlgorithmIdRsaPss,
36 new blink::WebCryptoRsaPssParams(salt_length_bytes));
37 }
38
39 // Test that no two RSA-PSS signatures are identical, when using a non-zero
40 // lengthed salt.
41 TEST(WebCryptoRsaPssTest, SignIsRandom) {
42 if (!SupportsRsaPss()) {
43 LOG(WARNING) << "Skipping test because RSA-PSS is not supported";
44 return;
45 }
46
47 // Import public/private key pair.
48 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
49 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
50
51 ImportRsaKeyPair(
52 HexStringToBytes(kPublicKeySpkiDerHex),
53 HexStringToBytes(kPrivateKeyPkcs8DerHex),
54 CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaPss,
55 blink::WebCryptoAlgorithmIdSha1),
56 true,
57 blink::WebCryptoKeyUsageVerify,
58 blink::WebCryptoKeyUsageSign,
59 &public_key,
60 &private_key);
61
62 // Use a 20-byte length salt.
63 blink::WebCryptoAlgorithm params = CreateRsaPssAlgorithm(20);
64
65 // Some random message to sign.
66 std::vector<uint8_t> message = HexStringToBytes(kPublicKeySpkiDerHex);
67
68 // Sign twice.
69 std::vector<uint8_t> signature1;
70 std::vector<uint8_t> signature2;
71
72 ASSERT_EQ(Status::Success(),
73 Sign(params, private_key, CryptoData(message), &signature1));
74 ASSERT_EQ(Status::Success(),
75 Sign(params, private_key, CryptoData(message), &signature2));
76
77 // The signatures will be different because of the salt.
78 EXPECT_NE(CryptoData(signature1), CryptoData(signature2));
79
80 // However both signatures should work when verifying.
81 bool is_match = false;
82
83 ASSERT_EQ(Status::Success(),
84 Verify(params,
85 public_key,
86 CryptoData(signature1),
87 CryptoData(message),
88 &is_match));
89 EXPECT_TRUE(is_match);
90
91 ASSERT_EQ(Status::Success(),
92 Verify(params,
93 public_key,
94 CryptoData(signature2),
95 CryptoData(message),
96 &is_match));
97 EXPECT_TRUE(is_match);
98
99 // Corrupt the signature and verification must fail.
100 ASSERT_EQ(Status::Success(),
101 Verify(params,
102 public_key,
103 CryptoData(Corrupted(signature2)),
104 CryptoData(message),
105 &is_match));
106 EXPECT_FALSE(is_match);
107 }
108
109 // Try signing and verifying when the salt length is 0. The signature in this
110 // case is not random.
111 TEST(WebCryptoRsaPssTest, SignVerifyNoSalt) {
112 if (!SupportsRsaPss()) {
113 LOG(WARNING) << "Skipping test because RSA-PSS is not supported";
114 return;
115 }
116
117 // Import public/private key pair.
118 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
119 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
120
121 ImportRsaKeyPair(
122 HexStringToBytes(kPublicKeySpkiDerHex),
123 HexStringToBytes(kPrivateKeyPkcs8DerHex),
124 CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaPss,
125 blink::WebCryptoAlgorithmIdSha1),
126 true,
127 blink::WebCryptoKeyUsageVerify,
128 blink::WebCryptoKeyUsageSign,
129 &public_key,
130 &private_key);
131
132 // Zero-length salt.
133 blink::WebCryptoAlgorithm params = CreateRsaPssAlgorithm(0);
134
135 // Some random message to sign.
136 std::vector<uint8_t> message = HexStringToBytes(kPublicKeySpkiDerHex);
137
138 // Sign twice.
139 std::vector<uint8_t> signature1;
140 std::vector<uint8_t> signature2;
141
142 ASSERT_EQ(Status::Success(),
143 Sign(params, private_key, CryptoData(message), &signature1));
144 ASSERT_EQ(Status::Success(),
145 Sign(params, private_key, CryptoData(message), &signature2));
146
147 // The signatures will be the same this time.
148 EXPECT_EQ(CryptoData(signature1), CryptoData(signature2));
149
150 // Make sure that verification works.
151 bool is_match = false;
152 ASSERT_EQ(Status::Success(),
153 Verify(params,
154 public_key,
155 CryptoData(signature1),
156 CryptoData(message),
157 &is_match));
158 EXPECT_TRUE(is_match);
159
160 // Corrupt the signature and verification must fail.
161 ASSERT_EQ(Status::Success(),
162 Verify(params,
163 public_key,
164 CryptoData(Corrupted(signature2)),
165 CryptoData(message),
166 &is_match));
167 EXPECT_FALSE(is_match);
168 }
169
170 TEST(WebCryptoRsaPssTest, SignEmptyMessage) {
171 if (!SupportsRsaPss()) {
172 LOG(WARNING) << "Skipping test because RSA-PSS is not supported";
173 return;
174 }
175
176 // Import public/private key pair.
177 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
178 blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
179
180 ImportRsaKeyPair(
181 HexStringToBytes(kPublicKeySpkiDerHex),
182 HexStringToBytes(kPrivateKeyPkcs8DerHex),
183 CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaPss,
184 blink::WebCryptoAlgorithmIdSha1),
185 true,
186 blink::WebCryptoKeyUsageVerify,
187 blink::WebCryptoKeyUsageSign,
188 &public_key,
189 &private_key);
190
191 blink::WebCryptoAlgorithm params = CreateRsaPssAlgorithm(20);
192 std::vector<uint8_t> message; // Empty message.
193 std::vector<uint8_t> signature;
194
195 ASSERT_EQ(Status::Success(),
196 Sign(params, private_key, CryptoData(message), &signature));
197
198 // Make sure that verification works.
199 bool is_match = false;
200 ASSERT_EQ(Status::Success(),
201 Verify(params,
202 public_key,
203 CryptoData(signature),
204 CryptoData(message),
205 &is_match));
206 EXPECT_TRUE(is_match);
207
208 // Corrupt the signature and verification must fail.
209 ASSERT_EQ(Status::Success(),
210 Verify(params,
211 public_key,
212 CryptoData(Corrupted(signature)),
213 CryptoData(message),
214 &is_match));
215 EXPECT_FALSE(is_match);
216 }
217
218 // Iterate through known answers and test verification.
219 // * Verify over original message should succeed
220 // * Verify over corrupted message should fail
221 // * Verification with corrupted signature should fail
222 TEST(WebCryptoRsaPssTest, VerifyKnownAnswer) {
223 if (!SupportsRsaPss()) {
224 LOG(WARNING) << "Skipping test because RSA-PSS is not supported";
225 return;
226 }
227
228 scoped_ptr<base::DictionaryValue> test_data;
229 ASSERT_TRUE(ReadJsonTestFileToDictionary("rsa_pss.json", &test_data));
230
231 const base::DictionaryValue* keys_dict = NULL;
232 ASSERT_TRUE(test_data->GetDictionary("keys", &keys_dict));
233
234 const base::ListValue* tests = NULL;
235 ASSERT_TRUE(test_data->GetList("tests", &tests));
236
237 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
238 SCOPED_TRACE(test_index);
239
240 const base::DictionaryValue* test;
241 ASSERT_TRUE(tests->GetDictionary(test_index, &test));
242
243 blink::WebCryptoAlgorithm hash = GetDigestAlgorithm(test, "hash");
244
245 std::string key_name;
246 ASSERT_TRUE(test->GetString("key", &key_name));
247
248 // Import the public key.
249 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
250 std::vector<uint8_t> spki_bytes =
251 GetBytesFromHexString(keys_dict, key_name);
252
253 ASSERT_EQ(Status::Success(),
254 ImportKey(blink::WebCryptoKeyFormatSpki,
255 CryptoData(spki_bytes),
256 CreateRsaHashedImportAlgorithm(
257 blink::WebCryptoAlgorithmIdRsaPss, hash.id()),
258 true,
259 blink::WebCryptoKeyUsageVerify,
260 &public_key));
261
262 int saltLength;
263 ASSERT_TRUE(test->GetInteger("saltLength", &saltLength));
264
265 std::vector<uint8_t> message = GetBytesFromHexString(test, "message");
266 std::vector<uint8_t> signature = GetBytesFromHexString(test, "signature");
267
268 // Test that verification returns true when it should.
269 bool is_match = false;
270 ASSERT_EQ(Status::Success(),
271 Verify(CreateRsaPssAlgorithm(saltLength),
272 public_key,
273 CryptoData(signature),
274 CryptoData(message),
275 &is_match));
276 EXPECT_TRUE(is_match);
277
278 // Corrupt the message and make sure that verification fails.
279 ASSERT_EQ(Status::Success(),
280 Verify(CreateRsaPssAlgorithm(saltLength),
281 public_key,
282 CryptoData(signature),
283 CryptoData(Corrupted(message)),
284 &is_match));
285 EXPECT_FALSE(is_match);
286
287 // Corrupt the signature and make sure that verification fails.
288 ASSERT_EQ(Status::Success(),
289 Verify(CreateRsaPssAlgorithm(saltLength),
290 public_key,
291 CryptoData(Corrupted(signature)),
292 CryptoData(message),
293 &is_match));
294 EXPECT_FALSE(is_match);
295 }
296 }
297
298 } // namespace
299
300 } // namespace webcrypto
301
302 } // namespace content
OLDNEW
« no previous file with comments | « content/child/webcrypto/platform_crypto.h ('k') | content/child/webcrypto/test/test_helpers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698