diff options
author | juanlang@google.com <juanlang@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-07 17:32:04 +0000 |
---|---|---|
committer | juanlang@google.com <juanlang@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-07 17:32:04 +0000 |
commit | 7047bbb6d9acd6bf67cae14aebe202d3c8e542ce (patch) | |
tree | 2703ac05611bc5951ad5547328694d6581ca502b /net | |
parent | 9ad935f7cd41740e4db1a708a1ab78b562801091 (diff) | |
download | chromium_src-7047bbb6d9acd6bf67cae14aebe202d3c8e542ce.zip chromium_src-7047bbb6d9acd6bf67cae14aebe202d3c8e542ce.tar.gz chromium_src-7047bbb6d9acd6bf67cae14aebe202d3c8e542ce.tar.bz2 |
Remove requested types from the server bound cert service: it only
supports a single type.
BUG=259097
Review URL: https://chromiumcodereview.appspot.com/20456002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216223 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/socket/ssl_client_socket_nss.cc | 34 | ||||
-rw-r--r-- | net/spdy/spdy_credential_builder.cc | 4 | ||||
-rw-r--r-- | net/spdy/spdy_credential_builder.h | 2 | ||||
-rw-r--r-- | net/spdy/spdy_credential_builder_unittest.cc | 44 | ||||
-rw-r--r-- | net/spdy/spdy_http_stream_unittest.cc | 9 | ||||
-rw-r--r-- | net/spdy/spdy_session.cc | 3 | ||||
-rw-r--r-- | net/spdy/spdy_session.h | 2 | ||||
-rw-r--r-- | net/spdy/spdy_stream.cc | 15 | ||||
-rw-r--r-- | net/spdy/spdy_stream.h | 1 | ||||
-rw-r--r-- | net/ssl/default_server_bound_cert_store.cc | 36 | ||||
-rw-r--r-- | net/ssl/default_server_bound_cert_store.h | 5 | ||||
-rw-r--r-- | net/ssl/default_server_bound_cert_store_unittest.cc | 157 | ||||
-rw-r--r-- | net/ssl/server_bound_cert_service.cc | 225 | ||||
-rw-r--r-- | net/ssl/server_bound_cert_service.h | 22 | ||||
-rw-r--r-- | net/ssl/server_bound_cert_service_unittest.cc | 294 | ||||
-rw-r--r-- | net/ssl/server_bound_cert_store.cc | 7 | ||||
-rw-r--r-- | net/ssl/server_bound_cert_store.h | 21 |
17 files changed, 335 insertions, 546 deletions
diff --git a/net/socket/ssl_client_socket_nss.cc b/net/socket/ssl_client_socket_nss.cc index a5645b9..7027686 100644 --- a/net/socket/ssl_client_socket_nss.cc +++ b/net/socket/ssl_client_socket_nss.cc @@ -771,8 +771,7 @@ class SSLClientSocketNSS::Core : public base::RefCountedThreadSafe<Core> { //////////////////////////////////////////////////////////////////////////// int DoBufferRecv(IOBuffer* buffer, int len); int DoBufferSend(IOBuffer* buffer, int len); - int DoGetDomainBoundCert(const std::string& host, - const std::vector<uint8>& requested_cert_types); + int DoGetDomainBoundCert(const std::string& host); void OnGetDomainBoundCertComplete(int result); void OnHandshakeStateUpdated(const HandshakeState& state); @@ -903,7 +902,6 @@ class SSLClientSocketNSS::Core : public base::RefCountedThreadSafe<Core> { // prior to invoking OnHandshakeIOComplete. // Read on the NSS task runner when once OnHandshakeIOComplete is invoked // on the NSS task runner. - SSLClientCertType domain_bound_cert_type_; std::string domain_bound_private_key_; std::string domain_bound_cert_; @@ -944,8 +942,7 @@ SSLClientSocketNSS::Core::Core( user_write_buf_len_(0), network_task_runner_(network_task_runner), nss_task_runner_(nss_task_runner), - weak_net_log_(weak_net_log_factory_.GetWeakPtr()), - domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE) { + weak_net_log_(weak_net_log_factory_.GetWeakPtr()) { } SSLClientSocketNSS::Core::~Core() { @@ -2318,17 +2315,15 @@ SECStatus SSLClientSocketNSS::Core::ClientChannelIDHandler( // We have negotiated the TLS channel ID extension. core->channel_id_xtn_negotiated_ = true; std::string host = core->host_and_port_.host(); - std::vector<uint8> requested_cert_types; - requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); int error = ERR_UNEXPECTED; if (core->OnNetworkTaskRunner()) { - error = core->DoGetDomainBoundCert(host, requested_cert_types); + error = core->DoGetDomainBoundCert(host); } else { bool posted = core->network_task_runner_->PostTask( FROM_HERE, base::Bind( IgnoreResult(&Core::DoGetDomainBoundCert), - core, host, requested_cert_types)); + core, host)); error = posted ? ERR_IO_PENDING : ERR_ABORTED; } @@ -2372,9 +2367,7 @@ int SSLClientSocketNSS::Core::ImportChannelIDKeys(SECKEYPublicKey** public_key, return MapNSSError(PORT_GetError()); // Set the private key. - switch (domain_bound_cert_type_) { - case CLIENT_CERT_ECDSA_SIGN: { - if (!crypto::ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( + if (!crypto::ECPrivateKey::ImportFromEncryptedPrivateKeyInfo( ServerBoundCertService::kEPKIPassword, reinterpret_cast<const unsigned char*>( domain_bound_private_key_.data()), @@ -2384,15 +2377,8 @@ int SSLClientSocketNSS::Core::ImportChannelIDKeys(SECKEYPublicKey** public_key, false, key, public_key)) { - int error = MapNSSError(PORT_GetError()); - return error; - } - break; - } - - default: - NOTREACHED(); - return ERR_INVALID_ARGUMENT; + int error = MapNSSError(PORT_GetError()); + return error; } return OK; @@ -2620,9 +2606,7 @@ int SSLClientSocketNSS::Core::DoBufferSend(IOBuffer* send_buffer, int len) { return rv; } -int SSLClientSocketNSS::Core::DoGetDomainBoundCert( - const std::string& host, - const std::vector<uint8>& requested_cert_types) { +int SSLClientSocketNSS::Core::DoGetDomainBoundCert(const std::string& host) { DCHECK(OnNetworkTaskRunner()); if (detached_) @@ -2632,8 +2616,6 @@ int SSLClientSocketNSS::Core::DoGetDomainBoundCert( int rv = server_bound_cert_service_->GetDomainBoundCert( host, - requested_cert_types, - &domain_bound_cert_type_, &domain_bound_private_key_, &domain_bound_cert_, base::Bind(&Core::OnGetDomainBoundCertComplete, base::Unretained(this)), diff --git a/net/spdy/spdy_credential_builder.cc b/net/spdy/spdy_credential_builder.cc index 1742aff..79567b6 100644 --- a/net/spdy/spdy_credential_builder.cc +++ b/net/spdy/spdy_credential_builder.cc @@ -26,14 +26,10 @@ std::vector<uint8> ToVector(base::StringPiece piece) { // static int SpdyCredentialBuilder::Build(const std::string& tls_unique, - SSLClientCertType type, const std::string& key, const std::string& cert, size_t slot, SpdyCredential* credential) { - if (type != CLIENT_CERT_ECDSA_SIGN) - return ERR_BAD_SSL_CLIENT_AUTH_CERT; - std::string secret = SpdyCredentialBuilder::GetCredentialSecret(tls_unique); // Extract the SubjectPublicKeyInfo from the certificate. diff --git a/net/spdy/spdy_credential_builder.h b/net/spdy/spdy_credential_builder.h index d74b600..3bdc0a1 100644 --- a/net/spdy/spdy_credential_builder.h +++ b/net/spdy/spdy_credential_builder.h @@ -8,7 +8,6 @@ #include <string> #include "net/base/net_export.h" -#include "net/ssl/ssl_client_cert_type.h" namespace net { @@ -20,7 +19,6 @@ struct SpdyCredential; class NET_EXPORT_PRIVATE SpdyCredentialBuilder { public: static int Build(const std::string& tls_unique, - SSLClientCertType type, const std::string& key, const std::string& cert, size_t slot, diff --git a/net/spdy/spdy_credential_builder_unittest.cc b/net/spdy/spdy_credential_builder_unittest.cc index 89332d5..bc67cc5 100644 --- a/net/spdy/spdy_credential_builder_unittest.cc +++ b/net/spdy/spdy_credential_builder_unittest.cc @@ -30,16 +30,12 @@ void CreateCertAndKey(std::string* cert, std::string* key) { sequenced_worker_pool)); TestCompletionCallback callback; - std::vector<uint8> requested_cert_types; - requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); - SSLClientCertType cert_type; ServerBoundCertService::RequestHandle request_handle; int rv = server_bound_cert_service->GetDomainBoundCert( - "www.google.com", requested_cert_types, &cert_type, key, cert, + "www.google.com", key, cert, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, rv); EXPECT_EQ(OK, callback.WaitForResult()); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, cert_type); sequenced_worker_pool->Shutdown(); } @@ -53,13 +49,9 @@ class SpdyCredentialBuilderTest : public testing::Test { } protected: - int BuildWithType(SSLClientCertType type) { - return SpdyCredentialBuilder::Build( - MockClientSocket::kTlsUnique, type, key_, cert_, kSlot, &credential_); - } - int Build() { - return BuildWithType(CLIENT_CERT_ECDSA_SIGN); + return SpdyCredentialBuilder::Build( + MockClientSocket::kTlsUnique, key_, cert_, kSlot, &credential_); } std::string GetCredentialSecret() { @@ -89,35 +81,13 @@ TEST_F(SpdyCredentialBuilderTest, MAYBE_GetCredentialSecret) { } #if defined(USE_OPENSSL) -#define MAYBE_SucceedsWithECDSACert DISABLED_SucceedsWithECDSACert -#else -#define MAYBE_SucceedsWithECDSACert SucceedsWithECDSACert -#endif - -TEST_F(SpdyCredentialBuilderTest, MAYBE_SucceedsWithECDSACert) { - EXPECT_EQ(OK, BuildWithType(CLIENT_CERT_ECDSA_SIGN)); -} - -#if defined(USE_OPENSSL) -#define MAYBE_FailsWithRSACert DISABLED_FailsWithRSACert -#else -#define MAYBE_FailsWithRSACert FailsWithRSACert -#endif - -TEST_F(SpdyCredentialBuilderTest, MAYBE_FailsWithRSACert) { - EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT, - BuildWithType(CLIENT_CERT_RSA_SIGN)); -} - -#if defined(USE_OPENSSL) -#define MAYBE_FailsWithDSACert DISABLED_FailsWithDSACert +#define MAYBE_Succeeds DISABLED_Succeeds #else -#define MAYBE_FailsWithDSACert FailsWithDSACert +#define MAYBE_Succeeds Succeeds #endif -TEST_F(SpdyCredentialBuilderTest, MAYBE_FailsWithDSACert) { - EXPECT_EQ(ERR_BAD_SSL_CLIENT_AUTH_CERT, - BuildWithType(CLIENT_CERT_DSS_SIGN)); +TEST_F(SpdyCredentialBuilderTest, MAYBE_Succeeds) { + EXPECT_EQ(OK, Build()); } #if defined(USE_OPENSSL) diff --git a/net/spdy/spdy_http_stream_unittest.cc b/net/spdy/spdy_http_stream_unittest.cc index 04a8eca..55387cf 100644 --- a/net/spdy/spdy_http_stream_unittest.cc +++ b/net/spdy/spdy_http_stream_unittest.cc @@ -540,23 +540,18 @@ void GetECServerBoundCertAndProof( std::string* cert, std::string* proof) { TestCompletionCallback callback; - std::vector<uint8> requested_cert_types; - requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); - SSLClientCertType cert_type; std::string key; ServerBoundCertService::RequestHandle request_handle; int rv = server_bound_cert_service->GetDomainBoundCert( - host, requested_cert_types, &cert_type, &key, cert, callback.callback(), + host, &key, cert, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, rv); EXPECT_EQ(OK, callback.WaitForResult()); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, cert_type); SpdyCredential credential; EXPECT_EQ(OK, SpdyCredentialBuilder::Build( - MockClientSocket::kTlsUnique, cert_type, key, - *cert, 2, &credential)); + MockClientSocket::kTlsUnique, key, *cert, 2, &credential)); ASSERT_FALSE(credential.certs.empty()); cert->assign(credential.certs[0]); diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 8a730ce..db47549 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -793,7 +793,6 @@ scoped_ptr<SpdyFrame> SpdySession::CreateSynStream( int SpdySession::CreateCredentialFrame( const std::string& origin, - SSLClientCertType type, const std::string& key, const std::string& cert, RequestPriority priority, @@ -807,7 +806,7 @@ int SpdySession::CreateCredentialFrame( std::string tls_unique; ssl_socket->GetTLSUniqueChannelBinding(&tls_unique); size_t slot = credential_state_.SetHasCredential(GURL(origin)); - int rv = SpdyCredentialBuilder::Build(tls_unique, type, key, cert, slot, + int rv = SpdyCredentialBuilder::Build(tls_unique, key, cert, slot, &credential); DCHECK_NE(rv, ERR_IO_PENDING); if (rv != OK) diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h index c6a22e6..819db11 100644 --- a/net/spdy/spdy_session.h +++ b/net/spdy/spdy_session.h @@ -35,7 +35,6 @@ #include "net/spdy/spdy_session_pool.h" #include "net/spdy/spdy_stream.h" #include "net/spdy/spdy_write_queue.h" -#include "net/ssl/ssl_client_cert_type.h" #include "net/ssl/ssl_config_service.h" #include "url/gurl.h" @@ -299,7 +298,6 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, // |credential_frame| and returns OK. Returns the error (guaranteed // to not be ERR_IO_PENDING) otherwise. int CreateCredentialFrame(const std::string& origin, - SSLClientCertType type, const std::string& key, const std::string& cert, RequestPriority priority, diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc index db085cf..18d20e8 100644 --- a/net/spdy/spdy_stream.cc +++ b/net/spdy/spdy_stream.cc @@ -108,7 +108,6 @@ SpdyStream::SpdyStream(SpdyStreamType type, net_log_(net_log), send_bytes_(0), recv_bytes_(0), - domain_bound_cert_type_(CLIENT_CERT_INVALID_TYPE), just_completed_frame_type_(DATA), just_completed_frame_size_(0) { CHECK(type_ == SPDY_BIDIRECTIONAL_STREAM || @@ -741,11 +740,10 @@ int SpdyStream::DoGetDomainBoundCert() { io_state_ = STATE_GET_DOMAIN_BOUND_CERT_COMPLETE; ServerBoundCertService* sbc_service = session_->GetServerBoundCertService(); DCHECK(sbc_service != NULL); - std::vector<uint8> requested_cert_types; - requested_cert_types.push_back(CLIENT_CERT_ECDSA_SIGN); int rv = sbc_service->GetDomainBoundCert( - url.GetOrigin().host(), requested_cert_types, - &domain_bound_cert_type_, &domain_bound_private_key_, &domain_bound_cert_, + url.GetOrigin().host(), + &domain_bound_private_key_, + &domain_bound_cert_, base::Bind(&SpdyStream::OnGetDomainBoundCertComplete, GetWeakPtr()), &domain_bound_cert_request_handle_); return rv; @@ -771,8 +769,11 @@ int SpdyStream::DoSendDomainBoundCert() { origin.erase(origin.length() - 1); // Trim trailing slash. scoped_ptr<SpdyFrame> frame; int rv = session_->CreateCredentialFrame( - origin, domain_bound_cert_type_, domain_bound_private_key_, - domain_bound_cert_, priority_, &frame); + origin, + domain_bound_private_key_, + domain_bound_cert_, + priority_, + &frame); if (rv != OK) { DCHECK_NE(rv, ERR_IO_PENDING); return rv; diff --git a/net/spdy/spdy_stream.h b/net/spdy/spdy_stream.h index 06209a1..4d18e3e 100644 --- a/net/spdy/spdy_stream.h +++ b/net/spdy/spdy_stream.h @@ -541,7 +541,6 @@ class NET_EXPORT_PRIVATE SpdyStream { // Data received before delegate is attached. ScopedVector<SpdyBuffer> pending_buffers_; - SSLClientCertType domain_bound_cert_type_; std::string domain_bound_private_key_; std::string domain_bound_cert_; ServerBoundCertService::RequestHandle domain_bound_cert_request_handle_; diff --git a/net/ssl/default_server_bound_cert_store.cc b/net/ssl/default_server_bound_cert_store.cc index b189661..6fb9180 100644 --- a/net/ssl/default_server_bound_cert_store.cc +++ b/net/ssl/default_server_bound_cert_store.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/message_loop/message_loop.h" #include "base/metrics/histogram.h" +#include "net/base/net_errors.h" namespace net { @@ -60,16 +61,15 @@ DefaultServerBoundCertStore::GetServerBoundCertTask::~GetServerBoundCertTask() { void DefaultServerBoundCertStore::GetServerBoundCertTask::Run( DefaultServerBoundCertStore* store) { - SSLClientCertType type = CLIENT_CERT_INVALID_TYPE; base::Time expiration_time; std::string private_key_result; std::string cert_result; - bool was_sync = store->GetServerBoundCert( - server_identifier_, &type, &expiration_time, &private_key_result, + int err = store->GetServerBoundCert( + server_identifier_, &expiration_time, &private_key_result, &cert_result, GetCertCallback()); - DCHECK(was_sync); + DCHECK(err != ERR_IO_PENDING); - InvokeCallback(base::Bind(callback_, server_identifier_, type, + InvokeCallback(base::Bind(callback_, err, server_identifier_, expiration_time, private_key_result, cert_result)); } @@ -79,7 +79,6 @@ class DefaultServerBoundCertStore::SetServerBoundCertTask : public DefaultServerBoundCertStore::Task { public: SetServerBoundCertTask(const std::string& server_identifier, - SSLClientCertType type, base::Time creation_time, base::Time expiration_time, const std::string& private_key, @@ -89,7 +88,6 @@ class DefaultServerBoundCertStore::SetServerBoundCertTask private: std::string server_identifier_; - SSLClientCertType type_; base::Time creation_time_; base::Time expiration_time_; std::string private_key_; @@ -98,13 +96,11 @@ class DefaultServerBoundCertStore::SetServerBoundCertTask DefaultServerBoundCertStore::SetServerBoundCertTask::SetServerBoundCertTask( const std::string& server_identifier, - SSLClientCertType type, base::Time creation_time, base::Time expiration_time, const std::string& private_key, const std::string& cert) : server_identifier_(server_identifier), - type_(type), creation_time_(creation_time), expiration_time_(expiration_time), private_key_(private_key), @@ -116,7 +112,7 @@ DefaultServerBoundCertStore::SetServerBoundCertTask::~SetServerBoundCertTask() { void DefaultServerBoundCertStore::SetServerBoundCertTask::Run( DefaultServerBoundCertStore* store) { - store->SyncSetServerBoundCert(server_identifier_, type_, creation_time_, + store->SyncSetServerBoundCert(server_identifier_, creation_time_, expiration_time_, private_key_, cert_); } @@ -236,9 +232,8 @@ DefaultServerBoundCertStore::DefaultServerBoundCertStore( store_(store), weak_ptr_factory_(this) {} -bool DefaultServerBoundCertStore::GetServerBoundCert( +int DefaultServerBoundCertStore::GetServerBoundCert( const std::string& server_identifier, - SSLClientCertType* type, base::Time* expiration_time, std::string* private_key_result, std::string* cert_result, @@ -249,34 +244,30 @@ bool DefaultServerBoundCertStore::GetServerBoundCert( if (!loaded_) { EnqueueTask(scoped_ptr<Task>( new GetServerBoundCertTask(server_identifier, callback))); - return false; + return ERR_IO_PENDING; } ServerBoundCertMap::iterator it = server_bound_certs_.find(server_identifier); - if (it == server_bound_certs_.end()) { - *type = CLIENT_CERT_INVALID_TYPE; - return true; - } + if (it == server_bound_certs_.end()) + return ERR_FILE_NOT_FOUND; ServerBoundCert* cert = it->second; - *type = cert->type(); *expiration_time = cert->expiration_time(); *private_key_result = cert->private_key(); *cert_result = cert->cert(); - return true; + return OK; } void DefaultServerBoundCertStore::SetServerBoundCert( const std::string& server_identifier, - SSLClientCertType type, base::Time creation_time, base::Time expiration_time, const std::string& private_key, const std::string& cert) { RunOrEnqueueTask(scoped_ptr<Task>(new SetServerBoundCertTask( - server_identifier, type, creation_time, expiration_time, private_key, + server_identifier, creation_time, expiration_time, private_key, cert))); } @@ -377,7 +368,6 @@ void DefaultServerBoundCertStore::OnLoaded( void DefaultServerBoundCertStore::SyncSetServerBoundCert( const std::string& server_identifier, - SSLClientCertType type, base::Time creation_time, base::Time expiration_time, const std::string& private_key, @@ -389,7 +379,7 @@ void DefaultServerBoundCertStore::SyncSetServerBoundCert( InternalInsertServerBoundCert( server_identifier, new ServerBoundCert( - server_identifier, type, creation_time, expiration_time, private_key, + server_identifier, creation_time, expiration_time, private_key, cert)); } diff --git a/net/ssl/default_server_bound_cert_store.h b/net/ssl/default_server_bound_cert_store.h index 8ec6805..6128218 100644 --- a/net/ssl/default_server_bound_cert_store.h +++ b/net/ssl/default_server_bound_cert_store.h @@ -43,16 +43,14 @@ class NET_EXPORT DefaultServerBoundCertStore : public ServerBoundCertStore { virtual ~DefaultServerBoundCertStore(); // ServerBoundCertStore implementation. - virtual bool GetServerBoundCert( + virtual int GetServerBoundCert( const std::string& server_identifier, - SSLClientCertType* type, base::Time* expiration_time, std::string* private_key_result, std::string* cert_result, const GetCertCallback& callback) OVERRIDE; virtual void SetServerBoundCert( const std::string& server_identifier, - SSLClientCertType type, base::Time creation_time, base::Time expiration_time, const std::string& private_key, @@ -110,7 +108,6 @@ class NET_EXPORT DefaultServerBoundCertStore : public ServerBoundCertStore { // initialization is complete. void SyncSetServerBoundCert( const std::string& server_identifier, - SSLClientCertType type, base::Time creation_time, base::Time expiration_time, const std::string& private_key, diff --git a/net/ssl/default_server_bound_cert_store_unittest.cc b/net/ssl/default_server_bound_cert_store_unittest.cc index 8673916..c3f8452 100644 --- a/net/ssl/default_server_bound_cert_store_unittest.cc +++ b/net/ssl/default_server_bound_cert_store_unittest.cc @@ -13,6 +13,7 @@ #include "base/logging.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" +#include "net/base/net_errors.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { @@ -27,8 +28,8 @@ void NotCalled() { ADD_FAILURE() << "Unexpected callback execution."; } -void GetCertCallbackNotCalled(const std::string& server_identifier, - SSLClientCertType type, +void GetCertCallbackNotCalled(int err, + const std::string& server_identifier, base::Time expiration_time, const std::string& private_key_result, const std::string& cert_result) { @@ -39,21 +40,21 @@ class AsyncGetCertHelper { public: AsyncGetCertHelper() : called_(false) {} - void Callback(const std::string& server_identifier, - SSLClientCertType type, + void Callback(int err, + const std::string& server_identifier, base::Time expiration_time, const std::string& private_key_result, const std::string& cert_result) { + err_ = err; server_identifier_ = server_identifier; - type_ = type; expiration_time_ = expiration_time; private_key_ = private_key_result; cert_ = cert_result; called_ = true; } + int err_; std::string server_identifier_; - SSLClientCertType type_; base::Time expiration_time_; std::string private_key_; std::string cert_; @@ -127,14 +128,12 @@ TEST(DefaultServerBoundCertStoreTest, TestLoading) { persistent_store->AddServerBoundCert( DefaultServerBoundCertStore::ServerBoundCert( "google.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "a", "b")); persistent_store->AddServerBoundCert( DefaultServerBoundCertStore::ServerBoundCert( "verisign.com", - CLIENT_CERT_ECDSA_SIGN, base::Time(), base::Time(), "c", "d")); @@ -145,7 +144,6 @@ TEST(DefaultServerBoundCertStoreTest, TestLoading) { EXPECT_EQ(0, store.GetCertCount()); store.SetServerBoundCert( "verisign.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "e", "f"); @@ -154,7 +152,6 @@ TEST(DefaultServerBoundCertStoreTest, TestLoading) { EXPECT_EQ(2, store.GetCertCount()); store.SetServerBoundCert( "twitter.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "g", "h"); @@ -166,32 +163,28 @@ TEST(DefaultServerBoundCertStoreTest, TestLoading) { TEST(DefaultServerBoundCertStoreTest, TestSettingAndGetting) { // No persistent store, all calls will be synchronous. DefaultServerBoundCertStore store(NULL); - SSLClientCertType type; base::Time expiration_time; std::string private_key, cert; EXPECT_EQ(0, store.GetCertCount()); - EXPECT_TRUE(store.GetServerBoundCert("verisign.com", - &type, - &expiration_time, - &private_key, - &cert, - base::Bind(&GetCertCallbackNotCalled))); - EXPECT_EQ(CLIENT_CERT_INVALID_TYPE, type); + EXPECT_EQ(ERR_FILE_NOT_FOUND, + store.GetServerBoundCert("verisign.com", + &expiration_time, + &private_key, + &cert, + base::Bind(&GetCertCallbackNotCalled))); EXPECT_TRUE(private_key.empty()); EXPECT_TRUE(cert.empty()); store.SetServerBoundCert( "verisign.com", - CLIENT_CERT_RSA_SIGN, base::Time::FromInternalValue(123), base::Time::FromInternalValue(456), "i", "j"); - EXPECT_TRUE(store.GetServerBoundCert("verisign.com", - &type, - &expiration_time, - &private_key, - &cert, - base::Bind(&GetCertCallbackNotCalled))); - EXPECT_EQ(CLIENT_CERT_RSA_SIGN, type); + EXPECT_EQ(OK, + store.GetServerBoundCert("verisign.com", + &expiration_time, + &private_key, + &cert, + base::Bind(&GetCertCallbackNotCalled))); EXPECT_EQ(456, expiration_time.ToInternalValue()); EXPECT_EQ("i", private_key); EXPECT_EQ("j", cert); @@ -201,19 +194,16 @@ TEST(DefaultServerBoundCertStoreTest, TestDuplicateCerts) { scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore); DefaultServerBoundCertStore store(persistent_store.get()); - SSLClientCertType type; base::Time expiration_time; std::string private_key, cert; EXPECT_EQ(0, store.GetCertCount()); store.SetServerBoundCert( "verisign.com", - CLIENT_CERT_RSA_SIGN, base::Time::FromInternalValue(123), base::Time::FromInternalValue(1234), "a", "b"); store.SetServerBoundCert( "verisign.com", - CLIENT_CERT_ECDSA_SIGN, base::Time::FromInternalValue(456), base::Time::FromInternalValue(4567), "c", "d"); @@ -221,13 +211,12 @@ TEST(DefaultServerBoundCertStoreTest, TestDuplicateCerts) { // Wait for load & queued set tasks. base::MessageLoop::current()->RunUntilIdle(); EXPECT_EQ(1, store.GetCertCount()); - EXPECT_TRUE(store.GetServerBoundCert("verisign.com", - &type, - &expiration_time, - &private_key, - &cert, - base::Bind(&GetCertCallbackNotCalled))); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type); + EXPECT_EQ(OK, + store.GetServerBoundCert("verisign.com", + &expiration_time, + &private_key, + &cert, + base::Bind(&GetCertCallbackNotCalled))); EXPECT_EQ(4567, expiration_time.ToInternalValue()); EXPECT_EQ("c", private_key); EXPECT_EQ("d", cert); @@ -237,29 +226,31 @@ TEST(DefaultServerBoundCertStoreTest, TestAsyncGet) { scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore); persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert( "verisign.com", - CLIENT_CERT_RSA_SIGN, base::Time::FromInternalValue(123), base::Time::FromInternalValue(1234), "a", "b")); DefaultServerBoundCertStore store(persistent_store.get()); AsyncGetCertHelper helper; - SSLClientCertType type; base::Time expiration_time; std::string private_key; std::string cert = "not set"; EXPECT_EQ(0, store.GetCertCount()); - EXPECT_FALSE(store.GetServerBoundCert( - "verisign.com", &type, &expiration_time, &private_key, &cert, - base::Bind(&AsyncGetCertHelper::Callback, base::Unretained(&helper)))); + EXPECT_EQ(ERR_IO_PENDING, + store.GetServerBoundCert("verisign.com", + &expiration_time, + &private_key, + &cert, + base::Bind(&AsyncGetCertHelper::Callback, + base::Unretained(&helper)))); // Wait for load & queued get tasks. base::MessageLoop::current()->RunUntilIdle(); EXPECT_EQ(1, store.GetCertCount()); EXPECT_EQ("not set", cert); EXPECT_TRUE(helper.called_); + EXPECT_EQ(OK, helper.err_); EXPECT_EQ("verisign.com", helper.server_identifier_); - EXPECT_EQ(CLIENT_CERT_RSA_SIGN, helper.type_); EXPECT_EQ(1234, helper.expiration_time_.ToInternalValue()); EXPECT_EQ("a", helper.private_key_); EXPECT_EQ("b", helper.cert_); @@ -271,19 +262,16 @@ TEST(DefaultServerBoundCertStoreTest, TestDeleteAll) { store.SetServerBoundCert( "verisign.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "a", "b"); store.SetServerBoundCert( "google.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "c", "d"); store.SetServerBoundCert( "harvard.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "e", "f"); @@ -301,13 +289,11 @@ TEST(DefaultServerBoundCertStoreTest, TestAsyncGetAndDeleteAll) { scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore); persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert( "verisign.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "a", "b")); persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert( "google.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "c", "d")); @@ -333,13 +319,11 @@ TEST(DefaultServerBoundCertStoreTest, TestDelete) { scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore); DefaultServerBoundCertStore store(persistent_store.get()); - SSLClientCertType type; base::Time expiration_time; std::string private_key, cert; EXPECT_EQ(0, store.GetCertCount()); store.SetServerBoundCert( "verisign.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "a", "b"); @@ -348,7 +332,6 @@ TEST(DefaultServerBoundCertStoreTest, TestDelete) { store.SetServerBoundCert( "google.com", - CLIENT_CERT_ECDSA_SIGN, base::Time(), base::Time(), "c", "d"); @@ -359,45 +342,40 @@ TEST(DefaultServerBoundCertStoreTest, TestDelete) { base::Bind(&CallCounter, &delete_finished)); ASSERT_EQ(1, delete_finished); EXPECT_EQ(1, store.GetCertCount()); - EXPECT_TRUE(store.GetServerBoundCert("verisign.com", - &type, - &expiration_time, - &private_key, - &cert, - base::Bind(&GetCertCallbackNotCalled))); - EXPECT_EQ(CLIENT_CERT_INVALID_TYPE, type); - EXPECT_TRUE(store.GetServerBoundCert("google.com", - &type, - &expiration_time, - &private_key, - &cert, - base::Bind(&GetCertCallbackNotCalled))); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type); + EXPECT_EQ(ERR_FILE_NOT_FOUND, + store.GetServerBoundCert("verisign.com", + &expiration_time, + &private_key, + &cert, + base::Bind(&GetCertCallbackNotCalled))); + EXPECT_EQ(OK, + store.GetServerBoundCert("google.com", + &expiration_time, + &private_key, + &cert, + base::Bind(&GetCertCallbackNotCalled))); int delete2_finished = 0; store.DeleteServerBoundCert("google.com", base::Bind(&CallCounter, &delete2_finished)); ASSERT_EQ(1, delete2_finished); EXPECT_EQ(0, store.GetCertCount()); - EXPECT_TRUE(store.GetServerBoundCert("google.com", - &type, - &expiration_time, - &private_key, - &cert, - base::Bind(&GetCertCallbackNotCalled))); - EXPECT_EQ(CLIENT_CERT_INVALID_TYPE, type); + EXPECT_EQ(ERR_FILE_NOT_FOUND, + store.GetServerBoundCert("google.com", + &expiration_time, + &private_key, + &cert, + base::Bind(&GetCertCallbackNotCalled))); } TEST(DefaultServerBoundCertStoreTest, TestAsyncDelete) { scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore); persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert( "a.com", - CLIENT_CERT_RSA_SIGN, base::Time::FromInternalValue(1), base::Time::FromInternalValue(2), "a", "b")); persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert( "b.com", - CLIENT_CERT_RSA_SIGN, base::Time::FromInternalValue(3), base::Time::FromInternalValue(4), "c", "d")); @@ -408,17 +386,20 @@ TEST(DefaultServerBoundCertStoreTest, TestAsyncDelete) { AsyncGetCertHelper a_helper; AsyncGetCertHelper b_helper; - SSLClientCertType type; base::Time expiration_time; std::string private_key; std::string cert = "not set"; EXPECT_EQ(0, store.GetCertCount()); - EXPECT_FALSE(store.GetServerBoundCert( - "a.com", &type, &expiration_time, &private_key, &cert, - base::Bind(&AsyncGetCertHelper::Callback, base::Unretained(&a_helper)))); - EXPECT_FALSE(store.GetServerBoundCert( - "b.com", &type, &expiration_time, &private_key, &cert, - base::Bind(&AsyncGetCertHelper::Callback, base::Unretained(&b_helper)))); + EXPECT_EQ(ERR_IO_PENDING, + store.GetServerBoundCert( + "a.com", &expiration_time, &private_key, &cert, + base::Bind(&AsyncGetCertHelper::Callback, + base::Unretained(&a_helper)))); + EXPECT_EQ(ERR_IO_PENDING, + store.GetServerBoundCert( + "b.com", &expiration_time, &private_key, &cert, + base::Bind(&AsyncGetCertHelper::Callback, + base::Unretained(&b_helper)))); EXPECT_EQ(0, delete_finished); EXPECT_FALSE(a_helper.called_); @@ -429,14 +410,14 @@ TEST(DefaultServerBoundCertStoreTest, TestAsyncDelete) { EXPECT_EQ(1, store.GetCertCount()); EXPECT_EQ("not set", cert); EXPECT_TRUE(a_helper.called_); + EXPECT_EQ(ERR_FILE_NOT_FOUND, a_helper.err_); EXPECT_EQ("a.com", a_helper.server_identifier_); - EXPECT_EQ(CLIENT_CERT_INVALID_TYPE, a_helper.type_); EXPECT_EQ(0, a_helper.expiration_time_.ToInternalValue()); EXPECT_EQ("", a_helper.private_key_); EXPECT_EQ("", a_helper.cert_); EXPECT_TRUE(b_helper.called_); + EXPECT_EQ(OK, b_helper.err_); EXPECT_EQ("b.com", b_helper.server_identifier_); - EXPECT_EQ(CLIENT_CERT_RSA_SIGN, b_helper.type_); EXPECT_EQ(4, b_helper.expiration_time_.ToInternalValue()); EXPECT_EQ("c", b_helper.private_key_); EXPECT_EQ("d", b_helper.cert_); @@ -449,25 +430,21 @@ TEST(DefaultServerBoundCertStoreTest, TestGetAll) { EXPECT_EQ(0, store.GetCertCount()); store.SetServerBoundCert( "verisign.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "a", "b"); store.SetServerBoundCert( "google.com", - CLIENT_CERT_ECDSA_SIGN, base::Time(), base::Time(), "c", "d"); store.SetServerBoundCert( "harvard.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "e", "f"); store.SetServerBoundCert( "mit.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "g", "h"); @@ -486,13 +463,11 @@ TEST(DefaultServerBoundCertStoreTest, TestInitializeFrom) { store.SetServerBoundCert( "preexisting.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "a", "b"); store.SetServerBoundCert( "both.com", - CLIENT_CERT_ECDSA_SIGN, base::Time(), base::Time(), "c", "d"); @@ -503,14 +478,12 @@ TEST(DefaultServerBoundCertStoreTest, TestInitializeFrom) { ServerBoundCertStore::ServerBoundCertList source_certs; source_certs.push_back(ServerBoundCertStore::ServerBoundCert( "both.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), // Key differs from above to test that existing entries are overwritten. "e", "f")); source_certs.push_back(ServerBoundCertStore::ServerBoundCert( "copied.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "g", "h")); @@ -538,13 +511,11 @@ TEST(DefaultServerBoundCertStoreTest, TestAsyncInitializeFrom) { scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore); persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert( "preexisting.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "a", "b")); persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert( "both.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "c", "d")); @@ -553,14 +524,12 @@ TEST(DefaultServerBoundCertStoreTest, TestAsyncInitializeFrom) { ServerBoundCertStore::ServerBoundCertList source_certs; source_certs.push_back(ServerBoundCertStore::ServerBoundCert( "both.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), // Key differs from above to test that existing entries are overwritten. "e", "f")); source_certs.push_back(ServerBoundCertStore::ServerBoundCert( "copied.com", - CLIENT_CERT_RSA_SIGN, base::Time(), base::Time(), "g", "h")); diff --git a/net/ssl/server_bound_cert_service.cc b/net/ssl/server_bound_cert_service.cc index 3740469..434f8ad 100644 --- a/net/ssl/server_bound_cert_service.cc +++ b/net/ssl/server_bound_cert_service.cc @@ -42,15 +42,6 @@ const int kValidityPeriodInDays = 365; // while. const int kSystemTimeValidityBufferInDays = 90; -bool IsSupportedCertType(uint8 type) { - switch(type) { - case CLIENT_CERT_ECDSA_SIGN: - return true; - default: - return false; - } -} - // Used by the GetDomainBoundCertResult histogram to record the final // outcome of each GetDomainBoundCert call. Do not re-use values. enum GetCertResult { @@ -96,7 +87,6 @@ void RecordGetCertTime(base::TimeDelta request_time) { // unjoined thread, due to relying on a non-leaked LazyInstance scoped_ptr<ServerBoundCertStore::ServerBoundCert> GenerateCert( const std::string& server_identifier, - SSLClientCertType type, uint32 serial_number, int* error) { scoped_ptr<ServerBoundCertStore::ServerBoundCert> result; @@ -107,34 +97,25 @@ scoped_ptr<ServerBoundCertStore::ServerBoundCert> GenerateCert( not_valid_before + base::TimeDelta::FromDays(kValidityPeriodInDays); std::string der_cert; std::vector<uint8> private_key_info; - switch (type) { - case CLIENT_CERT_ECDSA_SIGN: { - scoped_ptr<crypto::ECPrivateKey> key(crypto::ECPrivateKey::Create()); - if (!key.get()) { - DLOG(ERROR) << "Unable to create key pair for client"; - *error = ERR_KEY_GENERATION_FAILED; - return result.Pass(); - } - if (!x509_util::CreateDomainBoundCertEC(key.get(), server_identifier, - serial_number, not_valid_before, - not_valid_after, &der_cert)) { - DLOG(ERROR) << "Unable to create x509 cert for client"; - *error = ERR_ORIGIN_BOUND_CERT_GENERATION_FAILED; - return result.Pass(); - } + scoped_ptr<crypto::ECPrivateKey> key(crypto::ECPrivateKey::Create()); + if (!key.get()) { + DLOG(ERROR) << "Unable to create key pair for client"; + *error = ERR_KEY_GENERATION_FAILED; + return result.Pass(); + } + if (!x509_util::CreateDomainBoundCertEC(key.get(), server_identifier, + serial_number, not_valid_before, + not_valid_after, &der_cert)) { + DLOG(ERROR) << "Unable to create x509 cert for client"; + *error = ERR_ORIGIN_BOUND_CERT_GENERATION_FAILED; + return result.Pass(); + } - if (!key->ExportEncryptedPrivateKey(ServerBoundCertService::kEPKIPassword, - 1, &private_key_info)) { - DLOG(ERROR) << "Unable to export private key"; - *error = ERR_PRIVATE_KEY_EXPORT_FAILED; - return result.Pass(); - } - break; - } - default: - NOTREACHED(); - *error = ERR_INVALID_ARGUMENT; - return result.Pass(); + if (!key->ExportEncryptedPrivateKey(ServerBoundCertService::kEPKIPassword, + 1, &private_key_info)) { + DLOG(ERROR) << "Unable to export private key"; + *error = ERR_PRIVATE_KEY_EXPORT_FAILED; + return result.Pass(); } // TODO(rkn): Perhaps ExportPrivateKey should be changed to output a @@ -142,7 +123,10 @@ scoped_ptr<ServerBoundCertStore::ServerBoundCert> GenerateCert( std::string key_out(private_key_info.begin(), private_key_info.end()); result.reset(new ServerBoundCertStore::ServerBoundCert( - server_identifier, type, not_valid_before, not_valid_after, key_out, + server_identifier, + not_valid_before, + not_valid_after, + key_out, der_cert)); UMA_HISTOGRAM_CUSTOM_TIMES("DomainBoundCerts.GenerateCertTime", base::TimeTicks::Now() - start, @@ -160,12 +144,10 @@ class ServerBoundCertServiceRequest { public: ServerBoundCertServiceRequest(base::TimeTicks request_start, const CompletionCallback& callback, - SSLClientCertType* type, std::string* private_key, std::string* cert) : request_start_(request_start), callback_(callback), - type_(type), private_key_(private_key), cert_(cert) { } @@ -174,7 +156,6 @@ class ServerBoundCertServiceRequest { void Cancel() { RecordGetDomainBoundCertResult(ASYNC_CANCELLED); callback_.Reset(); - type_ = NULL; private_key_ = NULL; cert_ = NULL; } @@ -182,7 +163,6 @@ class ServerBoundCertServiceRequest { // Copies the contents of |private_key| and |cert| to the caller's output // arguments and calls the callback. void Post(int error, - SSLClientCertType type, const std::string& private_key, const std::string& cert) { switch (error) { @@ -214,7 +194,6 @@ class ServerBoundCertServiceRequest { break; } if (!callback_.is_null()) { - *type_ = type; *private_key_ = private_key; *cert_ = cert; callback_.Run(error); @@ -227,7 +206,6 @@ class ServerBoundCertServiceRequest { private: base::TimeTicks request_start_; CompletionCallback callback_; - SSLClientCertType* type_; std::string* private_key_; std::string* cert_; }; @@ -244,10 +222,8 @@ class ServerBoundCertServiceWorker { ServerBoundCertServiceWorker( const std::string& server_identifier, - SSLClientCertType type, const WorkerDoneCallback& callback) : server_identifier_(server_identifier), - type_(type), serial_number_(base::RandInt(0, std::numeric_limits<int>::max())), origin_loop_(base::MessageLoopProxy::current()), callback_(callback) { @@ -269,9 +245,8 @@ class ServerBoundCertServiceWorker { // Runs on a worker thread. int error = ERR_FAILED; scoped_ptr<ServerBoundCertStore::ServerBoundCert> cert = - GenerateCert(server_identifier_, type_, serial_number_, &error); - DVLOG(1) << "GenerateCert " << server_identifier_ << " " << type_ - << " returned " << error; + GenerateCert(server_identifier_, serial_number_, &error); + DVLOG(1) << "GenerateCert " << server_identifier_ << " returned " << error; #if defined(USE_NSS) // Detach the thread from NSPR. // Calling NSS functions attaches the thread to NSPR, which stores @@ -288,7 +263,6 @@ class ServerBoundCertServiceWorker { } const std::string server_identifier_; - const SSLClientCertType type_; // Note that serial_number_ must be initialized on a non-worker thread // (see documentation for GenerateCert). uint32 serial_number_; @@ -303,31 +277,25 @@ class ServerBoundCertServiceWorker { // origin message loop. class ServerBoundCertServiceJob { public: - ServerBoundCertServiceJob(SSLClientCertType type) - : type_(type) { - } + ServerBoundCertServiceJob() { } ~ServerBoundCertServiceJob() { if (!requests_.empty()) DeleteAllCanceled(); } - SSLClientCertType type() const { return type_; } - void AddRequest(ServerBoundCertServiceRequest* request) { requests_.push_back(request); } void HandleResult(int error, - SSLClientCertType type, const std::string& private_key, const std::string& cert) { - PostAll(error, type, private_key, cert); + PostAll(error, private_key, cert); } private: void PostAll(int error, - SSLClientCertType type, const std::string& private_key, const std::string& cert) { std::vector<ServerBoundCertServiceRequest*> requests; @@ -335,7 +303,7 @@ class ServerBoundCertServiceJob { for (std::vector<ServerBoundCertServiceRequest*>::iterator i = requests.begin(); i != requests.end(); i++) { - (*i)->Post(error, type, private_key, cert); + (*i)->Post(error, private_key, cert); // Post() causes the ServerBoundCertServiceRequest to delete itself. } } @@ -352,7 +320,6 @@ class ServerBoundCertServiceJob { } std::vector<ServerBoundCertServiceRequest*> requests_; - SSLClientCertType type_; }; // static @@ -422,20 +389,15 @@ std::string ServerBoundCertService::GetDomainForHost(const std::string& host) { int ServerBoundCertService::GetDomainBoundCert( const std::string& host, - const std::vector<uint8>& requested_types, - SSLClientCertType* type, std::string* private_key, std::string* cert, const CompletionCallback& callback, RequestHandle* out_req) { - DVLOG(1) << __FUNCTION__ << " " << host << " " - << (requested_types.empty() ? -1 : requested_types[0]) - << (requested_types.size() > 1 ? "..." : ""); + DVLOG(1) << __FUNCTION__ << " " << host; DCHECK(CalledOnValidThread()); base::TimeTicks request_start = base::TimeTicks::Now(); - if (callback.is_null() || !private_key || !cert || host.empty() || - requested_types.empty()) { + if (callback.is_null() || !private_key || !cert || host.empty()) { RecordGetDomainBoundCertResult(INVALID_ARGUMENT); return ERR_INVALID_ARGUMENT; } @@ -446,19 +408,6 @@ int ServerBoundCertService::GetDomainBoundCert( return ERR_INVALID_ARGUMENT; } - SSLClientCertType preferred_type = CLIENT_CERT_INVALID_TYPE; - for (size_t i = 0; i < requested_types.size(); ++i) { - if (IsSupportedCertType(requested_types[i])) { - preferred_type = static_cast<SSLClientCertType>(requested_types[i]); - break; - } - } - if (preferred_type == CLIENT_CERT_INVALID_TYPE) { - RecordGetDomainBoundCertResult(UNSUPPORTED_TYPE); - // None of the requested types are supported. - return ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED; - } - requests_++; // See if an identical request is currently in flight. @@ -469,26 +418,13 @@ int ServerBoundCertService::GetDomainBoundCert( // An identical request is in flight already. We'll just attach our // callback. job = j->second; - // Check that the job is for an acceptable type of cert. - if (std::find(requested_types.begin(), requested_types.end(), job->type()) - == requested_types.end()) { - DVLOG(1) << "Found inflight job of wrong type " << job->type() - << " for " << domain; - // If we get here, the server is asking for different types of certs in - // short succession. This probably means the server is broken or - // misconfigured. Since we only store one type of cert per domain, we - // are unable to handle this well. Just return an error and let the first - // job finish. - RecordGetDomainBoundCertResult(TYPE_MISMATCH); - return ERR_ORIGIN_BOUND_CERT_GENERATION_TYPE_MISMATCH; - } inflight_joins_++; ServerBoundCertServiceRequest* request = new ServerBoundCertServiceRequest( request_start, base::Bind(&RequestHandle::OnRequestComplete, base::Unretained(out_req)), - type, private_key, cert); + private_key, cert); job->AddRequest(request); out_req->RequestStarted(this, request, callback); return ERR_IO_PENDING; @@ -498,30 +434,29 @@ int ServerBoundCertService::GetDomainBoundCert( // domain. Note that |expiration_time| is ignored, and expired certs are // considered valid. base::Time expiration_time; - if (server_bound_cert_store_->GetServerBoundCert( - domain, - type, - &expiration_time /* ignored */, - private_key, - cert, - base::Bind(&ServerBoundCertService::GotServerBoundCert, - weak_ptr_factory_.GetWeakPtr()))) { - if (IsSupportedCertType(*type)) { - // Sync lookup found a valid cert. - DVLOG(1) << "Cert store had valid cert for " << domain - << " of type " << *type; - cert_store_hits_++; - RecordGetDomainBoundCertResult(SYNC_SUCCESS); - base::TimeDelta request_time = base::TimeTicks::Now() - request_start; - UMA_HISTOGRAM_TIMES("DomainBoundCerts.GetCertTimeSync", request_time); - RecordGetCertTime(request_time); - return OK; - } + int err = server_bound_cert_store_->GetServerBoundCert( + domain, + &expiration_time /* ignored */, + private_key, + cert, + base::Bind(&ServerBoundCertService::GotServerBoundCert, + weak_ptr_factory_.GetWeakPtr())); + if (err == OK) { + // Sync lookup found a valid cert. + DVLOG(1) << "Cert store had valid cert for " << domain; + cert_store_hits_++; + RecordGetDomainBoundCertResult(SYNC_SUCCESS); + base::TimeDelta request_time = base::TimeTicks::Now() - request_start; + UMA_HISTOGRAM_TIMES("DomainBoundCerts.GetCertTimeSync", request_time); + RecordGetCertTime(request_time); + return OK; + } + + if (err == ERR_FILE_NOT_FOUND) { // Sync lookup did not find a valid cert. Start generating a new one. ServerBoundCertServiceWorker* worker = new ServerBoundCertServiceWorker( domain, - preferred_type, base::Bind(&ServerBoundCertService::GeneratedServerBoundCert, weak_ptr_factory_.GetWeakPtr())); if (!worker->Start(task_runner_)) { @@ -532,23 +467,28 @@ int ServerBoundCertService::GetDomainBoundCert( } } - // We are either waiting for async DB lookup, or waiting for cert generation. - // Create a job & request to track it. - job = new ServerBoundCertServiceJob(preferred_type); - inflight_[domain] = job; - - ServerBoundCertServiceRequest* request = new ServerBoundCertServiceRequest( - request_start, - base::Bind(&RequestHandle::OnRequestComplete, base::Unretained(out_req)), - type, private_key, cert); - job->AddRequest(request); - out_req->RequestStarted(this, request, callback); - return ERR_IO_PENDING; + if (err == ERR_IO_PENDING || err == ERR_FILE_NOT_FOUND) { + // We are either waiting for async DB lookup, or waiting for cert + // generation. Create a job & request to track it. + job = new ServerBoundCertServiceJob(); + inflight_[domain] = job; + + ServerBoundCertServiceRequest* request = new ServerBoundCertServiceRequest( + request_start, + base::Bind(&RequestHandle::OnRequestComplete, + base::Unretained(out_req)), + private_key, cert); + job->AddRequest(request); + out_req->RequestStarted(this, request, callback); + return ERR_IO_PENDING; + } + + return err; } void ServerBoundCertService::GotServerBoundCert( + int err, const std::string& server_identifier, - SSLClientCertType type, base::Time expiration_time, const std::string& key, const std::string& cert) { @@ -560,22 +500,17 @@ void ServerBoundCertService::GotServerBoundCert( NOTREACHED(); return; } - ServerBoundCertServiceJob* job = j->second; - if (IsSupportedCertType(type)) { + if (err == OK) { // Async DB lookup found a valid cert. - DVLOG(1) << "Cert store had valid cert for " << server_identifier - << " of type " << type; + DVLOG(1) << "Cert store had valid cert for " << server_identifier; cert_store_hits_++; // ServerBoundCertServiceRequest::Post will do the histograms and stuff. - HandleResult(OK, server_identifier, type, key, cert); - return; + HandleResult(OK, server_identifier, key, cert); } - // Async lookup did not find a valid cert. Start generating a new one. ServerBoundCertServiceWorker* worker = new ServerBoundCertServiceWorker( server_identifier, - job->type(), base::Bind(&ServerBoundCertService::GeneratedServerBoundCert, weak_ptr_factory_.GetWeakPtr())); if (!worker->Start(task_runner_)) { @@ -583,7 +518,6 @@ void ServerBoundCertService::GotServerBoundCert( LOG(ERROR) << "ServerBoundCertServiceWorker couldn't be started."; HandleResult(ERR_INSUFFICIENT_RESOURCES, server_identifier, - CLIENT_CERT_INVALID_TYPE, std::string(), std::string()); return; @@ -609,24 +543,21 @@ void ServerBoundCertService::GeneratedServerBoundCert( // TODO(mattm): we should just Pass() the cert object to // SetServerBoundCert(). server_bound_cert_store_->SetServerBoundCert( - cert->server_identifier(), cert->type(), cert->creation_time(), - cert->expiration_time(), cert->private_key(), cert->cert()); + cert->server_identifier(), + cert->creation_time(), + cert->expiration_time(), + cert->private_key(), + cert->cert()); - HandleResult(error, server_identifier, cert->type(), cert->private_key(), - cert->cert()); + HandleResult(error, server_identifier, cert->private_key(), cert->cert()); } else { - HandleResult(error, - server_identifier, - CLIENT_CERT_INVALID_TYPE, - std::string(), - std::string()); + HandleResult(error, server_identifier, std::string(), std::string()); } } void ServerBoundCertService::HandleResult( int error, const std::string& server_identifier, - SSLClientCertType type, const std::string& private_key, const std::string& cert) { DCHECK(CalledOnValidThread()); @@ -640,7 +571,7 @@ void ServerBoundCertService::HandleResult( ServerBoundCertServiceJob* job = j->second; inflight_.erase(j); - job->HandleResult(error, type, private_key, cert); + job->HandleResult(error, private_key, cert); delete job; } diff --git a/net/ssl/server_bound_cert_service.h b/net/ssl/server_bound_cert_service.h index dd50590..5734a4c 100644 --- a/net/ssl/server_bound_cert_service.h +++ b/net/ssl/server_bound_cert_service.h @@ -17,7 +17,6 @@ #include "net/base/completion_callback.h" #include "net/base/net_export.h" #include "net/ssl/server_bound_cert_store.h" -#include "net/ssl/ssl_client_cert_type.h" namespace base { class TaskRunner; @@ -92,17 +91,13 @@ class NET_EXPORT ServerBoundCertService // longer hold. bool IsSystemTimeValid() const { return is_system_time_valid_; } - // Fetches the domain bound cert for the specified host of the specified - // type if one exists and creates one otherwise. Returns OK if successful or - // an error code upon failure. - // - // |requested_types| is a list of the TLS ClientCertificateTypes the site will - // accept, ordered from most preferred to least preferred. Types we don't - // support will be ignored. See ssl_client_cert_type.h. + // Fetches the domain bound cert for the specified host if one exists and + // creates one otherwise. Returns OK if successful or an error code upon + // failure. // // On successful completion, |private_key| stores a DER-encoded - // PrivateKeyInfo struct, and |cert| stores a DER-encoded certificate, and - // |type| specifies the type of certificate that was returned. + // PrivateKeyInfo struct, and |cert| stores a DER-encoded certificate. + // The PrivateKeyInfo is always an ECDSA private key. // // |callback| must not be null. ERR_IO_PENDING is returned if the operation // could not be completed immediately, in which case the result code will @@ -113,8 +108,6 @@ class NET_EXPORT ServerBoundCertService // ServerBoundCertService is destroyed. int GetDomainBoundCert( const std::string& host, - const std::vector<uint8>& requested_types, - SSLClientCertType* type, std::string* private_key, std::string* cert, const CompletionCallback& callback, @@ -135,8 +128,8 @@ class NET_EXPORT ServerBoundCertService // callback will not be called. void CancelRequest(ServerBoundCertServiceRequest* req); - void GotServerBoundCert(const std::string& server_identifier, - SSLClientCertType type, + void GotServerBoundCert(int err, + const std::string& server_identifier, base::Time expiration_time, const std::string& key, const std::string& cert); @@ -146,7 +139,6 @@ class NET_EXPORT ServerBoundCertService scoped_ptr<ServerBoundCertStore::ServerBoundCert> cert); void HandleResult(int error, const std::string& server_identifier, - SSLClientCertType type, const std::string& private_key, const std::string& cert); diff --git a/net/ssl/server_bound_cert_service_unittest.cc b/net/ssl/server_bound_cert_service_unittest.cc index 37a86a4..e0ee18f 100644 --- a/net/ssl/server_bound_cert_service_unittest.cc +++ b/net/ssl/server_bound_cert_service_unittest.cc @@ -10,6 +10,7 @@ #include "base/bind.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" +#include "base/task_runner.h" #include "base/threading/sequenced_worker_pool.h" #include "crypto/ec_private_key.h" #include "net/base/net_errors.h" @@ -47,6 +48,66 @@ class ServerBoundCertServiceTest : public testing::Test { scoped_ptr<ServerBoundCertService> service_; }; +class MockServerBoundCertStoreWithAsyncGet + : public DefaultServerBoundCertStore { + public: + MockServerBoundCertStoreWithAsyncGet() + : DefaultServerBoundCertStore(NULL), cert_count_(0) {} + + virtual int GetServerBoundCert(const std::string& server_identifier, + base::Time* expiration_time, + std::string* private_key_result, + std::string* cert_result, + const GetCertCallback& callback) OVERRIDE; + + virtual void SetServerBoundCert(const std::string& server_identifier, + base::Time creation_time, + base::Time expiration_time, + const std::string& private_key, + const std::string& cert) OVERRIDE { + cert_count_ = 1; + } + + virtual int GetCertCount() OVERRIDE { return cert_count_; } + + void CallGetServerBoundCertCallbackWithResult(int err, + base::Time expiration_time, + const std::string& private_key, + const std::string& cert); + + private: + GetCertCallback callback_; + std::string server_identifier_; + int cert_count_; +}; + +int MockServerBoundCertStoreWithAsyncGet::GetServerBoundCert( + const std::string& server_identifier, + base::Time* expiration_time, + std::string* private_key_result, + std::string* cert_result, + const GetCertCallback& callback) { + server_identifier_ = server_identifier; + callback_ = callback; + // Reset the cert count, it'll get incremented in either SetServerBoundCert or + // CallGetServerBoundCertCallbackWithResult. + cert_count_ = 0; + // Do nothing else: the results to be provided will be specified through + // CallGetServerBoundCertCallbackWithResult. + return ERR_IO_PENDING; +} + +void +MockServerBoundCertStoreWithAsyncGet::CallGetServerBoundCertCallbackWithResult( + int err, + base::Time expiration_time, + const std::string& private_key, + const std::string& cert) { + if (err == OK) + cert_count_ = 1; + callback_.Run(err, server_identifier_, expiration_time, private_key, cert); +} + TEST_F(ServerBoundCertServiceTest, GetDomainForHost) { EXPECT_EQ("google.com", ServerBoundCertService::GetDomainForHost("google.com")); @@ -73,38 +134,32 @@ TEST_F(ServerBoundCertServiceTest, CacheHit) { std::string host("encrypted.google.com"); int error; - std::vector<uint8> types; - types.push_back(CLIENT_CERT_ECDSA_SIGN); TestCompletionCallback callback; ServerBoundCertService::RequestHandle request_handle; // Asynchronous completion. - SSLClientCertType type1; std::string private_key_info1, der_cert1; EXPECT_EQ(0, service_->cert_count()); error = service_->GetDomainBoundCert( - host, types, &type1, &private_key_info1, &der_cert1, + host, &private_key_info1, &der_cert1, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle.is_active()); error = callback.WaitForResult(); EXPECT_EQ(OK, error); EXPECT_EQ(1, service_->cert_count()); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); EXPECT_FALSE(private_key_info1.empty()); EXPECT_FALSE(der_cert1.empty()); EXPECT_FALSE(request_handle.is_active()); // Synchronous completion. - SSLClientCertType type2; std::string private_key_info2, der_cert2; error = service_->GetDomainBoundCert( - host, types, &type2, &private_key_info2, &der_cert2, + host, &private_key_info2, &der_cert2, callback.callback(), &request_handle); EXPECT_FALSE(request_handle.is_active()); EXPECT_EQ(OK, error); EXPECT_EQ(1, service_->cert_count()); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); EXPECT_EQ(private_key_info1, private_key_info2); EXPECT_EQ(der_cert1, der_cert2); @@ -113,97 +168,16 @@ TEST_F(ServerBoundCertServiceTest, CacheHit) { EXPECT_EQ(0u, service_->inflight_joins()); } -TEST_F(ServerBoundCertServiceTest, UnsupportedTypes) { - std::string host("encrypted.google.com"); - - int error; - std::vector<uint8> types; - TestCompletionCallback callback; - ServerBoundCertService::RequestHandle request_handle; - - // Empty requested_types. - SSLClientCertType type1; - std::string private_key_info1, der_cert1; - error = service_->GetDomainBoundCert( - host, types, &type1, &private_key_info1, &der_cert1, - callback.callback(), &request_handle); - EXPECT_EQ(ERR_INVALID_ARGUMENT, error); - EXPECT_FALSE(request_handle.is_active()); - - // No supported types in requested_types. - types.push_back(CLIENT_CERT_RSA_SIGN); - types.push_back(2); - types.push_back(3); - error = service_->GetDomainBoundCert( - host, types, &type1, &private_key_info1, &der_cert1, - callback.callback(), &request_handle); - EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error); - EXPECT_FALSE(request_handle.is_active()); - - // Supported types after unsupported ones in requested_types. - types.push_back(CLIENT_CERT_ECDSA_SIGN); - // Asynchronous completion. - EXPECT_EQ(0, service_->cert_count()); - error = service_->GetDomainBoundCert( - host, types, &type1, &private_key_info1, &der_cert1, - callback.callback(), &request_handle); - EXPECT_EQ(ERR_IO_PENDING, error); - EXPECT_TRUE(request_handle.is_active()); - error = callback.WaitForResult(); - EXPECT_EQ(OK, error); - EXPECT_EQ(1, service_->cert_count()); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); - EXPECT_FALSE(private_key_info1.empty()); - EXPECT_FALSE(der_cert1.empty()); - - // Now that the cert is created, doing requests for unsupported types - // shouldn't affect the created cert. - // Empty requested_types. - types.clear(); - SSLClientCertType type2; - std::string private_key_info2, der_cert2; - error = service_->GetDomainBoundCert( - host, types, &type2, &private_key_info2, &der_cert2, - callback.callback(), &request_handle); - EXPECT_EQ(ERR_INVALID_ARGUMENT, error); - EXPECT_FALSE(request_handle.is_active()); - - // No supported types in requested_types. - types.push_back(CLIENT_CERT_RSA_SIGN); - types.push_back(2); - types.push_back(3); - error = service_->GetDomainBoundCert( - host, types, &type2, &private_key_info2, &der_cert2, - callback.callback(), &request_handle); - EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error); - EXPECT_FALSE(request_handle.is_active()); - - // If we request EC, the cert we created before should still be there. - types.push_back(CLIENT_CERT_ECDSA_SIGN); - error = service_->GetDomainBoundCert( - host, types, &type2, &private_key_info2, &der_cert2, - callback.callback(), &request_handle); - EXPECT_FALSE(request_handle.is_active()); - EXPECT_EQ(OK, error); - EXPECT_EQ(1, service_->cert_count()); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); - EXPECT_EQ(private_key_info1, private_key_info2); - EXPECT_EQ(der_cert1, der_cert2); -} - TEST_F(ServerBoundCertServiceTest, StoreCerts) { int error; - std::vector<uint8> types; - types.push_back(CLIENT_CERT_ECDSA_SIGN); TestCompletionCallback callback; ServerBoundCertService::RequestHandle request_handle; std::string host1("encrypted.google.com"); - SSLClientCertType type1; std::string private_key_info1, der_cert1; EXPECT_EQ(0, service_->cert_count()); error = service_->GetDomainBoundCert( - host1, types, &type1, &private_key_info1, &der_cert1, + host1, &private_key_info1, &der_cert1, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle.is_active()); @@ -212,10 +186,9 @@ TEST_F(ServerBoundCertServiceTest, StoreCerts) { EXPECT_EQ(1, service_->cert_count()); std::string host2("www.verisign.com"); - SSLClientCertType type2; std::string private_key_info2, der_cert2; error = service_->GetDomainBoundCert( - host2, types, &type2, &private_key_info2, &der_cert2, + host2, &private_key_info2, &der_cert2, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle.is_active()); @@ -224,10 +197,9 @@ TEST_F(ServerBoundCertServiceTest, StoreCerts) { EXPECT_EQ(2, service_->cert_count()); std::string host3("www.twitter.com"); - SSLClientCertType type3; std::string private_key_info3, der_cert3; error = service_->GetDomainBoundCert( - host3, types, &type3, &private_key_info3, &der_cert3, + host3, &private_key_info3, &der_cert3, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle.is_active()); @@ -241,38 +213,29 @@ TEST_F(ServerBoundCertServiceTest, StoreCerts) { EXPECT_NE(der_cert1, der_cert3); EXPECT_NE(private_key_info2, private_key_info3); EXPECT_NE(der_cert2, der_cert3); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3); } // Tests an inflight join. TEST_F(ServerBoundCertServiceTest, InflightJoin) { std::string host("encrypted.google.com"); int error; - std::vector<uint8> types; - types.push_back(CLIENT_CERT_ECDSA_SIGN); - SSLClientCertType type1; std::string private_key_info1, der_cert1; TestCompletionCallback callback1; ServerBoundCertService::RequestHandle request_handle1; - SSLClientCertType type2; std::string private_key_info2, der_cert2; TestCompletionCallback callback2; ServerBoundCertService::RequestHandle request_handle2; error = service_->GetDomainBoundCert( - host, types, &type1, &private_key_info1, &der_cert1, + host, &private_key_info1, &der_cert1, callback1.callback(), &request_handle1); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle1.is_active()); - // If we request RSA and EC in the 2nd request, should still join with the - // original request. - types.insert(types.begin(), CLIENT_CERT_RSA_SIGN); + // Should join with the original request. error = service_->GetDomainBoundCert( - host, types, &type2, &private_key_info2, &der_cert2, + host, &private_key_info2, &der_cert2, callback2.callback(), &request_handle2); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle2.is_active()); @@ -282,8 +245,6 @@ TEST_F(ServerBoundCertServiceTest, InflightJoin) { error = callback2.WaitForResult(); EXPECT_EQ(OK, error); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); EXPECT_EQ(2u, service_->requests()); EXPECT_EQ(0u, service_->cert_store_hits()); EXPECT_EQ(1u, service_->inflight_joins()); @@ -291,16 +252,13 @@ TEST_F(ServerBoundCertServiceTest, InflightJoin) { TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) { std::string host("encrypted.google.com"); - SSLClientCertType type; std::string private_key_info, der_cert; int error; - std::vector<uint8> types; - types.push_back(CLIENT_CERT_ECDSA_SIGN); TestCompletionCallback callback; ServerBoundCertService::RequestHandle request_handle; error = service_->GetDomainBoundCert( - host, types, &type, &private_key_info, &der_cert, callback.callback(), + host, &private_key_info, &der_cert, callback.callback(), &request_handle); EXPECT_EQ(ERR_IO_PENDING, error); EXPECT_TRUE(request_handle.is_active()); @@ -329,16 +287,11 @@ TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) { // Tests that the callback of a canceled request is never made. TEST_F(ServerBoundCertServiceTest, CancelRequest) { std::string host("encrypted.google.com"); - SSLClientCertType type; std::string private_key_info, der_cert; int error; - std::vector<uint8> types; - types.push_back(CLIENT_CERT_ECDSA_SIGN); ServerBoundCertService::RequestHandle request_handle; error = service_->GetDomainBoundCert(host, - types, - &type, &private_key_info, &der_cert, base::Bind(&FailTest), @@ -362,17 +315,12 @@ TEST_F(ServerBoundCertServiceTest, CancelRequest) { // Tests that destructing the RequestHandle cancels the request. TEST_F(ServerBoundCertServiceTest, CancelRequestByHandleDestruction) { std::string host("encrypted.google.com"); - SSLClientCertType type; std::string private_key_info, der_cert; int error; - std::vector<uint8> types; - types.push_back(CLIENT_CERT_ECDSA_SIGN); { ServerBoundCertService::RequestHandle request_handle; error = service_->GetDomainBoundCert(host, - types, - &type, &private_key_info, &der_cert, base::Bind(&FailTest), @@ -394,16 +342,11 @@ TEST_F(ServerBoundCertServiceTest, CancelRequestByHandleDestruction) { TEST_F(ServerBoundCertServiceTest, DestructionWithPendingRequest) { std::string host("encrypted.google.com"); - SSLClientCertType type; std::string private_key_info, der_cert; int error; - std::vector<uint8> types; - types.push_back(CLIENT_CERT_ECDSA_SIGN); ServerBoundCertService::RequestHandle request_handle; error = service_->GetDomainBoundCert(host, - types, - &type, &private_key_info, &der_cert, base::Bind(&FailTest), @@ -438,16 +381,11 @@ TEST_F(ServerBoundCertServiceTest, RequestAfterPoolShutdown) { // Make a request that will force synchronous completion. std::string host("encrypted.google.com"); - SSLClientCertType type; std::string private_key_info, der_cert; int error; - std::vector<uint8> types; - types.push_back(CLIENT_CERT_ECDSA_SIGN); ServerBoundCertService::RequestHandle request_handle; error = service_->GetDomainBoundCert(host, - types, - &type, &private_key_info, &der_cert, base::Bind(&FailTest), @@ -460,30 +398,23 @@ TEST_F(ServerBoundCertServiceTest, RequestAfterPoolShutdown) { // Tests that simultaneous creation of different certs works. TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) { int error; - std::vector<uint8> types; - types.push_back(CLIENT_CERT_ECDSA_SIGN); std::string host1("encrypted.google.com"); - SSLClientCertType type1; std::string private_key_info1, der_cert1; TestCompletionCallback callback1; ServerBoundCertService::RequestHandle request_handle1; std::string host2("foo.com"); - SSLClientCertType type2; std::string private_key_info2, der_cert2; TestCompletionCallback callback2; ServerBoundCertService::RequestHandle request_handle2; std::string host3("bar.com"); - SSLClientCertType type3; std::string private_key_info3, der_cert3; TestCompletionCallback callback3; ServerBoundCertService::RequestHandle request_handle3; error = service_->GetDomainBoundCert(host1, - types, - &type1, &private_key_info1, &der_cert1, callback1.callback(), @@ -492,8 +423,6 @@ TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) { EXPECT_TRUE(request_handle1.is_active()); error = service_->GetDomainBoundCert(host2, - types, - &type2, &private_key_info2, &der_cert2, callback2.callback(), @@ -502,8 +431,6 @@ TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) { EXPECT_TRUE(request_handle2.is_active()); error = service_->GetDomainBoundCert(host3, - types, - &type3, &private_key_info3, &der_cert3, callback3.callback(), @@ -513,19 +440,16 @@ TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) { error = callback1.WaitForResult(); EXPECT_EQ(OK, error); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); EXPECT_FALSE(private_key_info1.empty()); EXPECT_FALSE(der_cert1.empty()); error = callback2.WaitForResult(); EXPECT_EQ(OK, error); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); EXPECT_FALSE(private_key_info2.empty()); EXPECT_FALSE(der_cert2.empty()); error = callback3.WaitForResult(); EXPECT_EQ(OK, error); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3); EXPECT_FALSE(private_key_info3.empty()); EXPECT_FALSE(der_cert3.empty()); @@ -545,13 +469,11 @@ TEST_F(ServerBoundCertServiceTest, Expiration) { ServerBoundCertStore* store = service_->GetCertStore(); base::Time now = base::Time::Now(); store->SetServerBoundCert("good", - CLIENT_CERT_ECDSA_SIGN, now, now + base::TimeDelta::FromDays(1), "a", "b"); store->SetServerBoundCert("expired", - CLIENT_CERT_ECDSA_SIGN, now - base::TimeDelta::FromDays(2), now - base::TimeDelta::FromDays(1), "c", @@ -559,38 +481,98 @@ TEST_F(ServerBoundCertServiceTest, Expiration) { EXPECT_EQ(2, service_->cert_count()); int error; - std::vector<uint8> types; - types.push_back(CLIENT_CERT_ECDSA_SIGN); TestCompletionCallback callback; ServerBoundCertService::RequestHandle request_handle; // Cert is valid - synchronous completion. - SSLClientCertType type1; std::string private_key_info1, der_cert1; error = service_->GetDomainBoundCert( - "good", types, &type1, &private_key_info1, &der_cert1, + "good", &private_key_info1, &der_cert1, callback.callback(), &request_handle); EXPECT_EQ(OK, error); EXPECT_FALSE(request_handle.is_active()); EXPECT_EQ(2, service_->cert_count()); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1); EXPECT_STREQ("a", private_key_info1.c_str()); EXPECT_STREQ("b", der_cert1.c_str()); // Expired cert is valid as well - synchronous completion. - SSLClientCertType type2; std::string private_key_info2, der_cert2; error = service_->GetDomainBoundCert( - "expired", types, &type2, &private_key_info2, &der_cert2, + "expired", &private_key_info2, &der_cert2, callback.callback(), &request_handle); EXPECT_EQ(OK, error); EXPECT_FALSE(request_handle.is_active()); EXPECT_EQ(2, service_->cert_count()); - EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2); EXPECT_STREQ("c", private_key_info2.c_str()); EXPECT_STREQ("d", der_cert2.c_str()); } +TEST_F(ServerBoundCertServiceTest, AsyncStoreGetNoCertsInStore) { + MockServerBoundCertStoreWithAsyncGet* mock_store = + new MockServerBoundCertStoreWithAsyncGet(); + scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool( + new base::SequencedWorkerPool(3, "ServerBoundCertServiceTest")); + scoped_ptr<ServerBoundCertService> service( + new ServerBoundCertService(mock_store, sequenced_worker_pool)); + + std::string host("encrypted.google.com"); + + int error; + TestCompletionCallback callback; + ServerBoundCertService::RequestHandle request_handle; + + // Asynchronous completion with no certs in the store. + std::string private_key_info, der_cert; + EXPECT_EQ(0, service->cert_count()); + error = service->GetDomainBoundCert( + host, &private_key_info, &der_cert, callback.callback(), &request_handle); + EXPECT_EQ(ERR_IO_PENDING, error); + EXPECT_TRUE(request_handle.is_active()); + + mock_store->CallGetServerBoundCertCallbackWithResult( + ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string()); + + error = callback.WaitForResult(); + EXPECT_EQ(OK, error); + EXPECT_EQ(1, service->cert_count()); + EXPECT_FALSE(private_key_info.empty()); + EXPECT_FALSE(der_cert.empty()); + EXPECT_FALSE(request_handle.is_active()); +} + +TEST_F(ServerBoundCertServiceTest, AsyncStoreGetOneCertInStore) { + MockServerBoundCertStoreWithAsyncGet* mock_store = + new MockServerBoundCertStoreWithAsyncGet(); + scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool( + new base::SequencedWorkerPool(3, "ServerBoundCertServiceTest")); + scoped_ptr<ServerBoundCertService> service( + new ServerBoundCertService(mock_store, sequenced_worker_pool)); + + std::string host("encrypted.google.com"); + + int error; + TestCompletionCallback callback; + ServerBoundCertService::RequestHandle request_handle; + + // Asynchronous completion with a cert in the store. + std::string private_key_info, der_cert; + EXPECT_EQ(0, service->cert_count()); + error = service->GetDomainBoundCert( + host, &private_key_info, &der_cert, callback.callback(), &request_handle); + EXPECT_EQ(ERR_IO_PENDING, error); + EXPECT_TRUE(request_handle.is_active()); + + mock_store->CallGetServerBoundCertCallbackWithResult( + OK, base::Time(), "ab", "cd"); + + error = callback.WaitForResult(); + EXPECT_EQ(OK, error); + EXPECT_EQ(1, service->cert_count()); + EXPECT_STREQ("ab", private_key_info.c_str()); + EXPECT_STREQ("cd", der_cert.c_str()); + EXPECT_FALSE(request_handle.is_active()); +} + #endif // !defined(USE_OPENSSL) } // namespace diff --git a/net/ssl/server_bound_cert_store.cc b/net/ssl/server_bound_cert_store.cc index d0d520d..e778362 100644 --- a/net/ssl/server_bound_cert_store.cc +++ b/net/ssl/server_bound_cert_store.cc @@ -6,19 +6,16 @@ namespace net { -ServerBoundCertStore::ServerBoundCert::ServerBoundCert() - : type_(CLIENT_CERT_INVALID_TYPE) { +ServerBoundCertStore::ServerBoundCert::ServerBoundCert() { } ServerBoundCertStore::ServerBoundCert::ServerBoundCert( const std::string& server_identifier, - SSLClientCertType type, base::Time creation_time, base::Time expiration_time, const std::string& private_key, const std::string& cert) : server_identifier_(server_identifier), - type_(type), creation_time_(creation_time), expiration_time_(expiration_time), private_key_(private_key), @@ -29,7 +26,7 @@ ServerBoundCertStore::ServerBoundCert::~ServerBoundCert() {} void ServerBoundCertStore::InitializeFrom(const ServerBoundCertList& list) { for (ServerBoundCertList::const_iterator i = list.begin(); i != list.end(); ++i) { - SetServerBoundCert(i->server_identifier(), i->type(), i->creation_time(), + SetServerBoundCert(i->server_identifier(), i->creation_time(), i->expiration_time(), i->private_key(), i->cert()); } } diff --git a/net/ssl/server_bound_cert_store.h b/net/ssl/server_bound_cert_store.h index ad0ecb0..0de0f3e 100644 --- a/net/ssl/server_bound_cert_store.h +++ b/net/ssl/server_bound_cert_store.h @@ -12,7 +12,6 @@ #include "base/threading/non_thread_safe.h" #include "base/time/time.h" #include "net/base/net_export.h" -#include "net/ssl/ssl_client_cert_type.h" namespace net { @@ -27,12 +26,11 @@ class NET_EXPORT ServerBoundCertStore : NON_EXPORTED_BASE(public base::NonThreadSafe) { public: // The ServerBoundCert class contains a private key in addition to the server - // cert, and cert type. + // cert. class NET_EXPORT ServerBoundCert { public: ServerBoundCert(); ServerBoundCert(const std::string& server_identifier, - SSLClientCertType type, base::Time creation_time, base::Time expiration_time, const std::string& private_key, @@ -41,8 +39,6 @@ class NET_EXPORT ServerBoundCertStore // Server identifier. For domain bound certs, for instance "verisign.com". const std::string& server_identifier() const { return server_identifier_; } - // TLS ClientCertificateType. - SSLClientCertType type() const { return type_; } // The time the certificate was created, also the start of the certificate // validity period. base::Time creation_time() const { return creation_time_; } @@ -57,7 +53,6 @@ class NET_EXPORT ServerBoundCertStore private: std::string server_identifier_; - SSLClientCertType type_; base::Time creation_time_; base::Time expiration_time_; std::string private_key_; @@ -67,8 +62,8 @@ class NET_EXPORT ServerBoundCertStore typedef std::list<ServerBoundCert> ServerBoundCertList; typedef base::Callback<void( + int, const std::string&, - SSLClientCertType, base::Time, const std::string&, const std::string&)> GetCertCallback; @@ -77,14 +72,13 @@ class NET_EXPORT ServerBoundCertStore virtual ~ServerBoundCertStore() {} // GetServerBoundCert may return the result synchronously through the - // output parameters, in which case it will return true. Otherwise it will - // return false and the callback will be called with the result + // output parameters, in which case it will return either OK if a cert is + // found in the store, or ERR_FILE_NOT_FOUND if none is found. If the + // result cannot be returned synchronously, GetServerBoundCert will + // return ERR_IO_PENDING and the callback will be called with the result // asynchronously. - // In either case, the type will be CLIENT_CERT_INVALID_TYPE if no cert - // existed for the given |server_identifier|. - virtual bool GetServerBoundCert( + virtual int GetServerBoundCert( const std::string& server_identifier, - SSLClientCertType* type, base::Time* expiration_time, std::string* private_key_result, std::string* cert_result, @@ -93,7 +87,6 @@ class NET_EXPORT ServerBoundCertStore // Adds a server bound cert and the corresponding private key to the store. virtual void SetServerBoundCert( const std::string& server_identifier, - SSLClientCertType type, base::Time creation_time, base::Time expiration_time, const std::string& private_key, |