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

Side by Side Diff: chromeos/network/network_connection_handler_unittest.cc

Issue 135193007: Use user specific NSSDatabase in CertLoader. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 11 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chromeos/network/network_connection_handler.h" 5 #include "chromeos/network/network_connection_handler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/file_util.h"
8 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "base/strings/stringprintf.h"
10 #include "chromeos/dbus/dbus_thread_manager.h" 14 #include "chromeos/dbus/dbus_thread_manager.h"
11 #include "chromeos/dbus/shill_manager_client.h" 15 #include "chromeos/dbus/shill_manager_client.h"
12 #include "chromeos/dbus/shill_service_client.h" 16 #include "chromeos/dbus/shill_service_client.h"
13 #include "chromeos/network/network_configuration_handler.h" 17 #include "chromeos/network/network_configuration_handler.h"
14 #include "chromeos/network/network_state_handler.h" 18 #include "chromeos/network/network_state_handler.h"
15 #include "chromeos/network/onc/onc_utils.h" 19 #include "chromeos/network/onc/onc_utils.h"
20 #include "crypto/nss_util.h"
21 #include "crypto/nss_util_internal.h"
22 #include "net/base/net_errors.h"
23 #include "net/base/test_data_directory.h"
24 #include "net/cert/nss_cert_database_chromeos.h"
25 #include "net/cert/x509_certificate.h"
26 #include "net/test/cert_test_util.h"
16 #include "testing/gtest/include/gtest/gtest.h" 27 #include "testing/gtest/include/gtest/gtest.h"
17 #include "third_party/cros_system_api/dbus/service_constants.h" 28 #include "third_party/cros_system_api/dbus/service_constants.h"
18 29
19 namespace { 30 namespace {
20 31
21 const char* kSuccessResult = "success"; 32 const char* kSuccessResult = "success";
22 33
23 void ConfigureCallback(const dbus::ObjectPath& result) { 34 void ConfigureCallback(const dbus::ObjectPath& result) {
24 } 35 }
25 36
26 void ConfigureErrorCallback(const std::string& error_name, 37 void ConfigureErrorCallback(const std::string& error_name,
27 const std::string& error_message) { 38 const std::string& error_message) {
28 } 39 }
29 40
30 } // namespace 41 } // namespace
31 42
32 namespace chromeos { 43 namespace chromeos {
33 44
34 class NetworkConnectionHandlerTest : public testing::Test { 45 class NetworkConnectionHandlerTest : public testing::Test {
35 public: 46 public:
36 NetworkConnectionHandlerTest() { 47 NetworkConnectionHandlerTest() : user_("userhash") {
37 } 48 }
38 virtual ~NetworkConnectionHandlerTest() { 49 virtual ~NetworkConnectionHandlerTest() {
39 } 50 }
40 51
41 virtual void SetUp() OVERRIDE { 52 virtual void SetUp() OVERRIDE {
53 ASSERT_TRUE(user_.constructed_successfully());
54 user_.FinishInit();
55
56 test_nssdb_.reset(new net::NSSCertDatabaseChromeOS(
57 crypto::GetPublicSlotForChromeOSUser(user_.username_hash()),
58 crypto::GetPrivateSlotForChromeOSUser(
59 user_.username_hash(),
60 base::Callback<void(crypto::ScopedPK11Slot)>())));
61
62 CertLoader::Initialize();
63 CertLoader* cert_loader = CertLoader::Get();
64 cert_loader->SetSlowTaskRunnerForTest(message_loop_.message_loop_proxy());
65 cert_loader->SetCryptoTaskRunner(message_loop_.message_loop_proxy());
66 cert_loader->set_hardware_backed_for_test();
67
42 // Initialize DBusThreadManager with a stub implementation. 68 // Initialize DBusThreadManager with a stub implementation.
43 DBusThreadManager::InitializeWithStub(); 69 DBusThreadManager::InitializeWithStub();
44 message_loop_.RunUntilIdle(); 70 base::RunLoop().RunUntilIdle();
45 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface() 71 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
46 ->ClearServices(); 72 ->ClearServices();
47 message_loop_.RunUntilIdle(); 73 base::RunLoop().RunUntilIdle();
48 LoginState::Initialize(); 74 LoginState::Initialize();
49 network_state_handler_.reset(NetworkStateHandler::InitializeForTest()); 75 network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
50 network_configuration_handler_.reset( 76 network_configuration_handler_.reset(
51 NetworkConfigurationHandler::InitializeForTest( 77 NetworkConfigurationHandler::InitializeForTest(
52 network_state_handler_.get())); 78 network_state_handler_.get()));
79
53 network_connection_handler_.reset(new NetworkConnectionHandler); 80 network_connection_handler_.reset(new NetworkConnectionHandler);
54 // TODO(stevenjb): Test integration with CertLoader using a stub or mock.
55 network_connection_handler_->Init(network_state_handler_.get(), 81 network_connection_handler_->Init(network_state_handler_.get(),
56 network_configuration_handler_.get()); 82 network_configuration_handler_.get());
57 } 83 }
58 84
59 virtual void TearDown() OVERRIDE { 85 virtual void TearDown() OVERRIDE {
60 network_connection_handler_.reset(); 86 network_connection_handler_.reset();
61 network_configuration_handler_.reset(); 87 network_configuration_handler_.reset();
62 network_state_handler_.reset(); 88 network_state_handler_.reset();
89 CertLoader::Shutdown();
63 LoginState::Shutdown(); 90 LoginState::Shutdown();
64 DBusThreadManager::Shutdown(); 91 DBusThreadManager::Shutdown();
65 } 92 }
66 93
67 protected: 94 protected:
68 bool Configure(const std::string& json_string) { 95 bool Configure(const std::string& json_string) {
69 scoped_ptr<base::DictionaryValue> json_dict = 96 scoped_ptr<base::DictionaryValue> json_dict =
70 onc::ReadDictionaryFromJson(json_string); 97 onc::ReadDictionaryFromJson(json_string);
71 if (!json_dict) { 98 if (!json_dict) {
72 LOG(ERROR) << "Error parsing json: " << json_string; 99 LOG(ERROR) << "Error parsing json: " << json_string;
73 return false; 100 return false;
74 } 101 }
75 DBusThreadManager::Get()->GetShillManagerClient()->ConfigureService( 102 DBusThreadManager::Get()->GetShillManagerClient()->ConfigureService(
76 *json_dict, 103 *json_dict,
77 base::Bind(&ConfigureCallback), 104 base::Bind(&ConfigureCallback),
78 base::Bind(&ConfigureErrorCallback)); 105 base::Bind(&ConfigureErrorCallback));
79 message_loop_.RunUntilIdle(); 106 base::RunLoop().RunUntilIdle();
80 return true; 107 return true;
81 } 108 }
82 109
83 void Connect(const std::string& service_path) { 110 void Connect(const std::string& service_path) {
84 const bool check_error_state = true; 111 const bool check_error_state = true;
85 network_connection_handler_->ConnectToNetwork( 112 network_connection_handler_->ConnectToNetwork(
86 service_path, 113 service_path,
87 base::Bind(&NetworkConnectionHandlerTest::SuccessCallback, 114 base::Bind(&NetworkConnectionHandlerTest::SuccessCallback,
88 base::Unretained(this)), 115 base::Unretained(this)),
89 base::Bind(&NetworkConnectionHandlerTest::ErrorCallback, 116 base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
90 base::Unretained(this)), 117 base::Unretained(this)),
91 check_error_state); 118 check_error_state);
92 message_loop_.RunUntilIdle(); 119 base::RunLoop().RunUntilIdle();
93 } 120 }
94 121
95 void Disconnect(const std::string& service_path) { 122 void Disconnect(const std::string& service_path) {
96 network_connection_handler_->DisconnectNetwork( 123 network_connection_handler_->DisconnectNetwork(
97 service_path, 124 service_path,
98 base::Bind(&NetworkConnectionHandlerTest::SuccessCallback, 125 base::Bind(&NetworkConnectionHandlerTest::SuccessCallback,
99 base::Unretained(this)), 126 base::Unretained(this)),
100 base::Bind(&NetworkConnectionHandlerTest::ErrorCallback, 127 base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
101 base::Unretained(this))); 128 base::Unretained(this)));
102 message_loop_.RunUntilIdle(); 129 base::RunLoop().RunUntilIdle();
103 } 130 }
104 131
105 void SuccessCallback() { 132 void SuccessCallback() {
106 result_ = kSuccessResult; 133 result_ = kSuccessResult;
107 } 134 }
108 135
109 void ErrorCallback(const std::string& error_name, 136 void ErrorCallback(const std::string& error_name,
110 scoped_ptr<base::DictionaryValue> error_data) { 137 scoped_ptr<base::DictionaryValue> error_data) {
111 result_ = error_name; 138 result_ = error_name;
112 } 139 }
113 140
114 std::string GetResultAndReset() { 141 std::string GetResultAndReset() {
115 std::string result; 142 std::string result;
116 result.swap(result_); 143 result.swap(result_);
117 return result; 144 return result;
118 } 145 }
119 146
120 std::string GetServiceStringProperty(const std::string& service_path, 147 std::string GetServiceStringProperty(const std::string& service_path,
121 const std::string& key) { 148 const std::string& key) {
122 std::string result; 149 std::string result;
123 const base::DictionaryValue* properties = 150 const base::DictionaryValue* properties =
124 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()-> 151 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()->
125 GetServiceProperties(service_path); 152 GetServiceProperties(service_path);
126 if (properties) 153 if (properties)
127 properties->GetStringWithoutPathExpansion(key, &result); 154 properties->GetStringWithoutPathExpansion(key, &result);
128 return result; 155 return result;
129 } 156 }
130 157
158 void StartCertLoader() {
159 CertLoader::Get()->StartWithUser(user_.username_hash());
160 base::RunLoop().RunUntilIdle();
161 }
162
163 bool ImportClientCertAndKey(const std::string& pkcs12_file,
164 net::NSSCertDatabase* nssdb,
165 net::CertificateList* loaded_certs) {
166 std::string pkcs12_data;
167 base::FilePath pkcs12_path =
168 net::GetTestCertsDirectory().Append(pkcs12_file);
169 if (!base::ReadFileToString(pkcs12_path, &pkcs12_data))
170 return false;
171
172 scoped_refptr<net::CryptoModule> module(
173 net::CryptoModule::CreateFromHandle(nssdb->GetPrivateSlot().get()));
174 return net::OK ==
175 nssdb->ImportFromPKCS12(module, pkcs12_data, base::string16(), false,
176 loaded_certs);
177 }
178
131 scoped_ptr<NetworkStateHandler> network_state_handler_; 179 scoped_ptr<NetworkStateHandler> network_state_handler_;
132 scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_; 180 scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_;
133 scoped_ptr<NetworkConnectionHandler> network_connection_handler_; 181 scoped_ptr<NetworkConnectionHandler> network_connection_handler_;
182 crypto::ScopedTestNSSChromeOSUser user_;
183 scoped_ptr<net::NSSCertDatabaseChromeOS> test_nssdb_;
134 base::MessageLoopForUI message_loop_; 184 base::MessageLoopForUI message_loop_;
135 std::string result_; 185 std::string result_;
136 186
137 private: 187 private:
138 DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandlerTest); 188 DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandlerTest);
139 }; 189 };
140 190
141 namespace { 191 namespace {
142 192
143 const char* kConfigConnectable = 193 const char* kConfigConnectable =
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 GetResultAndReset()); 234 GetResultAndReset());
185 235
186 EXPECT_TRUE(Configure(kConfigRequiresActivation)); 236 EXPECT_TRUE(Configure(kConfigRequiresActivation));
187 Connect("cellular1"); 237 Connect("cellular1");
188 EXPECT_EQ(NetworkConnectionHandler::kErrorActivationRequired, 238 EXPECT_EQ(NetworkConnectionHandler::kErrorActivationRequired,
189 GetResultAndReset()); 239 GetResultAndReset());
190 } 240 }
191 241
192 namespace { 242 namespace {
193 243
194 const char* kConfigRequiresCertificate = 244 const char* kConfigRequiresCertificateTemplate =
195 "{ \"GUID\": \"wifi4\", \"Type\": \"wifi\", \"Connectable\": false," 245 "{ \"GUID\": \"wifi4\", \"Type\": \"wifi\", \"Connectable\": false,"
196 " \"Security\": \"802_1x\"," 246 " \"Security\": \"802_1x\","
197 " \"UIData\": \"{" 247 " \"UIData\": \"{"
198 " \\\"certificate_type\\\": \\\"pattern\\\"," 248 " \\\"certificate_type\\\": \\\"pattern\\\","
199 " \\\"certificate_pattern\\\": {" 249 " \\\"certificate_pattern\\\": {"
200 " \\\"Subject\\\": { \\\"CommonName\\\": \\\"Foo\\\" }" 250 " \\\"Subject\\\": {\\\"CommonName\\\": \\\"%s\\\" }"
201 " } }\" }"; 251 " } }\" }";
202 252
203 } // namespace 253 } // namespace
204 254
205 // Handle certificates. TODO(stevenjb): Add certificate stubs to improve 255 // Handle certificates.
206 // test coverage. 256 TEST_F(NetworkConnectionHandlerTest, ConnectCertificateMissing) {
207 TEST_F(NetworkConnectionHandlerTest, 257 StartCertLoader();
208 NetworkConnectionHandlerConnectCertificate) { 258
209 EXPECT_TRUE(Configure(kConfigRequiresCertificate)); 259 EXPECT_TRUE(Configure(
260 base::StringPrintf(kConfigRequiresCertificateTemplate, "unknown")));
261 Connect("wifi4");
262 EXPECT_EQ(NetworkConnectionHandler::kErrorCertificateRequired,
263 GetResultAndReset());
264 }
265
266 TEST_F(NetworkConnectionHandlerTest, ConnectWithCertificateSuccess) {
267 StartCertLoader();
268
269 net::CertificateList certs;
270 ASSERT_TRUE(ImportClientCertAndKey(
271 "websocket_client_cert.p12", test_nssdb_.get(), &certs));
272 ASSERT_EQ(1U, certs.size());
273
274 EXPECT_TRUE(Configure(
275 base::StringPrintf(kConfigRequiresCertificateTemplate,
276 certs[0]->subject().common_name.c_str())));
277
278 Connect("wifi4");
279 EXPECT_EQ(kSuccessResult, GetResultAndReset());
280 }
281
282 TEST_F(NetworkConnectionHandlerTest, ConnectCertificateFromSecondaryUserFails) {
283 StartCertLoader();
284
285 // Create secondary user and get it's nssdb.
286 crypto::ScopedTestNSSChromeOSUser secondary_user("secondary");
287 ASSERT_TRUE(secondary_user.constructed_successfully());
288 secondary_user.FinishInit();
289
290 scoped_ptr<net::NSSCertDatabaseChromeOS>secondary_nssdb(
291 new net::NSSCertDatabaseChromeOS(
292 crypto::GetPublicSlotForChromeOSUser(secondary_user.username_hash()),
293 crypto::GetPrivateSlotForChromeOSUser(
294 secondary_user.username_hash(),
295 base::Callback<void(crypto::ScopedPK11Slot)>())));
296
297 // Import client cert to the secondary user's nssdb. The certificate should
298 // not be visible to the cert loader, so the connection request should fail.
299 net::CertificateList certs;
300 ASSERT_TRUE(ImportClientCertAndKey(
301 "websocket_client_cert.p12", secondary_nssdb.get(), &certs));
302 ASSERT_EQ(1U, certs.size());
303
304 EXPECT_TRUE(Configure(
305 base::StringPrintf(kConfigRequiresCertificateTemplate,
306 certs[0]->subject().common_name.c_str())));
307
210 Connect("wifi4"); 308 Connect("wifi4");
211 EXPECT_EQ(NetworkConnectionHandler::kErrorCertificateRequired, 309 EXPECT_EQ(NetworkConnectionHandler::kErrorCertificateRequired,
212 GetResultAndReset()); 310 GetResultAndReset());
213 } 311 }
214 312
215 TEST_F(NetworkConnectionHandlerTest, 313 TEST_F(NetworkConnectionHandlerTest,
314 ConnectWithCertificateRequestedBeforeCertsAreLoaded) {
315 net::CertificateList certs;
316 ASSERT_TRUE(ImportClientCertAndKey(
317 "websocket_client_cert.p12", test_nssdb_.get(), &certs));
318 ASSERT_EQ(1U, certs.size());
319
320 EXPECT_TRUE(Configure(
321 base::StringPrintf(kConfigRequiresCertificateTemplate,
322 certs[0]->subject().common_name.c_str())));
323
324 Connect("wifi4");
325
326 // Connect request came before the cert loader loaded certificates, so the
327 // connect request should have been throttled until the certificates are
328 // loaded.
329 EXPECT_EQ("", GetResultAndReset());
330
331 StartCertLoader();
332
333 // |StartCertLoader| should have triggered certificate loading.
334 // When the certificates got loaded, the connection request should have
335 // proceeded and eventually succeeded.
336 EXPECT_EQ(kSuccessResult, GetResultAndReset());
337 }
338
339 TEST_F(NetworkConnectionHandlerTest,
216 NetworkConnectionHandlerDisconnectSuccess) { 340 NetworkConnectionHandlerDisconnectSuccess) {
217 EXPECT_TRUE(Configure(kConfigConnected)); 341 EXPECT_TRUE(Configure(kConfigConnected));
218 Disconnect("wifi1"); 342 Disconnect("wifi1");
219 EXPECT_EQ(kSuccessResult, GetResultAndReset()); 343 EXPECT_EQ(kSuccessResult, GetResultAndReset());
220 } 344 }
221 345
222 TEST_F(NetworkConnectionHandlerTest, 346 TEST_F(NetworkConnectionHandlerTest,
223 NetworkConnectionHandlerDisconnectFailure) { 347 NetworkConnectionHandlerDisconnectFailure) {
224 Connect("no-network"); 348 Connect("no-network");
225 EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed, 349 EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed,
226 GetResultAndReset()); 350 GetResultAndReset());
227 351
228 EXPECT_TRUE(Configure(kConfigConnectable)); 352 EXPECT_TRUE(Configure(kConfigConnectable));
229 Disconnect("wifi0"); 353 Disconnect("wifi0");
230 EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset()); 354 EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset());
231 } 355 }
232 356
233 } // namespace chromeos 357 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698