diff options
Diffstat (limited to 'chromium/net/ssl')
48 files changed, 786 insertions, 334 deletions
diff --git a/chromium/net/ssl/channel_id_service.cc b/chromium/net/ssl/channel_id_service.cc index cfa61ccdde7..e17b813cd73 100644 --- a/chromium/net/ssl/channel_id_service.cc +++ b/chromium/net/ssl/channel_id_service.cc @@ -6,6 +6,7 @@ #include <algorithm> #include <limits> +#include <utility> #include "base/bind.h" #include "base/bind_helpers.h" @@ -13,6 +14,7 @@ #include "base/compiler_specific.h" #include "base/location.h" #include "base/logging.h" +#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/metrics/histogram_macros.h" @@ -93,18 +95,18 @@ scoped_ptr<ChannelIDStore::ChannelID> GenerateChannelID( if (!key) { DLOG(ERROR) << "Unable to create channel ID key pair"; *error = ERR_KEY_GENERATION_FAILED; - return result.Pass(); + return result; } result.reset(new ChannelIDStore::ChannelID(server_identifier, creation_time, - key.Pass())); + std::move(key))); UMA_HISTOGRAM_CUSTOM_TIMES("DomainBoundCerts.GenerateCertTime", base::TimeTicks::Now() - start, base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(5), 50); *error = OK; - return result.Pass(); + return result; } } // namespace @@ -182,7 +184,7 @@ class ChannelIDServiceJob { } void HandleResult(int error, scoped_ptr<crypto::ECPrivateKey> key) { - PostAll(error, key.Pass()); + PostAll(error, std::move(key)); } bool CreateIfMissing() const { return create_if_missing_; } @@ -203,7 +205,7 @@ class ChannelIDServiceJob { scoped_ptr<crypto::ECPrivateKey> key_copy; if (key) key_copy.reset(key->Copy()); - (*i)->Post(error, key_copy.Pass()); + (*i)->Post(error, std::move(key_copy)); } } @@ -274,7 +276,7 @@ void ChannelIDService::Request::Post(int error, service_ = NULL; DCHECK(!callback_.is_null()); if (key) - *key_ = key.Pass(); + *key_ = std::move(key); // Running the callback might delete |this| (e.g. the callback cleans up // resources created for the request), so we can't touch any of our // members afterwards. Reset callback_ first. @@ -412,14 +414,14 @@ void ChannelIDService::GotChannelID(int err, // Async DB lookup found a valid channel ID. key_store_hits_++; // ChannelIDService::Request::Post will do the histograms and stuff. - HandleResult(OK, server_identifier, key.Pass()); + HandleResult(OK, server_identifier, std::move(key)); return; } // Async lookup failed or the channel ID was missing. Return the error // directly, unless the channel ID was missing and a request asked to create // one. if (err != ERR_FILE_NOT_FOUND || !j->second->CreateIfMissing()) { - HandleResult(err, server_identifier, key.Pass()); + HandleResult(err, server_identifier, std::move(key)); return; } // At least one request asked to create a channel ID => start generating a new @@ -449,9 +451,9 @@ void ChannelIDService::GeneratedChannelID( scoped_ptr<crypto::ECPrivateKey> key; if (error == OK) { key.reset(channel_id->key()->Copy()); - channel_id_store_->SetChannelID(channel_id.Pass()); + channel_id_store_->SetChannelID(std::move(channel_id)); } - HandleResult(error, server_identifier, key.Pass()); + HandleResult(error, server_identifier, std::move(key)); } void ChannelIDService::HandleResult(int error, @@ -468,7 +470,7 @@ void ChannelIDService::HandleResult(int error, ChannelIDServiceJob* job = j->second; inflight_.erase(j); - job->HandleResult(error, key.Pass()); + job->HandleResult(error, std::move(key)); delete job; } diff --git a/chromium/net/ssl/channel_id_service.h b/chromium/net/ssl/channel_id_service.h index abb22fa6862..eb4a92ae6f5 100644 --- a/chromium/net/ssl/channel_id_service.h +++ b/chromium/net/ssl/channel_id_service.h @@ -5,11 +5,13 @@ #ifndef NET_SSL_CHANNEL_ID_SERVICE_H_ #define NET_SSL_CHANNEL_ID_SERVICE_H_ +#include <stdint.h> + #include <map> #include <string> #include <vector> -#include "base/basictypes.h" +#include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/threading/non_thread_safe.h" @@ -129,10 +131,10 @@ class NET_EXPORT ChannelIDService // Public only for unit testing. int channel_id_count(); - uint64 requests() const { return requests_; } - uint64 key_store_hits() const { return key_store_hits_; } - uint64 inflight_joins() const { return inflight_joins_; } - uint64 workers_created() const { return workers_created_; } + uint64_t requests() const { return requests_; } + uint64_t key_store_hits() const { return key_store_hits_; } + uint64_t inflight_joins() const { return inflight_joins_; } + uint64_t workers_created() const { return workers_created_; } private: void GotChannelID(int err, @@ -174,10 +176,10 @@ class NET_EXPORT ChannelIDService // place. std::map<std::string, ChannelIDServiceJob*> inflight_; - uint64 requests_; - uint64 key_store_hits_; - uint64 inflight_joins_; - uint64 workers_created_; + uint64_t requests_; + uint64_t key_store_hits_; + uint64_t inflight_joins_; + uint64_t workers_created_; base::WeakPtrFactory<ChannelIDService> weak_ptr_factory_; diff --git a/chromium/net/ssl/channel_id_service_unittest.cc b/chromium/net/ssl/channel_id_service_unittest.cc index 2a2ec962d50..1e98b61a674 100644 --- a/chromium/net/ssl/channel_id_service_unittest.cc +++ b/chromium/net/ssl/channel_id_service_unittest.cc @@ -9,6 +9,7 @@ #include "base/bind.h" #include "base/location.h" +#include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" #include "base/single_thread_task_runner.h" diff --git a/chromium/net/ssl/channel_id_store.cc b/chromium/net/ssl/channel_id_store.cc index e1835ff1546..1345da13cbb 100644 --- a/chromium/net/ssl/channel_id_store.cc +++ b/chromium/net/ssl/channel_id_store.cc @@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "crypto/ec_private_key.h" #include "net/ssl/channel_id_store.h" +#include <utility> + +#include "crypto/ec_private_key.h" + namespace net { ChannelIDStore::ChannelID::ChannelID() { @@ -15,8 +18,7 @@ ChannelIDStore::ChannelID::ChannelID(const std::string& server_identifier, scoped_ptr<crypto::ECPrivateKey> key) : server_identifier_(server_identifier), creation_time_(creation_time), - key_(key.Pass()) { -} + key_(std::move(key)) {} ChannelIDStore::ChannelID::ChannelID(const ChannelID& other) : server_identifier_(other.server_identifier_), diff --git a/chromium/net/ssl/client_cert_store.h b/chromium/net/ssl/client_cert_store.h index b1172deb7d9..f87c22ee47f 100644 --- a/chromium/net/ssl/client_cert_store.h +++ b/chromium/net/ssl/client_cert_store.h @@ -5,8 +5,8 @@ #ifndef NET_SSL_CLIENT_CERT_STORE_H_ #define NET_SSL_CLIENT_CERT_STORE_H_ -#include "base/basictypes.h" #include "base/callback_forward.h" +#include "base/macros.h" #include "net/base/net_export.h" #include "net/cert/x509_certificate.h" diff --git a/chromium/net/ssl/client_cert_store_mac.h b/chromium/net/ssl/client_cert_store_mac.h index bca35b31eda..aade83ce595 100644 --- a/chromium/net/ssl/client_cert_store_mac.h +++ b/chromium/net/ssl/client_cert_store_mac.h @@ -5,8 +5,8 @@ #ifndef NET_SSL_CLIENT_CERT_STORE_MAC_H_ #define NET_SSL_CLIENT_CERT_STORE_MAC_H_ -#include "base/basictypes.h" #include "base/callback.h" +#include "base/macros.h" #include "net/base/net_export.h" #include "net/ssl/client_cert_store.h" #include "net/ssl/ssl_cert_request_info.h" diff --git a/chromium/net/ssl/client_cert_store_nss.cc b/chromium/net/ssl/client_cert_store_nss.cc index 169351710b5..8a6c329b58f 100644 --- a/chromium/net/ssl/client_cert_store_nss.cc +++ b/chromium/net/ssl/client_cert_store_nss.cc @@ -6,6 +6,7 @@ #include <nss.h> #include <ssl.h> +#include <utility> #include "base/bind.h" #include "base/bind_helpers.h" @@ -117,7 +118,7 @@ void ClientCertStoreNSS::GetAndFilterCertsOnWorkerThread( const SSLCertRequestInfo* request, CertificateList* selected_certs) { CertificateList platform_certs; - GetPlatformCertsOnWorkerThread(password_delegate.Pass(), &platform_certs); + GetPlatformCertsOnWorkerThread(std::move(password_delegate), &platform_certs); FilterCertsOnWorkerThread(platform_certs, *request, true, selected_certs); } diff --git a/chromium/net/ssl/client_cert_store_win.cc b/chromium/net/ssl/client_cert_store_win.cc index 2e9763ffdb2..1ebf02d79ef 100644 --- a/chromium/net/ssl/client_cert_store_win.cc +++ b/chromium/net/ssl/client_cert_store_win.cc @@ -13,7 +13,6 @@ #include "base/callback.h" #include "base/logging.h" -#include "crypto/scoped_capi_types.h" #include "crypto/wincrypt_shim.h" #include "net/cert/x509_util.h" @@ -99,7 +98,7 @@ void GetClientCertsImpl(HCERTSTORE cert_store, &find_by_issuer_para, chain_context); if (!chain_context) { - if (GetLastError() != CRYPT_E_NOT_FOUND) + if (GetLastError() != static_cast<DWORD>(CRYPT_E_NOT_FOUND)) DPLOG(ERROR) << "CertFindChainInStore failed: "; break; } @@ -129,6 +128,11 @@ void GetClientCertsImpl(HCERTSTORE cert_store, if (ok) intermediates.push_back(copied_intermediate); } + // TODO(svaldez): cert currently wraps cert_context2 which may be backed + // by a smartcard with threading difficulties. Instead, create a fresh + // X509Certificate with CreateFromBytes and route cert_context2 into the + // SSLPrivateKey. Probably changing CertificateList to be a + // pair<X509Certificate, SSLPrivateKeyCallback>. scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( cert_context2, intermediates); selected_certs->push_back(cert); @@ -145,13 +149,30 @@ void GetClientCertsImpl(HCERTSTORE cert_store, ClientCertStoreWin::ClientCertStoreWin() {} +ClientCertStoreWin::ClientCertStoreWin(HCERTSTORE cert_store) { + DCHECK(cert_store); + cert_store_.reset(cert_store); +} + ClientCertStoreWin::~ClientCertStoreWin() {} void ClientCertStoreWin::GetClientCerts(const SSLCertRequestInfo& request, - CertificateList* selected_certs, - const base::Closure& callback) { - // Client certificates of the user are in the "MY" system certificate store. - HCERTSTORE my_cert_store = CertOpenSystemStore(NULL, L"MY"); + CertificateList* selected_certs, + const base::Closure& callback) { + if (cert_store_) { + // Use the existing client cert store. Note: Under some situations, + // it's possible for this to return certificates that aren't usable + // (see below). + GetClientCertsImpl(cert_store_, request, selected_certs); + callback.Run(); + return; + } + + // Always open a new instance of the "MY" store, to ensure that there + // are no previously cached certificates being reused after they're + // no longer available (some smartcard providers fail to update the "MY" + // store handles and instead interpose CertOpenSystemStore). + ScopedHCERTSTORE my_cert_store(CertOpenSystemStore(NULL, L"MY")); if (!my_cert_store) { PLOG(ERROR) << "Could not open the \"MY\" system certificate store: "; selected_certs->clear(); @@ -160,8 +181,7 @@ void ClientCertStoreWin::GetClientCerts(const SSLCertRequestInfo& request, } GetClientCertsImpl(my_cert_store, request, selected_certs); - if (!CertCloseStore(my_cert_store, CERT_CLOSE_STORE_CHECK_FLAG)) - PLOG(ERROR) << "Could not close the \"MY\" system certificate store: "; + callback.Run(); } @@ -169,11 +189,6 @@ bool ClientCertStoreWin::SelectClientCertsForTesting( const CertificateList& input_certs, const SSLCertRequestInfo& request, CertificateList* selected_certs) { - typedef crypto::ScopedCAPIHandle< - HCERTSTORE, - crypto::CAPIDestroyerWithFlags<HCERTSTORE, - CertCloseStore, 0> > ScopedHCERTSTORE; - ScopedHCERTSTORE test_store(CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, 0, NULL)); if (!test_store) diff --git a/chromium/net/ssl/client_cert_store_win.h b/chromium/net/ssl/client_cert_store_win.h index 48500fa6d1e..ffbb301bd20 100644 --- a/chromium/net/ssl/client_cert_store_win.h +++ b/chromium/net/ssl/client_cert_store_win.h @@ -5,8 +5,9 @@ #ifndef NET_SSL_CLIENT_CERT_STORE_WIN_H_ #define NET_SSL_CLIENT_CERT_STORE_WIN_H_ -#include "base/basictypes.h" #include "base/callback.h" +#include "base/macros.h" +#include "crypto/scoped_capi_types.h" #include "net/base/net_export.h" #include "net/ssl/client_cert_store.h" #include "net/ssl/ssl_cert_request_info.h" @@ -15,15 +16,28 @@ namespace net { class NET_EXPORT ClientCertStoreWin : public ClientCertStore { public: + // Uses the "MY" current user system certificate store. ClientCertStoreWin(); + + // Takes ownership of |cert_store| and closes it at destruction time. + explicit ClientCertStoreWin(HCERTSTORE cert_store); + ~ClientCertStoreWin() override; - // ClientCertStore: + // If a cert store has been provided at construction time GetClientCerts + // will use that. Otherwise it will use the current user's "MY" cert store + // instead. void GetClientCerts(const SSLCertRequestInfo& cert_request_info, CertificateList* selected_certs, const base::Closure& callback) override; private: + using ScopedHCERTSTORE = crypto::ScopedCAPIHandle< + HCERTSTORE, + crypto::CAPIDestroyerWithFlags<HCERTSTORE, + CertCloseStore, + CERT_CLOSE_STORE_CHECK_FLAG>>; + friend class ClientCertStoreWinTestDelegate; // A hook for testing. Filters |input_certs| using the logic being used to @@ -34,6 +48,8 @@ class NET_EXPORT ClientCertStoreWin : public ClientCertStore { const SSLCertRequestInfo& cert_request_info, CertificateList* selected_certs); + ScopedHCERTSTORE cert_store_; + DISALLOW_COPY_AND_ASSIGN(ClientCertStoreWin); }; diff --git a/chromium/net/ssl/client_key_store.cc b/chromium/net/ssl/client_key_store.cc index 358bc8e2f57..87dafec16b0 100644 --- a/chromium/net/ssl/client_key_store.cc +++ b/chromium/net/ssl/client_key_store.cc @@ -5,6 +5,7 @@ #include "net/ssl/client_key_store.h" #include <algorithm> +#include <utility> #include "net/cert/x509_certificate.h" #include "net/ssl/ssl_private_key.h" @@ -38,14 +39,14 @@ void ClientKeyStore::RemoveProvider(const CertKeyProvider* provider) { providers_.erase(it); } -scoped_ptr<SSLPrivateKey> ClientKeyStore::FetchClientCertPrivateKey( +scoped_refptr<SSLPrivateKey> ClientKeyStore::FetchClientCertPrivateKey( const X509Certificate& certificate) { base::AutoLock auto_lock(lock_); for (const auto& provider : providers_) { - scoped_ptr<SSLPrivateKey> key; + scoped_refptr<SSLPrivateKey> key; if (provider->GetCertificateKey(certificate, &key)) - return key.Pass(); + return key; } return nullptr; } diff --git a/chromium/net/ssl/client_key_store.h b/chromium/net/ssl/client_key_store.h index 51eba4caad9..bab45f3267d 100644 --- a/chromium/net/ssl/client_key_store.h +++ b/chromium/net/ssl/client_key_store.h @@ -37,8 +37,9 @@ class NET_EXPORT ClientKeyStore { // it knows about the certificate, but is unable to return the private key, // returns true and sets |*private_key| to nullptr. // This can be called from any thread. - virtual bool GetCertificateKey(const X509Certificate& cert, - scoped_ptr<SSLPrivateKey>* private_key) = 0; + virtual bool GetCertificateKey( + const X509Certificate& cert, + scoped_refptr<SSLPrivateKey>* private_key) = 0; }; static ClientKeyStore* GetInstance(); @@ -53,7 +54,7 @@ class NET_EXPORT ClientKeyStore { // Given a |certificate|'s public key, return the corresponding private // key if any of the registered providers has a matching key. // Returns its matching private key on success, nullptr otherwise. - scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey( + scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( const X509Certificate& certificate); private: diff --git a/chromium/net/ssl/default_channel_id_store.cc b/chromium/net/ssl/default_channel_id_store.cc index b0497e1f631..8fff6f04132 100644 --- a/chromium/net/ssl/default_channel_id_store.cc +++ b/chromium/net/ssl/default_channel_id_store.cc @@ -4,6 +4,8 @@ #include "net/ssl/default_channel_id_store.h" +#include <utility> + #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "base/metrics/histogram_macros.h" @@ -68,7 +70,7 @@ void DefaultChannelIDStore::GetChannelIDTask::Run( DCHECK(err != ERR_IO_PENDING); InvokeCallback(base::Bind(callback_, err, server_identifier_, - base::Passed(key_result.Pass()))); + base::Passed(std::move(key_result)))); } // -------------------------------------------------------------------------- @@ -86,15 +88,14 @@ class DefaultChannelIDStore::SetChannelIDTask DefaultChannelIDStore::SetChannelIDTask::SetChannelIDTask( scoped_ptr<ChannelID> channel_id) - : channel_id_(channel_id.Pass()) { -} + : channel_id_(std::move(channel_id)) {} DefaultChannelIDStore::SetChannelIDTask::~SetChannelIDTask() { } void DefaultChannelIDStore::SetChannelIDTask::Run( DefaultChannelIDStore* store) { - store->SyncSetChannelID(channel_id_.Pass()); + store->SyncSetChannelID(std::move(channel_id_)); } // -------------------------------------------------------------------------- @@ -235,7 +236,7 @@ int DefaultChannelIDStore::GetChannelID( } void DefaultChannelIDStore::SetChannelID(scoped_ptr<ChannelID> channel_id) { - auto task = new SetChannelIDTask(channel_id.Pass()); + auto task = new SetChannelIDTask(std::move(channel_id)); RunOrEnqueueTask(scoped_ptr<Task>(task)); } @@ -302,16 +303,16 @@ void DefaultChannelIDStore::InitStore() { } void DefaultChannelIDStore::OnLoaded( - scoped_ptr<ScopedVector<ChannelID> > channel_ids) { + scoped_ptr<std::vector<scoped_ptr<ChannelID>>> channel_ids) { DCHECK(CalledOnValidThread()); - - for (std::vector<ChannelID*>::const_iterator it = channel_ids->begin(); + for (std::vector<scoped_ptr<ChannelID>>::iterator it = channel_ids->begin(); it != channel_ids->end(); ++it) { DCHECK(channel_ids_.find((*it)->server_identifier()) == channel_ids_.end()); - channel_ids_[(*it)->server_identifier()] = *it; + std::string ident = (*it)->server_identifier(); + channel_ids_[ident] = it->release(); } - channel_ids->weak_clear(); + channel_ids->clear(); loaded_ = true; @@ -327,10 +328,8 @@ void DefaultChannelIDStore::OnLoaded( UMA_HISTOGRAM_COUNTS_100("DomainBoundCerts.TaskWaitCount", waiting_tasks_.size()); - - for (ScopedVector<Task>::iterator i = waiting_tasks_.begin(); - i != waiting_tasks_.end(); ++i) - (*i)->Run(this); + for (scoped_ptr<Task>& i : waiting_tasks_) + i->Run(this); waiting_tasks_.clear(); } @@ -339,7 +338,7 @@ void DefaultChannelIDStore::SyncSetChannelID(scoped_ptr<ChannelID> channel_id) { DCHECK(loaded_); InternalDeleteChannelID(channel_id->server_identifier()); - InternalInsertChannelID(channel_id.Pass()); + InternalInsertChannelID(std::move(channel_id)); } void DefaultChannelIDStore::SyncDeleteChannelID( @@ -384,7 +383,7 @@ void DefaultChannelIDStore::EnqueueTask(scoped_ptr<Task> task) { DCHECK(!loaded_); if (waiting_tasks_.empty()) waiting_tasks_start_time_ = base::TimeTicks::Now(); - waiting_tasks_.push_back(task.Pass()); + waiting_tasks_.push_back(std::move(task)); } void DefaultChannelIDStore::RunOrEnqueueTask(scoped_ptr<Task> task) { @@ -392,7 +391,7 @@ void DefaultChannelIDStore::RunOrEnqueueTask(scoped_ptr<Task> task) { InitIfNecessary(); if (!loaded_) { - EnqueueTask(task.Pass()); + EnqueueTask(std::move(task)); return; } diff --git a/chromium/net/ssl/default_channel_id_store.h b/chromium/net/ssl/default_channel_id_store.h index db6ee97641a..52eb1d01947 100644 --- a/chromium/net/ssl/default_channel_id_store.h +++ b/chromium/net/ssl/default_channel_id_store.h @@ -11,6 +11,7 @@ #include "base/callback_forward.h" #include "base/compiler_specific.h" +#include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" @@ -93,7 +94,7 @@ class NET_EXPORT DefaultChannelIDStore : public ChannelIDStore { void InitStore(); // Callback for backing store loading completion. - void OnLoaded(scoped_ptr<ScopedVector<ChannelID> > certs); + void OnLoaded(scoped_ptr<std::vector<scoped_ptr<ChannelID>>> certs); // Syncronous methods which do the actual work. Can only be called after // initialization is complete. @@ -127,7 +128,7 @@ class NET_EXPORT DefaultChannelIDStore : public ChannelIDStore { bool loaded_; // Tasks that are waiting to be run once we finish loading. - ScopedVector<Task> waiting_tasks_; + std::vector<scoped_ptr<Task>> waiting_tasks_; base::TimeTicks waiting_tasks_start_time_; scoped_refptr<PersistentStore> store_; @@ -145,7 +146,7 @@ typedef base::RefCountedThreadSafe<DefaultChannelIDStore::PersistentStore> class NET_EXPORT DefaultChannelIDStore::PersistentStore : public RefcountedPersistentStore { public: - typedef base::Callback<void(scoped_ptr<ScopedVector<ChannelID> >)> + typedef base::Callback<void(scoped_ptr<std::vector<scoped_ptr<ChannelID>>>)> LoadedCallback; // Initializes the store and retrieves the existing channel_ids. This will be diff --git a/chromium/net/ssl/default_channel_id_store_unittest.cc b/chromium/net/ssl/default_channel_id_store_unittest.cc index fce807f0f6c..80f0657c086 100644 --- a/chromium/net/ssl/default_channel_id_store_unittest.cc +++ b/chromium/net/ssl/default_channel_id_store_unittest.cc @@ -6,6 +6,7 @@ #include <map> #include <string> +#include <utility> #include <vector> #include "base/bind.h" @@ -45,7 +46,7 @@ class AsyncGetChannelIDHelper { scoped_ptr<crypto::ECPrivateKey> key_result) { err_ = err; server_identifier_ = server_identifier; - key_ = key_result.Pass(); + key_ = std::move(key_result); called_ = true; } @@ -87,13 +88,14 @@ class MockPersistentStore MockPersistentStore::MockPersistentStore() {} void MockPersistentStore::Load(const LoadedCallback& loaded_callback) { - scoped_ptr<ScopedVector<DefaultChannelIDStore::ChannelID> > - channel_ids(new ScopedVector<DefaultChannelIDStore::ChannelID>()); + scoped_ptr<std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>>> + channel_ids( + new std::vector<scoped_ptr<DefaultChannelIDStore::ChannelID>>()); ChannelIDMap::iterator it; for (it = channel_ids_.begin(); it != channel_ids_.end(); ++it) { channel_ids->push_back( - new DefaultChannelIDStore::ChannelID(it->second)); + make_scoped_ptr(new DefaultChannelIDStore::ChannelID(it->second))); } base::ThreadTaskRunnerHandle::Get()->PostTask( diff --git a/chromium/net/ssl/openssl_client_key_store.h b/chromium/net/ssl/openssl_client_key_store.h index 16904ef3031..269565bfd36 100644 --- a/chromium/net/ssl/openssl_client_key_store.h +++ b/chromium/net/ssl/openssl_client_key_store.h @@ -9,7 +9,7 @@ #include <vector> -#include "base/basictypes.h" +#include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/memory/singleton.h" #include "crypto/openssl_util.h" diff --git a/chromium/net/ssl/openssl_ssl_util.cc b/chromium/net/ssl/openssl_ssl_util.cc index b6d48c75d57..b91acdd97a2 100644 --- a/chromium/net/ssl/openssl_ssl_util.cc +++ b/chromium/net/ssl/openssl_ssl_util.cc @@ -5,9 +5,9 @@ #include "net/ssl/openssl_ssl_util.h" #include <errno.h> - #include <openssl/err.h> #include <openssl/ssl.h> +#include <utility> #include "base/bind.h" #include "base/lazy_instance.h" @@ -69,7 +69,6 @@ int MapOpenSSLErrorSSL(uint32_t error_code) { case SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE: case SSL_R_UNKNOWN_SSL_VERSION: return ERR_NOT_IMPLEMENTED; - case SSL_R_UNSUPPORTED_SSL_VERSION: case SSL_R_NO_CIPHER_MATCH: case SSL_R_NO_SHARED_CIPHER: case SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY: @@ -94,38 +93,6 @@ int MapOpenSSLErrorSSL(uint32_t error_code) { return ERR_SSL_UNRECOGNIZED_NAME_ALERT; case SSL_R_BAD_DH_P_LENGTH: return ERR_SSL_WEAK_SERVER_EPHEMERAL_DH_KEY; - // SSL_R_UNKNOWN_PROTOCOL is reported if premature application data is - // received (see http://crbug.com/42538), and also if all the protocol - // versions supported by the server were disabled in this socket instance. - // Mapped to ERR_SSL_PROTOCOL_ERROR for compatibility with other SSL sockets - // in the former scenario. - case SSL_R_UNKNOWN_PROTOCOL: - case SSL_R_SSL_HANDSHAKE_FAILURE: - case SSL_R_DECRYPTION_FAILED: - case SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC: - case SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG: - case SSL_R_DIGEST_CHECK_FAILED: - case SSL_R_ENCRYPTED_LENGTH_TOO_LONG: - case SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST: - case SSL_R_EXCESSIVE_MESSAGE_SIZE: - case SSL_R_EXTRA_DATA_IN_MESSAGE: - case SSL_R_GOT_A_FIN_BEFORE_A_CCS: - case SSL_R_INVALID_COMMAND: - case SSL_R_INVALID_TICKET_KEYS_LENGTH: - // SSL_do_handshake reports this error when the server responds to a - // ClientHello with a fatal close_notify alert. - case SSL_R_SSLV3_ALERT_CLOSE_NOTIFY: - case SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE: - case SSL_R_SSLV3_ALERT_NO_CERTIFICATE: - case SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER: - case SSL_R_TLSV1_ALERT_DECODE_ERROR: - case SSL_R_TLSV1_ALERT_DECRYPTION_FAILED: - case SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION: - case SSL_R_TLSV1_ALERT_INTERNAL_ERROR: - case SSL_R_TLSV1_ALERT_NO_RENEGOTIATION: - case SSL_R_TLSV1_ALERT_RECORD_OVERFLOW: - case SSL_R_TLSV1_ALERT_USER_CANCELLED: - return ERR_SSL_PROTOCOL_ERROR; case SSL_R_CERTIFICATE_VERIFY_FAILED: // The only way that the certificate verify callback can fail is if // the leaf certificate changed during a renegotiation. @@ -145,7 +112,6 @@ int MapOpenSSLErrorSSL(uint32_t error_code) { return ERR_SSL_PROTOCOL_ERROR; } default: - LOG(WARNING) << "Unmapped error reason: " << ERR_GET_REASON(error_code); return ERR_SSL_PROTOCOL_ERROR; } } @@ -166,7 +132,7 @@ scoped_ptr<base::Value> NetLogOpenSSLErrorCallback( dict->SetString("file", error_info.file); if (error_info.line != 0) dict->SetInteger("line", error_info.line); - return dict.Pass(); + return std::move(dict); } } // namespace @@ -179,8 +145,8 @@ void OpenSSLPutNetError(const tracked_objects::Location& location, int err) { NOTREACHED(); err = ERR_INVALID_ARGUMENT; } - ERR_put_error(OpenSSLNetErrorLib(), err, location.function_name(), - location.file_name(), location.line_number()); + ERR_put_error(OpenSSLNetErrorLib(), 0 /* unused */, err, location.file_name(), + location.line_number()); } int MapOpenSSLError(int err, const crypto::OpenSSLErrStackTracer& tracer) { diff --git a/chromium/net/ssl/openssl_ssl_util.h b/chromium/net/ssl/openssl_ssl_util.h index 6c886cc1c9c..af8b9abb15b 100644 --- a/chromium/net/ssl/openssl_ssl_util.h +++ b/chromium/net/ssl/openssl_ssl_util.h @@ -5,6 +5,8 @@ #ifndef NET_SSL_OPENSSL_SSL_UTIL_H_ #define NET_SSL_OPENSSL_SSL_UTIL_H_ +#include <stdint.h> + #include "net/log/net_log.h" namespace crypto { diff --git a/chromium/net/ssl/ssl_cipher_suite_names.cc b/chromium/net/ssl/ssl_cipher_suite_names.cc index 0b21edb5217..2bfe72ac93f 100644 --- a/chromium/net/ssl/ssl_cipher_suite_names.cc +++ b/chromium/net/ssl/ssl_cipher_suite_names.cc @@ -31,7 +31,7 @@ namespace { struct CipherSuite { - uint16 cipher_suite, encoded; + uint16_t cipher_suite, encoded; }; const struct CipherSuite kCipherSuites[] = { @@ -199,9 +199,10 @@ const struct CipherSuite kCipherSuites[] = { {0xc08b, 0x1087}, // TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 {0xc08c, 0xf7f}, // TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 {0xc08d, 0xf87}, // TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - {0xcc13, 0x108f}, // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 - {0xcc14, 0x0e8f}, // TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 - {0xcc15, 0x0a8f}, // TLS_DHE_RSA_WITH_CHACHA20_POLY1305 + {0xcc13, 0x108f}, // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 (non-standard) + {0xcc14, 0x0e8f}, // TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 (non-standard) + {0xcca8, 0x108f}, // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + {0xcca9, 0x0e8f}, // TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 }; const struct { @@ -276,7 +277,7 @@ int CipherSuiteCmp(const void* ia, const void* ib) { } } -bool GetCipherProperties(uint16 cipher_suite, +bool GetCipherProperties(uint16_t cipher_suite, int* out_key_exchange, int* out_cipher, int* out_mac) { @@ -302,8 +303,8 @@ namespace net { void SSLCipherSuiteToStrings(const char** key_exchange_str, const char** cipher_str, const char** mac_str, - bool *is_aead, - uint16 cipher_suite) { + bool* is_aead, + uint16_t cipher_suite) { *key_exchange_str = *cipher_str = *mac_str = "???"; *is_aead = false; @@ -349,26 +350,25 @@ void SSLVersionToString(const char** name, int ssl_version) { } bool ParseSSLCipherString(const std::string& cipher_string, - uint16* cipher_suite) { + uint16_t* cipher_suite) { int value = 0; if (cipher_string.size() == 6 && base::StartsWith(cipher_string, "0x", base::CompareCase::INSENSITIVE_ASCII) && base::HexStringToInt(cipher_string, &value)) { - *cipher_suite = static_cast<uint16>(value); + *cipher_suite = static_cast<uint16_t>(value); return true; } return false; } -bool IsSecureTLSCipherSuite(uint16 cipher_suite) { +bool IsSecureTLSCipherSuite(uint16_t cipher_suite) { int key_exchange, cipher, mac; if (!GetCipherProperties(cipher_suite, &key_exchange, &cipher, &mac)) return false; - // Only allow forward secure key exchanges. + // Only allow ECDHE key exchanges. switch (key_exchange) { - case 10: // DHE_RSA case 14: // ECDHE_ECDSA case 16: // ECDHE_RSA break; @@ -392,13 +392,14 @@ bool IsSecureTLSCipherSuite(uint16 cipher_suite) { return true; } -bool IsFalseStartableTLSCipherSuite(uint16 cipher_suite) { +bool IsTLSCipherSuiteAllowedByHTTP2(uint16_t cipher_suite) { int key_exchange, cipher, mac; if (!GetCipherProperties(cipher_suite, &key_exchange, &cipher, &mac)) return false; - // Only allow ECDHE key exchanges. + // Only allow forward secure key exchanges. switch (key_exchange) { + case 10: // DHE_RSA case 14: // ECDHE_ECDSA case 16: // ECDHE_RSA break; @@ -422,7 +423,7 @@ bool IsFalseStartableTLSCipherSuite(uint16 cipher_suite) { return true; } -const char* ECCurveName(uint16 cipher_suite, int key_exchange_info) { +const char* ECCurveName(uint16_t cipher_suite, int key_exchange_info) { #if defined(USE_OPENSSL) int key_exchange, cipher, mac; if (!GetCipherProperties(cipher_suite, &key_exchange, &cipher, &mac)) diff --git a/chromium/net/ssl/ssl_cipher_suite_names.h b/chromium/net/ssl/ssl_cipher_suite_names.h index 207dbfbb8ed..4651eb188a7 100644 --- a/chromium/net/ssl/ssl_cipher_suite_names.h +++ b/chromium/net/ssl/ssl_cipher_suite_names.h @@ -5,9 +5,10 @@ #ifndef NET_SSL_SSL_CIPHER_SUITE_NAMES_H_ #define NET_SSL_SSL_CIPHER_SUITE_NAMES_H_ +#include <stdint.h> + #include <string> -#include "base/basictypes.h" #include "net/base/net_export.h" namespace net { @@ -23,7 +24,7 @@ NET_EXPORT void SSLCipherSuiteToStrings(const char** key_exchange_str, const char** cipher_str, const char** mac_str, bool* is_aead, - uint16 cipher_suite); + uint16_t cipher_suite); // SSLVersionToString returns the name of the SSL protocol version // specified by |ssl_version|, which is defined in @@ -44,26 +45,27 @@ NET_EXPORT void SSLVersionToString(const char** name, int ssl_version); // TODO(rsleevi): Support the full strings defined in the IANA TLS parameters // list. NET_EXPORT bool ParseSSLCipherString(const std::string& cipher_string, - uint16* cipher_suite); + uint16_t* cipher_suite); // |cipher_suite| is the IANA id for the cipher suite. What a "secure" // cipher suite is arbitrarily determined here. The intent is to indicate what // cipher suites meet modern security standards when backwards compatibility can -// be ignored. Notably, HTTP/2 requires/encourages this sort of validation of -// cipher suites: https://http2.github.io/http2-spec/#TLSUsage. +// be ignored. // // Currently, this function follows these criteria: -// 1) Only uses forward secure key exchanges +// 1) Only uses ECDHE-based key exchanges authenticated by a certificate // 2) Only uses AEADs -NET_EXPORT bool IsSecureTLSCipherSuite(uint16 cipher_suite); +NET_EXPORT bool IsSecureTLSCipherSuite(uint16_t cipher_suite); -// Returns true if |cipher_suite| is suitable for use with False Start. -NET_EXPORT bool IsFalseStartableTLSCipherSuite(uint16 cipher_suite); +// Returns true if |cipher_suite| is suitable for use with HTTP/2. See +// https://http2.github.io/http2-spec/#rfc.section.9.2.2. +NET_EXPORT bool IsTLSCipherSuiteAllowedByHTTP2(uint16_t cipher_suite); // Returns the static curve name of |key_exchange_info| if the |cipher_suite| // is an elliptic curve, and a name is known. Returns nullptr otherwise. // Only defined for OpenSSL, returns nullptr otherwise. -NET_EXPORT const char* ECCurveName(uint16 cipher_suite, int key_exchange_info); +NET_EXPORT const char* ECCurveName(uint16_t cipher_suite, + int key_exchange_info); } // namespace net diff --git a/chromium/net/ssl/ssl_cipher_suite_names_unittest.cc b/chromium/net/ssl/ssl_cipher_suite_names_unittest.cc index 6334c30d686..cfa26e0a6b2 100644 --- a/chromium/net/ssl/ssl_cipher_suite_names_unittest.cc +++ b/chromium/net/ssl/ssl_cipher_suite_names_unittest.cc @@ -4,7 +4,7 @@ #include "net/ssl/ssl_cipher_suite_names.h" -#include "base/basictypes.h" +#include "base/macros.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { @@ -27,8 +27,15 @@ TEST(CipherSuiteNamesTest, Basic) { EXPECT_TRUE(is_aead); EXPECT_EQ(NULL, mac); - SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, 0xcc15); - EXPECT_STREQ("DHE_RSA", key_exchange); + SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, 0xcca9); + EXPECT_STREQ("ECDHE_ECDSA", key_exchange); + EXPECT_STREQ("CHACHA20_POLY1305", cipher); + EXPECT_TRUE(is_aead); + EXPECT_EQ(NULL, mac); + + // Non-standard variant. + SSLCipherSuiteToStrings(&key_exchange, &cipher, &mac, &is_aead, 0xcc14); + EXPECT_STREQ("ECDHE_ECDSA", key_exchange); EXPECT_STREQ("CHACHA20_POLY1305", cipher); EXPECT_TRUE(is_aead); EXPECT_EQ(NULL, mac); @@ -41,7 +48,7 @@ TEST(CipherSuiteNamesTest, Basic) { } TEST(CipherSuiteNamesTest, ParseSSLCipherString) { - uint16 cipher_suite = 0; + uint16_t cipher_suite = 0; EXPECT_TRUE(ParseSSLCipherString("0x0004", &cipher_suite)); EXPECT_EQ(0x00004u, cipher_suite); @@ -57,26 +64,78 @@ TEST(CipherSuiteNamesTest, ParseSSLCipherStringFails) { }; for (size_t i = 0; i < arraysize(cipher_strings); ++i) { - uint16 cipher_suite = 0; + uint16_t cipher_suite = 0; EXPECT_FALSE(ParseSSLCipherString(cipher_strings[i], &cipher_suite)); } } TEST(CipherSuiteNamesTest, SecureCipherSuites) { // Picked some random cipher suites. - EXPECT_FALSE(IsSecureTLSCipherSuite(0x0)); - EXPECT_FALSE(IsSecureTLSCipherSuite(0x39)); - EXPECT_FALSE(IsSecureTLSCipherSuite(0xc5)); - EXPECT_FALSE(IsSecureTLSCipherSuite(0xc00f)); - EXPECT_FALSE(IsSecureTLSCipherSuite(0xc083)); + EXPECT_FALSE(IsSecureTLSCipherSuite(0x0 /* TLS_NULL_WITH_NULL_NULL */)); + EXPECT_FALSE( + IsSecureTLSCipherSuite(0x39 /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */)); + EXPECT_FALSE(IsSecureTLSCipherSuite( + 0xc5 /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */)); + EXPECT_FALSE( + IsSecureTLSCipherSuite(0xc00f /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */)); + EXPECT_FALSE(IsSecureTLSCipherSuite( + 0xc083 /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */)); + EXPECT_FALSE( + IsSecureTLSCipherSuite(0x9e /* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 */)); + EXPECT_FALSE( + IsSecureTLSCipherSuite(0xc014 /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */)); + EXPECT_FALSE( + IsSecureTLSCipherSuite(0x9c /* TLS_RSA_WITH_AES_128_GCM_SHA256 */)); // Non-existent cipher suite. EXPECT_FALSE(IsSecureTLSCipherSuite(0xffff)) << "Doesn't exist!"; // Secure ones. - EXPECT_TRUE(IsSecureTLSCipherSuite(0xcc13)); - EXPECT_TRUE(IsSecureTLSCipherSuite(0xcc14)); - EXPECT_TRUE(IsSecureTLSCipherSuite(0xcc15)); + EXPECT_TRUE(IsSecureTLSCipherSuite( + 0xc02f /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */)); + EXPECT_TRUE(IsSecureTLSCipherSuite( + 0xcc13 /* ECDHE_RSA_WITH_CHACHA20_POLY1305 (non-standard) */)); + EXPECT_TRUE(IsSecureTLSCipherSuite( + 0xcc14 /* ECDHE_ECDSA_WITH_CHACHA20_POLY1305 (non-standard) */)); + EXPECT_TRUE(IsSecureTLSCipherSuite( + 0xcca8 /* ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */)); + EXPECT_TRUE(IsSecureTLSCipherSuite( + 0xcca9 /* ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */)); +} + +TEST(CipherSuiteNamesTest, HTTP2CipherSuites) { + // Picked some random cipher suites. + EXPECT_FALSE( + IsTLSCipherSuiteAllowedByHTTP2(0x0 /* TLS_NULL_WITH_NULL_NULL */)); + EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( + 0x39 /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */)); + EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( + 0xc5 /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */)); + EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( + 0xc00f /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */)); + EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( + 0xc083 /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */)); + EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( + 0xc014 /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */)); + EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2( + 0x9c /* TLS_RSA_WITH_AES_128_GCM_SHA256 */)); + + // Non-existent cipher suite. + EXPECT_FALSE(IsTLSCipherSuiteAllowedByHTTP2(0xffff)) << "Doesn't exist!"; + + // HTTP/2-compatible ones. + EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( + 0x9e /* TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 */)); + EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( + 0xc02f /* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 */)); + EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( + 0xcc13 /* ECDHE_RSA_WITH_CHACHA20_POLY1305 (non-standard) */)); + EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( + 0xcc14 /* ECDHE_ECDSA_WITH_CHACHA20_POLY1305 (non-standard) */)); + EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( + 0xcca8 /* ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 */)); + EXPECT_TRUE(IsTLSCipherSuiteAllowedByHTTP2( + 0xcca9 /* ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 */)); } } // anonymous namespace diff --git a/chromium/net/ssl/ssl_client_auth_cache.cc b/chromium/net/ssl/ssl_client_auth_cache.cc index 4c6b0d82f15..ba60c1bc5fe 100644 --- a/chromium/net/ssl/ssl_client_auth_cache.cc +++ b/chromium/net/ssl/ssl_client_auth_cache.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "net/cert/x509_certificate.h" +#include "net/ssl/ssl_private_key.h" namespace net { @@ -17,22 +18,24 @@ SSLClientAuthCache::~SSLClientAuthCache() { CertDatabase::GetInstance()->RemoveObserver(this); } -bool SSLClientAuthCache::Lookup( - const HostPortPair& server, - scoped_refptr<X509Certificate>* certificate) { +bool SSLClientAuthCache::Lookup(const HostPortPair& server, + scoped_refptr<X509Certificate>* certificate, + scoped_refptr<SSLPrivateKey>* private_key) { DCHECK(certificate); AuthCacheMap::iterator iter = cache_.find(server); if (iter == cache_.end()) return false; - *certificate = iter->second; + *certificate = iter->second.first; + *private_key = iter->second.second; return true; } void SSLClientAuthCache::Add(const HostPortPair& server, - X509Certificate* value) { - cache_[server] = value; + X509Certificate* certificate, + SSLPrivateKey* private_key) { + cache_[server] = std::make_pair(certificate, private_key); // TODO(wtc): enforce a maximum number of entries. } diff --git a/chromium/net/ssl/ssl_client_auth_cache.h b/chromium/net/ssl/ssl_client_auth_cache.h index 53d5312a9ee..276fd37757f 100644 --- a/chromium/net/ssl/ssl_client_auth_cache.h +++ b/chromium/net/ssl/ssl_client_auth_cache.h @@ -7,12 +7,14 @@ #include <map> #include <string> +#include <utility> #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "net/base/host_port_pair.h" #include "net/base/net_export.h" #include "net/cert/cert_database.h" +#include "net/ssl/ssl_private_key.h" namespace net { @@ -36,13 +38,16 @@ class NET_EXPORT_PRIVATE SSLClientAuthCache : public CertDatabase::Observer { // indicates a preference to not send any certificate to |server|. // If a certificate preference is not found, returns false. bool Lookup(const HostPortPair& server, - scoped_refptr<X509Certificate>* certificate); + scoped_refptr<X509Certificate>* certificate, + scoped_refptr<SSLPrivateKey>* private_key); - // Add a client certificate for |server| to the cache. If there is already - // a client certificate for |server|, it will be overwritten. A NULL - // |client_cert| indicates a preference that no client certificate should - // be sent to |server|. - void Add(const HostPortPair& server, X509Certificate* client_cert); + // Add a client certificate and private key for |server| to the cache. If + // there is already a client certificate for |server|, it will be + // overwritten. A NULL |client_cert| indicates a preference that no client + // certificate should be sent to |server|. + void Add(const HostPortPair& server, + X509Certificate* client_cert, + SSLPrivateKey* private_key); // Remove the client certificate for |server| from the cache, if one exists. void Remove(const HostPortPair& server); @@ -52,7 +57,8 @@ class NET_EXPORT_PRIVATE SSLClientAuthCache : public CertDatabase::Observer { private: typedef HostPortPair AuthCacheKey; - typedef scoped_refptr<X509Certificate> AuthCacheValue; + typedef std::pair<scoped_refptr<X509Certificate>, + scoped_refptr<SSLPrivateKey>> AuthCacheValue; typedef std::map<AuthCacheKey, AuthCacheValue> AuthCacheMap; // internal representation of cache, an STL map. diff --git a/chromium/net/ssl/ssl_client_auth_cache_unittest.cc b/chromium/net/ssl/ssl_client_auth_cache_unittest.cc index 567418a3fb4..3107ab8a605 100644 --- a/chromium/net/ssl/ssl_client_auth_cache_unittest.cc +++ b/chromium/net/ssl/ssl_client_auth_cache_unittest.cc @@ -4,12 +4,42 @@ #include "net/ssl/ssl_client_auth_cache.h" +#include "base/macros.h" #include "base/time/time.h" #include "net/cert/x509_certificate.h" +#include "net/ssl/ssl_private_key.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { +class MockSSLPrivateKey : public SSLPrivateKey { + public: + MockSSLPrivateKey() {} + + Type GetType() override { return Type::RSA; } + + std::vector<SSLPrivateKey::Hash> GetDigestPreferences() override { + NOTIMPLEMENTED(); + return std::vector<SSLPrivateKey::Hash>(); + } + + size_t GetMaxSignatureLengthInBytes() override { + NOTIMPLEMENTED(); + return 0; + } + + void SignDigest(Hash hash, + const base::StringPiece& input, + const SignCallback& callback) override { + NOTIMPLEMENTED(); + } + + private: + ~MockSSLPrivateKey() override {} + + DISALLOW_COPY_AND_ASSIGN(MockSSLPrivateKey); +}; + TEST(SSLClientAuthCacheTest, LookupAddRemove) { SSLClientAuthCache cache; @@ -29,48 +59,49 @@ TEST(SSLClientAuthCacheTest, LookupAddRemove) { new X509Certificate("foo3", "CA", start_date, expiration_date)); scoped_refptr<X509Certificate> cached_cert; + scoped_refptr<SSLPrivateKey> cached_pkey; // Lookup non-existent client certificate. cached_cert = NULL; - EXPECT_FALSE(cache.Lookup(server1, &cached_cert)); + EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey)); // Add client certificate for server1. - cache.Add(server1, cert1.get()); + cache.Add(server1, cert1.get(), new MockSSLPrivateKey); cached_cert = NULL; - EXPECT_TRUE(cache.Lookup(server1, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey)); EXPECT_EQ(cert1, cached_cert); // Add client certificate for server2. - cache.Add(server2, cert2.get()); + cache.Add(server2, cert2.get(), new MockSSLPrivateKey); cached_cert = NULL; - EXPECT_TRUE(cache.Lookup(server1, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey)); EXPECT_EQ(cert1.get(), cached_cert.get()); cached_cert = NULL; - EXPECT_TRUE(cache.Lookup(server2, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey)); EXPECT_EQ(cert2, cached_cert); // Overwrite the client certificate for server1. - cache.Add(server1, cert3.get()); + cache.Add(server1, cert3.get(), new MockSSLPrivateKey); cached_cert = NULL; - EXPECT_TRUE(cache.Lookup(server1, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey)); EXPECT_EQ(cert3, cached_cert); cached_cert = NULL; - EXPECT_TRUE(cache.Lookup(server2, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey)); EXPECT_EQ(cert2, cached_cert); // Remove client certificate of server1. cache.Remove(server1); cached_cert = NULL; - EXPECT_FALSE(cache.Lookup(server1, &cached_cert)); + EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey)); cached_cert = NULL; - EXPECT_TRUE(cache.Lookup(server2, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey)); EXPECT_EQ(cert2, cached_cert); // Remove non-existent client certificate. cache.Remove(server1); cached_cert = NULL; - EXPECT_FALSE(cache.Lookup(server1, &cached_cert)); + EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey)); cached_cert = NULL; - EXPECT_TRUE(cache.Lookup(server2, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey)); EXPECT_EQ(cert2, cached_cert); } @@ -90,13 +121,14 @@ TEST(SSLClientAuthCacheTest, LookupWithPort) { scoped_refptr<X509Certificate> cert2( new X509Certificate("foo", "CA", start_date, expiration_date)); - cache.Add(server1, cert1.get()); - cache.Add(server2, cert2.get()); + cache.Add(server1, cert1.get(), new MockSSLPrivateKey); + cache.Add(server2, cert2.get(), new MockSSLPrivateKey); scoped_refptr<X509Certificate> cached_cert; - EXPECT_TRUE(cache.Lookup(server1, &cached_cert)); + scoped_refptr<SSLPrivateKey> cached_pkey; + EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey)); EXPECT_EQ(cert1.get(), cached_cert.get()); - EXPECT_TRUE(cache.Lookup(server2, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey)); EXPECT_EQ(cert2.get(), cached_cert.get()); } @@ -111,29 +143,30 @@ TEST(SSLClientAuthCacheTest, LookupNullPreference) { scoped_refptr<X509Certificate> cert1( new X509Certificate("foo", "CA", start_date, expiration_date)); - cache.Add(server1, NULL); + cache.Add(server1, NULL, new MockSSLPrivateKey); scoped_refptr<X509Certificate> cached_cert(cert1); + scoped_refptr<SSLPrivateKey> cached_pkey; // Make sure that |cached_cert| is updated to NULL, indicating the user // declined to send a certificate to |server1|. - EXPECT_TRUE(cache.Lookup(server1, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey)); EXPECT_EQ(NULL, cached_cert.get()); // Remove the existing cached certificate. cache.Remove(server1); cached_cert = NULL; - EXPECT_FALSE(cache.Lookup(server1, &cached_cert)); + EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey)); // Add a new preference for a specific certificate. - cache.Add(server1, cert1.get()); + cache.Add(server1, cert1.get(), new MockSSLPrivateKey); cached_cert = NULL; - EXPECT_TRUE(cache.Lookup(server1, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey)); EXPECT_EQ(cert1, cached_cert); // Replace the specific preference with a NULL certificate. - cache.Add(server1, NULL); + cache.Add(server1, NULL, new MockSSLPrivateKey); cached_cert = NULL; - EXPECT_TRUE(cache.Lookup(server1, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey)); EXPECT_EQ(NULL, cached_cert.get()); } @@ -147,25 +180,26 @@ TEST(SSLClientAuthCacheTest, OnCertAdded) { scoped_refptr<X509Certificate> cert1( new X509Certificate("foo", "CA", start_date, expiration_date)); - cache.Add(server1, cert1.get()); + cache.Add(server1, cert1.get(), new MockSSLPrivateKey); HostPortPair server2("foo2", 443); - cache.Add(server2, NULL); + cache.Add(server2, NULL, new MockSSLPrivateKey); scoped_refptr<X509Certificate> cached_cert; + scoped_refptr<SSLPrivateKey> cached_pkey; // Demonstrate the set up is correct. - EXPECT_TRUE(cache.Lookup(server1, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server1, &cached_cert, &cached_pkey)); EXPECT_EQ(cert1, cached_cert); - EXPECT_TRUE(cache.Lookup(server2, &cached_cert)); + EXPECT_TRUE(cache.Lookup(server2, &cached_cert, &cached_pkey)); EXPECT_EQ(NULL, cached_cert.get()); cache.OnCertAdded(NULL); // Check that we no longer have entries for either server. - EXPECT_FALSE(cache.Lookup(server1, &cached_cert)); - EXPECT_FALSE(cache.Lookup(server2, &cached_cert)); + EXPECT_FALSE(cache.Lookup(server1, &cached_cert, &cached_pkey)); + EXPECT_FALSE(cache.Lookup(server2, &cached_cert, &cached_pkey)); } } // namespace net diff --git a/chromium/net/ssl/ssl_client_session_cache_openssl.cc b/chromium/net/ssl/ssl_client_session_cache_openssl.cc index a0f03247a7a..6246bd54365 100644 --- a/chromium/net/ssl/ssl_client_session_cache_openssl.cc +++ b/chromium/net/ssl/ssl_client_session_cache_openssl.cc @@ -26,7 +26,7 @@ size_t SSLClientSessionCacheOpenSSL::size() const { return cache_.size(); } -SSL_SESSION* SSLClientSessionCacheOpenSSL::Lookup( +ScopedSSL_SESSION SSLClientSessionCacheOpenSSL::Lookup( const std::string& cache_key) { base::AutoLock lock(lock_); @@ -44,7 +44,7 @@ SSL_SESSION* SSLClientSessionCacheOpenSSL::Lookup( cache_.Erase(iter); return nullptr; } - return iter->second->session.get(); + return ScopedSSL_SESSION(SSL_SESSION_up_ref(iter->second->session.get())); } void SSLClientSessionCacheOpenSSL::Insert(const std::string& cache_key, @@ -68,7 +68,7 @@ void SSLClientSessionCacheOpenSSL::Flush() { void SSLClientSessionCacheOpenSSL::SetClockForTesting( scoped_ptr<base::Clock> clock) { - clock_ = clock.Pass(); + clock_ = std::move(clock); } SSLClientSessionCacheOpenSSL::CacheEntry::CacheEntry() { diff --git a/chromium/net/ssl/ssl_client_session_cache_openssl.h b/chromium/net/ssl/ssl_client_session_cache_openssl.h index 9d2f4b57b9b..b74042ed4ff 100644 --- a/chromium/net/ssl/ssl_client_session_cache_openssl.h +++ b/chromium/net/ssl/ssl_client_session_cache_openssl.h @@ -6,6 +6,7 @@ #define NET_SSL_SSL_CLIENT_SESSION_CACHE_OPENSSL_H #include <openssl/ssl.h> +#include <stddef.h> #include <string> @@ -41,10 +42,8 @@ class NET_EXPORT SSLClientSessionCacheOpenSSL { size_t size() const; // Returns the session associated with |cache_key| and moves it to the front - // of the MRU list. Returns null if there is none. The caller is responsible - // for taking a reference to the pointer if the cache is destroyed or a call - // to Insert is made. - SSL_SESSION* Lookup(const std::string& cache_key); + // of the MRU list. Returns nullptr if there is none. + ScopedSSL_SESSION Lookup(const std::string& cache_key); // Inserts |session| into the cache at |cache_key|. If there is an existing // one, it is released. Every |expiration_check_count| calls, the cache is diff --git a/chromium/net/ssl/ssl_client_session_cache_openssl_unittest.cc b/chromium/net/ssl/ssl_client_session_cache_openssl_unittest.cc index 7d8799ae999..ee579f00ee5 100644 --- a/chromium/net/ssl/ssl_client_session_cache_openssl_unittest.cc +++ b/chromium/net/ssl/ssl_client_session_cache_openssl_unittest.cc @@ -25,26 +25,26 @@ TEST(SSLClientSessionCacheOpenSSLTest, Basic) { EXPECT_EQ(1u, session2->references); EXPECT_EQ(1u, session3->references); - EXPECT_EQ(nullptr, cache.Lookup("key1")); - EXPECT_EQ(nullptr, cache.Lookup("key2")); + EXPECT_EQ(nullptr, cache.Lookup("key1").get()); + EXPECT_EQ(nullptr, cache.Lookup("key2").get()); EXPECT_EQ(0u, cache.size()); cache.Insert("key1", session1.get()); - EXPECT_EQ(session1.get(), cache.Lookup("key1")); - EXPECT_EQ(nullptr, cache.Lookup("key2")); + EXPECT_EQ(session1.get(), cache.Lookup("key1").get()); + EXPECT_EQ(nullptr, cache.Lookup("key2").get()); EXPECT_EQ(1u, cache.size()); cache.Insert("key2", session2.get()); - EXPECT_EQ(session1.get(), cache.Lookup("key1")); - EXPECT_EQ(session2.get(), cache.Lookup("key2")); + EXPECT_EQ(session1.get(), cache.Lookup("key1").get()); + EXPECT_EQ(session2.get(), cache.Lookup("key2").get()); EXPECT_EQ(2u, cache.size()); EXPECT_EQ(2u, session1->references); EXPECT_EQ(2u, session2->references); cache.Insert("key1", session3.get()); - EXPECT_EQ(session3.get(), cache.Lookup("key1")); - EXPECT_EQ(session2.get(), cache.Lookup("key2")); + EXPECT_EQ(session3.get(), cache.Lookup("key1").get()); + EXPECT_EQ(session2.get(), cache.Lookup("key2").get()); EXPECT_EQ(2u, cache.size()); EXPECT_EQ(1u, session1->references); @@ -52,9 +52,9 @@ TEST(SSLClientSessionCacheOpenSSLTest, Basic) { EXPECT_EQ(2u, session3->references); cache.Flush(); - EXPECT_EQ(nullptr, cache.Lookup("key1")); - EXPECT_EQ(nullptr, cache.Lookup("key2")); - EXPECT_EQ(nullptr, cache.Lookup("key3")); + EXPECT_EQ(nullptr, cache.Lookup("key1").get()); + EXPECT_EQ(nullptr, cache.Lookup("key2").get()); + EXPECT_EQ(nullptr, cache.Lookup("key3").get()); EXPECT_EQ(0u, cache.size()); EXPECT_EQ(1u, session1->references); @@ -71,27 +71,27 @@ TEST(SSLClientSessionCacheOpenSSLTest, DoubleInsert) { ScopedSSL_SESSION session(SSL_SESSION_new()); EXPECT_EQ(1u, session->references); - EXPECT_EQ(nullptr, cache.Lookup("key1")); - EXPECT_EQ(nullptr, cache.Lookup("key2")); + EXPECT_EQ(nullptr, cache.Lookup("key1").get()); + EXPECT_EQ(nullptr, cache.Lookup("key2").get()); EXPECT_EQ(0u, cache.size()); cache.Insert("key1", session.get()); - EXPECT_EQ(session.get(), cache.Lookup("key1")); - EXPECT_EQ(nullptr, cache.Lookup("key2")); + EXPECT_EQ(session.get(), cache.Lookup("key1").get()); + EXPECT_EQ(nullptr, cache.Lookup("key2").get()); EXPECT_EQ(1u, cache.size()); EXPECT_EQ(2u, session->references); cache.Insert("key2", session.get()); - EXPECT_EQ(session.get(), cache.Lookup("key1")); - EXPECT_EQ(session.get(), cache.Lookup("key2")); + EXPECT_EQ(session.get(), cache.Lookup("key1").get()); + EXPECT_EQ(session.get(), cache.Lookup("key2").get()); EXPECT_EQ(2u, cache.size()); EXPECT_EQ(3u, session->references); cache.Flush(); - EXPECT_EQ(nullptr, cache.Lookup("key1")); - EXPECT_EQ(nullptr, cache.Lookup("key2")); + EXPECT_EQ(nullptr, cache.Lookup("key1").get()); + EXPECT_EQ(nullptr, cache.Lookup("key2").get()); EXPECT_EQ(0u, cache.size()); EXPECT_EQ(1u, session->references); @@ -112,26 +112,26 @@ TEST(SSLClientSessionCacheOpenSSLTest, MaxEntries) { cache.Insert("key1", session1.get()); cache.Insert("key2", session2.get()); cache.Insert("key3", session3.get()); - EXPECT_EQ(session1.get(), cache.Lookup("key1")); - EXPECT_EQ(session2.get(), cache.Lookup("key2")); - EXPECT_EQ(session3.get(), cache.Lookup("key3")); + EXPECT_EQ(session1.get(), cache.Lookup("key1").get()); + EXPECT_EQ(session2.get(), cache.Lookup("key2").get()); + EXPECT_EQ(session3.get(), cache.Lookup("key3").get()); EXPECT_EQ(3u, cache.size()); // On insertion of a fourth, the first is removed. cache.Insert("key4", session4.get()); - EXPECT_EQ(nullptr, cache.Lookup("key1")); - EXPECT_EQ(session4.get(), cache.Lookup("key4")); - EXPECT_EQ(session3.get(), cache.Lookup("key3")); - EXPECT_EQ(session2.get(), cache.Lookup("key2")); + EXPECT_EQ(nullptr, cache.Lookup("key1").get()); + EXPECT_EQ(session4.get(), cache.Lookup("key4").get()); + EXPECT_EQ(session3.get(), cache.Lookup("key3").get()); + EXPECT_EQ(session2.get(), cache.Lookup("key2").get()); EXPECT_EQ(3u, cache.size()); // Despite being newest, the next to be removed is session4 as it was accessed // least. recently. cache.Insert("key1", session1.get()); - EXPECT_EQ(session1.get(), cache.Lookup("key1")); - EXPECT_EQ(session2.get(), cache.Lookup("key2")); - EXPECT_EQ(session3.get(), cache.Lookup("key3")); - EXPECT_EQ(nullptr, cache.Lookup("key4")); + EXPECT_EQ(session1.get(), cache.Lookup("key1").get()); + EXPECT_EQ(session2.get(), cache.Lookup("key2").get()); + EXPECT_EQ(session3.get(), cache.Lookup("key3").get()); + EXPECT_EQ(nullptr, cache.Lookup("key4").get()); EXPECT_EQ(3u, cache.size()); } @@ -174,7 +174,7 @@ TEST(SSLClientSessionCacheOpenSSLTest, Expiration) { // Perform one more lookup. This will expire all sessions but the last one. cache.Lookup("key"); EXPECT_EQ(1u, cache.size()); - EXPECT_EQ(session.get(), cache.Lookup("key")); + EXPECT_EQ(session.get(), cache.Lookup("key").get()); for (size_t i = 0; i < kNumEntries - 1; i++) { SCOPED_TRACE(i); EXPECT_EQ(nullptr, cache.Lookup(base::SizeTToString(i))); @@ -199,7 +199,7 @@ TEST(SSLClientSessionCacheOpenSSLTest, LookupExpirationCheck) { // Insert an entry into the session cache. ScopedSSL_SESSION session(SSL_SESSION_new()); cache.Insert("key", session.get()); - EXPECT_EQ(session.get(), cache.Lookup("key")); + EXPECT_EQ(session.get(), cache.Lookup("key").get()); EXPECT_EQ(1u, cache.size()); // Expire the session. @@ -209,17 +209,17 @@ TEST(SSLClientSessionCacheOpenSSLTest, LookupExpirationCheck) { EXPECT_EQ(1u, cache.size()); // But it will not be returned on lookup and gets pruned at that point. - EXPECT_EQ(nullptr, cache.Lookup("key")); + EXPECT_EQ(nullptr, cache.Lookup("key").get()); EXPECT_EQ(0u, cache.size()); // Sessions also are treated as expired if the clock rewinds. cache.Insert("key", session.get()); - EXPECT_EQ(session.get(), cache.Lookup("key")); + EXPECT_EQ(session.get(), cache.Lookup("key").get()); EXPECT_EQ(1u, cache.size()); clock->Advance(-kTimeout * 2); - EXPECT_EQ(nullptr, cache.Lookup("key")); + EXPECT_EQ(nullptr, cache.Lookup("key").get()); EXPECT_EQ(0u, cache.size()); } diff --git a/chromium/net/ssl/ssl_config.cc b/chromium/net/ssl/ssl_config.cc index 412bf0068ae..e3ced671925 100644 --- a/chromium/net/ssl/ssl_config.cc +++ b/chromium/net/ssl/ssl_config.cc @@ -24,7 +24,8 @@ SSLConfig::SSLConfig() version_min(kDefaultSSLVersionMin), version_max(kDefaultSSLVersionMax), version_fallback_min(kDefaultSSLVersionFallbackMin), - enable_deprecated_cipher_suites(false), + deprecated_cipher_suites_enabled(false), + rc4_enabled(false), channel_id_enabled(true), false_start_enabled(true), signed_cert_timestamps_enabled(true), diff --git a/chromium/net/ssl/ssl_config.h b/chromium/net/ssl/ssl_config.h index f1c70bb0dc4..5460f6640ef 100644 --- a/chromium/net/ssl/ssl_config.h +++ b/chromium/net/ssl/ssl_config.h @@ -11,13 +11,14 @@ #include "net/base/net_export.h" #include "net/cert/x509_certificate.h" #include "net/socket/next_proto.h" +#include "net/ssl/ssl_private_key.h" namespace net { -// Various TLS/SSL ProtocolVersion values encoded as uint16 +// Various TLS/SSL ProtocolVersion values encoded as uint16_t // struct { -// uint8 major; -// uint8 minor; +// uint8_t major; +// uint8_t minor; // } ProtocolVersion; // The most significant byte is |major|, and the least significant byte // is |minor|. @@ -27,6 +28,12 @@ enum { SSL_PROTOCOL_VERSION_TLS1_2 = 0x0303, }; +enum TokenBindingParam { + TB_PARAM_RSA2048_PKCS15 = 0, + TB_PARAM_RSA2048_PSS = 1, + TB_PARAM_ECDSAP256 = 2, +}; + // Default minimum protocol version. NET_EXPORT extern const uint16_t kDefaultSSLVersionMin; @@ -77,14 +84,14 @@ struct NET_EXPORT SSLConfig { // (Use the SSL_PROTOCOL_VERSION_xxx enumerators defined above.) // SSL 2.0 and SSL 3.0 are not supported. If version_max < version_min, it // means no protocol versions are enabled. - uint16 version_min; - uint16 version_max; + uint16_t version_min; + uint16_t version_max; // version_fallback_min contains the minimum version that is acceptable to // fallback to. Versions before this may be tried to see whether they would // have succeeded and thus to give a better message to the user, but the // resulting connection won't be used in these cases. - uint16 version_fallback_min; + uint16_t version_fallback_min; // Presorted list of cipher suites which should be explicitly prevented from // being used in addition to those disabled by the net built-in policy. @@ -102,17 +109,32 @@ struct NET_EXPORT SSLConfig { // The ciphers listed in |disabled_cipher_suites| will be removed in addition // to the above list. // - // Though cipher suites are sent in TLS as "uint8 CipherSuite[2]", in + // Though cipher suites are sent in TLS as "uint8_t CipherSuite[2]", in // big-endian form, they should be declared in host byte order, with the - // first uint8 occupying the most significant byte. + // first uint8_t occupying the most significant byte. // Ex: To disable TLS_RSA_WITH_RC4_128_MD5, specify 0x0004, while to // disable TLS_ECDH_ECDSA_WITH_RC4_128_SHA, specify 0xC002. - std::vector<uint16> disabled_cipher_suites; + std::vector<uint16_t> disabled_cipher_suites; + + // Enables deprecated cipher suites. These cipher suites are selected under a + // fallback to distinguish servers which require them from servers which + // merely prefer them. + // + // NOTE: because they are under a fallback, connections are still vulnerable + // to them as far as downgrades are concerned, so this should only be used for + // measurement of ciphers not to be carried long-term. It is no fix for + // servers with bad configurations without full removal. + bool deprecated_cipher_suites_enabled; - // Enables deprecated cipher suites. Currently, RC4 is deprecated. - bool enable_deprecated_cipher_suites; + // Enables RC4 cipher suites. + bool rc4_enabled; bool channel_id_enabled; // True if TLS channel ID extension is enabled. + + // List of Token Binding key parameters supported by the client. If empty, + // Token Binding will be disabled, even if token_binding_enabled is true. + std::vector<TokenBindingParam> token_binding_params; + bool false_start_enabled; // True if we'll use TLS False Start. // True if the Certificate Transparency signed_certificate_timestamp // TLS extension is enabled. @@ -154,13 +176,20 @@ struct NET_EXPORT SSLConfig { // NOTE: Only used by NSS. bool cert_io_enabled; - // The list of application level protocols supported. If set, this will - // enable Next Protocol Negotiation (if supported). The order of the - // protocols doesn't matter expect for one case: if the server supports Next - // Protocol Negotiation, but there is no overlap between the server's and - // client's protocol sets, then the first protocol in this list will be - // requested by the client. - NextProtoVector next_protos; + // The list of application level protocols supported with ALPN (Application + // Layer Protocol Negotation), in decreasing order of preference. Protocols + // will be advertised in this order during TLS handshake. + NextProtoVector alpn_protos; + + // The list of application level protocols supported with NPN (Next Protocol + // Negotiation). The last item on the list is selected if there is no overlap + // between |npn_protos| and the protocols supported by the server, otherwise + // server preference is observed and the order of |npn_protos| is irrelevant. + // Note that due to NSS limitations, ports which use NSS will use + // |alpn_protos| for both ALPN and NPN. However, if |npn_protos| is empty, NPN + // will still be disabled. + // TODO(bnc): Deprecate NPN, see https://crbug.com/526713. + NextProtoVector npn_protos; // True if renegotiation should be allowed for the default application-level // protocol when the peer negotiates neither ALPN nor NPN. @@ -170,6 +199,7 @@ struct NET_EXPORT SSLConfig { NextProtoVector renego_allowed_for_protos; scoped_refptr<X509Certificate> client_cert; + scoped_refptr<SSLPrivateKey> client_private_key; }; } // namespace net diff --git a/chromium/net/ssl/ssl_config_service_defaults.h b/chromium/net/ssl/ssl_config_service_defaults.h index de867da13ac..bec5b7a9ac6 100644 --- a/chromium/net/ssl/ssl_config_service_defaults.h +++ b/chromium/net/ssl/ssl_config_service_defaults.h @@ -5,6 +5,7 @@ #ifndef NET_SSL_SSL_CONFIG_SERVICE_DEFAULTS_H_ #define NET_SSL_SSL_CONFIG_SERVICE_DEFAULTS_H_ +#include "base/macros.h" #include "net/base/net_export.h" #include "net/ssl/ssl_config_service.h" diff --git a/chromium/net/ssl/ssl_config_service_unittest.cc b/chromium/net/ssl/ssl_config_service_unittest.cc index 7428dd00eb9..11f59cd8241 100644 --- a/chromium/net/ssl/ssl_config_service_unittest.cc +++ b/chromium/net/ssl/ssl_config_service_unittest.cc @@ -6,7 +6,6 @@ #include <vector> -#include "base/basictypes.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -94,7 +93,7 @@ TEST(SSLConfigServiceTest, ConfigUpdatesNotifyObservers) { mock_service->SetSSLConfig(initial_config); // Test that disabling certain cipher suites triggers an update. - std::vector<uint16> disabled_ciphers; + std::vector<uint16_t> disabled_ciphers; disabled_ciphers.push_back(0x0004u); disabled_ciphers.push_back(0xBEEFu); disabled_ciphers.push_back(0xDEADu); diff --git a/chromium/net/ssl/ssl_connection_status_flags.h b/chromium/net/ssl/ssl_connection_status_flags.h index 5d806ae7d72..c6c03059764 100644 --- a/chromium/net/ssl/ssl_connection_status_flags.h +++ b/chromium/net/ssl/ssl_connection_status_flags.h @@ -5,6 +5,8 @@ #ifndef NET_SSL_SSL_CONNECTION_STATUS_FLAGS_H_ #define NET_SSL_SSL_CONNECTION_STATUS_FLAGS_H_ +#include <stdint.h> + #include "base/logging.h" #include "base/macros.h" @@ -53,8 +55,8 @@ enum { static_assert(SSL_CONNECTION_VERSION_MAX - 1 <= SSL_CONNECTION_VERSION_MASK, "SSL_CONNECTION_VERSION_MASK too small"); -inline uint16 SSLConnectionStatusToCipherSuite(int connection_status) { - return static_cast<uint16>(connection_status); +inline uint16_t SSLConnectionStatusToCipherSuite(int connection_status) { + return static_cast<uint16_t>(connection_status); } inline int SSLConnectionStatusToVersion(int connection_status) { @@ -62,7 +64,7 @@ inline int SSLConnectionStatusToVersion(int connection_status) { SSL_CONNECTION_VERSION_MASK; } -inline void SSLConnectionStatusSetCipherSuite(uint16 cipher_suite, +inline void SSLConnectionStatusSetCipherSuite(uint16_t cipher_suite, int* connection_status) { // Clear out the old ciphersuite. *connection_status &= ~SSL_CONNECTION_CIPHERSUITE_MASK; diff --git a/chromium/net/ssl/ssl_connection_status_flags_unittest.cc b/chromium/net/ssl/ssl_connection_status_flags_unittest.cc index 98e4f53b3fd..9827605557e 100644 --- a/chromium/net/ssl/ssl_connection_status_flags_unittest.cc +++ b/chromium/net/ssl/ssl_connection_status_flags_unittest.cc @@ -21,7 +21,7 @@ TEST(SSLConnectionStatusTest, SetCipherSuite) { TEST(SSLConnectionStatusTest, SetVersion) { int connection_status = 0xDEADBEEF; - uint16 expected_cipher_suite = + uint16_t expected_cipher_suite = SSLConnectionStatusToCipherSuite(connection_status); SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2, diff --git a/chromium/net/ssl/ssl_info.cc b/chromium/net/ssl/ssl_info.cc index d3aae9d8f54..545bf7ec6df 100644 --- a/chromium/net/ssl/ssl_info.cc +++ b/chromium/net/ssl/ssl_info.cc @@ -32,6 +32,8 @@ SSLInfo& SSLInfo::operator=(const SSLInfo& info) { is_issued_by_known_root = info.is_issued_by_known_root; client_cert_sent = info.client_cert_sent; channel_id_sent = info.channel_id_sent; + token_binding_negotiated = info.token_binding_negotiated; + token_binding_key_param = info.token_binding_key_param; handshake_type = info.handshake_type; public_key_hashes = info.public_key_hashes; signed_certificate_timestamps = info.signed_certificate_timestamps; @@ -50,6 +52,8 @@ void SSLInfo::Reset() { is_issued_by_known_root = false; client_cert_sent = false; channel_id_sent = false; + token_binding_negotiated = false; + token_binding_key_param = TB_PARAM_ECDSAP256; handshake_type = HANDSHAKE_UNKNOWN; public_key_hashes.clear(); signed_certificate_timestamps.clear(); @@ -60,4 +64,20 @@ void SSLInfo::SetCertError(int error) { cert_status |= MapNetErrorToCertStatus(error); } +void SSLInfo::UpdateSignedCertificateTimestamps( + const ct::CTVerifyResult& ct_verify_result) { + for (const auto& sct : ct_verify_result.verified_scts) { + signed_certificate_timestamps.push_back( + SignedCertificateTimestampAndStatus(sct, ct::SCT_STATUS_OK)); + } + for (const auto& sct : ct_verify_result.invalid_scts) { + signed_certificate_timestamps.push_back( + SignedCertificateTimestampAndStatus(sct, ct::SCT_STATUS_INVALID)); + } + for (const auto& sct : ct_verify_result.unknown_logs_scts) { + signed_certificate_timestamps.push_back( + SignedCertificateTimestampAndStatus(sct, ct::SCT_STATUS_LOG_UNKNOWN)); + } +} + } // namespace net diff --git a/chromium/net/ssl/ssl_info.h b/chromium/net/ssl/ssl_info.h index 28ce82d0ae6..40dec286572 100644 --- a/chromium/net/ssl/ssl_info.h +++ b/chromium/net/ssl/ssl_info.h @@ -10,9 +10,11 @@ #include "base/memory/ref_counted.h" #include "net/base/net_export.h" #include "net/cert/cert_status_flags.h" +#include "net/cert/ct_verify_result.h" #include "net/cert/sct_status_flags.h" #include "net/cert/x509_cert_types.h" #include "net/ssl/signed_certificate_timestamp_and_status.h" +#include "net/ssl/ssl_config.h" namespace net { @@ -42,6 +44,14 @@ class NET_EXPORT SSLInfo { // Adds the specified |error| to the cert status. void SetCertError(int error); + // Adds the SignedCertificateTimestamps from ct_verify_result to + // |signed_certificate_timestamps|. SCTs are held in three separate vectors + // in ct_verify_result, each vetor representing a particular verification + // state, this method associates each of the SCTs with the corresponding + // SCTVerifyStatus as it adds it to the |signed_certificate_timestamps| list. + void UpdateSignedCertificateTimestamps( + const ct::CTVerifyResult& ct_verify_result); + // The SSL certificate. scoped_refptr<X509Certificate> cert; @@ -82,6 +92,15 @@ class NET_EXPORT SSLInfo { // True if a channel ID was sent to the server. bool channel_id_sent; + // True if Token Binding was negotiated with the server and we agreed on a + // version and key params. + bool token_binding_negotiated; + + // Only valid if |token_binding_negotiated| is true. Contains the key param + // negotiated by the client and server in the Token Binding Negotiation TLS + // extension. + TokenBindingParam token_binding_key_param; + HandshakeType handshake_type; // The hashes, in several algorithms, of the SubjectPublicKeyInfos from diff --git a/chromium/net/ssl/ssl_key_logger.cc b/chromium/net/ssl/ssl_key_logger.cc new file mode 100644 index 00000000000..42984dfaf37 --- /dev/null +++ b/chromium/net/ssl/ssl_key_logger.cc @@ -0,0 +1,69 @@ +// Copyright 2015 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. + +#include "net/ssl/ssl_key_logger.h" + +#include <stdio.h> + +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/files/scoped_file.h" +#include "base/location.h" +#include "base/logging.h" +#include "base/macros.h" +#include "base/sequence_checker.h" +#include "base/sequenced_task_runner.h" + +namespace net { + +// An object which lives on the background SequencedTaskRunner and performs the +// blocking file operations. +class SSLKeyLogger::Core { + public: + Core() { sequence_checker_.DetachFromSequence(); } + ~Core() { DCHECK(sequence_checker_.CalledOnValidSequencedThread()); } + + void OpenFile(const base::FilePath& path) { + DCHECK(sequence_checker_.CalledOnValidSequencedThread()); + DCHECK(!file_); + file_.reset(base::OpenFile(path, "a")); + if (!file_) + LOG(WARNING) << "Could not open " << path.value(); + } + + void WriteLine(const std::string& line) { + DCHECK(sequence_checker_.CalledOnValidSequencedThread()); + if (!file_) + return; + fprintf(file_.get(), "%s\n", line.c_str()); + fflush(file_.get()); + } + + private: + base::ScopedFILE file_; + base::SequenceChecker sequence_checker_; + + DISALLOW_COPY_AND_ASSIGN(Core); +}; + +SSLKeyLogger::SSLKeyLogger( + const base::FilePath& path, + const scoped_refptr<base::SequencedTaskRunner>& task_runner) + : task_runner_(task_runner), core_(new Core) { + task_runner_->PostTask( + FROM_HERE, + base::Bind(&Core::OpenFile, base::Unretained(core_.get()), path)); +} + +SSLKeyLogger::~SSLKeyLogger() { + task_runner_->DeleteSoon(FROM_HERE, core_.release()); +} + +void SSLKeyLogger::WriteLine(const std::string& line) { + task_runner_->PostTask( + FROM_HERE, + base::Bind(&Core::WriteLine, base::Unretained(core_.get()), line)); +} + +} // namespace net diff --git a/chromium/net/ssl/ssl_key_logger.h b/chromium/net/ssl/ssl_key_logger.h new file mode 100644 index 00000000000..dcaf6c6a89b --- /dev/null +++ b/chromium/net/ssl/ssl_key_logger.h @@ -0,0 +1,50 @@ +// Copyright 2015 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_SSL_SSL_KEY_LOGGER_H_ +#define NET_SSL_SSL_KEY_LOGGER_H_ + +#include <string> + +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" + +namespace base { +class FilePath; +class SequencedTaskRunner; +} + +namespace net { + +// SSLKeyLogger logs SSL key material for debugging purposes. This should only +// be used when requested by the user, typically via the SSLKEYLOGFILE +// environment variable. See also +// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. +class SSLKeyLogger { + public: + // Creates a new SSLKeyLogger which writes to |path|, scheduling write + // operations on |task_runner|. + SSLKeyLogger(const base::FilePath& path, + const scoped_refptr<base::SequencedTaskRunner>& task_runner); + ~SSLKeyLogger(); + + // Writes |line| followed by a newline. This may be called by multiple threads + // simultaneously. If two calls race, the order of the lines is undefined, but + // each line will be written atomically. + void WriteLine(const std::string& line); + + private: + class Core; + + scoped_refptr<base::SequencedTaskRunner> task_runner_; + // Destroyed on |task_runner_|. + scoped_ptr<Core> core_; + + DISALLOW_COPY_AND_ASSIGN(SSLKeyLogger); +}; + +} // namespace net + +#endif // NET_SSL_SSL_KEY_LOGGER_H_ diff --git a/chromium/net/ssl/ssl_platform_key.h b/chromium/net/ssl/ssl_platform_key.h index bcab6a4c32d..a6d53138cbd 100644 --- a/chromium/net/ssl/ssl_platform_key.h +++ b/chromium/net/ssl/ssl_platform_key.h @@ -5,8 +5,10 @@ #ifndef NET_SSL_SSL_PLATFORM_KEY_H_ #define NET_SSL_SSL_PLATFORM_KEY_H_ +#include "base/lazy_instance.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "net/base/net_export.h" namespace base { class SequencedTaskRunner; @@ -18,12 +20,10 @@ class SSLPrivateKey; class X509Certificate; // Looks up the private key from the platform key store corresponding to -// |certificate|'s public key and returns an SSLPrivateKey which offloads -// signing operations to |task_runner|. |task_runner| is a SequencedTaskRunner -// to allow for buggy third-party smartcard drivers. -scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey( - X509Certificate* certificate, - scoped_refptr<base::SequencedTaskRunner> task_runner); +// |certificate|'s public key and returns an SSLPrivateKey backed by the +// playform key. +NET_EXPORT scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( + X509Certificate* certificate); } // namespace net diff --git a/chromium/net/ssl/ssl_platform_key_android.cc b/chromium/net/ssl/ssl_platform_key_android.cc index 773844a08fa..6a6595cc0e6 100644 --- a/chromium/net/ssl/ssl_platform_key_android.cc +++ b/chromium/net/ssl/ssl_platform_key_android.cc @@ -6,13 +6,14 @@ #include <openssl/digest.h> #include <openssl/evp.h> +#include <utility> #include "base/logging.h" #include "base/macros.h" -#include "base/stl_util.h" #include "crypto/scoped_openssl_types.h" #include "net/base/net_errors.h" #include "net/ssl/openssl_client_key_store.h" +#include "net/ssl/ssl_platform_key_task_runner.h" #include "net/ssl/ssl_private_key.h" #include "net/ssl/threaded_ssl_private_key.h" @@ -23,7 +24,7 @@ namespace { class SSLPlatformKeyAndroid : public ThreadedSSLPrivateKey::Delegate { public: SSLPlatformKeyAndroid(crypto::ScopedEVP_PKEY key, SSLPrivateKey::Type type) - : key_(key.Pass()), type_(type) {} + : key_(std::move(key)), type_(type) {} ~SSLPlatformKeyAndroid() override {} @@ -79,19 +80,16 @@ class SSLPlatformKeyAndroid : public ThreadedSSLPrivateKey::Delegate { return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; } - uint8_t* input_ptr = - const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(input.data())); + const uint8_t* input_ptr = reinterpret_cast<const uint8_t*>(input.data()); size_t input_len = input.size(); size_t sig_len = 0; if (!EVP_PKEY_sign(ctx.get(), NULL, &sig_len, input_ptr, input_len)) return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; signature->resize(sig_len); - uint8_t* sig = const_cast<uint8_t*>( - reinterpret_cast<const uint8_t*>(vector_as_array(signature))); - if (!sig) - return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; - if (!EVP_PKEY_sign(ctx.get(), sig, &sig_len, input_ptr, input_len)) + if (!EVP_PKEY_sign(ctx.get(), signature->data(), &sig_len, input_ptr, + input_len)) { return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; + } signature->resize(sig_len); @@ -105,14 +103,7 @@ class SSLPlatformKeyAndroid : public ThreadedSSLPrivateKey::Delegate { DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyAndroid); }; -} // namespace - -scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey( - X509Certificate* certificate, - scoped_refptr<base::SequencedTaskRunner> task_runner) { - crypto::ScopedEVP_PKEY key = - OpenSSLClientKeyStore::GetInstance()->FetchClientCertPrivateKey( - certificate); +scoped_refptr<SSLPrivateKey> WrapOpenSSLPrivateKey(crypto::ScopedEVP_PKEY key) { if (!key) return nullptr; @@ -128,9 +119,19 @@ scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey( LOG(ERROR) << "Unknown key type: " << EVP_PKEY_id(key.get()); return nullptr; } - return make_scoped_ptr(new ThreadedSSLPrivateKey( - make_scoped_ptr(new SSLPlatformKeyAndroid(key.Pass(), type)), - task_runner.Pass())); + return make_scoped_refptr(new ThreadedSSLPrivateKey( + make_scoped_ptr(new SSLPlatformKeyAndroid(std::move(key), type)), + GetSSLPlatformKeyTaskRunner())); +} + +} // namespace + +scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( + X509Certificate* certificate) { + crypto::ScopedEVP_PKEY key = + OpenSSLClientKeyStore::GetInstance()->FetchClientCertPrivateKey( + certificate); + return WrapOpenSSLPrivateKey(std::move(key)); } } // namespace net diff --git a/chromium/net/ssl/ssl_platform_key_mac.cc b/chromium/net/ssl/ssl_platform_key_mac.cc index 0eb787a03eb..ec7cb42f0db 100644 --- a/chromium/net/ssl/ssl_platform_key_mac.cc +++ b/chromium/net/ssl/ssl_platform_key_mac.cc @@ -14,21 +14,21 @@ #include <Security/SecIdentity.h> #include <Security/SecKey.h> -#include "base/lazy_instance.h" #include "base/location.h" #include "base/logging.h" #include "base/mac/mac_logging.h" #include "base/mac/scoped_cftyperef.h" +#include "base/macros.h" #include "base/memory/scoped_policy.h" #include "base/memory/scoped_ptr.h" #include "base/sequenced_task_runner.h" -#include "base/stl_util.h" #include "base/synchronization/lock.h" #include "crypto/mac_security_services_lock.h" #include "crypto/openssl_util.h" #include "crypto/scoped_openssl_types.h" #include "net/base/net_errors.h" #include "net/cert/x509_certificate.h" +#include "net/ssl/ssl_platform_key_task_runner.h" #include "net/ssl/ssl_private_key.h" #include "net/ssl/threaded_ssl_private_key.h" @@ -199,7 +199,7 @@ class SSLPlatformKeyMac : public ThreadedSSLPrivateKey::Delegate { signature->resize(GetMaxSignatureLengthInBytes()); CSSM_DATA signature_data; signature_data.Length = signature->size(); - signature_data.Data = vector_as_array(signature); + signature_data.Data = signature->data(); if (CSSM_SignData(cssm_signature.get(), &hash_data, 1, CSSM_ALGID_NONE, &signature_data) != CSSM_OK) { @@ -218,9 +218,8 @@ class SSLPlatformKeyMac : public ThreadedSSLPrivateKey::Delegate { } // namespace -scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey( - X509Certificate* certificate, - scoped_refptr<base::SequencedTaskRunner> task_runner) { +scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( + X509Certificate* certificate) { // Look up the private key. base::ScopedCFTypeRef<SecKeyRef> private_key( FetchSecKeyRefForCertificate(certificate)); @@ -237,9 +236,9 @@ scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey( LOG(ERROR) << "Unknown key type: " << cssm_key->KeyHeader.AlgorithmId; return nullptr; } - return make_scoped_ptr(new ThreadedSSLPrivateKey( + return make_scoped_refptr(new ThreadedSSLPrivateKey( make_scoped_ptr(new SSLPlatformKeyMac(private_key.get(), cssm_key)), - task_runner.Pass())); + GetSSLPlatformKeyTaskRunner())); } } // namespace net diff --git a/chromium/net/ssl/ssl_platform_key_nss.cc b/chromium/net/ssl/ssl_platform_key_nss.cc index 25332104c9e..858ffb9db7f 100644 --- a/chromium/net/ssl/ssl_platform_key_nss.cc +++ b/chromium/net/ssl/ssl_platform_key_nss.cc @@ -5,21 +5,21 @@ #include "net/ssl/ssl_platform_key.h" #include <keyhi.h> -#include <pk11pub.h> -#include <prerror.h> - #include <openssl/bn.h> #include <openssl/ecdsa.h> #include <openssl/rsa.h> +#include <pk11pub.h> +#include <prerror.h> +#include <utility> #include "base/logging.h" #include "base/macros.h" #include "base/sequenced_task_runner.h" -#include "base/stl_util.h" #include "crypto/scoped_nss_types.h" #include "crypto/scoped_openssl_types.h" #include "net/cert/x509_certificate.h" #include "net/ssl/client_key_store.h" +#include "net/ssl/ssl_platform_key_task_runner.h" #include "net/ssl/ssl_private_key.h" #include "net/ssl/threaded_ssl_private_key.h" @@ -39,7 +39,7 @@ class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate { public: SSLPlatformKeyNSS(SSLPrivateKey::Type type, crypto::ScopedSECKEYPrivateKey key) - : type_(type), key_(key.Pass()) {} + : type_(type), key_(std::move(key)) {} ~SSLPlatformKeyNSS() override {} SSLPrivateKey::Type GetType() override { return type_; } @@ -110,7 +110,7 @@ class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate { } signature->resize(len); SECItem signature_item; - signature_item.data = vector_as_array(signature); + signature_item.data = signature->data(); signature_item.len = signature->size(); SECStatus rv = PK11_Sign(key_.get(), &signature_item, &digest_item); @@ -131,9 +131,8 @@ class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate { // Convert the RAW ECDSA signature to a DER-encoded ECDSA-Sig-Value. crypto::ScopedECDSA_SIG sig(ECDSA_SIG_new()); - if (!sig || !BN_bin2bn(vector_as_array(signature), order_len, sig->r) || - !BN_bin2bn(vector_as_array(signature) + order_len, order_len, - sig->s)) { + if (!sig || !BN_bin2bn(signature->data(), order_len, sig->r) || + !BN_bin2bn(signature->data() + order_len, order_len, sig->s)) { return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; } @@ -141,7 +140,7 @@ class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate { if (len <= 0) return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; signature->resize(len); - uint8_t* ptr = vector_as_array(signature); + uint8_t* ptr = signature->data(); len = i2d_ECDSA_SIG(sig.get(), &ptr); if (len <= 0) return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; @@ -160,9 +159,8 @@ class SSLPlatformKeyNSS : public ThreadedSSLPrivateKey::Delegate { } // namespace -scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey( - X509Certificate* certificate, - scoped_refptr<base::SequencedTaskRunner> task_runner) { +scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( + X509Certificate* certificate) { crypto::ScopedSECKEYPrivateKey key( PK11_FindKeyByAnyCert(certificate->os_cert_handle(), nullptr)); if (!key) { @@ -183,9 +181,9 @@ scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey( LOG(ERROR) << "Unknown key type: " << nss_type; return nullptr; } - return make_scoped_ptr(new ThreadedSSLPrivateKey( - make_scoped_ptr(new SSLPlatformKeyNSS(type, key.Pass())), - task_runner.Pass())); + return make_scoped_refptr(new ThreadedSSLPrivateKey( + make_scoped_ptr(new SSLPlatformKeyNSS(type, std::move(key))), + GetSSLPlatformKeyTaskRunner())); } } // namespace net diff --git a/chromium/net/ssl/ssl_platform_key_task_runner.cc b/chromium/net/ssl/ssl_platform_key_task_runner.cc new file mode 100644 index 00000000000..7611d60454d --- /dev/null +++ b/chromium/net/ssl/ssl_platform_key_task_runner.cc @@ -0,0 +1,31 @@ +// Copyright 2015 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. + +#include "base/lazy_instance.h" +#include "net/ssl/ssl_platform_key_task_runner.h" + +namespace net { + +SSLPlatformKeyTaskRunner::SSLPlatformKeyTaskRunner() { + worker_pool_ = new base::SequencedWorkerPool(1, "Platform Key Thread"); + task_runner_ = worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior( + worker_pool_->GetSequenceToken(), + base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN); +} + +SSLPlatformKeyTaskRunner::~SSLPlatformKeyTaskRunner() {} + +scoped_refptr<base::SequencedTaskRunner> +SSLPlatformKeyTaskRunner::task_runner() { + return task_runner_; +} + +base::LazyInstance<SSLPlatformKeyTaskRunner>::Leaky g_platform_key_task_runner = + LAZY_INSTANCE_INITIALIZER; + +scoped_refptr<base::SequencedTaskRunner> GetSSLPlatformKeyTaskRunner() { + return g_platform_key_task_runner.Get().task_runner(); +} + +} // namespace net diff --git a/chromium/net/ssl/ssl_platform_key_task_runner.h b/chromium/net/ssl/ssl_platform_key_task_runner.h new file mode 100644 index 00000000000..0c9b124f1fa --- /dev/null +++ b/chromium/net/ssl/ssl_platform_key_task_runner.h @@ -0,0 +1,33 @@ +// Copyright 2015 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_SSL_SSL_PLATFORM_KEY_TASK_RUNNER_H_ +#define NET_SSL_SSL_PLATFORM_KEY_TASK_RUNNER_H_ + +#include "base/macros.h" +#include "base/threading/sequenced_worker_pool.h" + +namespace net { + +// Serialize all the private key operations on a single background +// thread to avoid problems with buggy smartcards. +class SSLPlatformKeyTaskRunner { + public: + SSLPlatformKeyTaskRunner(); + ~SSLPlatformKeyTaskRunner(); + + scoped_refptr<base::SequencedTaskRunner> task_runner(); + + private: + scoped_refptr<base::SequencedWorkerPool> worker_pool_; + scoped_refptr<base::SequencedTaskRunner> task_runner_; + + DISALLOW_COPY_AND_ASSIGN(SSLPlatformKeyTaskRunner); +}; + +scoped_refptr<base::SequencedTaskRunner> GetSSLPlatformKeyTaskRunner(); + +} // namespace net + +#endif // NET_SSL_SSL_PLATFORM_KEY_TASK_RUNNER_H_ diff --git a/chromium/net/ssl/ssl_platform_key_win.cc b/chromium/net/ssl/ssl_platform_key_win.cc index 1cb846b8534..2f3e7c6764c 100644 --- a/chromium/net/ssl/ssl_platform_key_win.cc +++ b/chromium/net/ssl/ssl_platform_key_win.cc @@ -20,7 +20,6 @@ #include "base/logging.h" #include "base/macros.h" #include "base/sequenced_task_runner.h" -#include "base/stl_util.h" #include "base/win/windows_version.h" #include "crypto/openssl_util.h" #include "crypto/scoped_capi_types.h" @@ -28,6 +27,7 @@ #include "net/base/net_errors.h" #include "net/cert/x509_certificate.h" #include "net/ssl/scoped_openssl_types.h" +#include "net/ssl/ssl_platform_key_task_runner.h" #include "net/ssl/ssl_private_key.h" #include "net/ssl/threaded_ssl_private_key.h" @@ -145,7 +145,7 @@ class SSLPlatformKeyCAPI : public ThreadedSSLPrivateKey::Delegate { } signature->resize(signature_len); if (!CryptSignHash(hash_handle.get(), key_spec_, nullptr, 0, - vector_as_array(signature), &signature_len)) { + signature->data(), &signature_len)) { PLOG(ERROR) << "CryptSignHash failed"; return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; } @@ -242,8 +242,7 @@ class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate { status = g_cng_functions.Get().ncrypt_sign_hash()( key_, padding_info, const_cast<BYTE*>(reinterpret_cast<const BYTE*>(input.data())), - input.size(), vector_as_array(signature), signature_len, &signature_len, - flags); + input.size(), signature->data(), signature_len, &signature_len, flags); if (FAILED(status)) { LOG(ERROR) << "NCryptSignHash failed: " << status; return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; @@ -261,9 +260,8 @@ class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate { // Convert the RAW ECDSA signature to a DER-encoded ECDSA-Sig-Value. crypto::ScopedECDSA_SIG sig(ECDSA_SIG_new()); - if (!sig || !BN_bin2bn(vector_as_array(signature), order_len, sig->r) || - !BN_bin2bn(vector_as_array(signature) + order_len, order_len, - sig->s)) { + if (!sig || !BN_bin2bn(signature->data(), order_len, sig->r) || + !BN_bin2bn(signature->data() + order_len, order_len, sig->s)) { return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; } @@ -271,7 +269,7 @@ class SSLPlatformKeyCNG : public ThreadedSSLPrivateKey::Delegate { if (len <= 0) return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; signature->resize(len); - uint8_t* ptr = vector_as_array(signature); + uint8_t* ptr = signature->data(); len = i2d_ECDSA_SIG(sig.get(), &ptr); if (len <= 0) return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED; @@ -323,9 +321,8 @@ bool GetKeyInfo(const X509Certificate* certificate, } // namespace -scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey( - X509Certificate* certificate, - scoped_refptr<base::SequencedTaskRunner> task_runner) { +scoped_refptr<SSLPrivateKey> FetchClientCertPrivateKey( + X509Certificate* certificate) { // Rather than query the private key for metadata, extract the public key from // the certificate without using Windows APIs. CAPI and CNG do not // consistently work depending on the system. See https://crbug.com/468345. @@ -360,8 +357,8 @@ scoped_ptr<SSLPrivateKey> FetchClientCertPrivateKey( DCHECK(SSLPrivateKey::Type::RSA == key_type); delegate.reset(new SSLPlatformKeyCAPI(prov_or_key, key_spec, max_length)); } - return make_scoped_ptr( - new ThreadedSSLPrivateKey(delegate.Pass(), task_runner.Pass())); + return make_scoped_refptr(new ThreadedSSLPrivateKey( + delegate.Pass(), GetSSLPlatformKeyTaskRunner())); } } // namespace net diff --git a/chromium/net/ssl/ssl_private_key.h b/chromium/net/ssl/ssl_private_key.h index d1aa09951d7..2e382fbf3b2 100644 --- a/chromium/net/ssl/ssl_private_key.h +++ b/chromium/net/ssl/ssl_private_key.h @@ -5,20 +5,21 @@ #ifndef NET_SSL_SSL_PRIVATE_KEY_H_ #define NET_SSL_SSL_PRIVATE_KEY_H_ +#include <stddef.h> #include <stdint.h> #include <vector> #include "base/callback_forward.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ref_counted.h" #include "base/strings/string_piece.h" #include "net/base/net_errors.h" namespace net { // An interface for a private key for use with SSL client authentication. -class SSLPrivateKey { +class SSLPrivateKey : public base::RefCountedThreadSafe<SSLPrivateKey> { public: using SignCallback = base::Callback<void(Error, const std::vector<uint8_t>&)>; @@ -36,7 +37,6 @@ class SSLPrivateKey { }; SSLPrivateKey() {} - virtual ~SSLPrivateKey() {} // Returns whether the key is an RSA key or an ECDSA key. Although the signing // interface is type-agnositic and type tags in interfaces are discouraged, @@ -62,7 +62,11 @@ class SSLPrivateKey { const base::StringPiece& input, const SignCallback& callback) = 0; + protected: + virtual ~SSLPrivateKey() {} + private: + friend class base::RefCountedThreadSafe<SSLPrivateKey>; DISALLOW_COPY_AND_ASSIGN(SSLPrivateKey); }; diff --git a/chromium/net/ssl/ssl_server_config.cc b/chromium/net/ssl/ssl_server_config.cc new file mode 100644 index 00000000000..8b3e67f7f21 --- /dev/null +++ b/chromium/net/ssl/ssl_server_config.cc @@ -0,0 +1,20 @@ +// Copyright 2015 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. + +#include "net/ssl/ssl_server_config.h" + +#include "net/socket/ssl_client_socket.h" +#include "net/ssl/ssl_config.h" + +namespace net { + +SSLServerConfig::SSLServerConfig() + : version_min(kDefaultSSLVersionMin), + version_max(SSL_PROTOCOL_VERSION_TLS1_2), + require_ecdhe(false), + require_client_cert(false) {} + +SSLServerConfig::~SSLServerConfig() {} + +} // namespace net diff --git a/chromium/net/ssl/ssl_server_config.h b/chromium/net/ssl/ssl_server_config.h new file mode 100644 index 00000000000..36d1286b225 --- /dev/null +++ b/chromium/net/ssl/ssl_server_config.h @@ -0,0 +1,63 @@ +// Copyright 2015 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_SSL_SSL_SERVER_CONFIG_H_ +#define NET_SSL_SSL_SERVER_CONFIG_H_ + +#include <stdint.h> + +#include <vector> + +#include "net/base/net_export.h" +#include "net/ssl/ssl_config.h" + +namespace net { + +// A collection of server-side SSL-related configuration settings. +struct NET_EXPORT SSLServerConfig { + // Defaults + SSLServerConfig(); + ~SSLServerConfig(); + + // The minimum and maximum protocol versions that are enabled. + // (Use the SSL_PROTOCOL_VERSION_xxx enumerators defined in ssl_config.h) + // SSL 2.0 and SSL 3.0 are not supported. If version_max < version_min, it + // means no protocol versions are enabled. + uint16_t version_min; + uint16_t version_max; + + // Presorted list of cipher suites which should be explicitly prevented from + // being used in 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. + // - Weak cipher suites: < 80 bits of security strength. + // - FORTEZZA cipher suites (obsolete). + // - IDEA cipher suites (RFC 5469 explains why). + // - Anonymous cipher suites. + // - ECDSA cipher suites on platforms that do not support ECDSA signed + // certificates, as servers may use the presence of such ciphersuites as a + // hint to send an ECDSA certificate. + // The ciphers listed in |disabled_cipher_suites| will be removed in addition + // to the above list. + // + // Though cipher suites are sent in TLS as "uint8_t CipherSuite[2]", in + // big-endian form, they should be declared in host byte order, with the + // first uint8_t occupying the most significant byte. + // Ex: To disable TLS_RSA_WITH_RC4_128_MD5, specify 0x0004, while to + // disable TLS_ECDH_ECDSA_WITH_RC4_128_SHA, specify 0xC002. + std::vector<uint16_t> disabled_cipher_suites; + + // If true, causes only ECDHE cipher suites to be enabled. + bool require_ecdhe; + + // Requires a client certificate for client authentication from the client. + // This doesn't currently enforce certificate validity. + bool require_client_cert; +}; + +} // namespace net + +#endif // NET_SSL_SSL_SERVER_CONFIG_H_ diff --git a/chromium/net/ssl/threaded_ssl_private_key.cc b/chromium/net/ssl/threaded_ssl_private_key.cc index f395518e680..d2f1d95ea43 100644 --- a/chromium/net/ssl/threaded_ssl_private_key.cc +++ b/chromium/net/ssl/threaded_ssl_private_key.cc @@ -5,6 +5,7 @@ #include "net/ssl/threaded_ssl_private_key.h" #include <string> +#include <utility> #include "base/bind.h" #include "base/location.h" @@ -30,7 +31,7 @@ class ThreadedSSLPrivateKey::Core : public base::RefCountedThreadSafe<ThreadedSSLPrivateKey::Core> { public: Core(scoped_ptr<ThreadedSSLPrivateKey::Delegate> delegate) - : delegate_(delegate.Pass()) {} + : delegate_(std::move(delegate)) {} ThreadedSSLPrivateKey::Delegate* delegate() { return delegate_.get(); } @@ -50,13 +51,9 @@ class ThreadedSSLPrivateKey::Core ThreadedSSLPrivateKey::ThreadedSSLPrivateKey( scoped_ptr<ThreadedSSLPrivateKey::Delegate> delegate, scoped_refptr<base::TaskRunner> task_runner) - : core_(new Core(delegate.Pass())), - task_runner_(task_runner.Pass()), - weak_factory_(this) { -} - -ThreadedSSLPrivateKey::~ThreadedSSLPrivateKey() { -} + : core_(new Core(std::move(delegate))), + task_runner_(std::move(task_runner)), + weak_factory_(this) {} SSLPrivateKey::Type ThreadedSSLPrivateKey::GetType() { return core_->delegate()->GetType(); @@ -83,4 +80,6 @@ void ThreadedSSLPrivateKey::SignDigest( base::Owned(signature))); } +ThreadedSSLPrivateKey::~ThreadedSSLPrivateKey() {} + } // namespace net diff --git a/chromium/net/ssl/threaded_ssl_private_key.h b/chromium/net/ssl/threaded_ssl_private_key.h index afee1034727..629ce3b9160 100644 --- a/chromium/net/ssl/threaded_ssl_private_key.h +++ b/chromium/net/ssl/threaded_ssl_private_key.h @@ -5,6 +5,7 @@ #ifndef NET_SSL_THREADED_SSL_PRIVATE_KEY_H_ #define NET_SSL_THREADED_SSL_PRIVATE_KEY_H_ +#include <stddef.h> #include <stdint.h> #include <vector> @@ -38,7 +39,7 @@ class ThreadedSSLPrivateKey : public SSLPrivateKey { virtual std::vector<SSLPrivateKey::Hash> GetDigestPreferences() = 0; virtual size_t GetMaxSignatureLengthInBytes() = 0; - // Signs |input| as a digest of type |hash|. On sucess it returns OK and + // Signs |input| as a digest of type |hash|. On success it returns OK and // sets |signature| to the resulting signature. Otherwise it returns a net // error code. It will only be called on the task runner passed to the // owning ThreadedSSLPrivateKey. @@ -52,7 +53,6 @@ class ThreadedSSLPrivateKey : public SSLPrivateKey { ThreadedSSLPrivateKey(scoped_ptr<Delegate> delegate, scoped_refptr<base::TaskRunner> task_runner); - ~ThreadedSSLPrivateKey() override; // SSLPrivateKey implementation. Type GetType() override; @@ -63,6 +63,7 @@ class ThreadedSSLPrivateKey : public SSLPrivateKey { const SignCallback& callback) override; private: + ~ThreadedSSLPrivateKey() override; class Core; scoped_refptr<Core> core_; |