Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chromeos / network / network_cert_migrator_unittest.cc
blobff7191c059c9662e62a39a80af3c68bea0b78d82
1 // Copyright 2013 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.
5 #include "chromeos/network/network_cert_migrator.h"
7 #include <cert.h>
8 #include <pk11pub.h>
9 #include <string>
11 #include "base/files/file_path.h"
12 #include "base/run_loop.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "chromeos/cert_loader.h"
15 #include "chromeos/dbus/dbus_thread_manager.h"
16 #include "chromeos/dbus/shill_profile_client.h"
17 #include "chromeos/dbus/shill_service_client.h"
18 #include "chromeos/network/network_state_handler.h"
19 #include "crypto/scoped_nss_types.h"
20 #include "crypto/scoped_test_nss_db.h"
21 #include "net/base/test_data_directory.h"
22 #include "net/cert/nss_cert_database_chromeos.h"
23 #include "net/cert/x509_certificate.h"
24 #include "net/test/cert_test_util.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "third_party/cros_system_api/dbus/service_constants.h"
28 namespace chromeos {
30 namespace {
32 const char* kWifiStub = "wifi_stub";
33 const char* kEthernetEapStub = "ethernet_eap_stub";
34 const char* kVPNStub = "vpn_stub";
35 const char* kProfile = "/profile/profile1";
37 } // namespace
39 class NetworkCertMigratorTest : public testing::Test {
40 public:
41 NetworkCertMigratorTest() : service_test_(nullptr) {}
42 ~NetworkCertMigratorTest() override {}
44 void SetUp() override {
45 ASSERT_TRUE(test_nssdb_.is_open());
46 // Use the same DB for public and private slot.
47 test_nsscertdb_.reset(new net::NSSCertDatabaseChromeOS(
48 crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot())),
49 crypto::ScopedPK11Slot(PK11_ReferenceSlot(test_nssdb_.slot()))));
50 test_nsscertdb_->SetSlowTaskRunnerForTest(message_loop_.task_runner());
52 DBusThreadManager::Initialize();
53 service_test_ =
54 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
55 DBusThreadManager::Get()
56 ->GetShillProfileClient()
57 ->GetTestInterface()
58 ->AddProfile(kProfile, "" /* userhash */);
59 base::RunLoop().RunUntilIdle();
60 service_test_->ClearServices();
61 base::RunLoop().RunUntilIdle();
63 CertLoader::Initialize();
64 CertLoader* cert_loader_ = CertLoader::Get();
65 cert_loader_->StartWithNSSDB(test_nsscertdb_.get());
68 void TearDown() override {
69 network_cert_migrator_.reset();
70 network_state_handler_.reset();
71 CertLoader::Shutdown();
72 DBusThreadManager::Shutdown();
75 protected:
76 void SetupTestClientCert() {
77 test_client_cert_ = net::ImportClientCertAndKeyFromFile(
78 net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8",
79 test_nssdb_.slot());
80 ASSERT_TRUE(test_client_cert_.get());
82 int slot_id = -1;
83 test_client_cert_pkcs11_id_ = CertLoader::GetPkcs11IdAndSlotForCert(
84 *test_client_cert_, &slot_id);
85 ASSERT_FALSE(test_client_cert_pkcs11_id_.empty());
86 ASSERT_NE(-1, slot_id);
87 test_client_cert_slot_id_ = base::IntToString(slot_id);
90 void SetupNetworkHandlers() {
91 network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
92 network_cert_migrator_.reset(new NetworkCertMigrator);
93 network_cert_migrator_->Init(network_state_handler_.get());
96 void AddService(const std::string& network_id,
97 const std::string& type,
98 const std::string& state) {
99 service_test_->AddService(network_id /* service_path */,
100 network_id /* guid */,
101 network_id /* name */,
102 type,
103 state,
104 true /* add_to_visible */);
106 // Ensure that the service appears as 'configured', i.e. is associated to a
107 // Shill profile.
108 service_test_->SetServiceProperty(
109 network_id, shill::kProfileProperty, base::StringValue(kProfile));
112 void SetupNetworkWithEapCertId(bool wifi, const std::string& cert_id) {
113 std::string type = wifi ? shill::kTypeWifi: shill::kTypeEthernetEap;
114 std::string name = wifi ? kWifiStub : kEthernetEapStub;
115 AddService(name, type, shill::kStateOnline);
116 service_test_->SetServiceProperty(
117 name, shill::kEapCertIdProperty, base::StringValue(cert_id));
118 service_test_->SetServiceProperty(
119 name, shill::kEapKeyIdProperty, base::StringValue(cert_id));
121 if (wifi) {
122 service_test_->SetServiceProperty(
123 name,
124 shill::kSecurityClassProperty,
125 base::StringValue(shill::kSecurity8021x));
129 void GetEapCertId(bool wifi, std::string* cert_id) {
130 cert_id->clear();
132 std::string name = wifi ? kWifiStub : kEthernetEapStub;
133 const base::DictionaryValue* properties =
134 service_test_->GetServiceProperties(name);
135 properties->GetStringWithoutPathExpansion(shill::kEapCertIdProperty,
136 cert_id);
139 void SetupVpnWithCertId(bool open_vpn,
140 const std::string& slot_id,
141 const std::string& pkcs11_id) {
142 AddService(kVPNStub, shill::kTypeVPN, shill::kStateIdle);
143 base::DictionaryValue provider;
144 if (open_vpn) {
145 provider.SetStringWithoutPathExpansion(shill::kTypeProperty,
146 shill::kProviderOpenVpn);
147 provider.SetStringWithoutPathExpansion(
148 shill::kOpenVPNClientCertIdProperty, pkcs11_id);
149 } else {
150 provider.SetStringWithoutPathExpansion(shill::kTypeProperty,
151 shill::kProviderL2tpIpsec);
152 provider.SetStringWithoutPathExpansion(
153 shill::kL2tpIpsecClientCertSlotProperty, slot_id);
154 provider.SetStringWithoutPathExpansion(
155 shill::kL2tpIpsecClientCertIdProperty, pkcs11_id);
157 service_test_->SetServiceProperty(
158 kVPNStub, shill::kProviderProperty, provider);
161 void GetVpnCertId(bool open_vpn,
162 std::string* slot_id,
163 std::string* pkcs11_id) {
164 slot_id->clear();
165 pkcs11_id->clear();
167 const base::DictionaryValue* properties =
168 service_test_->GetServiceProperties(kVPNStub);
169 ASSERT_TRUE(properties);
170 const base::DictionaryValue* provider = nullptr;
171 properties->GetDictionaryWithoutPathExpansion(shill::kProviderProperty,
172 &provider);
173 if (!provider)
174 return;
175 if (open_vpn) {
176 provider->GetStringWithoutPathExpansion(
177 shill::kOpenVPNClientCertIdProperty, pkcs11_id);
178 } else {
179 provider->GetStringWithoutPathExpansion(
180 shill::kL2tpIpsecClientCertSlotProperty, slot_id);
181 provider->GetStringWithoutPathExpansion(
182 shill::kL2tpIpsecClientCertIdProperty, pkcs11_id);
186 ShillServiceClient::TestInterface* service_test_;
187 scoped_refptr<net::X509Certificate> test_client_cert_;
188 std::string test_client_cert_pkcs11_id_;
189 std::string test_client_cert_slot_id_;
190 base::MessageLoop message_loop_;
192 private:
193 scoped_ptr<NetworkStateHandler> network_state_handler_;
194 scoped_ptr<NetworkCertMigrator> network_cert_migrator_;
195 crypto::ScopedTestNSSDB test_nssdb_;
196 scoped_ptr<net::NSSCertDatabaseChromeOS> test_nsscertdb_;
198 DISALLOW_COPY_AND_ASSIGN(NetworkCertMigratorTest);
201 TEST_F(NetworkCertMigratorTest, MigrateOnInitialization) {
202 SetupTestClientCert();
203 // Add a network for migration before the handlers are initialized.
204 SetupNetworkWithEapCertId(true /* wifi */,
205 "123:" + test_client_cert_pkcs11_id_);
206 SetupNetworkHandlers();
207 base::RunLoop().RunUntilIdle();
209 std::string cert_id;
210 GetEapCertId(true /* wifi */, &cert_id);
211 std::string expected_cert_id =
212 test_client_cert_slot_id_ + ":" + test_client_cert_pkcs11_id_;
213 EXPECT_EQ(expected_cert_id, cert_id);
216 TEST_F(NetworkCertMigratorTest, MigrateEapCertIdNoMatchingCert) {
217 SetupTestClientCert();
218 SetupNetworkHandlers();
219 base::RunLoop().RunUntilIdle();
221 // Add a new network for migration after the handlers are initialized.
222 SetupNetworkWithEapCertId(true /* wifi */, "unknown pkcs11 id");
224 base::RunLoop().RunUntilIdle();
225 // Since the PKCS11 ID is unknown, the certificate configuration will be
226 // cleared.
227 std::string cert_id;
228 GetEapCertId(true /* wifi */, &cert_id);
229 EXPECT_EQ(std::string(), cert_id);
232 TEST_F(NetworkCertMigratorTest, MigrateEapCertIdNoSlotId) {
233 SetupTestClientCert();
234 SetupNetworkHandlers();
235 base::RunLoop().RunUntilIdle();
237 // Add a new network for migration after the handlers are initialized.
238 SetupNetworkWithEapCertId(true /* wifi */, test_client_cert_pkcs11_id_);
240 base::RunLoop().RunUntilIdle();
242 std::string cert_id;
243 GetEapCertId(true /* wifi */, &cert_id);
244 std::string expected_cert_id =
245 test_client_cert_slot_id_ + ":" + test_client_cert_pkcs11_id_;
246 EXPECT_EQ(expected_cert_id, cert_id);
249 TEST_F(NetworkCertMigratorTest, MigrateWifiEapCertIdWrongSlotId) {
250 SetupTestClientCert();
251 SetupNetworkHandlers();
252 base::RunLoop().RunUntilIdle();
254 // Add a new network for migration after the handlers are initialized.
255 SetupNetworkWithEapCertId(true /* wifi */,
256 "123:" + test_client_cert_pkcs11_id_);
258 base::RunLoop().RunUntilIdle();
260 std::string cert_id;
261 GetEapCertId(true /* wifi */, &cert_id);
262 std::string expected_cert_id =
263 test_client_cert_slot_id_ + ":" + test_client_cert_pkcs11_id_;
264 EXPECT_EQ(expected_cert_id, cert_id);
267 TEST_F(NetworkCertMigratorTest, DoNotChangeEapCertIdWithCorrectSlotId) {
268 SetupTestClientCert();
269 SetupNetworkHandlers();
270 base::RunLoop().RunUntilIdle();
272 std::string expected_cert_id =
273 test_client_cert_slot_id_ + ":" + test_client_cert_pkcs11_id_;
275 // Add a new network for migration after the handlers are initialized.
276 SetupNetworkWithEapCertId(true /* wifi */, expected_cert_id);
278 base::RunLoop().RunUntilIdle();
280 std::string cert_id;
281 GetEapCertId(true /* wifi */, &cert_id);
282 EXPECT_EQ(expected_cert_id, cert_id);
285 TEST_F(NetworkCertMigratorTest, IgnoreOpenVPNCertId) {
286 SetupTestClientCert();
287 SetupNetworkHandlers();
288 base::RunLoop().RunUntilIdle();
290 const char kPkcs11Id[] = "any slot id";
292 // Add a new network for migration after the handlers are initialized.
293 SetupVpnWithCertId(
294 true /* OpenVPN */, std::string() /* no slot id */, kPkcs11Id);
296 base::RunLoop().RunUntilIdle();
298 std::string pkcs11_id;
299 std::string unused_slot_id;
300 GetVpnCertId(true /* OpenVPN */, &unused_slot_id, &pkcs11_id);
301 EXPECT_EQ(kPkcs11Id, pkcs11_id);
304 TEST_F(NetworkCertMigratorTest, MigrateEthernetEapCertIdWrongSlotId) {
305 SetupTestClientCert();
306 SetupNetworkHandlers();
307 base::RunLoop().RunUntilIdle();
309 // Add a new network for migration after the handlers are initialized.
310 SetupNetworkWithEapCertId(
311 false /* ethernet */, "123:" + test_client_cert_pkcs11_id_);
313 base::RunLoop().RunUntilIdle();
315 std::string cert_id;
316 GetEapCertId(false /* ethernet */, &cert_id);
317 std::string expected_cert_id =
318 test_client_cert_slot_id_ + ":" + test_client_cert_pkcs11_id_;
319 EXPECT_EQ(expected_cert_id, cert_id);
322 TEST_F(NetworkCertMigratorTest, MigrateIpsecCertIdWrongSlotId) {
323 SetupTestClientCert();
324 SetupNetworkHandlers();
325 base::RunLoop().RunUntilIdle();
327 // Add a new network for migration after the handlers are initialized.
328 SetupVpnWithCertId(false /* IPsec */, "123", test_client_cert_pkcs11_id_);
330 base::RunLoop().RunUntilIdle();
332 std::string pkcs11_id;
333 std::string slot_id;
334 GetVpnCertId(false /* IPsec */, &slot_id, &pkcs11_id);
335 EXPECT_EQ(test_client_cert_pkcs11_id_, pkcs11_id);
336 EXPECT_EQ(test_client_cert_slot_id_, slot_id);
339 } // namespace chromeos