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(
51 message_loop_
.message_loop_proxy());
53 DBusThreadManager::Initialize();
55 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
56 DBusThreadManager::Get()
57 ->GetShillProfileClient()
59 ->AddProfile(kProfile
, "" /* userhash */);
60 base::RunLoop().RunUntilIdle();
61 service_test_
->ClearServices();
62 base::RunLoop().RunUntilIdle();
64 CertLoader::Initialize();
65 CertLoader
* cert_loader_
= CertLoader::Get();
66 cert_loader_
->StartWithNSSDB(test_nsscertdb_
.get());
69 void TearDown() override
{
70 network_cert_migrator_
.reset();
71 network_state_handler_
.reset();
72 CertLoader::Shutdown();
73 DBusThreadManager::Shutdown();
77 void SetupTestClientCert() {
78 test_client_cert_
= net::ImportClientCertAndKeyFromFile(
79 net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8",
81 ASSERT_TRUE(test_client_cert_
.get());
84 test_client_cert_pkcs11_id_
= CertLoader::GetPkcs11IdAndSlotForCert(
85 *test_client_cert_
, &slot_id
);
86 ASSERT_FALSE(test_client_cert_pkcs11_id_
.empty());
87 ASSERT_NE(-1, slot_id
);
88 test_client_cert_slot_id_
= base::IntToString(slot_id
);
91 void SetupNetworkHandlers() {
92 network_state_handler_
.reset(NetworkStateHandler::InitializeForTest());
93 network_cert_migrator_
.reset(new NetworkCertMigrator
);
94 network_cert_migrator_
->Init(network_state_handler_
.get());
97 void AddService(const std::string
& network_id
,
98 const std::string
& type
,
99 const std::string
& state
) {
100 service_test_
->AddService(network_id
/* service_path */,
101 network_id
/* guid */,
102 network_id
/* name */,
105 true /* add_to_visible */);
107 // Ensure that the service appears as 'configured', i.e. is associated to a
109 service_test_
->SetServiceProperty(
110 network_id
, shill::kProfileProperty
, base::StringValue(kProfile
));
113 void SetupNetworkWithEapCertId(bool wifi
, const std::string
& cert_id
) {
114 std::string type
= wifi
? shill::kTypeWifi
: shill::kTypeEthernetEap
;
115 std::string name
= wifi
? kWifiStub
: kEthernetEapStub
;
116 AddService(name
, type
, shill::kStateOnline
);
117 service_test_
->SetServiceProperty(
118 name
, shill::kEapCertIdProperty
, base::StringValue(cert_id
));
119 service_test_
->SetServiceProperty(
120 name
, shill::kEapKeyIdProperty
, base::StringValue(cert_id
));
123 service_test_
->SetServiceProperty(
125 shill::kSecurityClassProperty
,
126 base::StringValue(shill::kSecurity8021x
));
130 void GetEapCertId(bool wifi
, std::string
* cert_id
) {
133 std::string name
= wifi
? kWifiStub
: kEthernetEapStub
;
134 const base::DictionaryValue
* properties
=
135 service_test_
->GetServiceProperties(name
);
136 properties
->GetStringWithoutPathExpansion(shill::kEapCertIdProperty
,
140 void SetupVpnWithCertId(bool open_vpn
,
141 const std::string
& slot_id
,
142 const std::string
& pkcs11_id
) {
143 AddService(kVPNStub
, shill::kTypeVPN
, shill::kStateIdle
);
144 base::DictionaryValue provider
;
146 provider
.SetStringWithoutPathExpansion(shill::kTypeProperty
,
147 shill::kProviderOpenVpn
);
148 provider
.SetStringWithoutPathExpansion(
149 shill::kOpenVPNClientCertIdProperty
, pkcs11_id
);
151 provider
.SetStringWithoutPathExpansion(shill::kTypeProperty
,
152 shill::kProviderL2tpIpsec
);
153 provider
.SetStringWithoutPathExpansion(
154 shill::kL2tpIpsecClientCertSlotProperty
, slot_id
);
155 provider
.SetStringWithoutPathExpansion(
156 shill::kL2tpIpsecClientCertIdProperty
, pkcs11_id
);
158 service_test_
->SetServiceProperty(
159 kVPNStub
, shill::kProviderProperty
, provider
);
162 void GetVpnCertId(bool open_vpn
,
163 std::string
* slot_id
,
164 std::string
* pkcs11_id
) {
168 const base::DictionaryValue
* properties
=
169 service_test_
->GetServiceProperties(kVPNStub
);
170 ASSERT_TRUE(properties
);
171 const base::DictionaryValue
* provider
= nullptr;
172 properties
->GetDictionaryWithoutPathExpansion(shill::kProviderProperty
,
177 provider
->GetStringWithoutPathExpansion(
178 shill::kOpenVPNClientCertIdProperty
, pkcs11_id
);
180 provider
->GetStringWithoutPathExpansion(
181 shill::kL2tpIpsecClientCertSlotProperty
, slot_id
);
182 provider
->GetStringWithoutPathExpansion(
183 shill::kL2tpIpsecClientCertIdProperty
, pkcs11_id
);
187 ShillServiceClient::TestInterface
* service_test_
;
188 scoped_refptr
<net::X509Certificate
> test_client_cert_
;
189 std::string test_client_cert_pkcs11_id_
;
190 std::string test_client_cert_slot_id_
;
191 base::MessageLoop message_loop_
;
194 scoped_ptr
<NetworkStateHandler
> network_state_handler_
;
195 scoped_ptr
<NetworkCertMigrator
> network_cert_migrator_
;
196 crypto::ScopedTestNSSDB test_nssdb_
;
197 scoped_ptr
<net::NSSCertDatabaseChromeOS
> test_nsscertdb_
;
199 DISALLOW_COPY_AND_ASSIGN(NetworkCertMigratorTest
);
202 TEST_F(NetworkCertMigratorTest
, MigrateOnInitialization
) {
203 SetupTestClientCert();
204 // Add a network for migration before the handlers are initialized.
205 SetupNetworkWithEapCertId(true /* wifi */,
206 "123:" + test_client_cert_pkcs11_id_
);
207 SetupNetworkHandlers();
208 base::RunLoop().RunUntilIdle();
211 GetEapCertId(true /* wifi */, &cert_id
);
212 std::string expected_cert_id
=
213 test_client_cert_slot_id_
+ ":" + test_client_cert_pkcs11_id_
;
214 EXPECT_EQ(expected_cert_id
, cert_id
);
217 TEST_F(NetworkCertMigratorTest
, MigrateEapCertIdNoMatchingCert
) {
218 SetupTestClientCert();
219 SetupNetworkHandlers();
220 base::RunLoop().RunUntilIdle();
222 // Add a new network for migration after the handlers are initialized.
223 SetupNetworkWithEapCertId(true /* wifi */, "unknown pkcs11 id");
225 base::RunLoop().RunUntilIdle();
226 // Since the PKCS11 ID is unknown, the certificate configuration will be
229 GetEapCertId(true /* wifi */, &cert_id
);
230 EXPECT_EQ(std::string(), cert_id
);
233 TEST_F(NetworkCertMigratorTest
, MigrateEapCertIdNoSlotId
) {
234 SetupTestClientCert();
235 SetupNetworkHandlers();
236 base::RunLoop().RunUntilIdle();
238 // Add a new network for migration after the handlers are initialized.
239 SetupNetworkWithEapCertId(true /* wifi */, test_client_cert_pkcs11_id_
);
241 base::RunLoop().RunUntilIdle();
244 GetEapCertId(true /* wifi */, &cert_id
);
245 std::string expected_cert_id
=
246 test_client_cert_slot_id_
+ ":" + test_client_cert_pkcs11_id_
;
247 EXPECT_EQ(expected_cert_id
, cert_id
);
250 TEST_F(NetworkCertMigratorTest
, MigrateWifiEapCertIdWrongSlotId
) {
251 SetupTestClientCert();
252 SetupNetworkHandlers();
253 base::RunLoop().RunUntilIdle();
255 // Add a new network for migration after the handlers are initialized.
256 SetupNetworkWithEapCertId(true /* wifi */,
257 "123:" + test_client_cert_pkcs11_id_
);
259 base::RunLoop().RunUntilIdle();
262 GetEapCertId(true /* wifi */, &cert_id
);
263 std::string expected_cert_id
=
264 test_client_cert_slot_id_
+ ":" + test_client_cert_pkcs11_id_
;
265 EXPECT_EQ(expected_cert_id
, cert_id
);
268 TEST_F(NetworkCertMigratorTest
, DoNotChangeEapCertIdWithCorrectSlotId
) {
269 SetupTestClientCert();
270 SetupNetworkHandlers();
271 base::RunLoop().RunUntilIdle();
273 std::string expected_cert_id
=
274 test_client_cert_slot_id_
+ ":" + test_client_cert_pkcs11_id_
;
276 // Add a new network for migration after the handlers are initialized.
277 SetupNetworkWithEapCertId(true /* wifi */, expected_cert_id
);
279 base::RunLoop().RunUntilIdle();
282 GetEapCertId(true /* wifi */, &cert_id
);
283 EXPECT_EQ(expected_cert_id
, cert_id
);
286 TEST_F(NetworkCertMigratorTest
, IgnoreOpenVPNCertId
) {
287 SetupTestClientCert();
288 SetupNetworkHandlers();
289 base::RunLoop().RunUntilIdle();
291 const char kPkcs11Id
[] = "any slot id";
293 // Add a new network for migration after the handlers are initialized.
295 true /* OpenVPN */, std::string() /* no slot id */, kPkcs11Id
);
297 base::RunLoop().RunUntilIdle();
299 std::string pkcs11_id
;
300 std::string unused_slot_id
;
301 GetVpnCertId(true /* OpenVPN */, &unused_slot_id
, &pkcs11_id
);
302 EXPECT_EQ(kPkcs11Id
, pkcs11_id
);
305 TEST_F(NetworkCertMigratorTest
, MigrateEthernetEapCertIdWrongSlotId
) {
306 SetupTestClientCert();
307 SetupNetworkHandlers();
308 base::RunLoop().RunUntilIdle();
310 // Add a new network for migration after the handlers are initialized.
311 SetupNetworkWithEapCertId(
312 false /* ethernet */, "123:" + test_client_cert_pkcs11_id_
);
314 base::RunLoop().RunUntilIdle();
317 GetEapCertId(false /* ethernet */, &cert_id
);
318 std::string expected_cert_id
=
319 test_client_cert_slot_id_
+ ":" + test_client_cert_pkcs11_id_
;
320 EXPECT_EQ(expected_cert_id
, cert_id
);
323 TEST_F(NetworkCertMigratorTest
, MigrateIpsecCertIdWrongSlotId
) {
324 SetupTestClientCert();
325 SetupNetworkHandlers();
326 base::RunLoop().RunUntilIdle();
328 // Add a new network for migration after the handlers are initialized.
329 SetupVpnWithCertId(false /* IPsec */, "123", test_client_cert_pkcs11_id_
);
331 base::RunLoop().RunUntilIdle();
333 std::string pkcs11_id
;
335 GetVpnCertId(false /* IPsec */, &slot_id
, &pkcs11_id
);
336 EXPECT_EQ(test_client_cert_pkcs11_id_
, pkcs11_id
);
337 EXPECT_EQ(test_client_cert_slot_id_
, slot_id
);
340 } // namespace chromeos