Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chromeos/network/network_cert_migrator.h" | |
| 6 | |
| 7 #include <cert.h> | |
| 8 | |
| 9 #include "base/file_util.h" | |
| 10 #include "base/files/file_path.h" | |
| 11 #include "base/run_loop.h" | |
| 12 #include "chromeos/dbus/dbus_thread_manager.h" | |
| 13 #include "chromeos/dbus/shill_service_client.h" | |
| 14 #include "chromeos/login/login_state.h" | |
| 15 #include "chromeos/network/network_state_handler.h" | |
| 16 #include "crypto/nss_util.h" | |
| 17 #include "net/base/crypto_module.h" | |
| 18 #include "net/base/net_errors.h" | |
| 19 #include "net/base/test_data_directory.h" | |
| 20 #include "net/cert/nss_cert_database.h" | |
| 21 #include "net/cert/x509_certificate.h" | |
| 22 #include "net/test/cert_test_util.h" | |
| 23 #include "testing/gtest/include/gtest/gtest.h" | |
| 24 #include "third_party/cros_system_api/dbus/service_constants.h" | |
| 25 | |
| 26 namespace chromeos { | |
| 27 | |
| 28 namespace { | |
| 29 | |
| 30 const char* kWifiStub = "wifi_stub"; | |
| 31 const char* kVPNStub = "vpn_stub"; | |
| 32 const char* kNSSNickname = "nss_nickname"; | |
| 33 const char* kFakePEM = "pem"; | |
| 34 | |
| 35 } // namespace | |
| 36 | |
| 37 class NetworkCertMigratorTest : public testing::Test { | |
| 38 public: | |
| 39 NetworkCertMigratorTest() {} | |
| 40 virtual ~NetworkCertMigratorTest() {} | |
| 41 | |
| 42 virtual void SetUp() OVERRIDE { | |
| 43 ASSERT_TRUE(test_nssdb_.is_open()); | |
| 44 slot_ = net::NSSCertDatabase::GetInstance()->GetPublicModule(); | |
| 45 ASSERT_TRUE(slot_->os_module_handle()); | |
| 46 | |
| 47 LoginState::Initialize(); | |
| 48 | |
| 49 DBusThreadManager::InitializeWithStub(); | |
| 50 service_test_ = | |
| 51 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); | |
| 52 message_loop_.RunUntilIdle(); | |
| 53 service_test_->ClearServices(); | |
| 54 message_loop_.RunUntilIdle(); | |
| 55 } | |
| 56 | |
| 57 virtual void TearDown() OVERRIDE { | |
| 58 network_cert_migrator_.reset(); | |
| 59 network_state_handler_.reset(); | |
| 60 CertLoader::Shutdown(); | |
| 61 DBusThreadManager::Shutdown(); | |
| 62 LoginState::Shutdown(); | |
| 63 CleanupTestCert(); | |
| 64 } | |
| 65 | |
| 66 protected: | |
| 67 void SetupTestCACert() { | |
| 68 scoped_refptr<net::X509Certificate> cert_wo_nickname = | |
| 69 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(), | |
| 70 "eku-test-root.pem", | |
| 71 net::X509Certificate::FORMAT_AUTO) | |
| 72 .back(); | |
| 73 net::X509Certificate::GetPEMEncoded(cert_wo_nickname->os_cert_handle(), | |
| 74 &test_ca_cert_pem_); | |
| 75 std::string der_encoded; | |
| 76 net::X509Certificate::GetDEREncoded(cert_wo_nickname->os_cert_handle(), | |
| 77 &der_encoded); | |
| 78 cert_wo_nickname = NULL; | |
| 79 | |
| 80 test_ca_cert_ = net::X509Certificate::CreateFromBytesWithNickname( | |
| 81 der_encoded.data(), der_encoded.size(), kNSSNickname); | |
| 82 net::NSSCertDatabase* cert_database = net::NSSCertDatabase::GetInstance(); | |
| 83 net::CertificateList cert_list; | |
| 84 cert_list.push_back(test_ca_cert_); | |
| 85 net::NSSCertDatabase::ImportCertFailureList failures; | |
| 86 EXPECT_TRUE(cert_database->ImportCACerts( | |
| 87 cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures)); | |
| 88 ASSERT_TRUE(failures.empty()) << net::ErrorToString(failures[0].net_error); | |
| 89 } | |
| 90 | |
| 91 void SetupNetworkHandlers() { | |
| 92 CertLoader::Initialize(message_loop_.message_loop_proxy()); | |
| 93 CertLoader::Get()->SetCryptoTaskRunner(message_loop_.message_loop_proxy()); | |
|
stevenjb
2013/07/29 17:53:03
I don't like the inconsistency here. Rather than f
pneubeck (no reviews)
2013/08/05 08:51:22
Done.
| |
| 94 network_state_handler_.reset(NetworkStateHandler::InitializeForTest()); | |
| 95 network_cert_migrator_.reset(new NetworkCertMigrator); | |
| 96 network_cert_migrator_->Init(network_state_handler_.get()); | |
| 97 } | |
| 98 | |
| 99 void SetupWifiWithNss() { | |
| 100 const bool add_to_visible = true; | |
| 101 const bool add_to_watchlist = true; | |
| 102 service_test_->AddService(kWifiStub, | |
| 103 kWifiStub, | |
| 104 flimflam::kTypeWifi, | |
| 105 flimflam::kStateOnline, | |
| 106 add_to_visible, | |
| 107 add_to_watchlist); | |
| 108 service_test_->SetServiceProperty(kWifiStub, | |
| 109 flimflam::kEapCaCertNssProperty, | |
| 110 base::StringValue(kNSSNickname)); | |
| 111 } | |
| 112 | |
| 113 void GetEapCACertProperties(std::string* nss_nickname, std::string* ca_pem) { | |
| 114 nss_nickname->clear(); | |
| 115 ca_pem->clear(); | |
| 116 const base::DictionaryValue* properties = | |
| 117 service_test_->GetServiceProperties(kWifiStub); | |
| 118 properties->GetStringWithoutPathExpansion(flimflam::kEapCaCertNssProperty, | |
| 119 nss_nickname); | |
| 120 const base::ListValue* ca_pems = NULL; | |
| 121 properties->GetListWithoutPathExpansion(shill::kEapCaCertPemProperty, | |
| 122 &ca_pems); | |
| 123 if (ca_pems && !ca_pems->empty()) | |
| 124 ca_pems->GetString(0, ca_pem); | |
| 125 } | |
| 126 | |
| 127 void SetupVpnWithNss() { | |
| 128 const bool add_to_visible = true; | |
| 129 const bool add_to_watchlist = true; | |
| 130 service_test_->AddService(kVPNStub, | |
| 131 kVPNStub, | |
| 132 flimflam::kTypeVPN, | |
| 133 flimflam::kStateIdle, | |
| 134 add_to_visible, | |
| 135 add_to_watchlist); | |
| 136 base::DictionaryValue provider; | |
| 137 provider.SetStringWithoutPathExpansion(flimflam::kOpenVPNCaCertNSSProperty, | |
| 138 kNSSNickname); | |
| 139 service_test_->SetServiceProperty( | |
| 140 kVPNStub, flimflam::kProviderProperty, provider); | |
| 141 } | |
| 142 | |
| 143 void GetVpnCACertProperties(std::string* nss_nickname, std::string* ca_pem) { | |
| 144 nss_nickname->clear(); | |
| 145 ca_pem->clear(); | |
| 146 const base::DictionaryValue* properties = | |
| 147 service_test_->GetServiceProperties(kVPNStub); | |
| 148 const base::DictionaryValue* provider = NULL; | |
| 149 properties->GetDictionaryWithoutPathExpansion(flimflam::kProviderProperty, | |
| 150 &provider); | |
| 151 if (!provider) | |
| 152 return; | |
| 153 provider->GetStringWithoutPathExpansion(flimflam::kOpenVPNCaCertNSSProperty, | |
| 154 nss_nickname); | |
| 155 const base::ListValue* ca_pems = NULL; | |
| 156 properties->GetListWithoutPathExpansion(shill::kOpenVPNCaCertPemProperty, | |
| 157 &ca_pems); | |
| 158 if (ca_pems && !ca_pems->empty()) | |
| 159 ca_pems->GetString(0, ca_pem); | |
| 160 } | |
| 161 | |
| 162 ShillServiceClient::TestInterface* service_test_; | |
| 163 scoped_refptr<net::X509Certificate> test_ca_cert_; | |
| 164 std::string test_ca_cert_pem_; | |
| 165 base::MessageLoop message_loop_; | |
| 166 | |
| 167 private: | |
| 168 void CleanupTestCert() { | |
| 169 ASSERT_TRUE(net::NSSCertDatabase::GetInstance()->DeleteCertAndKey( | |
| 170 test_ca_cert_.get())); | |
| 171 } | |
| 172 | |
| 173 scoped_ptr<NetworkStateHandler> network_state_handler_; | |
| 174 scoped_ptr<NetworkCertMigrator> network_cert_migrator_; | |
| 175 scoped_refptr<net::CryptoModule> slot_; | |
| 176 crypto::ScopedTestNSSDB test_nssdb_; | |
| 177 | |
| 178 DISALLOW_COPY_AND_ASSIGN(NetworkCertMigratorTest); | |
| 179 }; | |
| 180 | |
| 181 TEST_F(NetworkCertMigratorTest, MigrateNssOnInitialization) { | |
| 182 // Add a new network for migration before the handlers are initialized. | |
| 183 SetupWifiWithNss(); | |
| 184 | |
| 185 SetupTestCACert(); | |
| 186 SetupNetworkHandlers(); | |
| 187 | |
| 188 message_loop_.RunUntilIdle(); | |
| 189 std::string nss_nickname, ca_pem; | |
| 190 GetEapCACertProperties(&nss_nickname, &ca_pem); | |
| 191 EXPECT_TRUE(nss_nickname.empty()); | |
| 192 EXPECT_EQ(test_ca_cert_pem_, ca_pem); | |
| 193 } | |
| 194 | |
| 195 TEST_F(NetworkCertMigratorTest, MigrateNssOnNetworkAppearance) { | |
| 196 SetupTestCACert(); | |
| 197 SetupNetworkHandlers(); | |
| 198 message_loop_.RunUntilIdle(); | |
| 199 | |
| 200 // Add a new network for migration after the handlers are initialized. | |
| 201 SetupWifiWithNss(); | |
| 202 | |
| 203 message_loop_.RunUntilIdle(); | |
| 204 std::string nss_nickname, ca_pem; | |
| 205 GetEapCACertProperties(&nss_nickname, &ca_pem); | |
| 206 EXPECT_TRUE(nss_nickname.empty()); | |
| 207 EXPECT_EQ(test_ca_cert_pem_, ca_pem); | |
| 208 } | |
| 209 | |
| 210 TEST_F(NetworkCertMigratorTest, DoNotMigrateNssIfPemSet) { | |
| 211 // Add a new network with an already set PEM property. | |
| 212 SetupWifiWithNss(); | |
| 213 base::ListValue ca_pems; | |
| 214 ca_pems.AppendString(kFakePEM); | |
| 215 service_test_->SetServiceProperty( | |
| 216 kWifiStub, shill::kEapCaCertPemProperty, ca_pems); | |
| 217 | |
| 218 SetupTestCACert(); | |
| 219 SetupNetworkHandlers(); | |
| 220 message_loop_.RunUntilIdle(); | |
| 221 | |
| 222 std::string nss_nickname, ca_pem; | |
| 223 GetEapCACertProperties(&nss_nickname, &ca_pem); | |
| 224 EXPECT_TRUE(nss_nickname.empty()); | |
| 225 EXPECT_EQ(kFakePEM, ca_pem); | |
| 226 } | |
| 227 | |
| 228 TEST_F(NetworkCertMigratorTest, MigrateOpenVpn) { | |
| 229 // Add a new network for migration before the handlers are initialized. | |
| 230 SetupVpnWithNss(); | |
| 231 | |
| 232 SetupTestCACert(); | |
| 233 SetupNetworkHandlers(); | |
| 234 | |
| 235 message_loop_.RunUntilIdle(); | |
| 236 std::string nss_nickname, ca_pem; | |
| 237 GetVpnCACertProperties(&nss_nickname, &ca_pem); | |
| 238 EXPECT_TRUE(nss_nickname.empty()); | |
| 239 EXPECT_EQ(test_ca_cert_pem_, ca_pem); | |
| 240 } | |
| 241 | |
| 242 } // namespace chromeos | |
| OLD | NEW |