Chromium Code Reviews| Index: net/android/keystore_openssl.cc |
| diff --git a/net/android/keystore_openssl.cc b/net/android/keystore_openssl.cc |
| index 5c02cfd194afa3635ced2f0bbf701e6a90847b2d..1ca9bc1b3b19248df0e33a8a0d3d833e0e4bb0fd 100644 |
| --- a/net/android/keystore_openssl.cc |
| +++ b/net/android/keystore_openssl.cc |
| @@ -20,7 +20,6 @@ |
| #include "base/lazy_instance.h" |
| #include "base/logging.h" |
| #include "crypto/openssl_util.h" |
| -#include "crypto/scoped_openssl_types.h" |
| #include "net/android/keystore.h" |
| #include "net/android/legacy_openssl.h" |
| #include "net/ssl/ssl_client_cert_type.h" |
| @@ -315,14 +314,12 @@ const RSA_METHOD android_rsa_method = { |
| // |legacy_rsa|, if non-NULL, is a pointer to the system OpenSSL RSA object |
| // backing |private_key|. This parameter is only used for Android < 4.2 to |
| // implement key operations not exposed by the platform. |
| -// |pkey| is the EVP_PKEY to setup as a wrapper. |
| -// Returns true on success, false otherwise. |
| +// Returns a new EVP_PKEY on success, NULL otherwise. |
| // On success, this creates a new global JNI reference to the object |
| // that is owned by and destroyed with the EVP_PKEY. I.e. caller can |
| // free |private_key| after the call. |
| -bool GetRsaPkeyWrapper(jobject private_key, |
| - AndroidRSA* legacy_rsa, |
| - EVP_PKEY* pkey) { |
| +crypto::ScopedEVP_PKEY GetRsaPkeyWrapper(jobject private_key, |
| + AndroidRSA* legacy_rsa) { |
| crypto::ScopedRSA rsa( |
| RSA_new_method(global_boringssl_engine.Get().engine())); |
| @@ -330,13 +327,13 @@ bool GetRsaPkeyWrapper(jobject private_key, |
| global_key.Reset(NULL, private_key); |
| if (global_key.is_null()) { |
| LOG(ERROR) << "Could not create global JNI reference"; |
| - return false; |
| + return crypto::ScopedEVP_PKEY(); |
| } |
| std::vector<uint8> modulus; |
| if (!GetRSAKeyModulus(private_key, &modulus)) { |
| LOG(ERROR) << "Failed to get private key modulus"; |
| - return false; |
| + return crypto::ScopedEVP_PKEY(); |
| } |
| KeyExData* ex_data = new KeyExData; |
| @@ -345,8 +342,13 @@ bool GetRsaPkeyWrapper(jobject private_key, |
| ex_data->cached_size = VectorBignumSize(modulus); |
| RSA_set_ex_data( |
| rsa.get(), global_boringssl_engine.Get().rsa_ex_index(), ex_data); |
| - EVP_PKEY_assign_RSA(pkey, rsa.release()); |
| - return true; |
| + |
| + crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); |
| + if (!pkey || |
| + !EVP_PKEY_set1_RSA(pkey.get(), rsa.get())) { |
|
davidben
2014/09/09 23:07:19
It doesn't really matter because EVP_PKEY_set1_RSA
|
| + return crypto::ScopedEVP_PKEY(); |
| + } |
| + return pkey.Pass(); |
| } |
| // On Android < 4.2, the libkeystore.so ENGINE uses CRYPTO_EX_DATA and is not |
| @@ -390,13 +392,13 @@ void LeakEngine(jobject private_key) { |
| // |private_key| is a JNI reference (local or global) to the object. |
| // |pkey| is the EVP_PKEY to setup as a wrapper. |
| // Returns true on success, false otherwise. |
| -EVP_PKEY* GetRsaLegacyKey(jobject private_key) { |
| +crypto::ScopedEVP_PKEY GetRsaLegacyKey(jobject private_key) { |
| AndroidEVP_PKEY* sys_pkey = |
| GetOpenSSLSystemHandleForPrivateKey(private_key); |
| if (sys_pkey != NULL) { |
| if (sys_pkey->type != ANDROID_EVP_PKEY_RSA) { |
| LOG(ERROR) << "Private key has wrong type!"; |
| - return NULL; |
| + return crypto::ScopedEVP_PKEY(); |
| } |
| AndroidRSA* sys_rsa = sys_pkey->pkey.rsa; |
| @@ -410,10 +412,7 @@ EVP_PKEY* GetRsaLegacyKey(jobject private_key) { |
| } |
| } |
| - crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); |
| - if (!GetRsaPkeyWrapper(private_key, sys_rsa, pkey.get())) |
| - return NULL; |
| - return pkey.release(); |
| + return GetRsaPkeyWrapper(private_key, sys_rsa); |
| } |
| // GetOpenSSLSystemHandleForPrivateKey() will fail on Android 4.0.3 and |
| @@ -423,17 +422,17 @@ EVP_PKEY* GetRsaLegacyKey(jobject private_key) { |
| std::vector<uint8> encoded; |
| if (!GetPrivateKeyEncodedBytes(private_key, &encoded)) { |
| LOG(ERROR) << "Can't get private key data!"; |
| - return NULL; |
| + return crypto::ScopedEVP_PKEY(); |
| } |
| const unsigned char* p = |
| reinterpret_cast<const unsigned char*>(&encoded[0]); |
| int len = static_cast<int>(encoded.size()); |
| - EVP_PKEY* pkey = d2i_AutoPrivateKey(NULL, &p, len); |
| - if (pkey == NULL) { |
| + crypto::ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, len)); |
| + if (!pkey) { |
| LOG(ERROR) << "Can't convert private key data!"; |
| - return NULL; |
| + return crypto::ScopedEVP_PKEY(); |
| } |
| - return pkey; |
| + return pkey.Pass(); |
| } |
| // Custom ECDSA_METHOD that uses the platform APIs. |
| @@ -499,12 +498,11 @@ int EcdsaMethodVerify(const uint8_t* digest, |
| // Setup an EVP_PKEY to wrap an existing platform PrivateKey object. |
| // |private_key| is the JNI reference (local or global) to the object. |
| -// |pkey| is the EVP_PKEY to setup as a wrapper. |
| -// Returns true on success, false otherwise. |
| +// Returns a new EVP_PKEY on success, NULL otherwise. |
| // On success, this creates a global JNI reference to the object that |
| // is owned by and destroyed with the EVP_PKEY. I.e. the caller shall |
| // always free |private_key| after the call. |
| -bool GetEcdsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { |
| +crypto::ScopedEVP_PKEY GetEcdsaPkeyWrapper(jobject private_key) { |
| crypto::ScopedEC_KEY ec_key( |
| EC_KEY_new_method(global_boringssl_engine.Get().engine())); |
| @@ -512,13 +510,13 @@ bool GetEcdsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { |
| global_key.Reset(NULL, private_key); |
| if (global_key.is_null()) { |
| LOG(ERROR) << "Can't create global JNI reference"; |
| - return false; |
| + return crypto::ScopedEVP_PKEY(); |
| } |
| std::vector<uint8> order; |
| if (!GetECKeyOrder(private_key, &order)) { |
| LOG(ERROR) << "Can't extract order parameter from EC private key"; |
| - return false; |
| + return crypto::ScopedEVP_PKEY(); |
| } |
| KeyExData* ex_data = new KeyExData; |
| @@ -529,8 +527,12 @@ bool GetEcdsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { |
| EC_KEY_set_ex_data( |
| ec_key.get(), global_boringssl_engine.Get().ec_key_ex_index(), ex_data); |
| - EVP_PKEY_assign_EC_KEY(pkey, ec_key.release()); |
| - return true; |
| + crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); |
| + if (!pkey || |
| + !EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get())) { |
| + return crypto::ScopedEVP_PKEY(); |
| + } |
| + return pkey.Pass(); |
| } |
| const ECDSA_METHOD android_ecdsa_method = { |
| @@ -550,45 +552,31 @@ const ECDSA_METHOD android_ecdsa_method = { |
| } // namespace |
| -EVP_PKEY* GetOpenSSLPrivateKeyWrapper(jobject private_key) { |
| - // Create new empty EVP_PKEY instance. |
| - crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); |
| - if (!pkey.get()) |
| - return NULL; |
| +crypto::ScopedEVP_PKEY GetOpenSSLPrivateKeyWrapper(jobject private_key) { |
| + const int kAndroid42ApiLevel = 17; |
| // Create sub key type, depending on private key's algorithm type. |
| PrivateKeyType key_type = GetPrivateKeyType(private_key); |
| switch (key_type) { |
| case PRIVATE_KEY_TYPE_RSA: |
| - { |
| - // Route around platform bug: if Android < 4.2, then |
| - // base::android::RawSignDigestWithPrivateKey() cannot work, so |
| - // instead, obtain a raw EVP_PKEY* to the system object |
| - // backing this PrivateKey object. |
| - const int kAndroid42ApiLevel = 17; |
| - if (base::android::BuildInfo::GetInstance()->sdk_int() < |
| - kAndroid42ApiLevel) { |
| - EVP_PKEY* legacy_key = GetRsaLegacyKey(private_key); |
| - if (legacy_key == NULL) |
| - return NULL; |
| - pkey.reset(legacy_key); |
| - } else { |
| - // Running on Android 4.2. |
| - if (!GetRsaPkeyWrapper(private_key, NULL, pkey.get())) |
| - return NULL; |
| - } |
| + // Route around platform bug: if Android < 4.2, then |
| + // base::android::RawSignDigestWithPrivateKey() cannot work, so |
| + // instead, obtain a raw EVP_PKEY* to the system object |
| + // backing this PrivateKey object. |
| + if (base::android::BuildInfo::GetInstance()->sdk_int() < |
| + kAndroid42ApiLevel) { |
| + return GetRsaLegacyKey(private_key); |
| + } else { |
| + // Running on Android 4.2. |
| + return GetRsaPkeyWrapper(private_key, NULL); |
| } |
| - break; |
| case PRIVATE_KEY_TYPE_ECDSA: |
| - if (!GetEcdsaPkeyWrapper(private_key, pkey.get())) |
| - return NULL; |
| - break; |
| + return GetEcdsaPkeyWrapper(private_key); |
| default: |
| LOG(WARNING) |
| << "GetOpenSSLPrivateKeyWrapper() called with invalid key type"; |
| - return NULL; |
| + return crypto::ScopedEVP_PKEY(); |
| } |
| - return pkey.release(); |
| } |
| } // namespace android |