Index: net/base/openssl_private_key_store_android.cc |
diff --git a/net/base/openssl_private_key_store_android.cc b/net/base/openssl_private_key_store_android.cc |
index 4bf1f3fedcb555fd316acfa0a183f0972079146b..17ed763690df34fed8115645aa0218a6fb09b738 100644 |
--- a/net/base/openssl_private_key_store_android.cc |
+++ b/net/base/openssl_private_key_store_android.cc |
@@ -9,18 +9,27 @@ |
#include "base/logging.h" |
#include "base/memory/singleton.h" |
+#include "base/synchronization/lock.h" |
#include "crypto/openssl_util.h" |
#include "net/android/network_library.h" |
+#include "net/base/openssl_util.h" |
namespace net { |
namespace { |
+typedef crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> ScopedEVP_PKEY; |
+ |
class OpenSSLKeyStoreAndroid : public OpenSSLPrivateKeyStore { |
public: |
- ~OpenSSLKeyStoreAndroid() {} |
+ ~OpenSSLKeyStoreAndroid() OVERRIDE {} |
Ryan Sleevi
2013/02/12 20:12:58
style: Don't put OVERRIDE on destructor
style: Put
digit1
2013/02/13 18:24:34
Done.
|
+ |
+ static OpenSSLKeyStoreAndroid* GetInstance() { |
+ return Singleton<OpenSSLKeyStoreAndroid, |
+ OpenSSLKeyStoreAndroidLeakyTraits>::get(); |
Ryan Sleevi
2013/02/12 20:12:58
nit: indents (align to < >
digit1
2013/02/13 18:24:34
Done.
|
+ } |
- virtual bool StorePrivateKey(const GURL& url, EVP_PKEY* pkey) { |
+ virtual bool StoreKeyPair(const GURL& url, EVP_PKEY* pkey) OVERRIDE { |
// Always clear openssl errors on exit. |
crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); |
@@ -45,25 +54,40 @@ class OpenSSLKeyStoreAndroid : public OpenSSLPrivateKeyStore { |
static_cast<const uint8*>(public_key), public_len, |
static_cast<const uint8*>(private_key), private_len); |
} |
- LOG_IF(ERROR, !ret) << "StorePrivateKey failed. pub len = " << public_len |
+ LOG_IF(ERROR, !ret) << "StoreKeyPair failed. pub len = " << public_len |
<< " priv len = " << private_len; |
OPENSSL_free(public_key); |
OPENSSL_free(private_key); |
return ret; |
} |
- virtual EVP_PKEY* FetchPrivateKey(EVP_PKEY* pkey) { |
- // TODO(joth): Implement when client authentication is required. |
- NOTIMPLEMENTED(); |
- return NULL; |
+ virtual bool RecordClientCertPrivateKey( |
+ const net::X509Certificate& client_cert, |
+ EVP_PKEY* private_key) OVERRIDE { |
+ // Sanity check. |
+ if (private_key == NULL) { |
+ LOG(ERROR) << "NULL private key for client certificate!"; |
+ return false; |
+ } |
+ // Get public key from certificate. |
+ ScopedEVP_PKEY pub_key(GetCertificatePublicKeyOpenSSL(client_cert)); |
+ if (!pub_key.get()) { |
+ LOG(ERROR) << "Can't extract public key from certificate!"; |
+ return false; |
+ } |
+ base::AutoLock lock(lock_); |
+ return pairs_.AddKeyPair(pub_key.get(), private_key); |
} |
- static OpenSSLKeyStoreAndroid* GetInstance() { |
- // Leak the OpenSSL key store as it is used from a non-joinable worker |
- // thread that may still be running at shutdown. |
- return Singleton< |
- OpenSSLKeyStoreAndroid, |
- OpenSSLKeyStoreAndroidLeakyTraits>::get(); |
+ virtual EVP_PKEY* FetchClientCertPrivateKey( |
+ const X509Certificate& client_cert) { |
+ ScopedEVP_PKEY pub_key(GetCertificatePublicKeyOpenSSL(client_cert)); |
+ if (!pub_key.get()) { |
+ LOG(ERROR) << "Could not extract public key from client certificate"; |
+ return NULL; |
+ } |
+ base::AutoLock lock(lock_); |
+ return pairs_.FindPrivateKey(pub_key.get()); |
} |
private: |
@@ -73,6 +97,9 @@ class OpenSSLKeyStoreAndroid : public OpenSSLPrivateKeyStore { |
OpenSSLKeyStoreAndroid() {} |
+ OpenSSLKeyPairList pairs_; |
+ base::Lock lock_; |
+ |
DISALLOW_COPY_AND_ASSIGN(OpenSSLKeyStoreAndroid); |
}; |