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

Side by Side Diff: net/base/openssl_private_key_store_android.cc

Issue 12220104: Wire up SSL client authentication for OpenSSL/Android through the net/ stack (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 7 years, 10 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/base/openssl_private_key_store.h" 5 #include "net/base/openssl_private_key_store.h"
6 6
7 #include <openssl/evp.h> 7 #include <openssl/evp.h>
8 #include <openssl/x509.h> 8 #include <openssl/x509.h>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/singleton.h" 11 #include "base/memory/singleton.h"
12 #include "base/synchronization/lock.h"
12 #include "crypto/openssl_util.h" 13 #include "crypto/openssl_util.h"
13 #include "net/android/network_library.h" 14 #include "net/android/network_library.h"
15 #include "net/base/openssl_util.h"
14 16
15 namespace net { 17 namespace net {
16 18
17 namespace { 19 namespace {
18 20
21 typedef crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> ScopedEVP_PKEY;
22
19 class OpenSSLKeyStoreAndroid : public OpenSSLPrivateKeyStore { 23 class OpenSSLKeyStoreAndroid : public OpenSSLPrivateKeyStore {
20 public: 24 public:
21 ~OpenSSLKeyStoreAndroid() {} 25 ~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.
22 26
23 virtual bool StorePrivateKey(const GURL& url, EVP_PKEY* pkey) { 27 static OpenSSLKeyStoreAndroid* GetInstance() {
28 return Singleton<OpenSSLKeyStoreAndroid,
29 OpenSSLKeyStoreAndroidLeakyTraits>::get();
Ryan Sleevi 2013/02/12 20:12:58 nit: indents (align to < >
digit1 2013/02/13 18:24:34 Done.
30 }
31
32 virtual bool StoreKeyPair(const GURL& url, EVP_PKEY* pkey) OVERRIDE {
24 // Always clear openssl errors on exit. 33 // Always clear openssl errors on exit.
25 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE); 34 crypto::OpenSSLErrStackTracer err_trace(FROM_HERE);
26 35
27 // Important: Do not use i2d_PublicKey() here, which returns data in 36 // Important: Do not use i2d_PublicKey() here, which returns data in
28 // PKCS#1 format, use i2d_PUBKEY() which returns it as DER-encoded 37 // PKCS#1 format, use i2d_PUBKEY() which returns it as DER-encoded
29 // SubjectPublicKeyInfo (X.509), as expected by the platform. 38 // SubjectPublicKeyInfo (X.509), as expected by the platform.
30 unsigned char* public_key = NULL; 39 unsigned char* public_key = NULL;
31 int public_len = i2d_PUBKEY(pkey, &public_key); 40 int public_len = i2d_PUBKEY(pkey, &public_key);
32 41
33 // Important: Do not use i2d_PrivateKey() here, it returns data 42 // Important: Do not use i2d_PrivateKey() here, it returns data
34 // in a format that is incompatible with what the platform expects. 43 // in a format that is incompatible with what the platform expects.
35 unsigned char* private_key = NULL; 44 unsigned char* private_key = NULL;
36 int private_len = 0; 45 int private_len = 0;
37 crypto::ScopedOpenSSL<PKCS8_PRIV_KEY_INFO, 46 crypto::ScopedOpenSSL<PKCS8_PRIV_KEY_INFO,
38 PKCS8_PRIV_KEY_INFO_free> pkcs8(EVP_PKEY2PKCS8(pkey)); 47 PKCS8_PRIV_KEY_INFO_free> pkcs8(EVP_PKEY2PKCS8(pkey));
39 if (pkcs8.get() != NULL) { 48 if (pkcs8.get() != NULL) {
40 private_len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &private_key); 49 private_len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &private_key);
41 } 50 }
42 bool ret = false; 51 bool ret = false;
43 if (public_len > 0 && private_len > 0) { 52 if (public_len > 0 && private_len > 0) {
44 ret = net::android::StoreKeyPair( 53 ret = net::android::StoreKeyPair(
45 static_cast<const uint8*>(public_key), public_len, 54 static_cast<const uint8*>(public_key), public_len,
46 static_cast<const uint8*>(private_key), private_len); 55 static_cast<const uint8*>(private_key), private_len);
47 } 56 }
48 LOG_IF(ERROR, !ret) << "StorePrivateKey failed. pub len = " << public_len 57 LOG_IF(ERROR, !ret) << "StoreKeyPair failed. pub len = " << public_len
49 << " priv len = " << private_len; 58 << " priv len = " << private_len;
50 OPENSSL_free(public_key); 59 OPENSSL_free(public_key);
51 OPENSSL_free(private_key); 60 OPENSSL_free(private_key);
52 return ret; 61 return ret;
53 } 62 }
54 63
55 virtual EVP_PKEY* FetchPrivateKey(EVP_PKEY* pkey) { 64 virtual bool RecordClientCertPrivateKey(
56 // TODO(joth): Implement when client authentication is required. 65 const net::X509Certificate& client_cert,
57 NOTIMPLEMENTED(); 66 EVP_PKEY* private_key) OVERRIDE {
58 return NULL; 67 // Sanity check.
68 if (private_key == NULL) {
69 LOG(ERROR) << "NULL private key for client certificate!";
70 return false;
71 }
72 // Get public key from certificate.
73 ScopedEVP_PKEY pub_key(GetCertificatePublicKeyOpenSSL(client_cert));
74 if (!pub_key.get()) {
75 LOG(ERROR) << "Can't extract public key from certificate!";
76 return false;
77 }
78 base::AutoLock lock(lock_);
79 return pairs_.AddKeyPair(pub_key.get(), private_key);
59 } 80 }
60 81
61 static OpenSSLKeyStoreAndroid* GetInstance() { 82 virtual EVP_PKEY* FetchClientCertPrivateKey(
62 // Leak the OpenSSL key store as it is used from a non-joinable worker 83 const X509Certificate& client_cert) {
63 // thread that may still be running at shutdown. 84 ScopedEVP_PKEY pub_key(GetCertificatePublicKeyOpenSSL(client_cert));
64 return Singleton< 85 if (!pub_key.get()) {
65 OpenSSLKeyStoreAndroid, 86 LOG(ERROR) << "Could not extract public key from client certificate";
66 OpenSSLKeyStoreAndroidLeakyTraits>::get(); 87 return NULL;
88 }
89 base::AutoLock lock(lock_);
90 return pairs_.FindPrivateKey(pub_key.get());
67 } 91 }
68 92
69 private: 93 private:
70 friend struct DefaultSingletonTraits<OpenSSLKeyStoreAndroid>; 94 friend struct DefaultSingletonTraits<OpenSSLKeyStoreAndroid>;
71 typedef LeakySingletonTraits<OpenSSLKeyStoreAndroid> 95 typedef LeakySingletonTraits<OpenSSLKeyStoreAndroid>
72 OpenSSLKeyStoreAndroidLeakyTraits; 96 OpenSSLKeyStoreAndroidLeakyTraits;
73 97
74 OpenSSLKeyStoreAndroid() {} 98 OpenSSLKeyStoreAndroid() {}
75 99
100 OpenSSLKeyPairList pairs_;
101 base::Lock lock_;
102
76 DISALLOW_COPY_AND_ASSIGN(OpenSSLKeyStoreAndroid); 103 DISALLOW_COPY_AND_ASSIGN(OpenSSLKeyStoreAndroid);
77 }; 104 };
78 105
79 } // namespace 106 } // namespace
80 107
81 OpenSSLPrivateKeyStore* OpenSSLPrivateKeyStore::GetInstance() { 108 OpenSSLPrivateKeyStore* OpenSSLPrivateKeyStore::GetInstance() {
82 return OpenSSLKeyStoreAndroid::GetInstance(); 109 return OpenSSLKeyStoreAndroid::GetInstance();
83 } 110 }
84 111
85 } // namespace net 112 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698