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

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: Add some tests from fips 186-2, covering sha-{256, 384, 512} 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
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
194 // Sign twice.
davidben 2014/10/19 03:42:34 Nit: This comment seems off.
eroman 2014/10/20 18:44:53 Done. (Copy paste error).
195 std::vector<uint8_t> signature;
196
197 ASSERT_EQ(Status::Success(),
198 Sign(params, private_key, CryptoData(message), &signature));
199
200 // Make sure that verification works.
201 bool is_match = false;
202 ASSERT_EQ(Status::Success(),
203 Verify(params,
204 public_key,
205 CryptoData(signature),
206 CryptoData(message),
207 &is_match));
208 EXPECT_TRUE(is_match);
209
210 // Corrupt the signature and verification must fail.
211 ASSERT_EQ(Status::Success(),
212 Verify(params,
213 public_key,
214 CryptoData(Corrupted(signature)),
215 CryptoData(message),
216 &is_match));
217 EXPECT_FALSE(is_match);
218 }
219
220 // Iterate through known answers and test verification.
221 // * Verify over original message should succeed
222 // * Verify over corrupted message should fail
223 // * Verification with corrupted signature should fail
224 TEST(WebCryptoRsaPssTest, VerifyKnownAnswer) {
225 if (!SupportsRsaPss()) {
226 LOG(WARNING) << "Skipping test because RSA-PSS is not supported";
227 return;
228 }
229
230 scoped_ptr<base::DictionaryValue> test_data;
231 ASSERT_TRUE(ReadJsonTestFileToDictionary("rsa_pss.json", &test_data));
232
233 const base::DictionaryValue* keys_dict = NULL;
234 ASSERT_TRUE(test_data->GetDictionary("keys", &keys_dict));
235
236 const base::ListValue* tests = NULL;
237 ASSERT_TRUE(test_data->GetList("tests", &tests));
238
239 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
240 SCOPED_TRACE(test_index);
241
242 const base::DictionaryValue* test;
243 ASSERT_TRUE(tests->GetDictionary(test_index, &test));
244
245 blink::WebCryptoAlgorithm hash = GetDigestAlgorithm(test, "hash");
246
247 std::string key_name;
248 ASSERT_TRUE(test->GetString("key", &key_name));
249
250 // Import the public key.
251 blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
252 std::vector<uint8_t> spki_bytes =
253 GetBytesFromHexString(keys_dict, key_name);
254
255 ASSERT_EQ(Status::Success(),
256 ImportKey(blink::WebCryptoKeyFormatSpki,
257 CryptoData(spki_bytes),
258 CreateRsaHashedImportAlgorithm(
259 blink::WebCryptoAlgorithmIdRsaPss, hash.id()),
260 true,
261 blink::WebCryptoKeyUsageVerify,
262 &public_key));
263
264 int saltLength;
265 ASSERT_TRUE(test->GetInteger("saltLength", &saltLength));
266
267 std::vector<uint8_t> message = GetBytesFromHexString(test, "message");
268 std::vector<uint8_t> signature = GetBytesFromHexString(test, "signature");
269
270 // Test that verification returns true when it should.
271 bool is_match = false;
272 ASSERT_EQ(Status::Success(),
273 Verify(CreateRsaPssAlgorithm(saltLength),
274 public_key,
275 CryptoData(signature),
276 CryptoData(message),
277 &is_match));
278 EXPECT_TRUE(is_match);
279
280 // Corrupt the message and make sure that verification fails.
281 ASSERT_EQ(Status::Success(),
282 Verify(CreateRsaPssAlgorithm(saltLength),
283 public_key,
284 CryptoData(signature),
285 CryptoData(Corrupted(message)),
286 &is_match));
287 EXPECT_FALSE(is_match);
288
289 // Corrupt the signature and make sure that verification fails.
290 ASSERT_EQ(Status::Success(),
291 Verify(CreateRsaPssAlgorithm(saltLength),
292 public_key,
293 CryptoData(Corrupted(signature)),
294 CryptoData(message),
295 &is_match));
296 EXPECT_FALSE(is_match);
297 }
298 }
299
300 } // namespace
301
302 } // namespace webcrypto
303
304 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698