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"
9 #include "base/file_util.h"
10 #include "base/files/file_path.h"
11 #include "base/run_loop.h"
12 #include "chromeos/cert_loader.h"
13 #include "chromeos/dbus/dbus_thread_manager.h"
14 #include "chromeos/dbus/shill_service_client.h"
15 #include "chromeos/network/network_state_handler.h"
16 #include "chromeos/tpm_token_loader.h"
17 #include "crypto/nss_util.h"
18 #include "crypto/nss_util_internal.h"
19 #include "net/base/crypto_module.h"
20 #include "net/base/net_errors.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* kVPNStub
= "vpn_stub";
34 const char* kNSSNickname
= "nss_nickname";
35 const char* kFakePEM
= "pem";
39 class NetworkCertMigratorTest
: public testing::Test
{
41 NetworkCertMigratorTest() : service_test_(NULL
),
44 virtual ~NetworkCertMigratorTest() {}
46 virtual void SetUp() OVERRIDE
{
47 // Initialize NSS db for the user.
48 ASSERT_TRUE(user_
.constructed_successfully());
50 test_nssdb_
.reset(new net::NSSCertDatabaseChromeOS(
51 crypto::GetPublicSlotForChromeOSUser(user_
.username_hash()),
52 crypto::GetPrivateSlotForChromeOSUser(
53 user_
.username_hash(),
54 base::Callback
<void(crypto::ScopedPK11Slot
)>())));
55 test_nssdb_
->SetSlowTaskRunnerForTest(message_loop_
.message_loop_proxy());
57 DBusThreadManager::InitializeWithStub();
59 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
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_nssdb_
.get());
69 virtual void TearDown() OVERRIDE
{
70 network_cert_migrator_
.reset();
71 network_state_handler_
.reset();
72 CertLoader::Shutdown();
73 DBusThreadManager::Shutdown();
78 void SetupTestCACert() {
79 scoped_refptr
<net::X509Certificate
> cert_wo_nickname
=
80 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(),
82 net::X509Certificate::FORMAT_AUTO
)
84 net::X509Certificate::GetPEMEncoded(cert_wo_nickname
->os_cert_handle(),
86 std::string der_encoded
;
87 net::X509Certificate::GetDEREncoded(cert_wo_nickname
->os_cert_handle(),
89 cert_wo_nickname
= NULL
;
91 test_ca_cert_
= net::X509Certificate::CreateFromBytesWithNickname(
92 der_encoded
.data(), der_encoded
.size(), kNSSNickname
);
93 net::CertificateList cert_list
;
94 cert_list
.push_back(test_ca_cert_
);
95 net::NSSCertDatabase::ImportCertFailureList failures
;
96 EXPECT_TRUE(test_nssdb_
->ImportCACerts(
97 cert_list
, net::NSSCertDatabase::TRUST_DEFAULT
, &failures
));
98 ASSERT_TRUE(failures
.empty()) << net::ErrorToString(failures
[0].net_error
);
101 void SetupNetworkHandlers() {
102 network_state_handler_
.reset(NetworkStateHandler::InitializeForTest());
103 network_cert_migrator_
.reset(new NetworkCertMigrator
);
104 network_cert_migrator_
->Init(network_state_handler_
.get());
107 void SetupWifiWithNss() {
108 const bool add_to_visible
= true;
109 const bool add_to_watchlist
= true;
110 service_test_
->AddService(kWifiStub
,
116 service_test_
->SetServiceProperty(kWifiStub
,
117 shill::kEapCaCertNssProperty
,
118 base::StringValue(kNSSNickname
));
121 void GetEapCACertProperties(std::string
* nss_nickname
, std::string
* ca_pem
) {
122 nss_nickname
->clear();
124 const base::DictionaryValue
* properties
=
125 service_test_
->GetServiceProperties(kWifiStub
);
126 properties
->GetStringWithoutPathExpansion(shill::kEapCaCertNssProperty
,
128 const base::ListValue
* ca_pems
= NULL
;
129 properties
->GetListWithoutPathExpansion(shill::kEapCaCertPemProperty
,
131 if (ca_pems
&& !ca_pems
->empty())
132 ca_pems
->GetString(0, ca_pem
);
135 void SetupVpnWithNss(bool open_vpn
) {
136 const bool add_to_visible
= true;
137 const bool add_to_watchlist
= true;
138 service_test_
->AddService(kVPNStub
,
144 base::DictionaryValue provider
;
145 const char* nss_property
= open_vpn
? shill::kOpenVPNCaCertNSSProperty
146 : shill::kL2tpIpsecCaCertNssProperty
;
147 provider
.SetStringWithoutPathExpansion(nss_property
, kNSSNickname
);
148 service_test_
->SetServiceProperty(
149 kVPNStub
, shill::kProviderProperty
, provider
);
152 void GetVpnCACertProperties(bool open_vpn
,
153 std::string
* nss_nickname
,
154 std::string
* ca_pem
) {
155 nss_nickname
->clear();
157 const base::DictionaryValue
* properties
=
158 service_test_
->GetServiceProperties(kVPNStub
);
159 const base::DictionaryValue
* provider
= NULL
;
160 properties
->GetDictionaryWithoutPathExpansion(shill::kProviderProperty
,
164 const char* nss_property
= open_vpn
? shill::kOpenVPNCaCertNSSProperty
165 : shill::kL2tpIpsecCaCertNssProperty
;
166 provider
->GetStringWithoutPathExpansion(nss_property
, nss_nickname
);
167 const base::ListValue
* ca_pems
= NULL
;
168 const char* pem_property
= open_vpn
? shill::kOpenVPNCaCertPemProperty
169 : shill::kL2tpIpsecCaCertPemProperty
;
170 provider
->GetListWithoutPathExpansion(pem_property
, &ca_pems
);
171 if (ca_pems
&& !ca_pems
->empty())
172 ca_pems
->GetString(0, ca_pem
);
175 ShillServiceClient::TestInterface
* service_test_
;
176 scoped_refptr
<net::X509Certificate
> test_ca_cert_
;
177 std::string test_ca_cert_pem_
;
178 base::MessageLoop message_loop_
;
181 void CleanupTestCert() {
182 ASSERT_TRUE(test_nssdb_
->DeleteCertAndKey(test_ca_cert_
.get()));
185 scoped_ptr
<NetworkStateHandler
> network_state_handler_
;
186 scoped_ptr
<NetworkCertMigrator
> network_cert_migrator_
;
187 crypto::ScopedTestNSSChromeOSUser user_
;
188 scoped_ptr
<net::NSSCertDatabaseChromeOS
> test_nssdb_
;
190 DISALLOW_COPY_AND_ASSIGN(NetworkCertMigratorTest
);
193 TEST_F(NetworkCertMigratorTest
, MigrateNssOnInitialization
) {
194 // Add a new network for migration before the handlers are initialized.
197 SetupNetworkHandlers();
199 base::RunLoop().RunUntilIdle();
200 std::string nss_nickname
, ca_pem
;
201 GetEapCACertProperties(&nss_nickname
, &ca_pem
);
202 EXPECT_TRUE(nss_nickname
.empty());
203 EXPECT_EQ(test_ca_cert_pem_
, ca_pem
);
206 TEST_F(NetworkCertMigratorTest
, MigrateNssOnNetworkAppearance
) {
208 SetupNetworkHandlers();
209 base::RunLoop().RunUntilIdle();
211 // Add a new network for migration after the handlers are initialized.
214 base::RunLoop().RunUntilIdle();
215 std::string nss_nickname
, ca_pem
;
216 GetEapCACertProperties(&nss_nickname
, &ca_pem
);
217 EXPECT_TRUE(nss_nickname
.empty());
218 EXPECT_EQ(test_ca_cert_pem_
, ca_pem
);
221 TEST_F(NetworkCertMigratorTest
, DoNotMigrateNssIfPemSet
) {
222 // Add a new network with an already set PEM property.
224 base::ListValue ca_pems
;
225 ca_pems
.AppendString(kFakePEM
);
226 service_test_
->SetServiceProperty(
227 kWifiStub
, shill::kEapCaCertPemProperty
, ca_pems
);
230 SetupNetworkHandlers();
231 base::RunLoop().RunUntilIdle();
233 std::string nss_nickname
, ca_pem
;
234 GetEapCACertProperties(&nss_nickname
, &ca_pem
);
235 EXPECT_TRUE(nss_nickname
.empty());
236 EXPECT_EQ(kFakePEM
, ca_pem
);
239 TEST_F(NetworkCertMigratorTest
, MigrateOpenVpn
) {
240 // Add a new network for migration before the handlers are initialized.
241 SetupVpnWithNss(true /* OpenVPN */);
244 SetupNetworkHandlers();
246 base::RunLoop().RunUntilIdle();
247 std::string nss_nickname
, ca_pem
;
248 GetVpnCACertProperties(true /* OpenVPN */, &nss_nickname
, &ca_pem
);
249 EXPECT_TRUE(nss_nickname
.empty());
250 EXPECT_EQ(test_ca_cert_pem_
, ca_pem
);
253 TEST_F(NetworkCertMigratorTest
, MigrateIpsecVpn
) {
254 // Add a new network for migration before the handlers are initialized.
255 SetupVpnWithNss(false /* not OpenVPN */);
258 SetupNetworkHandlers();
260 base::RunLoop().RunUntilIdle();
261 std::string nss_nickname
, ca_pem
;
262 GetVpnCACertProperties(false /* not OpenVPN */, &nss_nickname
, &ca_pem
);
263 EXPECT_TRUE(nss_nickname
.empty());
264 EXPECT_EQ(test_ca_cert_pem_
, ca_pem
);
267 } // namespace chromeos