summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/base/cert_database_openssl.cc20
-rw-r--r--net/base/keygen_handler_openssl.cc8
-rw-r--r--net/base/openssl_memory_private_key_store.cc64
-rw-r--r--net/base/openssl_private_key_store.h51
-rw-r--r--net/base/ssl_config_service.h2
-rw-r--r--net/net.gyp4
-rw-r--r--net/socket/ssl_client_socket_openssl.cc17
7 files changed, 152 insertions, 14 deletions
diff --git a/net/base/cert_database_openssl.cc b/net/base/cert_database_openssl.cc
index 73a67c1..ec5ec24 100644
--- a/net/base/cert_database_openssl.cc
+++ b/net/base/cert_database_openssl.cc
@@ -4,7 +4,11 @@
#include "net/base/cert_database.h"
+#include <openssl/x509.h>
+
+#include "base/logging.h"
#include "net/base/net_errors.h"
+#include "net/base/openssl_private_key_store.h"
#include "net/base/x509_certificate.h"
namespace net {
@@ -18,22 +22,28 @@ int CertDatabase::CheckUserCert(X509Certificate* cert) {
if (cert->HasExpired())
return ERR_CERT_DATE_INVALID;
- // TODO(bulach): implement me.
- return ERR_NOT_IMPLEMENTED;
+ if (!OpenSSLPrivateKeyStore::GetInstance()->FetchPrivateKey(
+ X509_PUBKEY_get(X509_get_X509_PUBKEY(cert->os_cert_handle()))))
+ return ERR_NO_PRIVATE_KEY_FOR_CERT;
+
+ return OK;
}
int CertDatabase::AddUserCert(X509Certificate* cert) {
// TODO(bulach): implement me.
+ NOTIMPLEMENTED();
return ERR_NOT_IMPLEMENTED;
}
void CertDatabase::ListCerts(CertificateList* certs) {
// TODO(bulach): implement me.
+ NOTIMPLEMENTED();
}
int CertDatabase::ImportFromPKCS12(const std::string& data,
const string16& password) {
// TODO(bulach): implement me.
+ NOTIMPLEMENTED();
return ERR_NOT_IMPLEMENTED;
}
@@ -41,18 +51,20 @@ int CertDatabase::ExportToPKCS12(const CertificateList& certs,
const string16& password,
std::string* output) const {
// TODO(bulach): implement me.
+ NOTIMPLEMENTED();
return 0;
}
bool CertDatabase::DeleteCertAndKey(const X509Certificate* cert) {
// TODO(bulach): implement me.
+ NOTIMPLEMENTED();
return false;
}
unsigned int CertDatabase::GetCertTrust(const X509Certificate* cert,
CertType type) const {
// TODO(bulach): implement me.
- // NOTE: This method is currently only declared for USE_NSS builds.
+ NOTIMPLEMENTED();
return 0;
}
@@ -60,7 +72,7 @@ bool CertDatabase::SetCertTrust(const X509Certificate* cert,
CertType type,
unsigned int trust_bits) {
// TODO(bulach): implement me.
- // NOTE: This method is currently only declared for USE_NSS builds.
+ NOTIMPLEMENTED();
return false;
}
diff --git a/net/base/keygen_handler_openssl.cc b/net/base/keygen_handler_openssl.cc
index b04f098..73aabd7 100644
--- a/net/base/keygen_handler_openssl.cc
+++ b/net/base/keygen_handler_openssl.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "base/openssl_util.h"
#include "base/scoped_ptr.h"
+#include "net/base/openssl_private_key_store.h"
namespace net {
@@ -18,11 +19,8 @@ std::string KeygenHandler::GenKeyAndSignChallenge() {
base::RSAPrivateKey::Create(key_size_in_bits_));
EVP_PKEY* pkey = key->key();
- if (stores_key_) {
- // TODO(joth): Add an abstraction for persisting OpenSSL private keys.
- // See http://crbug.com/64917
- NOTIMPLEMENTED();
- }
+ if (stores_key_)
+ OpenSSLPrivateKeyStore::GetInstance()->StorePrivateKey(url_, pkey);
base::ScopedOpenSSL<NETSCAPE_SPKI, NETSCAPE_SPKI_free> spki(
NETSCAPE_SPKI_new());
diff --git a/net/base/openssl_memory_private_key_store.cc b/net/base/openssl_memory_private_key_store.cc
new file mode 100644
index 0000000..8dc69a0
--- /dev/null
+++ b/net/base/openssl_memory_private_key_store.cc
@@ -0,0 +1,64 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Defines an in-memory private key store, primarily used for testing.
+
+#include <openssl/evp.h>
+
+#include "net/base/openssl_private_key_store.h"
+
+#include "base/logging.h"
+#include "base/openssl_util.h"
+#include "base/singleton.h"
+#include "net/base/x509_certificate.h"
+
+namespace net {
+
+namespace {
+
+class OpenSSLMemoryKeyStore : public OpenSSLPrivateKeyStore {
+ public:
+ OpenSSLMemoryKeyStore() {}
+
+ virtual ~OpenSSLMemoryKeyStore() {
+ AutoLock lock(lock_);
+ for (std::vector<EVP_PKEY*>::iterator it = keys_.begin();
+ it != keys_.end(); ++it) {
+ EVP_PKEY_free(*it);
+ }
+ }
+
+ virtual bool StorePrivateKey(const GURL& url, EVP_PKEY* pkey) {
+ CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+ AutoLock lock(lock_);
+ keys_.push_back(pkey);
+ return true;
+ }
+
+ virtual EVP_PKEY* FetchPrivateKey(EVP_PKEY* pkey) {
+ AutoLock lock(lock_);
+ for (std::vector<EVP_PKEY*>::iterator it = keys_.begin();
+ it != keys_.end(); ++it) {
+ if (EVP_PKEY_cmp(*it, pkey) == 1)
+ return *it;
+ }
+ return NULL;
+ }
+
+ private:
+ std::vector<EVP_PKEY*> keys_;
+ Lock lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(OpenSSLMemoryKeyStore);
+};
+
+} // namespace
+
+// static
+OpenSSLPrivateKeyStore* OpenSSLPrivateKeyStore::GetInstance() {
+ return Singleton<OpenSSLMemoryKeyStore>::get();
+}
+
+} // namespace net
+
diff --git a/net/base/openssl_private_key_store.h b/net/base/openssl_private_key_store.h
new file mode 100644
index 0000000..17f8fe1
--- /dev/null
+++ b/net/base/openssl_private_key_store.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_BASE_OPENSSL_PRIVATE_KEY_STORE_H_
+#define NET_BASE_OPENSSL_PRIVATE_KEY_STORE_H_
+#pragma once
+
+#include "base/basictypes.h"
+
+typedef struct evp_pkey_st EVP_PKEY;
+
+class GURL;
+
+namespace net {
+
+// Defines an abstract store for private keys; the OpenSSL library does not
+// provide this service so it is left to individual platforms to provide it.
+//
+// The contract is that the private key will be stored in an appropriate secure
+// system location, and be available to the SSLClientSocketOpenSSL when using a
+// client certificate created against the associated public key for client
+// authentication.
+class OpenSSLPrivateKeyStore {
+ public:
+ // Platforms must define this factory function as appropriate.
+ static OpenSSLPrivateKeyStore* GetInstance();
+
+ virtual ~OpenSSLPrivateKeyStore() {}
+
+ // Called to store a private key generated via <keygen> while visiting |url|.
+ // Does not takes ownership of |pkey|, the caller reamins responsible to
+ // EVP_PKEY_free it. (Internally, a copy maybe made or the reference count
+ // incremented).
+ // Returns false if an error occurred whilst attempting to store the key.
+ virtual bool StorePrivateKey(const GURL& url, EVP_PKEY* pkey) = 0;
+
+ // Given a |public_key| part returns the corresponding private key, or NULL
+ // if no key found. Does NOT return ownership.
+ virtual EVP_PKEY* FetchPrivateKey(EVP_PKEY* public_key) = 0;
+
+ protected:
+ OpenSSLPrivateKeyStore() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(OpenSSLPrivateKeyStore);
+};
+
+} // namespace net
+
+#endif // NET_BASE_OPENSSL_PRIVATE_KEY_STORE_H_
diff --git a/net/base/ssl_config_service.h b/net/base/ssl_config_service.h
index 899b329..c1ae553 100644
--- a/net/base/ssl_config_service.h
+++ b/net/base/ssl_config_service.h
@@ -33,7 +33,7 @@ struct SSLConfig {
bool dns_cert_provenance_checking_enabled;
// Cipher suites which should be explicitly prevented from being used in
- // addition to those disabled by the net built in policy -- by default, all
+ // addition to those disabled by the net built-in policy -- by default, all
// cipher suites supported by the underlying SSL implementation will be
// enabled except for:
// - Null encryption cipher suites.
diff --git a/net/net.gyp b/net/net.gyp
index cb589ea..31b9cea 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -142,6 +142,8 @@
'base/network_config_watcher_mac.h',
'base/nss_memio.c',
'base/nss_memio.h',
+ 'base/openssl_memory_private_key_store.cc',
+ 'base/openssl_private_key_store.h',
'base/pem_tokenizer.cc',
'base/pem_tokenizer.h',
'base/platform_mime_util.h',
@@ -285,6 +287,8 @@
'sources!': [
'base/cert_database_openssl.cc',
'base/keygen_handler_openssl.cc',
+ 'base/openssl_memory_private_key_store.cc',
+ 'base/openssl_private_key_store.h',
'base/x509_certificate_openssl.cc',
'base/x509_openssl_util.cc',
'base/x509_openssl_util.h',
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index b3690a9..145aec9 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -16,6 +16,7 @@
#include "base/singleton.h"
#include "net/base/cert_verifier.h"
#include "net/base/net_errors.h"
+#include "net/base/openssl_private_key_store.h"
#include "net/base/ssl_cert_request_info.h"
#include "net/base/ssl_connection_status_flags.h"
#include "net/base/ssl_info.h"
@@ -528,10 +529,18 @@ int SSLClientSocketOpenSSL::ClientCertRequestCallback(SSL* ssl,
// Second pass: a client certificate should have been selected.
if (ssl_config_.client_cert) {
- // TODO(joth): We need a way to lookup the private key this
- // certificate. See http://crbug.com/64951 and example code in
- // http://codereview.chromium.org/5195001/diff/6001/net/socket/ssl_client_socket_openssl.cc
- NOTIMPLEMENTED();
+ EVP_PKEY* privkey = OpenSSLPrivateKeyStore::GetInstance()->FetchPrivateKey(
+ X509_PUBKEY_get(X509_get_X509_PUBKEY(
+ ssl_config_.client_cert->os_cert_handle())));
+ if (privkey) {
+ // TODO(joth): (copied from NSS) We should wait for server certificate
+ // verification before sending our credentials. See http://crbug.com/13934
+ *x509 = X509Certificate::DupOSCertHandle(
+ ssl_config_.client_cert->os_cert_handle());
+ *pkey = privkey;
+ return 1;
+ }
+ LOG(WARNING) << "Client cert found without private key";
}
// Send no client certificate.