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

Unified Diff: net/socket/ssl_client_socket_openssl.cc

Issue 8857002: net: split the SSL session cache between incognito and normal. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ... Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/socket/ssl_client_socket_openssl.cc
diff --git a/net/socket/ssl_client_socket_openssl.cc b/net/socket/ssl_client_socket_openssl.cc
index f933031539b007fb3dd02cd4616538b8f065d050..547de444b415611d1ebc64481263efcda89ed0ce 100644
--- a/net/socket/ssl_client_socket_openssl.cc
+++ b/net/socket/ssl_client_socket_openssl.cc
@@ -200,28 +200,32 @@ int NoOpVerifyCallback(X509_STORE_CTX*, void *) {
// OpenSSL manages a cache of SSL_SESSION, this class provides the application
// side policy for that cache about session re-use: we retain one session per
-// unique HostPortPair.
+// unique HostPortPair, per shard.
class SSLSessionCache {
public:
SSLSessionCache() {}
- void OnSessionAdded(const HostPortPair& host_and_port, SSL_SESSION* session) {
+ void OnSessionAdded(const HostPortPair& host_and_port,
+ const std::string& shard,
+ SSL_SESSION* session) {
// Declare the session cleaner-upper before the lock, so any call into
// OpenSSL to free the session will happen after the lock is released.
crypto::ScopedOpenSSL<SSL_SESSION, SSL_SESSION_free> session_to_free;
base::AutoLock lock(lock_);
DCHECK_EQ(0U, session_map_.count(session));
+ const std::string cache_key = GetCacheKey(host_and_port, shard);
+
std::pair<HostPortMap::iterator, bool> res =
- host_port_map_.insert(std::make_pair(host_and_port, session));
+ host_port_map_.insert(std::make_pair(cache_key, session));
if (!res.second) { // Already exists: replace old entry.
session_to_free.reset(res.first->second);
session_map_.erase(session_to_free.get());
res.first->second = session;
}
DVLOG(2) << "Adding session " << session << " => "
- << host_and_port.ToString() << ", new entry = " << res.second;
- DCHECK(host_port_map_[host_and_port] == session);
+ << cache_key << ", new entry = " << res.second;
+ DCHECK(host_port_map_[cache_key] == session);
session_map_[session] = res.first;
DCHECK_EQ(host_port_map_.size(), session_map_.size());
DCHECK_LE(host_port_map_.size(), kSessionCacheMaxEntires);
@@ -236,8 +240,7 @@ class SSLSessionCache {
SessionMap::iterator it = session_map_.find(session);
if (it == session_map_.end())
return;
- DVLOG(2) << "Remove session " << session << " => "
- << it->second->first.ToString();
+ DVLOG(2) << "Remove session " << session << " => " << it->second->first;
DCHECK(it->second->second == session);
host_port_map_.erase(it->second);
session_map_.erase(it);
@@ -247,13 +250,14 @@ class SSLSessionCache {
// Looks up the host:port in the cache, and if a session is found it is added
// to |ssl|, returning true on success.
- bool SetSSLSession(SSL* ssl, const HostPortPair& host_and_port) {
+ bool SetSSLSession(SSL* ssl, const HostPortPair& host_and_port,
+ const std::string& shard) {
base::AutoLock lock(lock_);
- HostPortMap::iterator it = host_port_map_.find(host_and_port);
+ const std::string cache_key = GetCacheKey(host_and_port, shard);
+ HostPortMap::iterator it = host_port_map_.find(cache_key);
if (it == host_port_map_.end())
return false;
- DVLOG(2) << "Lookup session: " << it->second << " => "
- << host_and_port.ToString();
+ DVLOG(2) << "Lookup session: " << it->second << " => " << cache_key;
SSL_SESSION* session = it->second;
DCHECK(session);
DCHECK(session_map_[session] == it);
@@ -265,12 +269,26 @@ class SSLSessionCache {
return SSL_set_session(ssl, session) == 1;
}
+ // Flush removes all entries from the cache. This is called when a client
+ // certificate is added.
+ void Flush() {
+ for (HostPortMap::iterator i = host_port_map_.begin();
+ i != host_port_map_.end(); i++) {
+ SSL_SESSION_free(i->second);
+ }
+ host_port_map_.clear();
+ session_map_.clear();
+ }
+
private:
+ static std::string GetCacheKey(const HostPortPair& host_and_port,
+ const std::string& shard) {
+ return host_and_port.ToString() + "/" + shard;
+ }
+
// A pair of maps to allow bi-directional lookups between host:port and an
// associated session.
- // TODO(joth): When client certificates are implemented we should key the
- // cache on the client certificate used in addition to the host-port pair.
- typedef std::map<HostPortPair, SSL_SESSION*> HostPortMap;
+ typedef std::map<std::string, SSL_SESSION*> HostPortMap;
typedef std::map<SSL_SESSION*, HostPortMap::iterator> SessionMap;
HostPortMap host_port_map_;
SessionMap session_map_;
@@ -329,7 +347,9 @@ class SSLContext {
int NewSessionCallback(SSL* ssl, SSL_SESSION* session) {
SSLClientSocketOpenSSL* socket = GetClientSocketFromSSL(ssl);
- session_cache_.OnSessionAdded(socket->host_and_port(), session);
+ session_cache_.OnSessionAdded(socket->host_and_port(),
+ socket->ssl_session_cache_shard(),
+ session);
return 1; // 1 => We took ownership of |session|.
}
@@ -360,8 +380,11 @@ class SSLContext {
// SSLClientSocketOpenSSL object from an SSL instance.
int ssl_socket_data_index_;
- crypto::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_;
+ // session_cache_ must appear before |ssl_ctx_| because the destruction of
+ // |ssl_ctx_| may trigger callbacks into |session_cache_|. Therefore,
+ // |session_cache_| must be destructed after |ssl_ctx_|.
SSLSessionCache session_cache_;
+ crypto::ScopedOpenSSL<SSL_CTX, SSL_CTX_free> ssl_ctx_;
};
// Utility to construct the appropriate set & clear masks for use the OpenSSL
@@ -379,6 +402,12 @@ struct SslSetClearMask {
} // namespace
+// static
+void SSLClientSocket::ClearSessionCache() {
+ SSLContext* context = SSLContext::GetInstance();
+ context->session_cache()->Flush();
+}
+
SSLClientSocketOpenSSL::SSLClientSocketOpenSSL(
ClientSocketHandle* transport_socket,
const HostPortPair& host_and_port,
@@ -394,6 +423,7 @@ SSLClientSocketOpenSSL::SSLClientSocketOpenSSL(
transport_(transport_socket),
host_and_port_(host_and_port),
ssl_config_(ssl_config),
+ ssl_session_cache_shard_(context.ssl_session_cache_shard),
trying_cached_session_(false),
npn_status_(kNextProtoUnsupported),
net_log_(transport_socket->socket()->NetLog()) {
@@ -418,7 +448,8 @@ bool SSLClientSocketOpenSSL::Init() {
return false;
trying_cached_session_ =
- context->session_cache()->SetSSLSession(ssl_, host_and_port_);
+ context->session_cache()->SetSSLSession(ssl_, host_and_port_,
+ ssl_session_cache_shard_);
BIO* ssl_bio = NULL;
// 0 => use default buffer sizes.
@@ -651,6 +682,9 @@ int SSLClientSocketOpenSSL::Connect(const CompletionCallback& callback) {
void SSLClientSocketOpenSSL::Disconnect() {
if (ssl_) {
+ // Calling SSL_shutdown prevents the session from being marked as
+ // unresumable.
+ SSL_shutdown(ssl_);
SSL_free(ssl_);
ssl_ = NULL;
}

Powered by Google App Engine
This is Rietveld 408576698