1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string> 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/ref_counted.h" 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_vector.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/net_util.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/base/request_priority.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/dns/mock_host_resolver.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_auth_handler_mock.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_network_session.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_network_transaction.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_request_info.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_server_properties_impl.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/transport_security_state.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/proxy/proxy_service.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/socket_test_util.h" 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace net { 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TLS10SSLConfigService : public SSLConfigService { 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TLS10SSLConfigService() { 30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ssl_config_.version_min = SSL_PROTOCOL_VERSION_SSL3; 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ssl_config_.version_max = SSL_PROTOCOL_VERSION_TLS1; 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void GetSSLConfig(SSLConfig* config) OVERRIDE { 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *config = ssl_config_; 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~TLS10SSLConfigService() {} 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SSLConfig ssl_config_; 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class TLS11SSLConfigService : public SSLConfigService { 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TLS11SSLConfigService() { 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ssl_config_.version_min = SSL_PROTOCOL_VERSION_SSL3; 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ssl_config_.version_max = SSL_PROTOCOL_VERSION_TLS1_1; 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void GetSSLConfig(SSLConfig* config) OVERRIDE { 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *config = ssl_config_; 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~TLS11SSLConfigService() {} 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SSLConfig ssl_config_; 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class HttpNetworkTransactionSSLTest : public testing::Test { 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SetUp() { 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ssl_config_service_ = new TLS10SSLConfigService; 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_params_.ssl_config_service = ssl_config_service_.get(); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) auth_handler_factory_.reset(new HttpAuthHandlerMock::Factory()); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_params_.http_auth_handler_factory = auth_handler_factory_.get(); 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) proxy_service_.reset(ProxyService::CreateDirect()); 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_params_.proxy_service = proxy_service_.get(); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_params_.client_socket_factory = &mock_socket_factory_; 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_params_.host_resolver = &mock_resolver_; 77ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch session_params_.http_server_properties = 78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch http_server_properties_.GetWeakPtr(); 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_params_.transport_security_state = &transport_security_state_; 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HttpRequestInfo* GetRequestInfo(const std::string& url) { 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HttpRequestInfo* request_info = new HttpRequestInfo; 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_info->url = GURL(url); 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_info->method = "GET"; 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_info_vector_.push_back(request_info); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return request_info; 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SSLConfig& GetServerSSLConfig(HttpNetworkTransaction* trans) { 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return trans->server_ssl_config_; 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<SSLConfigService> ssl_config_service_; 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory_; 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<ProxyService> proxy_service_; 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockClientSocketFactory mock_socket_factory_; 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MockHostResolver mock_resolver_; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HttpServerPropertiesImpl http_server_properties_; 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TransportSecurityState transport_security_state_; 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HttpNetworkSession::Params session_params_; 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScopedVector<HttpRequestInfo> request_info_vector_; 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Tests that HttpNetworkTransaction attempts to fallback from 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TLS 1.1 to TLS 1.0, then from TLS 1.0 to SSL 3.0. 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(HttpNetworkTransactionSSLTest, SSLFallback) { 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ssl_config_service_ = new TLS11SSLConfigService; 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session_params_.ssl_config_service = ssl_config_service_.get(); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |ssl_data1| is for the first handshake (TLS 1.1), which will fail 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // for protocol reasons (e.g., simulating a version rollback attack). 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SSLSocketDataProvider ssl_data1(ASYNC, ERR_SSL_PROTOCOL_ERROR); 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mock_socket_factory_.AddSSLSocketDataProvider(&ssl_data1); 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StaticSocketDataProvider data1(NULL, 0, NULL, 0); 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mock_socket_factory_.AddSocketDataProvider(&data1); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |ssl_data2| contains the handshake result for a TLS 1.0 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // handshake which will be attempted after the TLS 1.1 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // handshake fails. 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SSLSocketDataProvider ssl_data2(ASYNC, ERR_SSL_PROTOCOL_ERROR); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mock_socket_factory_.AddSSLSocketDataProvider(&ssl_data2); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StaticSocketDataProvider data2(NULL, 0, NULL, 0); 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mock_socket_factory_.AddSocketDataProvider(&data2); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |ssl_data3| contains the handshake result for a SSL 3.0 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // handshake which will be attempted after the TLS 1.0 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // handshake fails. 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SSLSocketDataProvider ssl_data3(ASYNC, ERR_SSL_PROTOCOL_ERROR); 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mock_socket_factory_.AddSSLSocketDataProvider(&ssl_data3); 131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StaticSocketDataProvider data3(NULL, 0, NULL, 0); 132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mock_socket_factory_.AddSocketDataProvider(&data3); 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<HttpNetworkSession> session( 135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) new HttpNetworkSession(session_params_)); 136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<HttpNetworkTransaction> trans( 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) TestCompletionCallback callback; 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This will consume |ssl_data1|, |ssl_data2| and |ssl_data3|. 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int rv = callback.GetResult( 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) trans->Start(GetRequestInfo("https://www.paypal.com/"), 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.callback(), BoundNetLog())); 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, rv); 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SocketDataProviderArray<SocketDataProvider>& mock_data = 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mock_socket_factory_.mock_data(); 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Confirms that |ssl_data1|, |ssl_data2| and |ssl_data3| are consumed. 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(3u, mock_data.next_index()); 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SSLConfig& ssl_config = GetServerSSLConfig(trans.get()); 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |version_max| fallbacks to SSL 3.0. 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_EQ(SSL_PROTOCOL_VERSION_SSL3, ssl_config.version_max); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(ssl_config.version_fallback); 155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace net 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 159