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