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 "content/child/webcrypto/openssl/ec_algorithm_openssl.h" | 5 #include "content/child/webcrypto/openssl/ec_algorithm_openssl.h" |
6 | 6 |
7 #include <openssl/ec.h> | 7 #include <openssl/ec.h> |
8 #include <openssl/ec_key.h> | 8 #include <openssl/ec_key.h> |
9 #include <openssl/evp.h> | 9 #include <openssl/evp.h> |
10 #include <openssl/pkcs12.h> | 10 #include <openssl/pkcs12.h> |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 return Status::ErrorUnexpected(); | 116 return Status::ErrorUnexpected(); |
117 | 117 |
118 // When importing an ECPrivateKey, the public key is optional. If it was | 118 // When importing an ECPrivateKey, the public key is optional. If it was |
119 // omitted then the public key will be calculated by BoringSSL and added into | 119 // omitted then the public key will be calculated by BoringSSL and added into |
120 // the EC_KEY. However an encoding flag is set such that when exporting to | 120 // the EC_KEY. However an encoding flag is set such that when exporting to |
121 // PKCS8 format the public key is once again omitted. Remove this flag. | 121 // PKCS8 format the public key is once again omitted. Remove this flag. |
122 unsigned int enc_flags = EC_KEY_get_enc_flags(ec.get()); | 122 unsigned int enc_flags = EC_KEY_get_enc_flags(ec.get()); |
123 enc_flags &= ~EC_PKEY_NO_PUBKEY; | 123 enc_flags &= ~EC_PKEY_NO_PUBKEY; |
124 EC_KEY_set_enc_flags(ec.get(), enc_flags); | 124 EC_KEY_set_enc_flags(ec.get(), enc_flags); |
125 | 125 |
126 // TODO(eroman): Is this necessary? From my tests it seems that BoringSSL | |
127 // already does these checks when setting the public key's affine coordinates. | |
128 if (!EC_KEY_check_key(ec.get())) | 126 if (!EC_KEY_check_key(ec.get())) |
129 return Status::ErrorEcKeyInvalid(); | 127 return Status::ErrorEcKeyInvalid(); |
130 | 128 |
131 // Make sure the curve matches the expected curve name. | 129 // Make sure the curve matches the expected curve name. |
132 int curve_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec.get())); | 130 int curve_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec.get())); |
133 blink::WebCryptoNamedCurve named_curve = blink::WebCryptoNamedCurveP256; | 131 blink::WebCryptoNamedCurve named_curve = blink::WebCryptoNamedCurveP256; |
134 Status status = NidToWebCryptoCurve(curve_nid, &named_curve); | 132 Status status = NidToWebCryptoCurve(curve_nid, &named_curve); |
135 if (status.IsError()) | 133 if (status.IsError()) |
136 return status; | 134 return status; |
137 | 135 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 crypto::ScopedBIGNUM x; | 398 crypto::ScopedBIGNUM x; |
401 status = ReadPaddedBIGNUM(jwk, "x", degree_bytes, &x); | 399 status = ReadPaddedBIGNUM(jwk, "x", degree_bytes, &x); |
402 if (status.IsError()) | 400 if (status.IsError()) |
403 return status; | 401 return status; |
404 | 402 |
405 crypto::ScopedBIGNUM y; | 403 crypto::ScopedBIGNUM y; |
406 status = ReadPaddedBIGNUM(jwk, "y", degree_bytes, &y); | 404 status = ReadPaddedBIGNUM(jwk, "y", degree_bytes, &y); |
407 if (status.IsError()) | 405 if (status.IsError()) |
408 return status; | 406 return status; |
409 | 407 |
410 // TODO(eroman): This internally runs EC_KEY_check_key(). Can avoid calling it | 408 // TODO(eroman): Distinguish more accurately between a DataError and |
411 // again by the JWK import code if private key were set before public key. | 409 // OperationError. In general if this fails it was due to the key being an |
| 410 // invalid EC key. |
412 if (!EC_KEY_set_public_key_affine_coordinates(ec.get(), x.get(), y.get())) | 411 if (!EC_KEY_set_public_key_affine_coordinates(ec.get(), x.get(), y.get())) |
413 return Status::OperationError(); | 412 return Status::DataError(); |
414 | 413 |
415 // Extract the "d" parameters. | 414 // Extract the "d" parameters. |
416 if (is_private_key) { | 415 if (is_private_key) { |
417 crypto::ScopedBIGNUM d; | 416 crypto::ScopedBIGNUM d; |
418 status = ReadPaddedBIGNUM(jwk, "d", degree_bytes, &d); | 417 status = ReadPaddedBIGNUM(jwk, "d", degree_bytes, &d); |
419 if (status.IsError()) | 418 if (status.IsError()) |
420 return status; | 419 return status; |
421 | 420 |
422 if (!EC_KEY_set_private_key(ec.get(), d.get())) | 421 if (!EC_KEY_set_private_key(ec.get(), d.get())) |
423 return Status::OperationError(); | 422 return Status::OperationError(); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 key->algorithm().ecParams()->namedCurve()) { | 559 key->algorithm().ecParams()->namedCurve()) { |
561 return Status::ErrorUnexpected(); | 560 return Status::ErrorUnexpected(); |
562 } | 561 } |
563 | 562 |
564 return Status::Success(); | 563 return Status::Success(); |
565 } | 564 } |
566 | 565 |
567 } // namespace webcrypto | 566 } // namespace webcrypto |
568 | 567 |
569 } // namespace content | 568 } // namespace content |
OLD | NEW |