Index: crypto/ec_private_key.cc |
diff --git a/crypto/ec_private_key.cc b/crypto/ec_private_key.cc |
index 5e8d0549a85f00f60fa7f699898af354bfd6df49..300d498368dd5857f4b6735eec1245176c4c4e48 100644 |
--- a/crypto/ec_private_key.cc |
+++ b/crypto/ec_private_key.cc |
@@ -90,6 +90,30 @@ ECPrivateKey* ECPrivateKey::Create() { |
} |
// static |
+std::unique_ptr<ECPrivateKey> ECPrivateKey::CreateFromPrivateKeyInfo( |
+ const std::vector<uint8_t>& input) { |
+ OpenSSLErrStackTracer err_tracer(FROM_HERE); |
+ |
+ CBS cbs; |
+ CBS_init(&cbs, input.data(), input.size()); |
+ ScopedEVP_PKEY pkey(EVP_parse_private_key(&cbs)); |
+ if (!pkey || CBS_len(&cbs) != 0) |
+ return nullptr; |
+ |
+ // Check this is a P-256 key. |
+ EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(pkey.get()); |
+ if (!ec_key || |
+ EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) != |
+ NID_X9_62_prime256v1) { |
Ryan Sleevi
2016/05/02 23:26:56
Why? We don't enforce this elsewhere, AFAICT. It's
davidben
2016/06/01 17:19:39
I think it's a little poor to have parsing be able
davidben
2016/06/01 17:19:58
s/would never parse/would never create/
|
+ return nullptr; |
+ } |
+ |
+ std::unique_ptr<ECPrivateKey> result(new ECPrivateKey); |
+ result->key_ = pkey.release(); |
+ return result; |
+} |
+ |
+// static |
ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( |
const std::string& password, |
const std::vector<uint8_t>& encrypted_private_key_info, |
@@ -137,9 +161,24 @@ ECPrivateKey* ECPrivateKey::CreateFromEncryptedPrivateKeyInfo( |
return result.release(); |
} |
-bool ECPrivateKey::ExportEncryptedPrivateKey(const std::string& password, |
- int iterations, |
- std::vector<uint8_t>* output) { |
+bool ECPrivateKey::ExportPrivateKey(std::vector<uint8_t>* output) const { |
+ OpenSSLErrStackTracer err_tracer(FROM_HERE); |
+ uint8_t* der; |
+ size_t der_len; |
+ AutoCBB cbb; |
+ if (!CBB_init(cbb.get(), 0) || !EVP_marshal_private_key(cbb.get(), key_) || |
+ !CBB_finish(cbb.get(), &der, &der_len)) { |
+ return false; |
+ } |
+ output->assign(der, der + der_len); |
+ OPENSSL_free(der); |
+ return true; |
+} |
+ |
+bool ECPrivateKey::ExportEncryptedPrivateKey( |
+ const std::string& password, |
+ int iterations, |
+ std::vector<uint8_t>* output) const { |
OpenSSLErrStackTracer err_tracer(FROM_HERE); |
// Convert into a PKCS#8 object. |
ScopedPKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(key_)); |
@@ -168,7 +207,7 @@ bool ECPrivateKey::ExportEncryptedPrivateKey(const std::string& password, |
output); |
} |
-bool ECPrivateKey::ExportPublicKey(std::vector<uint8_t>* output) { |
+bool ECPrivateKey::ExportPublicKey(std::vector<uint8_t>* output) const { |
OpenSSLErrStackTracer err_tracer(FROM_HERE); |
uint8_t *der; |
size_t der_len; |
@@ -183,7 +222,7 @@ bool ECPrivateKey::ExportPublicKey(std::vector<uint8_t>* output) { |
return true; |
} |
-bool ECPrivateKey::ExportRawPublicKey(std::string* output) { |
+bool ECPrivateKey::ExportRawPublicKey(std::string* output) const { |
OpenSSLErrStackTracer err_tracer(FROM_HERE); |
// Export the x and y field elements as 32-byte, big-endian numbers. (This is |
@@ -205,22 +244,6 @@ bool ECPrivateKey::ExportRawPublicKey(std::string* output) { |
return true; |
} |
-bool ECPrivateKey::ExportValueForTesting(std::vector<uint8_t>* output) { |
- OpenSSLErrStackTracer err_tracer(FROM_HERE); |
- EC_KEY* ec_key = EVP_PKEY_get0_EC_KEY(key_); |
- uint8_t *der; |
- size_t der_len; |
- AutoCBB cbb; |
- if (!CBB_init(cbb.get(), 0) || |
- !EC_KEY_marshal_private_key(cbb.get(), ec_key, 0 /* enc_flags */) || |
- !CBB_finish(cbb.get(), &der, &der_len)) { |
- return false; |
- } |
- output->assign(der, der + der_len); |
- OPENSSL_free(der); |
- return true; |
-} |
- |
ECPrivateKey::ECPrivateKey() : key_(NULL) {} |
} // namespace crypto |