| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.h" | 5 #include "chrome/browser/chromeos/login/auth/chrome_cryptohome_authenticator.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 kOwnerPrivateKey + arraysize(kOwnerPrivateKey)); | 124 kOwnerPrivateKey + arraysize(kOwnerPrivateKey)); |
| 125 return crypto::ImportNSSKeyFromPrivateKeyInfo(slot, key, | 125 return crypto::ImportNSSKeyFromPrivateKeyInfo(slot, key, |
| 126 true /* permanent */); | 126 true /* permanent */); |
| 127 } | 127 } |
| 128 | 128 |
| 129 } // namespace | 129 } // namespace |
| 130 | 130 |
| 131 class CryptohomeAuthenticatorTest : public testing::Test { | 131 class CryptohomeAuthenticatorTest : public testing::Test { |
| 132 public: | 132 public: |
| 133 CryptohomeAuthenticatorTest() | 133 CryptohomeAuthenticatorTest() |
| 134 : user_context_(AccountId::FromUserEmail("me@nowhere.org")), | 134 : user_context_("me@nowhere.org"), |
| 135 user_manager_(new user_manager::FakeUserManager()), | 135 user_manager_(new user_manager::FakeUserManager()), |
| 136 user_manager_enabler_(user_manager_), | 136 user_manager_enabler_(user_manager_), |
| 137 mock_caller_(NULL), | 137 mock_caller_(NULL), |
| 138 mock_homedir_methods_(NULL), | 138 mock_homedir_methods_(NULL), |
| 139 owner_key_util_(new ownership::MockOwnerKeyUtil()) { | 139 owner_key_util_(new ownership::MockOwnerKeyUtil()) { |
| 140 OwnerSettingsServiceChromeOSFactory::GetInstance() | 140 OwnerSettingsServiceChromeOSFactory::GetInstance() |
| 141 ->SetOwnerKeyUtilForTesting(owner_key_util_); | 141 ->SetOwnerKeyUtilForTesting(owner_key_util_); |
| 142 user_context_.SetKey(Key("fakepass")); | 142 user_context_.SetKey(Key("fakepass")); |
| 143 user_context_.SetUserIDHash("me_nowhere_com_hash"); | 143 user_context_.SetUserIDHash("me_nowhere_com_hash"); |
| 144 const user_manager::User* user = | 144 const user_manager::User* user = |
| 145 user_manager_->AddUser(user_context_.GetAccountId()); | 145 user_manager_->AddUser(user_context_.GetUserID()); |
| 146 profile_.set_profile_name(user_context_.GetAccountId().GetUserEmail()); | 146 profile_.set_profile_name(user_context_.GetUserID()); |
| 147 | 147 |
| 148 ProfileHelper::Get()->SetUserToProfileMappingForTesting(user, &profile_); | 148 ProfileHelper::Get()->SetUserToProfileMappingForTesting(user, &profile_); |
| 149 | 149 |
| 150 CreateTransformedKey(Key::KEY_TYPE_SALTED_SHA256_TOP_HALF, | 150 CreateTransformedKey(Key::KEY_TYPE_SALTED_SHA256_TOP_HALF, |
| 151 SystemSaltGetter::ConvertRawSaltToHexString( | 151 SystemSaltGetter::ConvertRawSaltToHexString( |
| 152 FakeCryptohomeClient::GetStubSystemSalt())); | 152 FakeCryptohomeClient::GetStubSystemSalt())); |
| 153 } | 153 } |
| 154 | 154 |
| 155 ~CryptohomeAuthenticatorTest() override {} | 155 ~CryptohomeAuthenticatorTest() override {} |
| 156 | 156 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 if (key_type) { | 257 if (key_type) { |
| 258 key_definition.provider_data.push_back( | 258 key_definition.provider_data.push_back( |
| 259 cryptohome::KeyDefinition::ProviderData("type")); | 259 cryptohome::KeyDefinition::ProviderData("type")); |
| 260 key_definition.provider_data.back().number = key_type.Pass(); | 260 key_definition.provider_data.back().number = key_type.Pass(); |
| 261 } | 261 } |
| 262 if (salt) { | 262 if (salt) { |
| 263 key_definition.provider_data.push_back( | 263 key_definition.provider_data.push_back( |
| 264 cryptohome::KeyDefinition::ProviderData("salt")); | 264 cryptohome::KeyDefinition::ProviderData("salt")); |
| 265 key_definition.provider_data.back().bytes = salt.Pass(); | 265 key_definition.provider_data.back().bytes = salt.Pass(); |
| 266 } | 266 } |
| 267 EXPECT_CALL(*mock_homedir_methods_, | 267 EXPECT_CALL(*mock_homedir_methods_, GetKeyDataEx( |
| 268 GetKeyDataEx(cryptohome::Identification( | 268 cryptohome::Identification(user_context_.GetUserID()), |
| 269 user_context_.GetAccountId().GetUserEmail()), | 269 kCryptohomeGAIAKeyLabel, |
| 270 kCryptohomeGAIAKeyLabel, _)) | 270 _)) |
| 271 .WillOnce(WithArg<2>(Invoke( | 271 .WillOnce(WithArg<2>(Invoke( |
| 272 this, &CryptohomeAuthenticatorTest::InvokeGetDataExCallback))); | 272 this, |
| 273 &CryptohomeAuthenticatorTest::InvokeGetDataExCallback))); |
| 273 } | 274 } |
| 274 | 275 |
| 275 void ExpectMountExCall(bool expect_create_attempt) { | 276 void ExpectMountExCall(bool expect_create_attempt) { |
| 276 const cryptohome::KeyDefinition auth_key(transformed_key_.GetSecret(), | 277 const cryptohome::KeyDefinition auth_key(transformed_key_.GetSecret(), |
| 277 std::string(), | 278 std::string(), |
| 278 cryptohome::PRIV_DEFAULT); | 279 cryptohome::PRIV_DEFAULT); |
| 279 cryptohome::MountParameters mount(false /* ephemeral */); | 280 cryptohome::MountParameters mount(false /* ephemeral */); |
| 280 if (expect_create_attempt) { | 281 if (expect_create_attempt) { |
| 281 mount.create_keys.push_back(cryptohome::KeyDefinition( | 282 mount.create_keys.push_back(cryptohome::KeyDefinition( |
| 282 transformed_key_.GetSecret(), | 283 transformed_key_.GetSecret(), |
| 283 kCryptohomeGAIAKeyLabel, | 284 kCryptohomeGAIAKeyLabel, |
| 284 cryptohome::PRIV_DEFAULT)); | 285 cryptohome::PRIV_DEFAULT)); |
| 285 } | 286 } |
| 286 EXPECT_CALL(*mock_homedir_methods_, | 287 EXPECT_CALL(*mock_homedir_methods_, |
| 287 MountEx(cryptohome::Identification( | 288 MountEx(cryptohome::Identification(user_context_.GetUserID()), |
| 288 user_context_.GetAccountId().GetUserEmail()), | 289 cryptohome::Authorization(auth_key), |
| 289 cryptohome::Authorization(auth_key), mount, _)) | 290 mount, |
| 291 _)) |
| 290 .Times(1) | 292 .Times(1) |
| 291 .RetiresOnSaturation(); | 293 .RetiresOnSaturation(); |
| 292 } | 294 } |
| 293 | 295 |
| 294 void RunResolve(CryptohomeAuthenticator* auth) { | 296 void RunResolve(CryptohomeAuthenticator* auth) { |
| 295 auth->Resolve(); | 297 auth->Resolve(); |
| 296 base::MessageLoop::current()->RunUntilIdle(); | 298 base::MessageLoop::current()->RunUntilIdle(); |
| 297 } | 299 } |
| 298 | 300 |
| 299 void SetAttemptState(CryptohomeAuthenticator* auth, TestAttemptState* state) { | 301 void SetAttemptState(CryptohomeAuthenticator* auth, TestAttemptState* state) { |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 TEST_F(CryptohomeAuthenticatorTest, DriveDataResync) { | 555 TEST_F(CryptohomeAuthenticatorTest, DriveDataResync) { |
| 554 UserContext expected_user_context(user_context_with_transformed_key_); | 556 UserContext expected_user_context(user_context_with_transformed_key_); |
| 555 expected_user_context.SetUserIDHash( | 557 expected_user_context.SetUserIDHash( |
| 556 cryptohome::MockAsyncMethodCaller::kFakeSanitizedUsername); | 558 cryptohome::MockAsyncMethodCaller::kFakeSanitizedUsername); |
| 557 ExpectLoginSuccess(expected_user_context); | 559 ExpectLoginSuccess(expected_user_context); |
| 558 FailOnLoginFailure(); | 560 FailOnLoginFailure(); |
| 559 | 561 |
| 560 // Set up mock async method caller to respond successfully to a cryptohome | 562 // Set up mock async method caller to respond successfully to a cryptohome |
| 561 // remove attempt. | 563 // remove attempt. |
| 562 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE); | 564 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE); |
| 563 EXPECT_CALL(*mock_caller_, | 565 EXPECT_CALL(*mock_caller_, AsyncRemove(user_context_.GetUserID(), _)) |
| 564 AsyncRemove(user_context_.GetAccountId().GetUserEmail(), _)) | |
| 565 .Times(1) | 566 .Times(1) |
| 566 .RetiresOnSaturation(); | 567 .RetiresOnSaturation(); |
| 567 | 568 |
| 568 // Set up mock homedir methods to respond successfully to a cryptohome create | 569 // Set up mock homedir methods to respond successfully to a cryptohome create |
| 569 // attempt. | 570 // attempt. |
| 570 ExpectGetKeyDataExCall(scoped_ptr<int64>(), scoped_ptr<std::string>()); | 571 ExpectGetKeyDataExCall(scoped_ptr<int64>(), scoped_ptr<std::string>()); |
| 571 ExpectMountExCall(true /* expect_create_attempt */); | 572 ExpectMountExCall(true /* expect_create_attempt */); |
| 572 | 573 |
| 573 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone()); | 574 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone()); |
| 574 SetAttemptState(auth_.get(), state_.release()); | 575 SetAttemptState(auth_.get(), state_.release()); |
| 575 | 576 |
| 576 auth_->ResyncEncryptedData(); | 577 auth_->ResyncEncryptedData(); |
| 577 base::MessageLoop::current()->Run(); | 578 base::MessageLoop::current()->Run(); |
| 578 } | 579 } |
| 579 | 580 |
| 580 TEST_F(CryptohomeAuthenticatorTest, DriveResyncFail) { | 581 TEST_F(CryptohomeAuthenticatorTest, DriveResyncFail) { |
| 581 FailOnLoginSuccess(); | 582 FailOnLoginSuccess(); |
| 582 ExpectLoginFailure(AuthFailure(AuthFailure::DATA_REMOVAL_FAILED)); | 583 ExpectLoginFailure(AuthFailure(AuthFailure::DATA_REMOVAL_FAILED)); |
| 583 | 584 |
| 584 // Set up mock async method caller to fail a cryptohome remove attempt. | 585 // Set up mock async method caller to fail a cryptohome remove attempt. |
| 585 mock_caller_->SetUp(false, cryptohome::MOUNT_ERROR_NONE); | 586 mock_caller_->SetUp(false, cryptohome::MOUNT_ERROR_NONE); |
| 586 EXPECT_CALL(*mock_caller_, | 587 EXPECT_CALL(*mock_caller_, AsyncRemove(user_context_.GetUserID(), _)) |
| 587 AsyncRemove(user_context_.GetAccountId().GetUserEmail(), _)) | |
| 588 .Times(1) | 588 .Times(1) |
| 589 .RetiresOnSaturation(); | 589 .RetiresOnSaturation(); |
| 590 | 590 |
| 591 SetAttemptState(auth_.get(), state_.release()); | 591 SetAttemptState(auth_.get(), state_.release()); |
| 592 | 592 |
| 593 auth_->ResyncEncryptedData(); | 593 auth_->ResyncEncryptedData(); |
| 594 base::MessageLoop::current()->Run(); | 594 base::MessageLoop::current()->Run(); |
| 595 } | 595 } |
| 596 | 596 |
| 597 TEST_F(CryptohomeAuthenticatorTest, DriveRequestOldPassword) { | 597 TEST_F(CryptohomeAuthenticatorTest, DriveRequestOldPassword) { |
| 598 FailOnLoginSuccess(); | 598 FailOnLoginSuccess(); |
| 599 ExpectPasswordChange(); | 599 ExpectPasswordChange(); |
| 600 | 600 |
| 601 state_->PresetCryptohomeStatus(false, cryptohome::MOUNT_ERROR_KEY_FAILURE); | 601 state_->PresetCryptohomeStatus(false, cryptohome::MOUNT_ERROR_KEY_FAILURE); |
| 602 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone()); | 602 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone()); |
| 603 SetAttemptState(auth_.get(), state_.release()); | 603 SetAttemptState(auth_.get(), state_.release()); |
| 604 | 604 |
| 605 RunResolve(auth_.get()); | 605 RunResolve(auth_.get()); |
| 606 } | 606 } |
| 607 | 607 |
| 608 TEST_F(CryptohomeAuthenticatorTest, DriveDataRecover) { | 608 TEST_F(CryptohomeAuthenticatorTest, DriveDataRecover) { |
| 609 UserContext expected_user_context(user_context_with_transformed_key_); | 609 UserContext expected_user_context(user_context_with_transformed_key_); |
| 610 expected_user_context.SetUserIDHash( | 610 expected_user_context.SetUserIDHash( |
| 611 cryptohome::MockAsyncMethodCaller::kFakeSanitizedUsername); | 611 cryptohome::MockAsyncMethodCaller::kFakeSanitizedUsername); |
| 612 ExpectLoginSuccess(expected_user_context); | 612 ExpectLoginSuccess(expected_user_context); |
| 613 FailOnLoginFailure(); | 613 FailOnLoginFailure(); |
| 614 | 614 |
| 615 // Set up mock async method caller to respond successfully to a key migration. | 615 // Set up mock async method caller to respond successfully to a key migration. |
| 616 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE); | 616 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE); |
| 617 EXPECT_CALL(*mock_caller_, | 617 EXPECT_CALL( |
| 618 AsyncMigrateKey(user_context_.GetAccountId().GetUserEmail(), _, | 618 *mock_caller_, |
| 619 transformed_key_.GetSecret(), _)) | 619 AsyncMigrateKey( |
| 620 user_context_.GetUserID(), _, transformed_key_.GetSecret(), _)) |
| 620 .Times(1) | 621 .Times(1) |
| 621 .RetiresOnSaturation(); | 622 .RetiresOnSaturation(); |
| 622 | 623 |
| 623 // Set up mock homedir methods to respond successfully to a cryptohome mount | 624 // Set up mock homedir methods to respond successfully to a cryptohome mount |
| 624 // attempt. | 625 // attempt. |
| 625 ExpectGetKeyDataExCall(scoped_ptr<int64>(), scoped_ptr<std::string>()); | 626 ExpectGetKeyDataExCall(scoped_ptr<int64>(), scoped_ptr<std::string>()); |
| 626 ExpectMountExCall(false /* expect_create_attempt */); | 627 ExpectMountExCall(false /* expect_create_attempt */); |
| 627 | 628 |
| 628 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone()); | 629 state_->PresetOnlineLoginStatus(AuthFailure::AuthFailureNone()); |
| 629 SetAttemptState(auth_.get(), state_.release()); | 630 SetAttemptState(auth_.get(), state_.release()); |
| 630 | 631 |
| 631 auth_->RecoverEncryptedData(std::string()); | 632 auth_->RecoverEncryptedData(std::string()); |
| 632 base::MessageLoop::current()->Run(); | 633 base::MessageLoop::current()->Run(); |
| 633 } | 634 } |
| 634 | 635 |
| 635 TEST_F(CryptohomeAuthenticatorTest, DriveDataRecoverButFail) { | 636 TEST_F(CryptohomeAuthenticatorTest, DriveDataRecoverButFail) { |
| 636 FailOnLoginSuccess(); | 637 FailOnLoginSuccess(); |
| 637 ExpectPasswordChange(); | 638 ExpectPasswordChange(); |
| 638 | 639 |
| 639 // Set up mock async method caller to fail a key migration attempt, | 640 // Set up mock async method caller to fail a key migration attempt, |
| 640 // asserting that the wrong password was used. | 641 // asserting that the wrong password was used. |
| 641 mock_caller_->SetUp(false, cryptohome::MOUNT_ERROR_KEY_FAILURE); | 642 mock_caller_->SetUp(false, cryptohome::MOUNT_ERROR_KEY_FAILURE); |
| 642 EXPECT_CALL(*mock_caller_, | 643 EXPECT_CALL( |
| 643 AsyncMigrateKey(user_context_.GetAccountId().GetUserEmail(), _, | 644 *mock_caller_, |
| 644 transformed_key_.GetSecret(), _)) | 645 AsyncMigrateKey( |
| 646 user_context_.GetUserID(), _, transformed_key_.GetSecret(), _)) |
| 645 .Times(1) | 647 .Times(1) |
| 646 .RetiresOnSaturation(); | 648 .RetiresOnSaturation(); |
| 647 | 649 |
| 648 SetAttemptState(auth_.get(), state_.release()); | 650 SetAttemptState(auth_.get(), state_.release()); |
| 649 | 651 |
| 650 auth_->RecoverEncryptedData(std::string()); | 652 auth_->RecoverEncryptedData(std::string()); |
| 651 base::MessageLoop::current()->Run(); | 653 base::MessageLoop::current()->Run(); |
| 652 } | 654 } |
| 653 | 655 |
| 654 TEST_F(CryptohomeAuthenticatorTest, ResolveNoMountToFailedMount) { | 656 TEST_F(CryptohomeAuthenticatorTest, ResolveNoMountToFailedMount) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 RunResolve(auth_.get()); | 725 RunResolve(auth_.get()); |
| 724 } | 726 } |
| 725 | 727 |
| 726 TEST_F(CryptohomeAuthenticatorTest, DriveUnlock) { | 728 TEST_F(CryptohomeAuthenticatorTest, DriveUnlock) { |
| 727 ExpectLoginSuccess(user_context_); | 729 ExpectLoginSuccess(user_context_); |
| 728 FailOnLoginFailure(); | 730 FailOnLoginFailure(); |
| 729 | 731 |
| 730 // Set up mock async method caller to respond successfully to a cryptohome | 732 // Set up mock async method caller to respond successfully to a cryptohome |
| 731 // key-check attempt. | 733 // key-check attempt. |
| 732 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE); | 734 mock_caller_->SetUp(true, cryptohome::MOUNT_ERROR_NONE); |
| 733 EXPECT_CALL(*mock_caller_, | 735 EXPECT_CALL(*mock_caller_, AsyncCheckKey(user_context_.GetUserID(), _, _)) |
| 734 AsyncCheckKey(user_context_.GetAccountId().GetUserEmail(), _, _)) | |
| 735 .Times(1) | 736 .Times(1) |
| 736 .RetiresOnSaturation(); | 737 .RetiresOnSaturation(); |
| 737 | 738 |
| 738 auth_->AuthenticateToUnlock(user_context_); | 739 auth_->AuthenticateToUnlock(user_context_); |
| 739 base::MessageLoop::current()->Run(); | 740 base::MessageLoop::current()->Run(); |
| 740 } | 741 } |
| 741 | 742 |
| 742 TEST_F(CryptohomeAuthenticatorTest, DriveLoginWithPreHashedPassword) { | 743 TEST_F(CryptohomeAuthenticatorTest, DriveLoginWithPreHashedPassword) { |
| 743 CreateTransformedKey(Key::KEY_TYPE_SALTED_SHA256, kSalt); | 744 CreateTransformedKey(Key::KEY_TYPE_SALTED_SHA256, kSalt); |
| 744 | 745 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 772 // salt. | 773 // salt. |
| 773 ExpectGetKeyDataExCall( | 774 ExpectGetKeyDataExCall( |
| 774 make_scoped_ptr(new int64(Key::KEY_TYPE_SALTED_SHA256)), | 775 make_scoped_ptr(new int64(Key::KEY_TYPE_SALTED_SHA256)), |
| 775 scoped_ptr<std::string>()); | 776 scoped_ptr<std::string>()); |
| 776 | 777 |
| 777 auth_->AuthenticateToLogin(NULL, user_context_); | 778 auth_->AuthenticateToLogin(NULL, user_context_); |
| 778 base::RunLoop().Run(); | 779 base::RunLoop().Run(); |
| 779 } | 780 } |
| 780 | 781 |
| 781 } // namespace chromeos | 782 } // namespace chromeos |
| OLD | NEW |