Commit 1531adb9 authored by pneubeck@chromium.org's avatar pneubeck@chromium.org

Cleanup safe mode tests.

- Adds a positive test, where the owner logs-in while in safe mode.
- Fixes the test, where a non-owner tries to login: It failed because the MockOwnerKeyUtil had no key set. Now it fails because the private key cannot be found.
- Removes the ScopedTestNSSDB usage.
- Speeds up the test by factor 10, because of the removed NSS initialization in the test fixture.

BUG=210525

Review URL: https://codereview.chromium.org/398363002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284106 0039d316-1c4b-4281-b951-d872f2087c98
parent 6ec23f84
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "chromeos/login/auth/user_context.h" #include "chromeos/login/auth/user_context.h"
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "crypto/nss_util.h" #include "crypto/nss_util.h"
#include "crypto/nss_util_internal.h"
#include "google_apis/gaia/mock_url_fetcher_factory.h" #include "google_apis/gaia/mock_url_fetcher_factory.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/url_request/url_request_status.h" #include "net/url_request/url_request_status.h"
...@@ -52,6 +53,67 @@ using ::testing::_; ...@@ -52,6 +53,67 @@ using ::testing::_;
namespace chromeos { namespace chromeos {
namespace {
// An owner key in PKCS#8 PrivateKeyInfo for testing owner checks.
const uint8 kOwnerPrivateKey[] = {
0x30, 0x82, 0x01, 0x53, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
0x01, 0x3d, 0x30, 0x82, 0x01, 0x39, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
0xb4, 0xf5, 0xab, 0xfe, 0xd8, 0xf1, 0xcb, 0x5f, 0x8f, 0x48, 0x3e, 0xdf,
0x40, 0x8e, 0x2b, 0x15, 0x43, 0x6c, 0x67, 0x74, 0xa2, 0xcb, 0xe4, 0xf3,
0xec, 0xab, 0x41, 0x57, 0x1d, 0x5f, 0xed, 0xcf, 0x09, 0xf4, 0xcc, 0xbb,
0x52, 0x52, 0xe8, 0x46, 0xf5, 0xc5, 0x01, 0xa3, 0xd8, 0x24, 0xc0, 0x15,
0xc5, 0x65, 0x50, 0x7d, 0xbd, 0x4e, 0x81, 0xb2, 0x28, 0x38, 0xf9, 0x3d,
0x3e, 0x2a, 0x68, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x40, 0x40,
0xc7, 0xb5, 0xb3, 0xbc, 0xac, 0x0a, 0x77, 0x02, 0x0f, 0x05, 0xda, 0xdb,
0xfc, 0x48, 0xf6, 0x0a, 0xb5, 0xf2, 0xef, 0x31, 0x1c, 0x36, 0xb1, 0x0f,
0xa7, 0x5a, 0xf3, 0xb9, 0xa3, 0x4e, 0xb8, 0xf6, 0x10, 0xfe, 0x25, 0x7b,
0x36, 0xb4, 0x1b, 0x80, 0xe3, 0x92, 0x37, 0x83, 0xf0, 0x43, 0xb3, 0x00,
0xa6, 0x53, 0xc6, 0x1b, 0x7e, 0x4b, 0xb0, 0x33, 0xd4, 0xe1, 0x03, 0xc4,
0xaa, 0xbc, 0x89, 0x02, 0x21, 0x00, 0xde, 0xc8, 0x8d, 0x10, 0xbc, 0xf3,
0x43, 0x49, 0x1f, 0x07, 0xf7, 0x12, 0xeb, 0x0a, 0x90, 0xab, 0xb9, 0xaa,
0x81, 0xb5, 0x54, 0x71, 0xf4, 0x2e, 0xc4, 0x44, 0xec, 0xff, 0x7d, 0xff,
0xe8, 0xa5, 0x02, 0x21, 0x00, 0xcf, 0xf0, 0xbe, 0xa6, 0xde, 0x9c, 0x70,
0xed, 0xf0, 0xc3, 0x18, 0x9b, 0xca, 0xe5, 0x7c, 0x4b, 0x9b, 0xf5, 0x12,
0x5d, 0x86, 0xbe, 0x8d, 0xf1, 0xbc, 0x2c, 0x79, 0x59, 0xf5, 0xff, 0xbc,
0x6b, 0x02, 0x20, 0x7c, 0x09, 0x1c, 0xc1, 0x1c, 0xf2, 0x33, 0x9c, 0x1a,
0x72, 0xcc, 0xd4, 0xf3, 0x97, 0xc6, 0x44, 0x55, 0xf2, 0xe0, 0x94, 0x9c,
0x97, 0x75, 0x64, 0x34, 0x52, 0x4b, 0xc1, 0x53, 0xdd, 0x8f, 0x21, 0x02,
0x20, 0x0e, 0xef, 0x48, 0x92, 0x2d, 0x9c, 0xe8, 0xd3, 0x7e, 0x1e, 0x55,
0x0f, 0x23, 0x74, 0x76, 0x07, 0xec, 0x2c, 0x9e, 0xe4, 0x0e, 0xc0, 0x72,
0xeb, 0x70, 0xcb, 0x74, 0xef, 0xcc, 0x26, 0x50, 0xff, 0x02, 0x20, 0x29,
0x32, 0xd0, 0xbf, 0x11, 0xf2, 0xbf, 0x54, 0xfd, 0x6d, 0xf2, 0x1c, 0xbe,
0x50, 0x18, 0x62, 0x6d, 0x23, 0xe4, 0x26, 0x03, 0x8b, 0xb3, 0x42, 0x24,
0x7e, 0x68, 0x37, 0x26, 0xda, 0xb9, 0x87
};
// The public key alone matcing kOwnerPrivateKey.
const uint8 kOwnerPublicKey[] = {
0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
0x00, 0xb4, 0xf5, 0xab, 0xfe, 0xd8, 0xf1, 0xcb, 0x5f, 0x8f, 0x48, 0x3e,
0xdf, 0x40, 0x8e, 0x2b, 0x15, 0x43, 0x6c, 0x67, 0x74, 0xa2, 0xcb, 0xe4,
0xf3, 0xec, 0xab, 0x41, 0x57, 0x1d, 0x5f, 0xed, 0xcf, 0x09, 0xf4, 0xcc,
0xbb, 0x52, 0x52, 0xe8, 0x46, 0xf5, 0xc5, 0x01, 0xa3, 0xd8, 0x24, 0xc0,
0x15, 0xc5, 0x65, 0x50, 0x7d, 0xbd, 0x4e, 0x81, 0xb2, 0x28, 0x38, 0xf9,
0x3d, 0x3e, 0x2a, 0x68, 0xf7, 0x02, 0x03, 0x01, 0x00, 0x01
};
std::vector<uint8> GetOwnerPublicKey() {
return std::vector<uint8>(kOwnerPublicKey,
kOwnerPublicKey + arraysize(kOwnerPublicKey));
}
scoped_ptr<crypto::RSAPrivateKey> CreateOwnerKeyInSlot(PK11SlotInfo* slot) {
const std::vector<uint8> key(kOwnerPrivateKey,
kOwnerPrivateKey + arraysize(kOwnerPrivateKey));
return make_scoped_ptr(
crypto::RSAPrivateKey::CreateSensitiveFromPrivateKeyInfo(slot, key));
}
} // namespace
class ParallelAuthenticatorTest : public testing::Test { class ParallelAuthenticatorTest : public testing::Test {
public: public:
ParallelAuthenticatorTest() ParallelAuthenticatorTest()
...@@ -207,7 +269,6 @@ class ParallelAuthenticatorTest : public testing::Test { ...@@ -207,7 +269,6 @@ class ParallelAuthenticatorTest : public testing::Test {
cryptohome::MockAsyncMethodCaller* mock_caller_; cryptohome::MockAsyncMethodCaller* mock_caller_;
MockAuthStatusConsumer consumer_; MockAuthStatusConsumer consumer_;
crypto::ScopedTestNSSDB test_nssdb_;
scoped_refptr<ParallelAuthenticator> auth_; scoped_refptr<ParallelAuthenticator> auth_;
scoped_ptr<TestAttemptState> state_; scoped_ptr<TestAttemptState> state_;
...@@ -280,14 +341,17 @@ TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededMount) { ...@@ -280,14 +341,17 @@ TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededMount) {
// the mount finish successfully. // the mount finish successfully.
state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE); state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
SetOwnerState(false, false); SetOwnerState(false, false);
// Test that the mount has succeeded.
state_.reset(new TestAttemptState(user_context_, false));
state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
EXPECT_EQ(ParallelAuthenticator::OFFLINE_LOGIN, EXPECT_EQ(ParallelAuthenticator::OFFLINE_LOGIN,
SetAndResolveState(auth_.get(), state_.release())); SetAndResolveState(auth_.get(), state_.release()));
} }
// Test the case that login switches to SafeMode and a User that is not the
// owner tries to log in. The login should fail because of the missing owner
// private key.
TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededFailedMount) { TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededFailedMount) {
crypto::ScopedTestNSSChromeOSUser user_slot(user_context_.GetUserIDHash());
owner_key_util_->SetPublicKey(GetOwnerPublicKey());
profile_manager_.reset( profile_manager_.reset(
new TestingProfileManager(TestingBrowserProcess::GetGlobal())); new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
ASSERT_TRUE(profile_manager_->SetUp()); ASSERT_TRUE(profile_manager_->SetUp());
...@@ -296,20 +360,17 @@ TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededFailedMount) { ...@@ -296,20 +360,17 @@ TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededFailedMount) {
AuthFailure failure = AuthFailure(AuthFailure::OWNER_REQUIRED); AuthFailure failure = AuthFailure(AuthFailure::OWNER_REQUIRED);
ExpectLoginFailure(failure); ExpectLoginFailure(failure);
fake_cryptohome_client_->set_unmount_result(true);
CrosSettingsProvider* device_settings_provider;
StubCrosSettingsProvider stub_settings_provider;
// Set up state as though a cryptohome mount attempt has occurred // Set up state as though a cryptohome mount attempt has occurred
// and succeeded but we are in safe mode and the current user is not owner. // and succeeded but we are in safe mode and the current user is not owner.
state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE); state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
SetOwnerState(false, false); SetOwnerState(false, false);
// Remove the real DeviceSettingsProvider and replace it with a stub. // Remove the real DeviceSettingsProvider and replace it with a stub.
device_settings_provider = CrosSettingsProvider* device_settings_provider =
CrosSettings::Get()->GetProvider(chromeos::kReportDeviceVersionInfo); CrosSettings::Get()->GetProvider(chromeos::kReportDeviceVersionInfo);
EXPECT_TRUE(device_settings_provider != NULL); EXPECT_TRUE(device_settings_provider != NULL);
EXPECT_TRUE( EXPECT_TRUE(
CrosSettings::Get()->RemoveSettingsProvider(device_settings_provider)); CrosSettings::Get()->RemoveSettingsProvider(device_settings_provider));
StubCrosSettingsProvider stub_settings_provider;
CrosSettings::Get()->AddSettingsProvider(&stub_settings_provider); CrosSettings::Get()->AddSettingsProvider(&stub_settings_provider);
CrosSettings::Get()->SetBoolean(kPolicyMissingMitigationMode, true); CrosSettings::Get()->SetBoolean(kPolicyMissingMitigationMode, true);
...@@ -335,6 +396,65 @@ TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededFailedMount) { ...@@ -335,6 +396,65 @@ TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededFailedMount) {
EXPECT_TRUE(LoginState::Get()->IsInSafeMode()); EXPECT_TRUE(LoginState::Get()->IsInSafeMode());
// Unset global objects used by this test. // Unset global objects used by this test.
fake_cryptohome_client_->set_unmount_result(true);
LoginState::Shutdown();
EXPECT_TRUE(
CrosSettings::Get()->RemoveSettingsProvider(&stub_settings_provider));
CrosSettings::Get()->AddSettingsProvider(device_settings_provider);
}
// Test the case that login switches to SafeMode and the Owner logs in, which
// should lead to a successful login.
TEST_F(ParallelAuthenticatorTest, ResolveOwnerNeededSuccess) {
crypto::ScopedTestNSSChromeOSUser test_user_db(user_context_.GetUserIDHash());
owner_key_util_->SetPublicKey(GetOwnerPublicKey());
crypto::ScopedPK11Slot user_slot(
crypto::GetPublicSlotForChromeOSUser(user_context_.GetUserIDHash()));
CreateOwnerKeyInSlot(user_slot.get());
profile_manager_.reset(
new TestingProfileManager(TestingBrowserProcess::GetGlobal()));
ASSERT_TRUE(profile_manager_->SetUp());
ExpectLoginSuccess(user_context_);
// Set up state as though a cryptohome mount attempt has occurred
// and succeeded but we are in safe mode and the current user is not owner.
state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
SetOwnerState(false, false);
// Remove the real DeviceSettingsProvider and replace it with a stub.
CrosSettingsProvider* device_settings_provider =
CrosSettings::Get()->GetProvider(chromeos::kReportDeviceVersionInfo);
EXPECT_TRUE(device_settings_provider != NULL);
EXPECT_TRUE(
CrosSettings::Get()->RemoveSettingsProvider(device_settings_provider));
StubCrosSettingsProvider stub_settings_provider;
CrosSettings::Get()->AddSettingsProvider(&stub_settings_provider);
CrosSettings::Get()->SetBoolean(kPolicyMissingMitigationMode, true);
// Initialize login state for this test to verify the login state is changed
// to SAFE_MODE.
LoginState::Initialize();
EXPECT_EQ(ParallelAuthenticator::CONTINUE,
SetAndResolveState(auth_.get(), state_.release()));
EXPECT_TRUE(LoginState::Get()->IsInSafeMode());
// Flush all the pending operations. The operations should induce an owner
// verification.
device_settings_test_helper_.Flush();
state_.reset(new TestAttemptState(user_context_, false));
state_->PresetCryptohomeStatus(true, cryptohome::MOUNT_ERROR_NONE);
// The owner key util should find the owner key, so login should succeed.
EXPECT_EQ(ParallelAuthenticator::OFFLINE_LOGIN,
SetAndResolveState(auth_.get(), state_.release()));
EXPECT_TRUE(LoginState::Get()->IsInSafeMode());
// Unset global objects used by this test.
fake_cryptohome_client_->set_unmount_result(true);
LoginState::Shutdown(); LoginState::Shutdown();
EXPECT_TRUE( EXPECT_TRUE(
CrosSettings::Get()->RemoveSettingsProvider(&stub_settings_provider)); CrosSettings::Get()->RemoveSettingsProvider(&stub_settings_provider));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment