Chromium Code Reviews| Index: net/socket/ssl_client_socket_unittest.cc |
| diff --git a/net/socket/ssl_client_socket_unittest.cc b/net/socket/ssl_client_socket_unittest.cc |
| index b7dd90bd7e4858efbcaf8d92f44aea4cfca6a266..f0652622b37f05647926012a2a7802d7d9bd5012 100644 |
| --- a/net/socket/ssl_client_socket_unittest.cc |
| +++ b/net/socket/ssl_client_socket_unittest.cc |
| @@ -29,6 +29,8 @@ |
| #include "net/ssl/default_channel_id_store.h" |
| #include "net/ssl/ssl_cert_request_info.h" |
| #include "net/ssl/ssl_config_service.h" |
| +#include "net/ssl/ssl_connection_status_flags.h" |
| +#include "net/ssl/ssl_info.h" |
| #include "net/test/cert_test_util.h" |
| #include "net/test/spawned_test_server/spawned_test_server.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| @@ -2790,6 +2792,77 @@ TEST_F(SSLClientSocketTest, ReuseStates) { |
| // attempt to read one byte extra. |
| } |
| +// Tests that session caches are sharded by max_version. |
| +TEST_F(SSLClientSocketTest, FallbackShardSessionCache) { |
| + SpawnedTestServer::SSLOptions ssl_options; |
| + ASSERT_TRUE(StartTestServer(ssl_options)); |
| + |
| + // Prepare a normal and fallback SSL config. |
| + SSLConfig ssl_config; |
| + SSLConfig fallback_ssl_config; |
| + fallback_ssl_config.version_max = SSL_PROTOCOL_VERSION_TLS1; |
| + fallback_ssl_config.version_fallback = true; |
| + |
| + // Connect with a fallback config from the test server to add an entry to the |
| + // session cache. |
| + TestCompletionCallback callback; |
| + scoped_ptr<StreamSocket> transport( |
| + new TCPClientSocket(addr(), &log_, NetLog::Source())); |
| + EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback()))); |
| + scoped_ptr<SSLClientSocket> sock(CreateSSLClientSocket( |
| + transport.Pass(), test_server()->host_port_pair(), fallback_ssl_config)); |
| + EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback()))); |
| + SSLInfo ssl_info; |
| + EXPECT_TRUE(sock->GetSSLInfo(&ssl_info)); |
| + EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type); |
| + EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1, |
| + SSLConnectionStatusToVersion(ssl_info.connection_status)); |
| + |
| + // A non-fallback connection needs a full handshake. |
| + transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source())); |
| + EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback()))); |
| + sock = CreateSSLClientSocket(transport.Pass(), |
| + test_server()->host_port_pair(), ssl_config); |
| + EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback()))); |
| + EXPECT_TRUE(sock->GetSSLInfo(&ssl_info)); |
| + EXPECT_EQ(SSLInfo::HANDSHAKE_FULL, ssl_info.handshake_type); |
| + // This does not check for equality because TLS 1.2 support is conditional on |
| + // system NSS features. |
| + EXPECT_LT(SSL_CONNECTION_VERSION_TLS1, |
| + SSLConnectionStatusToVersion(ssl_info.connection_status)); |
| + |
| + // Note: if the server (correctly) declines to resume a TLS 1.0 session at TLS |
| + // 1.2, the above test would not be sufficient to prove the session caches are |
| + // sharded. Implementations vary here, so, to avoid being sensitive to this, |
| + // attempt to resume with two more connections. |
|
davidben
2015/02/20 22:57:56
Ideally, this test should function correctly under
|
| + |
| + // The non-fallback connection added a > TLS 1.0 entry to the session cache. |
| + transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source())); |
| + EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback()))); |
| + sock = CreateSSLClientSocket(transport.Pass(), |
| + test_server()->host_port_pair(), ssl_config); |
| + EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback()))); |
| + EXPECT_TRUE(sock->GetSSLInfo(&ssl_info)); |
| + EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type); |
| + // This does not check for equality because TLS 1.2 support is conditional on |
| + // system NSS features. |
| + EXPECT_LT(SSL_CONNECTION_VERSION_TLS1, |
| + SSLConnectionStatusToVersion(ssl_info.connection_status)); |
| + |
| + // The fallback connection still resumes from its session cache. It cannot |
| + // offer the > TLS 1.0 session, so this must have been the session from the |
| + // first fallback connection. |
| + transport.reset(new TCPClientSocket(addr(), &log_, NetLog::Source())); |
| + EXPECT_EQ(OK, callback.GetResult(transport->Connect(callback.callback()))); |
| + sock = CreateSSLClientSocket( |
| + transport.Pass(), test_server()->host_port_pair(), fallback_ssl_config); |
| + EXPECT_EQ(OK, callback.GetResult(sock->Connect(callback.callback()))); |
| + EXPECT_TRUE(sock->GetSSLInfo(&ssl_info)); |
| + EXPECT_EQ(SSLInfo::HANDSHAKE_RESUME, ssl_info.handshake_type); |
| + EXPECT_EQ(SSL_CONNECTION_VERSION_TLS1, |
| + SSLConnectionStatusToVersion(ssl_info.connection_status)); |
| +} |
| + |
| #if defined(USE_OPENSSL) |
| TEST_F(SSLClientSocketTest, HandshakeCallbackIsRun_WithFailure) { |