1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/net/ssl_config_service_manager.h"
6
7#include "base/command_line.h"
8#include "base/memory/ref_counted.h"
9#include "base/message_loop/message_loop.h"
10#include "base/prefs/pref_registry_simple.h"
11#include "base/prefs/testing_pref_store.h"
12#include "base/values.h"
13#include "chrome/browser/content_settings/host_content_settings_map.h"
14#include "chrome/browser/prefs/pref_service_mock_factory.h"
15#include "chrome/common/chrome_switches.h"
16#include "chrome/common/pref_names.h"
17#include "chrome/test/base/testing_pref_service_syncable.h"
18#include "chrome/test/base/testing_profile.h"
19#include "components/content_settings/core/common/content_settings.h"
20#include "content/public/test/test_browser_thread.h"
21#include "net/ssl/ssl_config_service.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24using base::ListValue;
25using base::Value;
26using content::BrowserThread;
27using net::SSLConfig;
28using net::SSLConfigService;
29
30class SSLConfigServiceManagerPrefTest : public testing::Test {
31 public:
32  SSLConfigServiceManagerPrefTest()
33      : ui_thread_(BrowserThread::UI, &message_loop_),
34        io_thread_(BrowserThread::IO, &message_loop_) {}
35
36 protected:
37  base::MessageLoop message_loop_;
38  content::TestBrowserThread ui_thread_;
39  content::TestBrowserThread io_thread_;
40};
41
42// Test channel id with no user prefs.
43TEST_F(SSLConfigServiceManagerPrefTest, ChannelIDWithoutUserPrefs) {
44  TestingPrefServiceSimple local_state;
45  SSLConfigServiceManager::RegisterPrefs(local_state.registry());
46
47  scoped_ptr<SSLConfigServiceManager> config_manager(
48      SSLConfigServiceManager::CreateDefaultManager(&local_state));
49  ASSERT_TRUE(config_manager.get());
50  scoped_refptr<SSLConfigService> config_service(config_manager->Get());
51  ASSERT_TRUE(config_service.get());
52
53  SSLConfig config;
54  config_service->GetSSLConfig(&config);
55  EXPECT_TRUE(config.channel_id_enabled);
56}
57
58// Test that cipher suites can be disabled. "Good" refers to the fact that
59// every value is expected to be successfully parsed into a cipher suite.
60TEST_F(SSLConfigServiceManagerPrefTest, GoodDisabledCipherSuites) {
61  TestingPrefServiceSimple local_state;
62  SSLConfigServiceManager::RegisterPrefs(local_state.registry());
63
64  scoped_ptr<SSLConfigServiceManager> config_manager(
65      SSLConfigServiceManager::CreateDefaultManager(&local_state));
66  ASSERT_TRUE(config_manager.get());
67  scoped_refptr<SSLConfigService> config_service(config_manager->Get());
68  ASSERT_TRUE(config_service.get());
69
70  SSLConfig old_config;
71  config_service->GetSSLConfig(&old_config);
72  EXPECT_TRUE(old_config.disabled_cipher_suites.empty());
73
74  base::ListValue* list_value = new base::ListValue();
75  list_value->Append(new base::StringValue("0x0004"));
76  list_value->Append(new base::StringValue("0x0005"));
77  local_state.SetUserPref(prefs::kCipherSuiteBlacklist, list_value);
78
79  // Pump the message loop to notify the SSLConfigServiceManagerPref that the
80  // preferences changed.
81  message_loop_.RunUntilIdle();
82
83  SSLConfig config;
84  config_service->GetSSLConfig(&config);
85
86  EXPECT_NE(old_config.disabled_cipher_suites, config.disabled_cipher_suites);
87  ASSERT_EQ(2u, config.disabled_cipher_suites.size());
88  EXPECT_EQ(0x0004, config.disabled_cipher_suites[0]);
89  EXPECT_EQ(0x0005, config.disabled_cipher_suites[1]);
90}
91
92// Test that cipher suites can be disabled. "Bad" refers to the fact that
93// there are one or more non-cipher suite strings in the preference. They
94// should be ignored.
95TEST_F(SSLConfigServiceManagerPrefTest, BadDisabledCipherSuites) {
96  TestingPrefServiceSimple local_state;
97  SSLConfigServiceManager::RegisterPrefs(local_state.registry());
98
99  scoped_ptr<SSLConfigServiceManager> config_manager(
100      SSLConfigServiceManager::CreateDefaultManager(&local_state));
101  ASSERT_TRUE(config_manager.get());
102  scoped_refptr<SSLConfigService> config_service(config_manager->Get());
103  ASSERT_TRUE(config_service.get());
104
105  SSLConfig old_config;
106  config_service->GetSSLConfig(&old_config);
107  EXPECT_TRUE(old_config.disabled_cipher_suites.empty());
108
109  base::ListValue* list_value = new base::ListValue();
110  list_value->Append(new base::StringValue("0x0004"));
111  list_value->Append(new base::StringValue("TLS_NOT_WITH_A_CIPHER_SUITE"));
112  list_value->Append(new base::StringValue("0x0005"));
113  list_value->Append(new base::StringValue("0xBEEFY"));
114  local_state.SetUserPref(prefs::kCipherSuiteBlacklist, list_value);
115
116  // Pump the message loop to notify the SSLConfigServiceManagerPref that the
117  // preferences changed.
118  message_loop_.RunUntilIdle();
119
120  SSLConfig config;
121  config_service->GetSSLConfig(&config);
122
123  EXPECT_NE(old_config.disabled_cipher_suites, config.disabled_cipher_suites);
124  ASSERT_EQ(2u, config.disabled_cipher_suites.size());
125  EXPECT_EQ(0x0004, config.disabled_cipher_suites[0]);
126  EXPECT_EQ(0x0005, config.disabled_cipher_suites[1]);
127}
128
129// Test that without command-line settings for minimum and maximum SSL versions,
130// SSL 3.0 ~ kDefaultSSLVersionMax are enabled.
131TEST_F(SSLConfigServiceManagerPrefTest, NoCommandLinePrefs) {
132  scoped_refptr<TestingPrefStore> local_state_store(new TestingPrefStore());
133
134  PrefServiceMockFactory factory;
135  factory.set_user_prefs(local_state_store);
136  scoped_refptr<PrefRegistrySimple> registry = new PrefRegistrySimple;
137  scoped_ptr<PrefService> local_state(factory.Create(registry.get()));
138
139  SSLConfigServiceManager::RegisterPrefs(registry.get());
140
141  scoped_ptr<SSLConfigServiceManager> config_manager(
142      SSLConfigServiceManager::CreateDefaultManager(local_state.get()));
143  ASSERT_TRUE(config_manager.get());
144  scoped_refptr<SSLConfigService> config_service(config_manager->Get());
145  ASSERT_TRUE(config_service.get());
146
147  SSLConfig ssl_config;
148  config_service->GetSSLConfig(&ssl_config);
149  // The default value in the absence of command-line options is that
150  // SSL 3.0 ~ kDefaultSSLVersionMax are enabled.
151  EXPECT_EQ(net::SSL_PROTOCOL_VERSION_SSL3, ssl_config.version_min);
152  EXPECT_EQ(net::kDefaultSSLVersionMax, ssl_config.version_max);
153
154  // The settings should not be added to the local_state.
155  EXPECT_FALSE(local_state->HasPrefPath(prefs::kSSLVersionMin));
156  EXPECT_FALSE(local_state->HasPrefPath(prefs::kSSLVersionMax));
157
158  // Explicitly double-check the settings are not in the preference store.
159  std::string version_min_str;
160  std::string version_max_str;
161  EXPECT_FALSE(local_state_store->GetString(prefs::kSSLVersionMin,
162                                            &version_min_str));
163  EXPECT_FALSE(local_state_store->GetString(prefs::kSSLVersionMax,
164                                            &version_max_str));
165}
166
167// Test that command-line settings for minimum and maximum SSL versions are
168// respected and that they do not persist to the preferences files.
169TEST_F(SSLConfigServiceManagerPrefTest, CommandLinePrefs) {
170  scoped_refptr<TestingPrefStore> local_state_store(new TestingPrefStore());
171
172  CommandLine command_line(CommandLine::NO_PROGRAM);
173  command_line.AppendSwitchASCII(switches::kSSLVersionMin, "tls1");
174  command_line.AppendSwitchASCII(switches::kSSLVersionMax, "ssl3");
175
176  PrefServiceMockFactory factory;
177  factory.set_user_prefs(local_state_store);
178  factory.SetCommandLine(&command_line);
179  scoped_refptr<PrefRegistrySimple> registry = new PrefRegistrySimple;
180  scoped_ptr<PrefService> local_state(factory.Create(registry.get()));
181
182  SSLConfigServiceManager::RegisterPrefs(registry.get());
183
184  scoped_ptr<SSLConfigServiceManager> config_manager(
185      SSLConfigServiceManager::CreateDefaultManager(local_state.get()));
186  ASSERT_TRUE(config_manager.get());
187  scoped_refptr<SSLConfigService> config_service(config_manager->Get());
188  ASSERT_TRUE(config_service.get());
189
190  SSLConfig ssl_config;
191  config_service->GetSSLConfig(&ssl_config);
192  // Command-line flags should be respected.
193  EXPECT_EQ(net::SSL_PROTOCOL_VERSION_TLS1, ssl_config.version_min);
194  EXPECT_EQ(net::SSL_PROTOCOL_VERSION_SSL3, ssl_config.version_max);
195
196  // Explicitly double-check the settings are not in the preference store.
197  const PrefService::Preference* version_min_pref =
198      local_state->FindPreference(prefs::kSSLVersionMin);
199  EXPECT_FALSE(version_min_pref->IsUserModifiable());
200
201  const PrefService::Preference* version_max_pref =
202      local_state->FindPreference(prefs::kSSLVersionMax);
203  EXPECT_FALSE(version_max_pref->IsUserModifiable());
204
205  std::string version_min_str;
206  std::string version_max_str;
207  EXPECT_FALSE(local_state_store->GetString(prefs::kSSLVersionMin,
208                                            &version_min_str));
209  EXPECT_FALSE(local_state_store->GetString(prefs::kSSLVersionMax,
210                                            &version_max_str));
211}
212