| 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 |