#include "chromeos/network/network_connection_handler.h"
#include "base/bind.h"
+#include "base/callback.h"
+#include "base/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
+#include "chromeos/cert_loader.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/shill_manager_client.h"
#include "chromeos/dbus/shill_service_client.h"
#include "chromeos/network/network_configuration_handler.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/onc/onc_utils.h"
+#include "chromeos/tpm_token_loader.h"
+#include "crypto/nss_util.h"
+#include "crypto/nss_util_internal.h"
+#include "net/base/net_errors.h"
+#include "net/base/test_data_directory.h"
+#include "net/cert/nss_cert_database_chromeos.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"
class NetworkConnectionHandlerTest : public testing::Test {
public:
- NetworkConnectionHandlerTest() {
+ NetworkConnectionHandlerTest() : user_("userhash") {
}
virtual ~NetworkConnectionHandlerTest() {
}
virtual void SetUp() OVERRIDE {
+ ASSERT_TRUE(user_.constructed_successfully());
+ user_.FinishInit();
+
+ test_nssdb_.reset(new net::NSSCertDatabaseChromeOS(
+ crypto::GetPublicSlotForChromeOSUser(user_.username_hash()),
+ crypto::GetPrivateSlotForChromeOSUser(
+ user_.username_hash(),
+ base::Callback<void(crypto::ScopedPK11Slot)>())));
+ test_nssdb_->SetSlowTaskRunnerForTest(message_loop_.message_loop_proxy());
+
+ TPMTokenLoader::InitializeForTest();
+
+ CertLoader::Initialize();
+ CertLoader* cert_loader = CertLoader::Get();
+ cert_loader->force_hardware_backed_for_test();
+
// Initialize DBusThreadManager with a stub implementation.
DBusThreadManager::InitializeWithStub();
- message_loop_.RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
->ClearServices();
- message_loop_.RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
LoginState::Initialize();
network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
network_configuration_handler_.reset(
NetworkConfigurationHandler::InitializeForTest(
network_state_handler_.get()));
+
network_connection_handler_.reset(new NetworkConnectionHandler);
- // TODO(stevenjb): Test integration with CertLoader using a stub or mock.
network_connection_handler_->Init(network_state_handler_.get(),
network_configuration_handler_.get());
}
network_connection_handler_.reset();
network_configuration_handler_.reset();
network_state_handler_.reset();
+ CertLoader::Shutdown();
+ TPMTokenLoader::Shutdown();
LoginState::Shutdown();
DBusThreadManager::Shutdown();
}
*json_dict,
base::Bind(&ConfigureCallback),
base::Bind(&ConfigureErrorCallback));
- message_loop_.RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
return true;
}
base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
base::Unretained(this)),
check_error_state);
- message_loop_.RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
}
void Disconnect(const std::string& service_path) {
base::Unretained(this)),
base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
base::Unretained(this)));
- message_loop_.RunUntilIdle();
+ base::RunLoop().RunUntilIdle();
}
void SuccessCallback() {
return result;
}
+ void StartCertLoader() {
+ CertLoader::Get()->StartWithNSSDB(test_nssdb_.get());
+ base::RunLoop().RunUntilIdle();
+ }
+
+ void ImportClientCertAndKey(const std::string& pkcs12_file,
+ net::NSSCertDatabase* nssdb,
+ net::CertificateList* loaded_certs) {
+ std::string pkcs12_data;
+ base::FilePath pkcs12_path =
+ net::GetTestCertsDirectory().Append(pkcs12_file);
+ ASSERT_TRUE(base::ReadFileToString(pkcs12_path, &pkcs12_data));
+
+ scoped_refptr<net::CryptoModule> module(
+ net::CryptoModule::CreateFromHandle(nssdb->GetPrivateSlot().get()));
+ ASSERT_EQ(
+ net::OK,
+ nssdb->ImportFromPKCS12(module, pkcs12_data, base::string16(), false,
+ loaded_certs));
+ ASSERT_EQ(1U, loaded_certs->size());
+ }
+
scoped_ptr<NetworkStateHandler> network_state_handler_;
scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_;
scoped_ptr<NetworkConnectionHandler> network_connection_handler_;
+ crypto::ScopedTestNSSChromeOSUser user_;
+ scoped_ptr<net::NSSCertDatabaseChromeOS> test_nssdb_;
base::MessageLoopForUI message_loop_;
std::string result_;
namespace {
-const char* kConfigRequiresCertificate =
+const char* kConfigRequiresCertificateTemplate =
"{ \"GUID\": \"wifi4\", \"Type\": \"wifi\", \"Connectable\": false,"
" \"Security\": \"802_1x\","
" \"UIData\": \"{"
" \\\"certificate_type\\\": \\\"pattern\\\","
" \\\"certificate_pattern\\\": {"
- " \\\"Subject\\\": { \\\"CommonName\\\": \\\"Foo\\\" }"
+ " \\\"Subject\\\": {\\\"CommonName\\\": \\\"%s\\\" }"
" } }\" }";
} // namespace
-// Handle certificates. TODO(stevenjb): Add certificate stubs to improve
-// test coverage.
-TEST_F(NetworkConnectionHandlerTest,
- NetworkConnectionHandlerConnectCertificate) {
- EXPECT_TRUE(Configure(kConfigRequiresCertificate));
+// Handle certificates.
+TEST_F(NetworkConnectionHandlerTest, ConnectCertificateMissing) {
+ StartCertLoader();
+
+ EXPECT_TRUE(Configure(
+ base::StringPrintf(kConfigRequiresCertificateTemplate, "unknown")));
Connect("wifi4");
EXPECT_EQ(NetworkConnectionHandler::kErrorCertificateRequired,
GetResultAndReset());
}
+TEST_F(NetworkConnectionHandlerTest, ConnectWithCertificateSuccess) {
+ StartCertLoader();
+
+ net::CertificateList certs;
+ ImportClientCertAndKey("websocket_client_cert.p12",
+ test_nssdb_.get(),
+ &certs);
+
+ EXPECT_TRUE(Configure(
+ base::StringPrintf(kConfigRequiresCertificateTemplate,
+ certs[0]->subject().common_name.c_str())));
+
+ Connect("wifi4");
+ EXPECT_EQ(kSuccessResult, GetResultAndReset());
+}
+
+TEST_F(NetworkConnectionHandlerTest,
+ ConnectWithCertificateRequestedBeforeCertsAreLoaded) {
+ net::CertificateList certs;
+ ImportClientCertAndKey("websocket_client_cert.p12",
+ test_nssdb_.get(),
+ &certs);
+
+ EXPECT_TRUE(Configure(
+ base::StringPrintf(kConfigRequiresCertificateTemplate,
+ certs[0]->subject().common_name.c_str())));
+
+ Connect("wifi4");
+
+ // Connect request came before the cert loader loaded certificates, so the
+ // connect request should have been throttled until the certificates are
+ // loaded.
+ EXPECT_EQ("", GetResultAndReset());
+
+ StartCertLoader();
+
+ // |StartCertLoader| should have triggered certificate loading.
+ // When the certificates got loaded, the connection request should have
+ // proceeded and eventually succeeded.
+ EXPECT_EQ(kSuccessResult, GetResultAndReset());
+}
+
TEST_F(NetworkConnectionHandlerTest,
NetworkConnectionHandlerDisconnectSuccess) {
EXPECT_TRUE(Configure(kConfigConnected));