Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Unified Diff: net/android/keystore_openssl.cc

Issue 833243008: Update from https://crrev.com/311145 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « mojo/edk/test/multiprocess_test_helper.cc ('k') | net/http/transport_security_state_static.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/android/keystore_openssl.cc
diff --git a/net/android/keystore_openssl.cc b/net/android/keystore_openssl.cc
index c0f308d517bcc2ecb18e840329f942ba7b1b0168..886b9ee67f8c51b141a997facf6ee4bba0d2cfc3 100644
--- a/net/android/keystore_openssl.cc
+++ b/net/android/keystore_openssl.cc
@@ -12,6 +12,7 @@
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
+#include <openssl/x509.h>
#include "base/android/build_info.h"
#include "base/android/jni_android.h"
@@ -66,6 +67,9 @@ namespace android {
namespace {
+using ScopedPKCS8_PRIV_KEY_INFO =
+ crypto::ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free>::Type;
+
extern const RSA_METHOD android_rsa_method;
extern const ECDSA_METHOD android_ecdsa_method;
@@ -318,8 +322,10 @@ const RSA_METHOD android_rsa_method = {
// 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.
-crypto::ScopedEVP_PKEY GetRsaPkeyWrapper(jobject private_key,
- AndroidRSA* legacy_rsa) {
+crypto::ScopedEVP_PKEY CreateRsaPkeyWrapper(
+ jobject private_key,
+ AndroidRSA* legacy_rsa,
+ const crypto::OpenSSLErrStackTracer& tracer) {
crypto::ScopedRSA rsa(
RSA_new_method(global_boringssl_engine.Get().engine()));
@@ -387,18 +393,26 @@ void LeakEngine(jobject private_key) {
s_instance.Get().LeakEngine(private_key);
}
-// Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object
-// for Android 4.0 to 4.1.x. Must only be used on Android < 4.2.
-// |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.
-crypto::ScopedEVP_PKEY GetRsaLegacyKey(jobject private_key) {
+// Creates an EVP_PKEY wrapper corresponding to the RSA key
+// |private_key|. Returns nullptr on failure.
+crypto::ScopedEVP_PKEY GetRsaPkeyWrapper(jobject private_key) {
+ const int kAndroid42ApiLevel = 17;
+ crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
+
+ if (base::android::BuildInfo::GetInstance()->sdk_int() >=
+ kAndroid42ApiLevel) {
+ return CreateRsaPkeyWrapper(private_key, nullptr, tracer);
+ }
+
+ // Route around platform bug: if Android < 4.2, then
+ // base::android::RawSignDigestWithPrivateKey() cannot work, so instead, try
+ // to get the system OpenSSL's EVP_PKEY begin this PrivateKey object.
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 crypto::ScopedEVP_PKEY();
+ return nullptr;
}
AndroidRSA* sys_rsa = sys_pkey->pkey.rsa;
@@ -412,25 +426,29 @@ crypto::ScopedEVP_PKEY GetRsaLegacyKey(jobject private_key) {
}
}
- return GetRsaPkeyWrapper(private_key, sys_rsa);
+ return CreateRsaPkeyWrapper(private_key, sys_rsa, tracer);
}
// GetOpenSSLSystemHandleForPrivateKey() will fail on Android 4.0.3 and
// earlier. However, it is possible to get the key content with
// PrivateKey.getEncoded() on these platforms. Note that this method may
- // return NULL on 4.0.4 and later.
- std::vector<uint8> encoded;
- if (!GetPrivateKeyEncodedBytes(private_key, &encoded)) {
+ // return false on 4.0.4 and later.
+ std::vector<uint8_t> encoded;
+ if (!GetPrivateKeyEncodedBytes(private_key, &encoded) || encoded.empty()) {
LOG(ERROR) << "Can't get private key data!";
- return crypto::ScopedEVP_PKEY();
+ return nullptr;
}
- const unsigned char* p =
- reinterpret_cast<const unsigned char*>(&encoded[0]);
- int len = static_cast<int>(encoded.size());
- crypto::ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, len));
- if (!pkey) {
- LOG(ERROR) << "Can't convert private key data!";
- return crypto::ScopedEVP_PKEY();
+ const uint8_t* p = &encoded[0];
+ ScopedPKCS8_PRIV_KEY_INFO pkcs8(
+ d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, encoded.size()));
+ if (!pkcs8.get() || p != &encoded[0] + encoded.size()) {
+ LOG(ERROR) << "Can't decode PrivateKeyInfo";
+ return nullptr;
+ }
+ crypto::ScopedEVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
+ if (!pkey || EVP_PKEY_id(pkey.get()) != EVP_PKEY_RSA) {
+ LOG(ERROR) << "Can't decode RSA key";
+ return nullptr;
}
return pkey.Pass();
}
@@ -503,6 +521,7 @@ int EcdsaMethodVerify(const uint8_t* digest,
// is owned by and destroyed with the EVP_PKEY. I.e. the caller shall
// always free |private_key| after the call.
crypto::ScopedEVP_PKEY GetEcdsaPkeyWrapper(jobject private_key) {
+ crypto::OpenSSLErrStackTracer tracer(FROM_HERE);
crypto::ScopedEC_KEY ec_key(
EC_KEY_new_method(global_boringssl_engine.Get().engine()));
@@ -553,29 +572,17 @@ const ECDSA_METHOD android_ecdsa_method = {
} // namespace
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.
- if (base::android::BuildInfo::GetInstance()->sdk_int() <
- kAndroid42ApiLevel) {
- return GetRsaLegacyKey(private_key);
- } else {
- // Running on Android 4.2.
- return GetRsaPkeyWrapper(private_key, NULL);
- }
+ return GetRsaPkeyWrapper(private_key);
case PRIVATE_KEY_TYPE_ECDSA:
return GetEcdsaPkeyWrapper(private_key);
default:
LOG(WARNING)
<< "GetOpenSSLPrivateKeyWrapper() called with invalid key type";
- return crypto::ScopedEVP_PKEY();
+ return nullptr;
}
}
« no previous file with comments | « mojo/edk/test/multiprocess_test_helper.cc ('k') | net/http/transport_security_state_static.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698