Chromium Code Reviews| Index: chromeos/network/client_cert_resolver_unittest.cc |
| diff --git a/chromeos/network/client_cert_resolver_unittest.cc b/chromeos/network/client_cert_resolver_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e0d4b068a3de97bd94dfba883493bf1a42d47267 |
| --- /dev/null |
| +++ b/chromeos/network/client_cert_resolver_unittest.cc |
| @@ -0,0 +1,245 @@ |
| +// Copyright 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| +#include "chromeos/network/client_cert_resolver.h" |
| + |
| +#include <cert.h> |
| +#include <pk11pub.h> |
| + |
| +#include "base/file_util.h" |
| +#include "base/files/file_path.h" |
| +#include "base/json/json_reader.h" |
| +#include "base/run_loop.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "chromeos/dbus/dbus_thread_manager.h" |
| +#include "chromeos/dbus/shill_profile_client.h" |
| +#include "chromeos/dbus/shill_service_client.h" |
| +#include "chromeos/login/login_state.h" |
| +#include "chromeos/network/managed_network_configuration_handler.h" |
| +#include "chromeos/network/network_configuration_handler.h" |
| +#include "chromeos/network/network_profile_handler.h" |
| +#include "chromeos/network/network_state_handler.h" |
| +#include "crypto/nss_util.h" |
| +#include "net/base/crypto_module.h" |
| +#include "net/base/net_errors.h" |
| +#include "net/base/test_data_directory.h" |
| +#include "net/cert/nss_cert_database.h" |
| +#include "net/cert/x509_certificate.h" |
| +#include "net/test/cert_test_util.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| +#include "third_party/cros_system_api/dbus/service_constants.h" |
| + |
| +namespace chromeos { |
| + |
| +namespace { |
| + |
| +const char* kWifiStub = "wifi_stub"; |
| +const char* kWifiSSID = "wifi_ssid"; |
| +//const char* kFakePEM = "pem"; |
|
stevenjb
2013/08/10 00:11:58
remove until used
pneubeck (no reviews)
2013/08/11 18:37:02
Done.
|
| +const char* kUserProfilePath = "user_profile"; |
| +const char* kUserHash = "user_hash"; |
| + |
| +} // namespace |
| + |
| +class ClientCertResolverTest : public testing::Test { |
| + public: |
| + ClientCertResolverTest() {} |
| + virtual ~ClientCertResolverTest() {} |
| + |
| + virtual void SetUp() OVERRIDE { |
| + ASSERT_TRUE(test_nssdb_.is_open()); |
| + slot_ = net::NSSCertDatabase::GetInstance()->GetPublicModule(); |
| + ASSERT_TRUE(slot_->os_module_handle()); |
| + |
| + LoginState::Initialize(); |
| + |
| + DBusThreadManager::InitializeWithStub(); |
| + service_test_ = |
| + DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); |
| + profile_test_ = |
| + DBusThreadManager::Get()->GetShillProfileClient()->GetTestInterface(); |
| + message_loop_.RunUntilIdle(); |
| + service_test_->ClearServices(); |
| + message_loop_.RunUntilIdle(); |
| + |
| + CertLoader::Initialize(); |
| + CertLoader* cert_loader = CertLoader::Get(); |
| + cert_loader->InitializeTPMForTest(); |
| + cert_loader->SetSlowTaskRunnerForTest( |
| + message_loop_.message_loop_proxy()); |
| + cert_loader->SetCryptoTaskRunner(message_loop_.message_loop_proxy()); |
| + } |
| + |
| + virtual void TearDown() OVERRIDE { |
| + client_cert_resolver_.reset(); |
| + managed_config_handler_.reset(); |
| + network_config_handler_.reset(); |
| + network_profile_handler_.reset(); |
| + network_state_handler_.reset(); |
| + CertLoader::Shutdown(); |
| + DBusThreadManager::Shutdown(); |
| + LoginState::Shutdown(); |
| + CleanupSlotContents(); |
| + } |
| + |
| + protected: |
| + void SetupTestCerts() { |
| + net::NSSCertDatabase* cert_db = net::NSSCertDatabase::GetInstance(); |
| + net::CertificateList ca_cert_list = |
| + net::CreateCertificateListFromFile(net::GetTestCertsDirectory(), |
| + "websocket_cacert.pem", |
|
stevenjb
2013/08/10 00:11:58
FILE_PATH_LITERAL() ?
Also, make this a const with
pneubeck (no reviews)
2013/08/11 18:37:02
AFAIU, FILE_PATH_LITERAL helps for cross-platform
|
| + net::X509Certificate::FORMAT_AUTO); |
| + ASSERT_TRUE(!ca_cert_list.empty()); |
| + net::NSSCertDatabase::ImportCertFailureList failures; |
| + EXPECT_TRUE(cert_db->ImportCACerts( |
| + ca_cert_list, net::NSSCertDatabase::TRUST_DEFAULT, &failures)); |
| + ASSERT_TRUE(failures.empty()) << net::ErrorToString(failures[0].net_error); |
| + |
| + net::X509Certificate::GetPEMEncoded(ca_cert_list[0]->os_cert_handle(), |
| + &test_ca_cert_pem_); |
| + ASSERT_TRUE(!test_ca_cert_pem_.empty()); |
| + |
| + scoped_refptr<net::CryptoModule> crypt_module = cert_db->GetPrivateModule(); |
| + std::string pkcs12_data; |
| + ASSERT_TRUE(file_util::ReadFileToString( |
| + net::GetTestCertsDirectory().Append("websocket_client_cert.p12"), |
|
stevenjb
2013/08/10 00:11:58
named const
pneubeck (no reviews)
2013/08/11 18:37:02
ditto.
|
| + &pkcs12_data)); |
| + |
| + net::CertificateList client_cert_list; |
| + ASSERT_EQ(net::OK, |
| + cert_db->ImportFromPKCS12(crypt_module.get(), |
| + pkcs12_data, |
| + string16(), |
| + false, |
| + &client_cert_list)); |
| + ASSERT_TRUE(!client_cert_list.empty()); |
| + test_pkcs11_id_ = CertLoader::GetPkcs11IdForCert(*client_cert_list[0]); |
| + ASSERT_TRUE(!test_pkcs11_id_.empty()); |
| + } |
| + |
| + void SetupNetworkHandlers() { |
| + network_state_handler_.reset(NetworkStateHandler::InitializeForTest()); |
| + network_profile_handler_.reset(new NetworkProfileHandler()); |
| + network_config_handler_.reset(new NetworkConfigurationHandler()); |
| + managed_config_handler_.reset( |
| + new ManagedNetworkConfigurationHandler()); |
| + client_cert_resolver_.reset(new ClientCertResolver()); |
| + |
| + network_profile_handler_->Init(network_state_handler_.get()); |
| + network_config_handler_->Init(network_state_handler_.get()); |
| + managed_config_handler_->Init(network_state_handler_.get(), |
| + network_profile_handler_.get(), |
| + network_config_handler_.get()); |
| + client_cert_resolver_->Init(network_state_handler_.get(), |
| + managed_config_handler_.get()); |
| + client_cert_resolver_->SetSlowTaskRunnerForTest( |
| + message_loop_.message_loop_proxy()); |
| + } |
| + |
| + void SetupWifiWithPattern() { |
| + profile_test_->AddProfile(kUserProfilePath, kUserHash); |
| + |
| + const bool add_to_visible = true; |
| + const bool add_to_watchlist = true; |
| + service_test_->AddService(kWifiStub, |
| + kWifiSSID, |
| + flimflam::kTypeWifi, |
| + flimflam::kStateOnline, |
| + add_to_visible, |
| + add_to_watchlist); |
| + service_test_->SetServiceProperty(kWifiStub, |
| + flimflam::kGuidProperty, |
| + base::StringValue(kWifiStub)); |
| + profile_test_->AddService(kUserProfilePath, kWifiStub); |
| + } |
| + |
| + void SetupPolicy() { |
| + const char* kTestPolicyTemplate = |
| + "[ { \"GUID\": \"wifi_stub\"," |
| + " \"Name\": \"wifi_stub\"," |
| + " \"Type\": \"WiFi\"," |
| + " \"WiFi\": {" |
| + " \"Security\": \"WPA-EAP\"," |
| + " \"SSID\": \"wifi_ssid\"," |
| + " \"EAP\": {" |
| + " \"Outer\": \"EAP-TLS\"," |
| + " \"ClientCertType\": \"Pattern\"," |
| + " \"ClientCertPattern\": {" |
| + " \"IssuerCAPEMs\": [ \"%s\" ]" |
| + " }" |
| + " }" |
| + " }" |
| + "} ]"; |
| + std::string policy_json = |
| + base::StringPrintf(kTestPolicyTemplate, test_ca_cert_pem_.c_str()); |
| + |
| + std::string error; |
| + scoped_ptr<base::Value> policy_value(base::JSONReader::ReadAndReturnError( |
| + policy_json, base::JSON_ALLOW_TRAILING_COMMAS, NULL, &error)); |
| + ASSERT_TRUE(policy_value) << error; |
| + |
| + base::ListValue* policy = NULL; |
| + ASSERT_TRUE(policy_value->GetAsList(&policy) && policy); |
|
stevenjb
2013/08/10 00:11:58
nit: && policy redundant; GetAsList only returns t
pneubeck (no reviews)
2013/08/11 18:37:02
Done.
|
| + |
| + managed_config_handler_->SetPolicy( |
| + onc::ONC_SOURCE_USER_POLICY, kUserHash, *policy); |
| + } |
| + |
| + void GetClientCertProperties(std::string* pkcs11_id) { |
| + pkcs11_id->clear(); |
| + const base::DictionaryValue* properties = |
| + service_test_->GetServiceProperties(kWifiStub); |
| + properties->GetStringWithoutPathExpansion(flimflam::kEapCertIdProperty, |
| + pkcs11_id); |
| + } |
| + |
| + ShillServiceClient::TestInterface* service_test_; |
| + ShillProfileClient::TestInterface* profile_test_; |
| + std::string test_pkcs11_id_; |
| + scoped_refptr<net::X509Certificate> test_ca_cert_; |
| + std::string test_ca_cert_pem_; |
| + base::MessageLoop message_loop_; |
| + |
| + private: |
| + void CleanupSlotContents() { |
| + CERTCertList* cert_list = PK11_ListCertsInSlot(slot_->os_module_handle()); |
| + for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); |
| + !CERT_LIST_END(node, cert_list); |
| + node = CERT_LIST_NEXT(node)) { |
| + scoped_refptr<net::X509Certificate> cert( |
| + net::X509Certificate::CreateFromHandle( |
| + node->cert, net::X509Certificate::OSCertHandles())); |
| + net::NSSCertDatabase::GetInstance()->DeleteCertAndKey(cert.get()); |
| + } |
| + CERT_DestroyCertList(cert_list); |
| + } |
| + |
| + scoped_ptr<NetworkStateHandler> network_state_handler_; |
| + scoped_ptr<NetworkProfileHandler> network_profile_handler_; |
| + scoped_ptr<NetworkConfigurationHandler> network_config_handler_; |
| + scoped_ptr<ManagedNetworkConfigurationHandler> |
| + managed_config_handler_; |
| + scoped_ptr<ClientCertResolver> client_cert_resolver_; |
| + scoped_refptr<net::CryptoModule> slot_; |
| + crypto::ScopedTestNSSDB test_nssdb_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(ClientCertResolverTest); |
| +}; |
| + |
| +TEST_F(ClientCertResolverTest, ResolveOnInitialization) { |
| + // Add a new network for migration before the handlers are initialized. |
| + SetupTestCerts(); |
| + SetupNetworkHandlers(); |
| + SetupPolicy(); |
| + |
| + message_loop_.RunUntilIdle(); |
| + |
| + SetupWifiWithPattern(); |
| + message_loop_.RunUntilIdle(); |
| + |
| + std::string pkcs11_id; |
| + GetClientCertProperties(&pkcs11_id); |
| + EXPECT_EQ(test_pkcs11_id_, pkcs11_id); |
| +} |
| + |
| +} // namespace chromeos |