summaryrefslogtreecommitdiffstats
path: root/net/android
diff options
context:
space:
mode:
authordavidben <davidben@chromium.org>2014-09-10 15:13:19 -0700
committerCommit bot <commit-bot@chromium.org>2014-09-10 22:24:55 +0000
commit2a463aa5cfadb60605e7d63cd00af8fd7ffbadf7 (patch)
tree52043825007b53feb00cfdd9f1ce2f265ebd4031 /net/android
parentdd89f911f78a0082a238c46e80edef583fe21acd (diff)
downloadchromium_src-2a463aa5cfadb60605e7d63cd00af8fd7ffbadf7.zip
chromium_src-2a463aa5cfadb60605e7d63cd00af8fd7ffbadf7.tar.gz
chromium_src-2a463aa5cfadb60605e7d63cd00af8fd7ffbadf7.tar.bz2
Use ScopedEVP_PKEY in keystore_openssl.cc.
Somewhat cleaner without having to pass around half-constructed EVP_PKEY objects everywhere. BUG=none Review URL: https://codereview.chromium.org/553223002 Cr-Commit-Position: refs/heads/master@{#294241}
Diffstat (limited to 'net/android')
-rw-r--r--net/android/keystore_openssl.cc100
-rw-r--r--net/android/keystore_openssl.h4
2 files changed, 47 insertions, 57 deletions
diff --git a/net/android/keystore_openssl.cc b/net/android/keystore_openssl.cc
index 5c02cfd..1ca9bc1 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())) {
+ 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
diff --git a/net/android/keystore_openssl.h b/net/android/keystore_openssl.h
index ceb900c..2de4e0a 100644
--- a/net/android/keystore_openssl.h
+++ b/net/android/keystore_openssl.h
@@ -8,6 +8,7 @@
#include <jni.h>
#include <openssl/evp.h>
+#include "crypto/scoped_openssl_types.h"
#include "net/base/net_export.h"
// OpenSSL-specific functions to use the Android platform keystore.
@@ -40,7 +41,8 @@ namespace android {
// *sign* the digest that is part of the "Verify Certificate" message
// during the OpenSSL handshake. Anything else will result in undefined
// behaviour.
-NET_EXPORT EVP_PKEY* GetOpenSSLPrivateKeyWrapper(jobject private_key);
+NET_EXPORT crypto::ScopedEVP_PKEY GetOpenSSLPrivateKeyWrapper(
+ jobject private_key);
} // namespace android
} // namespace net