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"
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"
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";
39 class NetworkCertMigratorTest
: public testing::Test
{
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();
54 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
55 DBusThreadManager::Get()
56 ->GetShillProfileClient()
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();
76 void SetupTestClientCert() {
77 test_client_cert_
= net::ImportClientCertAndKeyFromFile(
78 net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8",
80 ASSERT_TRUE(test_client_cert_
.get());
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 */,
104 true /* add_to_visible */);
106 // Ensure that the service appears as 'configured', i.e. is associated to a
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
));
122 service_test_
->SetServiceProperty(
124 shill::kSecurityClassProperty
,
125 base::StringValue(shill::kSecurity8021x
));
129 void GetEapCertId(bool wifi
, std::string
* cert_id
) {
132 std::string name
= wifi
? kWifiStub
: kEthernetEapStub
;
133 const base::DictionaryValue
* properties
=
134 service_test_
->GetServiceProperties(name
);
135 properties
->GetStringWithoutPathExpansion(shill::kEapCertIdProperty
,
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
;
145 provider
.SetStringWithoutPathExpansion(shill::kTypeProperty
,
146 shill::kProviderOpenVpn
);
147 provider
.SetStringWithoutPathExpansion(
148 shill::kOpenVPNClientCertIdProperty
, pkcs11_id
);
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
) {
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
,
176 provider
->GetStringWithoutPathExpansion(
177 shill::kOpenVPNClientCertIdProperty
, pkcs11_id
);
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_
;
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();
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
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();
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();
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();
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.
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();
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
;
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