Remove old about scheme URL constants.
[chromium-blink-merge.git] / chromeos / network / client_cert_resolver_unittest.cc
blobabcdfd4f147f0b9009b52733a98b4b57e44d4a4a
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/file_util.h"
10 #include "base/files/file_path.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_profile_client.h"
18 #include "chromeos/dbus/shill_service_client.h"
19 #include "chromeos/login/login_state.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 "crypto/nss_util.h"
26 #include "net/base/crypto_module.h"
27 #include "net/base/net_errors.h"
28 #include "net/base/test_data_directory.h"
29 #include "net/cert/nss_cert_database.h"
30 #include "net/cert/x509_certificate.h"
31 #include "net/test/cert_test_util.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "third_party/cros_system_api/dbus/service_constants.h"
35 namespace chromeos {
37 namespace {
39 const char* kWifiStub = "wifi_stub";
40 const char* kWifiSSID = "wifi_ssid";
41 const char* kUserProfilePath = "user_profile";
42 const char* kUserHash = "user_hash";
44 } // namespace
46 class ClientCertResolverTest : public testing::Test {
47 public:
48 ClientCertResolverTest() {}
49 virtual ~ClientCertResolverTest() {}
51 virtual void SetUp() OVERRIDE {
52 ASSERT_TRUE(test_nssdb_.is_open());
53 slot_ = net::NSSCertDatabase::GetInstance()->GetPublicModule();
54 ASSERT_TRUE(slot_->os_module_handle());
56 LoginState::Initialize();
58 DBusThreadManager::InitializeWithStub();
59 service_test_ =
60 DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface();
61 profile_test_ =
62 DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface();
63 message_loop_.RunUntilIdle();
64 service_test_->ClearServices();
65 message_loop_.RunUntilIdle();
67 TPMTokenLoader::Initialize();
68 TPMTokenLoader* tpm_token_loader = TPMTokenLoader::Get();
69 tpm_token_loader->InitializeTPMForTest();
70 tpm_token_loader->SetCryptoTaskRunner(message_loop_.message_loop_proxy());
72 CertLoader::Initialize();
73 CertLoader::Get()->SetSlowTaskRunnerForTest(
74 message_loop_.message_loop_proxy());
77 virtual void TearDown() OVERRIDE {
78 client_cert_resolver_.reset();
79 managed_config_handler_.reset();
80 network_config_handler_.reset();
81 network_profile_handler_.reset();
82 network_state_handler_.reset();
83 CertLoader::Shutdown();
84 TPMTokenLoader::Shutdown();
85 DBusThreadManager::Shutdown();
86 LoginState::Shutdown();
87 CleanupSlotContents();
90 protected:
91 // Imports a CA cert (stored as PEM in test_ca_cert_pem_) and a client
92 // certificate signed by that CA. Its PKCS#11 ID is stored in
93 // |test_pkcs11_id_|.
94 void SetupTestCerts() {
95 // Import a CA cert.
96 net::NSSCertDatabase* cert_db = net::NSSCertDatabase::GetInstance();
97 net::CertificateList ca_cert_list =
98 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(),
99 "websocket_cacert.pem",
100 net::X509Certificate::FORMAT_AUTO);
101 ASSERT_TRUE(!ca_cert_list.empty());
102 net::NSSCertDatabase::ImportCertFailureList failures;
103 EXPECT_TRUE(cert_db->ImportCACerts(
104 ca_cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures));
105 ASSERT_TRUE(failures.empty()) << net::ErrorToString(failures[0].net_error);
107 net::X509Certificate::GetPEMEncoded(ca_cert_list[0]->os_cert_handle(),
108 &test_ca_cert_pem_);
109 ASSERT_TRUE(!test_ca_cert_pem_.empty());
111 // Import a client cert signed by that CA.
112 scoped_refptr<net::CryptoModule> crypt_module = cert_db->GetPrivateModule();
113 std::string pkcs12_data;
114 ASSERT_TRUE(base::ReadFileToString(
115 net::GetTestCertsDirectory().Append("websocket_client_cert.p12"),
116 &pkcs12_data));
118 net::CertificateList client_cert_list;
119 ASSERT_EQ(net::OK,
120 cert_db->ImportFromPKCS12(crypt_module.get(),
121 pkcs12_data,
122 base::string16(),
123 false,
124 &client_cert_list));
125 ASSERT_TRUE(!client_cert_list.empty());
126 test_pkcs11_id_ = CertLoader::GetPkcs11IdForCert(*client_cert_list[0]);
127 ASSERT_TRUE(!test_pkcs11_id_.empty());
130 void SetupNetworkHandlers() {
131 network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
132 network_profile_handler_.reset(new NetworkProfileHandler());
133 network_config_handler_.reset(new NetworkConfigurationHandler());
134 managed_config_handler_.reset(new ManagedNetworkConfigurationHandlerImpl());
135 client_cert_resolver_.reset(new ClientCertResolver());
137 network_profile_handler_->Init(network_state_handler_.get());
138 network_config_handler_->Init(network_state_handler_.get());
139 managed_config_handler_->Init(network_state_handler_.get(),
140 network_profile_handler_.get(),
141 network_config_handler_.get());
142 client_cert_resolver_->Init(network_state_handler_.get(),
143 managed_config_handler_.get());
144 client_cert_resolver_->SetSlowTaskRunnerForTest(
145 message_loop_.message_loop_proxy());
147 profile_test_->AddProfile(kUserProfilePath, kUserHash);
150 void SetupWifi() {
151 const bool add_to_visible = true;
152 const bool add_to_watchlist = true;
153 service_test_->AddService(kWifiStub,
154 kWifiSSID,
155 shill::kTypeWifi,
156 shill::kStateOnline,
157 add_to_visible,
158 add_to_watchlist);
159 service_test_->SetServiceProperty(
160 kWifiStub, shill::kGuidProperty, base::StringValue(kWifiStub));
162 profile_test_->AddService(kUserProfilePath, kWifiStub);
165 // Setup a policy with a certificate pattern that matches any client cert that
166 // is signed by the test CA cert (stored in |test_ca_cert_pem_|). In
167 // particular it will match the test client cert.
168 void SetupPolicy() {
169 const char* kTestPolicyTemplate =
170 "[ { \"GUID\": \"wifi_stub\","
171 " \"Name\": \"wifi_stub\","
172 " \"Type\": \"WiFi\","
173 " \"WiFi\": {"
174 " \"Security\": \"WPA-EAP\","
175 " \"SSID\": \"wifi_ssid\","
176 " \"EAP\": {"
177 " \"Outer\": \"EAP-TLS\","
178 " \"ClientCertType\": \"Pattern\","
179 " \"ClientCertPattern\": {"
180 " \"IssuerCAPEMs\": [ \"%s\" ]"
181 " }"
182 " }"
183 " }"
184 "} ]";
185 std::string policy_json =
186 base::StringPrintf(kTestPolicyTemplate, test_ca_cert_pem_.c_str());
188 std::string error;
189 scoped_ptr<base::Value> policy_value(base::JSONReader::ReadAndReturnError(
190 policy_json, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error));
191 ASSERT_TRUE(policy_value) << error;
193 base::ListValue* policy = NULL;
194 ASSERT_TRUE(policy_value->GetAsList(&policy));
196 managed_config_handler_->SetPolicy(
197 onc::ONC_SOURCE_USER_POLICY,
198 kUserHash,
199 *policy,
200 base::DictionaryValue() /* no global network config */);
203 void GetClientCertProperties(std::string* pkcs11_id) {
204 pkcs11_id->clear();
205 const base::DictionaryValue* properties =
206 service_test_->GetServiceProperties(kWifiStub);
207 if (!properties)
208 return;
209 properties->GetStringWithoutPathExpansion(shill::kEapCertIdProperty,
210 pkcs11_id);
213 ShillServiceClient::TestInterface* service_test_;
214 ShillProfileClient::TestInterface* profile_test_;
215 std::string test_pkcs11_id_;
216 scoped_refptr<net::X509Certificate> test_ca_cert_;
217 std::string test_ca_cert_pem_;
218 base::MessageLoop message_loop_;
220 private:
221 void CleanupSlotContents() {
222 CERTCertList* cert_list = PK11_ListCertsInSlot(slot_->os_module_handle());
223 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list);
224 !CERT_LIST_END(node, cert_list);
225 node = CERT_LIST_NEXT(node)) {
226 scoped_refptr<net::X509Certificate> cert(
227 net::X509Certificate::CreateFromHandle(
228 node->cert, net::X509Certificate::OSCertHandles()));
229 net::NSSCertDatabase::GetInstance()->DeleteCertAndKey(cert.get());
231 CERT_DestroyCertList(cert_list);
234 scoped_ptr<NetworkStateHandler> network_state_handler_;
235 scoped_ptr<NetworkProfileHandler> network_profile_handler_;
236 scoped_ptr<NetworkConfigurationHandler> network_config_handler_;
237 scoped_ptr<ManagedNetworkConfigurationHandlerImpl> managed_config_handler_;
238 scoped_ptr<ClientCertResolver> client_cert_resolver_;
239 scoped_refptr<net::CryptoModule> slot_;
240 crypto::ScopedTestNSSDB test_nssdb_;
242 DISALLOW_COPY_AND_ASSIGN(ClientCertResolverTest);
245 TEST_F(ClientCertResolverTest, NoMatchingCertificates) {
246 SetupNetworkHandlers();
247 SetupPolicy();
248 message_loop_.RunUntilIdle();
250 SetupWifi();
251 message_loop_.RunUntilIdle();
253 // Verify that no client certificate was configured.
254 std::string pkcs11_id;
255 GetClientCertProperties(&pkcs11_id);
256 EXPECT_TRUE(pkcs11_id.empty());
259 TEST_F(ClientCertResolverTest, ResolveOnInitialization) {
260 SetupTestCerts();
261 SetupNetworkHandlers();
262 SetupPolicy();
263 message_loop_.RunUntilIdle();
265 SetupWifi();
266 message_loop_.RunUntilIdle();
268 // Verify that the resolver positively matched the pattern in the policy with
269 // the test client cert and configured the network.
270 std::string pkcs11_id;
271 GetClientCertProperties(&pkcs11_id);
272 EXPECT_EQ(test_pkcs11_id_, pkcs11_id);
275 TEST_F(ClientCertResolverTest, ResolveAfterPolicyApplication) {
276 SetupTestCerts();
277 SetupNetworkHandlers();
278 message_loop_.RunUntilIdle();
280 // The policy will trigger the creation of a new wifi service.
281 SetupPolicy();
282 message_loop_.RunUntilIdle();
284 // Verify that the resolver positively matched the pattern in the policy with
285 // the test client cert and configured the network.
286 std::string pkcs11_id;
287 GetClientCertProperties(&pkcs11_id);
288 EXPECT_EQ(test_pkcs11_id_, pkcs11_id);
291 } // namespace chromeos