[SyncFS] Use variadic template in callback_tracker_internal.h
[chromium-blink-merge.git] / chromeos / network / client_cert_resolver_unittest.cc
blobd426c97aacbaaad435c5a6af0c98354da43b39ec
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.
4 #include "chromeos/network/client_cert_resolver.h"
6 #include <cert.h>
7 #include <pk11pub.h>
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/json/json_reader.h"
12 #include "base/run_loop.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/values.h"
15 #include "chromeos/cert_loader.h"
16 #include "chromeos/dbus/dbus_thread_manager.h"
17 #include "chromeos/dbus/shill_manager_client.h"
18 #include "chromeos/dbus/shill_profile_client.h"
19 #include "chromeos/dbus/shill_service_client.h"
20 #include "chromeos/network/managed_network_configuration_handler_impl.h"
21 #include "chromeos/network/network_configuration_handler.h"
22 #include "chromeos/network/network_profile_handler.h"
23 #include "chromeos/network/network_state_handler.h"
24 #include "chromeos/tpm_token_loader.h"
25 #include "components/onc/onc_constants.h"
26 #include "crypto/nss_util_internal.h"
27 #include "crypto/scoped_test_nss_chromeos_user.h"
28 #include "net/base/crypto_module.h"
29 #include "net/base/net_errors.h"
30 #include "net/base/test_data_directory.h"
31 #include "net/cert/nss_cert_database_chromeos.h"
32 #include "net/cert/x509_certificate.h"
33 #include "net/test/cert_test_util.h"
34 #include "testing/gtest/include/gtest/gtest.h"
35 #include "third_party/cros_system_api/dbus/service_constants.h"
37 namespace chromeos {
39 namespace {
41 const char* kWifiStub = "wifi_stub";
42 const char* kWifiSSID = "wifi_ssid";
43 const char* kUserProfilePath = "user_profile";
44 const char* kUserHash = "user_hash";
46 } // namespace
48 class ClientCertResolverTest : public testing::Test {
49 public:
50 ClientCertResolverTest() : service_test_(NULL),
51 profile_test_(NULL),
52 cert_loader_(NULL),
53 user_(kUserHash) {
55 virtual ~ClientCertResolverTest() {}
57 virtual void SetUp() OVERRIDE {
58 // Initialize NSS db for the user.
59 ASSERT_TRUE(user_.constructed_successfully());
60 user_.FinishInit();
61 private_slot_ = crypto::GetPrivateSlotForChromeOSUser(
62 user_.username_hash(),
63 base::Callback<void(crypto::ScopedPK11Slot)>());
64 ASSERT_TRUE(private_slot_.get());
65 test_nssdb_.reset(new net::NSSCertDatabaseChromeOS(
66 crypto::GetPublicSlotForChromeOSUser(user_.username_hash()),
67 crypto::GetPrivateSlotForChromeOSUser(
68 user_.username_hash(),
69 base::Callback<void(crypto::ScopedPK11Slot)>())));
70 test_nssdb_->SetSlowTaskRunnerForTest(message_loop_.message_loop_proxy());
72 DBusThreadManager::Initialize();
73 service_test_ =
74 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
75 profile_test_ =
76 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
77 base::RunLoop().RunUntilIdle();
78 service_test_->ClearServices();
79 base::RunLoop().RunUntilIdle();
81 TPMTokenLoader::InitializeForTest();
83 CertLoader::Initialize();
84 cert_loader_ = CertLoader::Get();
85 cert_loader_->force_hardware_backed_for_test();
88 virtual void TearDown() OVERRIDE {
89 client_cert_resolver_.reset();
90 managed_config_handler_.reset();
91 network_config_handler_.reset();
92 network_profile_handler_.reset();
93 network_state_handler_.reset();
94 CertLoader::Shutdown();
95 TPMTokenLoader::Shutdown();
96 DBusThreadManager::Shutdown();
97 CleanupSlotContents();
100 protected:
101 void StartCertLoader() {
102 cert_loader_->StartWithNSSDB(test_nssdb_.get());
103 if (test_client_cert_.get()) {
104 int slot_id = 0;
105 const std::string pkcs11_id =
106 CertLoader::GetPkcs11IdAndSlotForCert(*test_client_cert_, &slot_id);
107 test_cert_id_ = base::StringPrintf("%i:%s", slot_id, pkcs11_id.c_str());
111 // Imports a CA cert (stored as PEM in test_ca_cert_pem_) and a client
112 // certificate signed by that CA. Its PKCS#11 ID is stored in
113 // |test_cert_id_|.
114 void SetupTestCerts() {
115 // Import a CA cert.
116 net::CertificateList ca_cert_list =
117 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(),
118 "websocket_cacert.pem",
119 net::X509Certificate::FORMAT_AUTO);
120 ASSERT_TRUE(!ca_cert_list.empty());
121 net::NSSCertDatabase::ImportCertFailureList failures;
122 EXPECT_TRUE(test_nssdb_->ImportCACerts(
123 ca_cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures));
124 ASSERT_TRUE(failures.empty()) << net::ErrorToString(failures[0].net_error);
126 net::X509Certificate::GetPEMEncoded(ca_cert_list[0]->os_cert_handle(),
127 &test_ca_cert_pem_);
128 ASSERT_TRUE(!test_ca_cert_pem_.empty());
130 // Import a client cert signed by that CA.
131 std::string pkcs12_data;
132 ASSERT_TRUE(base::ReadFileToString(
133 net::GetTestCertsDirectory().Append("websocket_client_cert.p12"),
134 &pkcs12_data));
136 net::CertificateList client_cert_list;
137 scoped_refptr<net::CryptoModule> module(
138 net::CryptoModule::CreateFromHandle(private_slot_.get()));
139 ASSERT_EQ(net::OK,
140 test_nssdb_->ImportFromPKCS12(module.get(),
141 pkcs12_data,
142 base::string16(),
143 false,
144 &client_cert_list));
145 ASSERT_TRUE(!client_cert_list.empty());
146 test_client_cert_ = client_cert_list[0];
149 void SetupNetworkHandlers() {
150 network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
151 network_profile_handler_.reset(new NetworkProfileHandler());
152 network_config_handler_.reset(new NetworkConfigurationHandler());
153 managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl());
154 client_cert_resolver_.reset(new ClientCertResolver());
156 network_profile_handler_->Init();
157 network_config_handler_->Init(network_state_handler_.get());
158 managed_config_handler_->Init(network_state_handler_.get(),
159 network_profile_handler_.get(),
160 network_config_handler_.get(),
161 NULL /* network_device_handler */);
162 client_cert_resolver_->Init(network_state_handler_.get(),
163 managed_config_handler_.get());
164 client_cert_resolver_->SetSlowTaskRunnerForTest(
165 message_loop_.message_loop_proxy());
167 profile_test_->AddProfile(kUserProfilePath, kUserHash);
170 void SetupWifi() {
171 service_test_->SetServiceProperties(kWifiStub,
172 kWifiStub,
173 kWifiSSID,
174 shill::kTypeWifi,
175 shill::kStateOnline,
176 true /* visible */);
177 // Set an arbitrary cert id, so that we can check afterwards whether we
178 // cleared the property or not.
179 service_test_->SetServiceProperty(
180 kWifiStub, shill::kEapCertIdProperty, base::StringValue("invalid id"));
181 profile_test_->AddService(kUserProfilePath, kWifiStub);
183 DBusThreadManager::Get()
184 ->GetShillManagerClient()
185 ->GetTestInterface()
186 ->AddManagerService(kWifiStub, true);
189 // Setup a policy with a certificate pattern that matches any client cert that
190 // is signed by the test CA cert (stored in |test_ca_cert_pem_|). In
191 // particular it will match the test client cert.
192 void SetupPolicy() {
193 const char* kTestPolicyTemplate =
194 "[ { \"GUID\": \"wifi_stub\","
195 " \"Name\": \"wifi_stub\","
196 " \"Type\": \"WiFi\","
197 " \"WiFi\": {"
198 " \"Security\": \"WPA-EAP\","
199 " \"SSID\": \"wifi_ssid\","
200 " \"EAP\": {"
201 " \"Outer\": \"EAP-TLS\","
202 " \"ClientCertType\": \"Pattern\","
203 " \"ClientCertPattern\": {"
204 " \"IssuerCAPEMs\": [ \"%s\" ]"
205 " }"
206 " }"
207 " }"
208 "} ]";
209 std::string policy_json =
210 base::StringPrintf(kTestPolicyTemplate, test_ca_cert_pem_.c_str());
212 std::string error;
213 scoped_ptr<base::Value> policy_value(base::JSONReader::ReadAndReturnError(
214 policy_json, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error));
215 ASSERT_TRUE(policy_value) << error;
217 base::ListValue* policy = NULL;
218 ASSERT_TRUE(policy_value->GetAsList(&policy));
220 managed_config_handler_->SetPolicy(
221 onc::ONC_SOURCE_USER_POLICY,
222 kUserHash,
223 *policy,
224 base::DictionaryValue() /* no global network config */);
227 void GetClientCertProperties(std::string* pkcs11_id) {
228 pkcs11_id->clear();
229 const base::DictionaryValue* properties =
230 service_test_->GetServiceProperties(kWifiStub);
231 if (!properties)
232 return;
233 properties->GetStringWithoutPathExpansion(shill::kEapCertIdProperty,
234 pkcs11_id);
237 ShillServiceClient::TestInterface* service_test_;
238 ShillProfileClient::TestInterface* profile_test_;
239 std::string test_cert_id_;
240 scoped_refptr<net::X509Certificate> test_ca_cert_;
241 std::string test_ca_cert_pem_;
242 base::MessageLoop message_loop_;
244 private:
245 void CleanupSlotContents() {
246 CERTCertList* cert_list = PK11_ListCertsInSlot(private_slot_.get());
247 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
248 !CERT_LIST_END(node, cert_list);
249 node = CERT_LIST_NEXT(node)) {
250 scoped_refptr<net::X509Certificate> cert(
251 net::X509Certificate::CreateFromHandle(
252 node->cert, net::X509Certificate::OSCertHandles()));
253 test_nssdb_->DeleteCertAndKey(cert.get());
255 CERT_DestroyCertList(cert_list);
258 CertLoader* cert_loader_;
259 scoped_refptr<net::X509Certificate> test_client_cert_;
260 scoped_ptr<NetworkStateHandler> network_state_handler_;
261 scoped_ptr<NetworkProfileHandler> network_profile_handler_;
262 scoped_ptr<NetworkConfigurationHandler> network_config_handler_;
263 scoped_ptr<ManagedNetworkConfigurationHandlerImpl> managed_config_handler_;
264 scoped_ptr<ClientCertResolver> client_cert_resolver_;
265 crypto::ScopedTestNSSChromeOSUser user_;
266 scoped_ptr<net::NSSCertDatabaseChromeOS> test_nssdb_;
267 crypto::ScopedPK11Slot private_slot_;
269 DISALLOW_COPY_AND_ASSIGN(ClientCertResolverTest);
272 TEST_F(ClientCertResolverTest, NoMatchingCertificates) {
273 SetupNetworkHandlers();
274 SetupWifi();
275 StartCertLoader();
276 SetupPolicy();
277 base::RunLoop().RunUntilIdle();
279 // Verify that no client certificate was configured.
280 std::string pkcs11_id;
281 GetClientCertProperties(&pkcs11_id);
282 EXPECT_EQ(std::string(), pkcs11_id);
285 TEST_F(ClientCertResolverTest, ResolveOnCertificatesLoaded) {
286 SetupNetworkHandlers();
287 SetupWifi();
288 SetupTestCerts();
289 SetupPolicy();
290 base::RunLoop().RunUntilIdle();
292 StartCertLoader();
293 base::RunLoop().RunUntilIdle();
295 // Verify that the resolver positively matched the pattern in the policy with
296 // the test client cert and configured the network.
297 std::string pkcs11_id;
298 GetClientCertProperties(&pkcs11_id);
299 EXPECT_EQ(test_cert_id_, pkcs11_id);
302 TEST_F(ClientCertResolverTest, ResolveAfterPolicyApplication) {
303 SetupTestCerts();
304 StartCertLoader();
305 SetupNetworkHandlers();
306 SetupWifi();
307 base::RunLoop().RunUntilIdle();
309 // Policy application will trigger the ClientCertResolver.
310 SetupPolicy();
311 base::RunLoop().RunUntilIdle();
313 // Verify that the resolver positively matched the pattern in the policy with
314 // the test client cert and configured the network.
315 std::string pkcs11_id;
316 GetClientCertProperties(&pkcs11_id);
317 EXPECT_EQ(test_cert_id_, pkcs11_id);
320 } // namespace chromeos