OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 "base/stl_util.h" | 5 #include "base/stl_util.h" |
6 #include "components/webcrypto/algorithm_dispatch.h" | 6 #include "components/webcrypto/algorithm_dispatch.h" |
7 #include "components/webcrypto/algorithms/test_helpers.h" | 7 #include "components/webcrypto/algorithms/test_helpers.h" |
8 #include "components/webcrypto/crypto_data.h" | 8 #include "components/webcrypto/crypto_data.h" |
9 #include "components/webcrypto/jwk.h" | 9 #include "components/webcrypto/jwk.h" |
10 #include "components/webcrypto/status.h" | 10 #include "components/webcrypto/status.h" |
11 #include "components/webcrypto/webcrypto_util.h" | 11 #include "components/webcrypto/webcrypto_util.h" |
12 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" | 12 #include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h" |
13 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 13 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
14 | 14 |
15 namespace webcrypto { | 15 namespace webcrypto { |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 bool SupportsEcdsa() { | |
20 #if defined(USE_OPENSSL) | |
21 return true; | |
22 #else | |
23 LOG(ERROR) << "Skipping ECDSA test because unsupported"; | |
24 return false; | |
25 #endif | |
26 } | |
27 | |
28 blink::WebCryptoAlgorithm CreateEcdsaKeyGenAlgorithm( | 19 blink::WebCryptoAlgorithm CreateEcdsaKeyGenAlgorithm( |
29 blink::WebCryptoNamedCurve named_curve) { | 20 blink::WebCryptoNamedCurve named_curve) { |
30 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 21 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
31 blink::WebCryptoAlgorithmIdEcdsa, | 22 blink::WebCryptoAlgorithmIdEcdsa, |
32 new blink::WebCryptoEcKeyGenParams(named_curve)); | 23 new blink::WebCryptoEcKeyGenParams(named_curve)); |
33 } | 24 } |
34 | 25 |
35 blink::WebCryptoAlgorithm CreateEcdsaImportAlgorithm( | 26 blink::WebCryptoAlgorithm CreateEcdsaImportAlgorithm( |
36 blink::WebCryptoNamedCurve named_curve) { | 27 blink::WebCryptoNamedCurve named_curve) { |
37 return CreateEcImportAlgorithm(blink::WebCryptoAlgorithmIdEcdsa, named_curve); | 28 return CreateEcImportAlgorithm(blink::WebCryptoAlgorithmIdEcdsa, named_curve); |
38 } | 29 } |
39 | 30 |
40 blink::WebCryptoAlgorithm CreateEcdsaAlgorithm( | 31 blink::WebCryptoAlgorithm CreateEcdsaAlgorithm( |
41 blink::WebCryptoAlgorithmId hash_id) { | 32 blink::WebCryptoAlgorithmId hash_id) { |
42 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( | 33 return blink::WebCryptoAlgorithm::adoptParamsAndCreate( |
43 blink::WebCryptoAlgorithmIdEcdsa, | 34 blink::WebCryptoAlgorithmIdEcdsa, |
44 new blink::WebCryptoEcdsaParams(CreateAlgorithm(hash_id))); | 35 new blink::WebCryptoEcdsaParams(CreateAlgorithm(hash_id))); |
45 } | 36 } |
46 | 37 |
47 class WebCryptoEcdsaTest : public WebCryptoTestBase {}; | 38 class WebCryptoEcdsaTest : public WebCryptoTestBase {}; |
48 | 39 |
49 // Generates some ECDSA key pairs. Validates basic properties on the keys, and | 40 // Generates some ECDSA key pairs. Validates basic properties on the keys, and |
50 // ensures the serialized key (as JWK) is unique. This test does nothing to | 41 // ensures the serialized key (as JWK) is unique. This test does nothing to |
51 // ensure that the keys are otherwise usable (by trying to sign/verify with | 42 // ensure that the keys are otherwise usable (by trying to sign/verify with |
52 // them). | 43 // them). |
53 TEST_F(WebCryptoEcdsaTest, GenerateKeyIsRandom) { | 44 TEST_F(WebCryptoEcdsaTest, GenerateKeyIsRandom) { |
54 if (!SupportsEcdsa()) | |
55 return; | |
56 | |
57 blink::WebCryptoNamedCurve named_curve = blink::WebCryptoNamedCurveP256; | 45 blink::WebCryptoNamedCurve named_curve = blink::WebCryptoNamedCurveP256; |
58 | 46 |
59 std::vector<std::vector<uint8_t>> serialized_keys; | 47 std::vector<std::vector<uint8_t>> serialized_keys; |
60 | 48 |
61 // Generate a small sample of keys. | 49 // Generate a small sample of keys. |
62 for (int j = 0; j < 4; ++j) { | 50 for (int j = 0; j < 4; ++j) { |
63 blink::WebCryptoKey public_key; | 51 blink::WebCryptoKey public_key; |
64 blink::WebCryptoKey private_key; | 52 blink::WebCryptoKey private_key; |
65 | 53 |
66 ASSERT_EQ(Status::Success(), | 54 ASSERT_EQ(Status::Success(), |
(...skipping 17 matching lines...) Expand all Loading... |
84 ExportKey(blink::WebCryptoKeyFormatJwk, private_key, &key_bytes)); | 72 ExportKey(blink::WebCryptoKeyFormatJwk, private_key, &key_bytes)); |
85 serialized_keys.push_back(key_bytes); | 73 serialized_keys.push_back(key_bytes); |
86 } | 74 } |
87 | 75 |
88 // Ensure all entries in the key sample set are unique. This is a simplistic | 76 // Ensure all entries in the key sample set are unique. This is a simplistic |
89 // estimate of whether the generated keys appear random. | 77 // estimate of whether the generated keys appear random. |
90 EXPECT_FALSE(CopiesExist(serialized_keys)); | 78 EXPECT_FALSE(CopiesExist(serialized_keys)); |
91 } | 79 } |
92 | 80 |
93 TEST_F(WebCryptoEcdsaTest, GenerateKeyEmptyUsage) { | 81 TEST_F(WebCryptoEcdsaTest, GenerateKeyEmptyUsage) { |
94 if (!SupportsEcdsa()) | |
95 return; | |
96 | |
97 blink::WebCryptoNamedCurve named_curve = blink::WebCryptoNamedCurveP256; | 82 blink::WebCryptoNamedCurve named_curve = blink::WebCryptoNamedCurveP256; |
98 blink::WebCryptoKey public_key; | 83 blink::WebCryptoKey public_key; |
99 blink::WebCryptoKey private_key; | 84 blink::WebCryptoKey private_key; |
100 ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(), | 85 ASSERT_EQ(Status::ErrorCreateKeyEmptyUsages(), |
101 GenerateKeyPair(CreateEcdsaKeyGenAlgorithm(named_curve), true, 0, | 86 GenerateKeyPair(CreateEcdsaKeyGenAlgorithm(named_curve), true, 0, |
102 &public_key, &private_key)); | 87 &public_key, &private_key)); |
103 } | 88 } |
104 | 89 |
105 // Verify that ECDSA signatures are probabilistic. Signing the same message two | 90 // Verify that ECDSA signatures are probabilistic. Signing the same message two |
106 // times should yield different signatures. However both signatures should | 91 // times should yield different signatures. However both signatures should |
107 // verify correctly. | 92 // verify correctly. |
108 TEST_F(WebCryptoEcdsaTest, SignatureIsRandom) { | 93 TEST_F(WebCryptoEcdsaTest, SignatureIsRandom) { |
109 if (!SupportsEcdsa()) | |
110 return; | |
111 | |
112 // Import a public and private keypair from "ec_private_keys.json". It doesn't | 94 // Import a public and private keypair from "ec_private_keys.json". It doesn't |
113 // really matter which one is used since they are all valid. In this case | 95 // really matter which one is used since they are all valid. In this case |
114 // using the first one. | 96 // using the first one. |
115 scoped_ptr<base::ListValue> private_keys; | 97 scoped_ptr<base::ListValue> private_keys; |
116 ASSERT_TRUE(ReadJsonTestFileToList("ec_private_keys.json", &private_keys)); | 98 ASSERT_TRUE(ReadJsonTestFileToList("ec_private_keys.json", &private_keys)); |
117 const base::DictionaryValue* key_dict; | 99 const base::DictionaryValue* key_dict; |
118 ASSERT_TRUE(private_keys->GetDictionary(0, &key_dict)); | 100 ASSERT_TRUE(private_keys->GetDictionary(0, &key_dict)); |
119 blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(key_dict); | 101 blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(key_dict); |
120 const base::DictionaryValue* key_jwk; | 102 const base::DictionaryValue* key_jwk; |
121 ASSERT_TRUE(key_dict->GetDictionary("jwk", &key_jwk)); | 103 ASSERT_TRUE(key_dict->GetDictionary("jwk", &key_jwk)); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 EXPECT_TRUE(signature_matches); | 142 EXPECT_TRUE(signature_matches); |
161 ASSERT_EQ(Status::Success(), | 143 ASSERT_EQ(Status::Success(), |
162 Verify(algorithm, public_key, CryptoData(signature2), | 144 Verify(algorithm, public_key, CryptoData(signature2), |
163 CryptoData(message), &signature_matches)); | 145 CryptoData(message), &signature_matches)); |
164 EXPECT_TRUE(signature_matches); | 146 EXPECT_TRUE(signature_matches); |
165 } | 147 } |
166 | 148 |
167 // Tests verify() for ECDSA using an assortment of keys, curves and hashes. | 149 // Tests verify() for ECDSA using an assortment of keys, curves and hashes. |
168 // These tests also include expected failures for bad signatures and keys. | 150 // These tests also include expected failures for bad signatures and keys. |
169 TEST_F(WebCryptoEcdsaTest, VerifyKnownAnswer) { | 151 TEST_F(WebCryptoEcdsaTest, VerifyKnownAnswer) { |
170 if (!SupportsEcdsa()) | |
171 return; | |
172 | |
173 scoped_ptr<base::ListValue> tests; | 152 scoped_ptr<base::ListValue> tests; |
174 ASSERT_TRUE(ReadJsonTestFileToList("ecdsa.json", &tests)); | 153 ASSERT_TRUE(ReadJsonTestFileToList("ecdsa.json", &tests)); |
175 | 154 |
176 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { | 155 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { |
177 SCOPED_TRACE(test_index); | 156 SCOPED_TRACE(test_index); |
178 | 157 |
179 const base::DictionaryValue* test; | 158 const base::DictionaryValue* test; |
180 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); | 159 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); |
181 | 160 |
182 blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test); | 161 blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 return key->HasKey("d") ? kPrivateUsages : kPublicUsages; | 224 return key->HasKey("d") ? kPrivateUsages : kPublicUsages; |
246 } | 225 } |
247 } | 226 } |
248 | 227 |
249 // Appease compiler. | 228 // Appease compiler. |
250 return kPrivateUsages; | 229 return kPrivateUsages; |
251 } | 230 } |
252 | 231 |
253 // Tests importing bad public/private keys in a variety of formats. | 232 // Tests importing bad public/private keys in a variety of formats. |
254 TEST_F(WebCryptoEcdsaTest, ImportBadKeys) { | 233 TEST_F(WebCryptoEcdsaTest, ImportBadKeys) { |
255 if (!SupportsEcdsa()) | |
256 return; | |
257 | |
258 scoped_ptr<base::ListValue> tests; | 234 scoped_ptr<base::ListValue> tests; |
259 ASSERT_TRUE(ReadJsonTestFileToList("bad_ec_keys.json", &tests)); | 235 ASSERT_TRUE(ReadJsonTestFileToList("bad_ec_keys.json", &tests)); |
260 | 236 |
261 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { | 237 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { |
262 SCOPED_TRACE(test_index); | 238 SCOPED_TRACE(test_index); |
263 | 239 |
264 const base::DictionaryValue* test; | 240 const base::DictionaryValue* test; |
265 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); | 241 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); |
266 | 242 |
267 blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test); | 243 blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test); |
(...skipping 10 matching lines...) Expand all Loading... |
278 ASSERT_EQ(expected_error, StatusToString(status)); | 254 ASSERT_EQ(expected_error, StatusToString(status)); |
279 } | 255 } |
280 } | 256 } |
281 | 257 |
282 // Tests importing and exporting of EC private keys, using both JWK and PKCS8 | 258 // Tests importing and exporting of EC private keys, using both JWK and PKCS8 |
283 // formats. | 259 // formats. |
284 // | 260 // |
285 // The test imports a key first using JWK, and then exporting it to JWK and | 261 // The test imports a key first using JWK, and then exporting it to JWK and |
286 // PKCS8. It does the same thing using PKCS8 as the original source of truth. | 262 // PKCS8. It does the same thing using PKCS8 as the original source of truth. |
287 TEST_F(WebCryptoEcdsaTest, ImportExportPrivateKey) { | 263 TEST_F(WebCryptoEcdsaTest, ImportExportPrivateKey) { |
288 if (!SupportsEcdsa()) | |
289 return; | |
290 | |
291 scoped_ptr<base::ListValue> tests; | 264 scoped_ptr<base::ListValue> tests; |
292 ASSERT_TRUE(ReadJsonTestFileToList("ec_private_keys.json", &tests)); | 265 ASSERT_TRUE(ReadJsonTestFileToList("ec_private_keys.json", &tests)); |
293 | 266 |
294 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { | 267 for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) { |
295 SCOPED_TRACE(test_index); | 268 SCOPED_TRACE(test_index); |
296 | 269 |
297 const base::DictionaryValue* test; | 270 const base::DictionaryValue* test; |
298 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); | 271 ASSERT_TRUE(tests->GetDictionary(test_index, &test)); |
299 | 272 |
300 blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test); | 273 blink::WebCryptoNamedCurve curve = GetCurveNameFromDictionary(test); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 // Export the key as JWK | 341 // Export the key as JWK |
369 ASSERT_EQ(Status::Success(), | 342 ASSERT_EQ(Status::Success(), |
370 ExportKey(blink::WebCryptoKeyFormatJwk, key, &exported_bytes)); | 343 ExportKey(blink::WebCryptoKeyFormatJwk, key, &exported_bytes)); |
371 EXPECT_EQ(CryptoData(jwk_bytes), CryptoData(exported_bytes)); | 344 EXPECT_EQ(CryptoData(jwk_bytes), CryptoData(exported_bytes)); |
372 } | 345 } |
373 } | 346 } |
374 | 347 |
375 } // namespace | 348 } // namespace |
376 | 349 |
377 } // namespace webcrypto | 350 } // namespace webcrypto |
OLD | NEW |