Commit d93e9273 authored by Ryo Hashimoto's avatar Ryo Hashimoto Committed by Commit Bot

chromeos: Remove cryptohome::MountParameters

HomedirMethods::MountEx was converting MountParameters to MountRequest proto.
To simplify this, remove MountParameters and use MountRequest everywhere.

- Construct MountRequest directly in MountEx's caller sites.
- Rename FillKeyProtobuf() in homedir_methods.cc to
KeyDefinitionToKey(), and make it public.

BUG=741274

Change-Id: Ibb8dd4a7975f6aff87ada881938be29300e7344c
Reviewed-on: https://chromium-review.googlesource.com/567844Reviewed-by: default avatarSatoru Takabayashi <satorux@chromium.org>
Commit-Queue: Ryo Hashimoto <hashimoto@chromium.org>
Cr-Commit-Position: refs/heads/master@{#486689}
parent a872e762
......@@ -34,7 +34,6 @@
#include "chromeos/cryptohome/cryptohome_parameters.h"
#include "chromeos/cryptohome/homedir_methods.h"
#include "chromeos/cryptohome/mock_async_method_caller.h"
#include "chromeos/cryptohome/mock_homedir_methods.h"
#include "chromeos/cryptohome/system_salt_getter.h"
#include "chromeos/dbus/cros_disks_client.h"
#include "chromeos/dbus/cryptohome/rpc.pb.h"
......@@ -129,6 +128,54 @@ bool CreateOwnerKeyInSlot(PK11SlotInfo* slot) {
slot, key, true /* permanent */) != nullptr;
}
// Fake CryptohomeClient implementation for this test.
class TestCryptohomeClient : public ::chromeos::FakeCryptohomeClient {
public:
TestCryptohomeClient() = default;
~TestCryptohomeClient() override = default;
void set_expected_id(const cryptohome::Identification& id) {
expected_id_ = id;
}
void set_expected_authorization_secret(const std::string& secret) {
expected_authorization_secret_ = secret;
}
void set_is_create_attempt_expected(bool expected) {
is_create_attempt_expected_ = expected;
}
void MountEx(const cryptohome::Identification& cryptohome_id,
const cryptohome::AuthorizationRequest& auth,
const cryptohome::MountRequest& request,
const ProtobufMethodCallback& callback) override {
EXPECT_EQ(is_create_attempt_expected_, request.has_create());
if (is_create_attempt_expected_) {
EXPECT_EQ(expected_authorization_secret_,
request.create().keys(0).secret());
EXPECT_EQ(kCryptohomeGAIAKeyLabel,
request.create().keys(0).data().label());
}
EXPECT_EQ(expected_id_, cryptohome_id);
EXPECT_EQ(expected_authorization_secret_, auth.key().secret());
cryptohome::BaseReply reply;
reply.MutableExtension(cryptohome::MountReply::reply)
->set_sanitized_username(
cryptohome::MockAsyncMethodCaller::kFakeSanitizedUsername);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(callback, DBUS_METHOD_CALL_SUCCESS, true, reply));
}
private:
cryptohome::Identification expected_id_;
std::string expected_authorization_secret_;
bool is_create_attempt_expected_ = false;
DISALLOW_COPY_AND_ASSIGN(TestCryptohomeClient);
};
} // namespace
class CryptohomeAuthenticatorTest : public testing::Test {
......@@ -138,7 +185,6 @@ class CryptohomeAuthenticatorTest : public testing::Test {
user_manager_(new chromeos::FakeChromeUserManager()),
user_manager_enabler_(user_manager_),
mock_caller_(NULL),
mock_homedir_methods_(NULL),
owner_key_util_(new ownership::MockOwnerKeyUtil()) {
// Testing profile must be initialized after user_manager_ +
// user_manager_enabler_, because it will create another UserManager
......@@ -168,11 +214,9 @@ class CryptohomeAuthenticatorTest : public testing::Test {
mock_caller_ = new cryptohome::MockAsyncMethodCaller;
cryptohome::AsyncMethodCaller::InitializeForTesting(mock_caller_);
mock_homedir_methods_ = new cryptohome::MockHomedirMethods;
mock_homedir_methods_->SetUp(true, cryptohome::MOUNT_ERROR_NONE);
cryptohome::HomedirMethods::InitializeForTesting(mock_homedir_methods_);
cryptohome::HomedirMethods::Initialize();
fake_cryptohome_client_ = new FakeCryptohomeClient;
fake_cryptohome_client_ = new TestCryptohomeClient;
chromeos::DBusThreadManager::GetSetterForTesting()->SetCryptohomeClient(
std::unique_ptr<CryptohomeClient>(fake_cryptohome_client_));
......@@ -190,7 +234,6 @@ class CryptohomeAuthenticatorTest : public testing::Test {
cryptohome::AsyncMethodCaller::Shutdown();
mock_caller_ = NULL;
cryptohome::HomedirMethods::Shutdown();
mock_homedir_methods_ = NULL;
}
void CreateTransformedKey(Key::KeyType type, const std::string& salt) {
......@@ -255,12 +298,9 @@ class CryptohomeAuthenticatorTest : public testing::Test {
void ExpectGetKeyDataExCall(std::unique_ptr<int64_t> key_type,
std::unique_ptr<std::string> salt) {
key_definitions_.clear();
key_definitions_.push_back(cryptohome::KeyDefinition(
std::string() /* secret */,
kCryptohomeGAIAKeyLabel,
cryptohome::PRIV_DEFAULT));
cryptohome::KeyDefinition& key_definition = key_definitions_.back();
cryptohome::KeyDefinition key_definition(std::string() /* secret */,
kCryptohomeGAIAKeyLabel,
cryptohome::PRIV_DEFAULT);
key_definition.revision = 1;
if (key_type) {
key_definition.provider_data.push_back(
......@@ -272,31 +312,26 @@ class CryptohomeAuthenticatorTest : public testing::Test {
cryptohome::KeyDefinition::ProviderData("salt"));
key_definition.provider_data.back().bytes = std::move(salt);
}
EXPECT_CALL(
*mock_homedir_methods_,
GetKeyDataEx(cryptohome::Identification(user_context_.GetAccountId()),
kCryptohomeGAIAKeyLabel, _))
.WillOnce(WithArg<2>(Invoke(
this, &CryptohomeAuthenticatorTest::InvokeGetDataExCallback)));
// Add the key to the fake.
cryptohome::AddKeyRequest request;
KeyDefinitionToKey(key_definition, request.mutable_key());
fake_cryptohome_client_->AddKeyEx(
cryptohome::Identification(user_context_.GetAccountId()),
cryptohome::AuthorizationRequest(), request,
base::Bind(
[](DBusMethodCallStatus call_status, bool result,
const cryptohome::BaseReply& reply) { EXPECT_TRUE(result); }));
base::RunLoop().RunUntilIdle();
}
void ExpectMountExCall(bool expect_create_attempt) {
const cryptohome::KeyDefinition auth_key(transformed_key_.GetSecret(),
std::string(),
cryptohome::PRIV_DEFAULT);
cryptohome::MountParameters mount(false /* ephemeral */);
if (expect_create_attempt) {
mount.create_keys.push_back(cryptohome::KeyDefinition(
transformed_key_.GetSecret(),
kCryptohomeGAIAKeyLabel,
cryptohome::PRIV_DEFAULT));
}
EXPECT_CALL(
*mock_homedir_methods_,
MountEx(cryptohome::Identification(user_context_.GetAccountId()),
cryptohome::Authorization(auth_key), mount, _))
.Times(1)
.RetiresOnSaturation();
fake_cryptohome_client_->set_expected_id(
cryptohome::Identification(user_context_.GetAccountId()));
fake_cryptohome_client_->set_expected_authorization_secret(
transformed_key_.GetSecret());
fake_cryptohome_client_->set_is_create_attempt_expected(
expect_create_attempt);
}
void RunResolve(CryptohomeAuthenticator* auth) {
......@@ -325,8 +360,6 @@ class CryptohomeAuthenticatorTest : public testing::Test {
UserContext user_context_with_transformed_key_;
Key transformed_key_;
std::vector<cryptohome::KeyDefinition> key_definitions_;
ScopedDeviceSettingsTestHelper device_settings_test_helper_;
ScopedTestCrosSettings test_cros_settings_;
......@@ -336,23 +369,14 @@ class CryptohomeAuthenticatorTest : public testing::Test {
ScopedUserManagerEnabler user_manager_enabler_;
cryptohome::MockAsyncMethodCaller* mock_caller_;
cryptohome::MockHomedirMethods* mock_homedir_methods_;
MockAuthStatusConsumer consumer_;
scoped_refptr<CryptohomeAuthenticator> auth_;
std::unique_ptr<TestAttemptState> state_;
FakeCryptohomeClient* fake_cryptohome_client_;
TestCryptohomeClient* fake_cryptohome_client_;
scoped_refptr<ownership::MockOwnerKeyUtil> owner_key_util_;
private:
void InvokeGetDataExCallback(
const cryptohome::HomedirMethods::GetKeyDataCallback& callback) {
callback.Run(true /* success */,
cryptohome::MOUNT_ERROR_NONE,
key_definitions_);
}
};
TEST_F(CryptohomeAuthenticatorTest, OnAuthSuccess) {
......
......@@ -495,10 +495,10 @@ void EncryptionMigrationScreenHandler::StartMigration() {
initial_battery_percent_ = *current_battery_percent_;
// Mount the existing eCryptfs vault to a temporary location for migration.
cryptohome::MountParameters mount(false);
mount.to_migrate_from_ecryptfs = true;
cryptohome::MountRequest mount;
mount.set_to_migrate_from_ecryptfs(true);
if (IsArcKiosk()) {
mount.public_mount = true;
mount.set_public_mount(true);
cryptohome::HomedirMethods::GetInstance()->MountEx(
cryptohome::Identification(user_context_.GetAccountId()),
cryptohome::Authorization(cryptohome::KeyDefinition()), mount,
......
......@@ -230,18 +230,6 @@ bool Authorization::operator==(const Authorization& other) const {
return key == other.key && label == other.label;
}
MountParameters::MountParameters(bool ephemeral) : ephemeral(ephemeral) {
}
MountParameters::MountParameters(const MountParameters& other) = default;
bool MountParameters::operator==(const MountParameters& other) const {
return ephemeral == other.ephemeral && create_keys == other.create_keys;
}
MountParameters::~MountParameters() {
}
bool GetGaiaIdMigrationStatus(const AccountId& account_id) {
return user_manager::known_user::GetGaiaIdMigrationStatus(account_id,
kCryptohome);
......
......@@ -149,36 +149,6 @@ struct CHROMEOS_EXPORT Authorization {
std::string label;
};
// Parameters for Mount call.
class CHROMEOS_EXPORT MountParameters {
public:
explicit MountParameters(bool ephemeral);
MountParameters(const MountParameters& other);
~MountParameters();
bool operator==(const MountParameters& other) const;
// If |true|, the mounted home dir will be backed by tmpfs. If |false|, the
// ephemeral users policy decides whether tmpfs or an encrypted directory is
// used as the backend.
bool ephemeral;
// If not empty, home dir will be created with these keys if it exist.
std::vector<KeyDefinition> create_keys;
// If |true|, and cryptohomed supports the new "dircrypto" encryption,
// forces to use the new encryption. That is, makes it an error to mount
// an existing home directory encrypted in the old way (ecryptfs).
bool force_dircrypto_if_available = false;
// If |true|, mounts the existing ecryptfs vault to a temporary location while
// setting up a new dircrypto directory.
bool to_migrate_from_ecryptfs = false;
// If |true|, the home dir will be mounted as public mount.
bool public_mount = false;
};
// This function returns true if cryptohome of |account_id| is migrated to
// accountId-based identifier (AccountId::GetAccountIdKey()).
bool GetGaiaIdMigrationStatus(const AccountId& account_id);
......
......@@ -25,71 +25,6 @@ namespace {
HomedirMethods* g_homedir_methods = NULL;
void FillKeyProtobuf(const KeyDefinition& key_def, Key* key) {
key->set_secret(key_def.secret);
KeyData* data = key->mutable_data();
DCHECK_EQ(KeyDefinition::TYPE_PASSWORD, key_def.type);
data->set_type(KeyData::KEY_TYPE_PASSWORD);
data->set_label(key_def.label);
if (key_def.revision > 0)
data->set_revision(key_def.revision);
if (key_def.privileges != 0) {
KeyPrivileges* privileges = data->mutable_privileges();
privileges->set_mount(key_def.privileges & PRIV_MOUNT);
privileges->set_add(key_def.privileges & PRIV_ADD);
privileges->set_remove(key_def.privileges & PRIV_REMOVE);
privileges->set_update(key_def.privileges & PRIV_MIGRATE);
privileges->set_authorized_update(key_def.privileges &
PRIV_AUTHORIZED_UPDATE);
}
for (std::vector<KeyDefinition::AuthorizationData>::const_iterator auth_it =
key_def.authorization_data.begin();
auth_it != key_def.authorization_data.end(); ++auth_it) {
KeyAuthorizationData* auth_data = data->add_authorization_data();
switch (auth_it->type) {
case KeyDefinition::AuthorizationData::TYPE_HMACSHA256:
auth_data->set_type(
KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256);
break;
case KeyDefinition::AuthorizationData::TYPE_AES256CBC_HMACSHA256:
auth_data->set_type(
KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_AES256CBC_HMACSHA256);
break;
default:
NOTREACHED();
break;
}
for (std::vector<KeyDefinition::AuthorizationData::Secret>::const_iterator
secret_it = auth_it->secrets.begin();
secret_it != auth_it->secrets.end(); ++secret_it) {
KeyAuthorizationSecret* secret = auth_data->add_secrets();
secret->mutable_usage()->set_encrypt(secret_it->encrypt);
secret->mutable_usage()->set_sign(secret_it->sign);
if (!secret_it->symmetric_key.empty())
secret->set_symmetric_key(secret_it->symmetric_key);
if (!secret_it->public_key.empty())
secret->set_public_key(secret_it->public_key);
secret->set_wrapped(secret_it->wrapped);
}
}
for (std::vector<KeyDefinition::ProviderData>::const_iterator it =
key_def.provider_data.begin(); it != key_def.provider_data.end();
++it) {
KeyProviderData::Entry* entry =
data->mutable_provider_data()->add_entry();
entry->set_name(it->name);
if (it->number)
entry->set_number(*it->number);
if (it->bytes)
entry->set_bytes(*it->bytes);
}
}
// Fill authorization protobuffer.
void FillAuthorizationProtobuf(const Authorization& auth,
cryptohome::AuthorizationRequest* auth_proto) {
......@@ -203,33 +138,13 @@ class HomedirMethodsImpl : public HomedirMethods {
void MountEx(const Identification& id,
const Authorization& auth,
const MountParameters& request,
const MountRequest& request,
const MountCallback& callback) override {
cryptohome::AuthorizationRequest auth_proto;
cryptohome::MountRequest request_proto;
FillAuthorizationProtobuf(auth, &auth_proto);
if (request.ephemeral)
request_proto.set_require_ephemeral(true);
if (!request.create_keys.empty()) {
CreateRequest* create = request_proto.mutable_create();
for (size_t i = 0; i < request.create_keys.size(); ++i)
FillKeyProtobuf(request.create_keys[i], create->add_keys());
}
if (request.force_dircrypto_if_available)
request_proto.set_force_dircrypto_if_available(true);
if (request.to_migrate_from_ecryptfs)
request_proto.set_to_migrate_from_ecryptfs(true);
if (request.public_mount)
request_proto.set_public_mount(true);
DBusThreadManager::Get()->GetCryptohomeClient()->MountEx(
id, auth_proto, request_proto,
id, auth_proto, request,
base::Bind(&HomedirMethodsImpl::OnMountExCallback,
weak_ptr_factory_.GetWeakPtr(), callback));
}
......@@ -243,7 +158,7 @@ class HomedirMethodsImpl : public HomedirMethods {
cryptohome::AddKeyRequest request;
FillAuthorizationProtobuf(auth, &auth_proto);
FillKeyProtobuf(new_key, request.mutable_key());
KeyDefinitionToKey(new_key, request.mutable_key());
request.set_clobber_if_exists(clobber_if_exists);
DBusThreadManager::Get()->GetCryptohomeClient()->AddKeyEx(
......@@ -277,7 +192,7 @@ class HomedirMethodsImpl : public HomedirMethods {
cryptohome::UpdateKeyRequest pb_update_key;
FillAuthorizationProtobuf(auth, &auth_proto);
FillKeyProtobuf(new_key, pb_update_key.mutable_changes());
KeyDefinitionToKey(new_key, pb_update_key.mutable_changes());
pb_update_key.set_authorization_signature(signature);
DBusThreadManager::Get()->GetCryptohomeClient()->UpdateKeyEx(
......@@ -484,6 +399,70 @@ class HomedirMethodsImpl : public HomedirMethods {
} // namespace
void KeyDefinitionToKey(const KeyDefinition& key_def, Key* key) {
key->set_secret(key_def.secret);
KeyData* data = key->mutable_data();
DCHECK_EQ(KeyDefinition::TYPE_PASSWORD, key_def.type);
data->set_type(KeyData::KEY_TYPE_PASSWORD);
data->set_label(key_def.label);
if (key_def.revision > 0)
data->set_revision(key_def.revision);
if (key_def.privileges != 0) {
KeyPrivileges* privileges = data->mutable_privileges();
privileges->set_mount(key_def.privileges & PRIV_MOUNT);
privileges->set_add(key_def.privileges & PRIV_ADD);
privileges->set_remove(key_def.privileges & PRIV_REMOVE);
privileges->set_update(key_def.privileges & PRIV_MIGRATE);
privileges->set_authorized_update(key_def.privileges &
PRIV_AUTHORIZED_UPDATE);
}
for (std::vector<KeyDefinition::AuthorizationData>::const_iterator auth_it =
key_def.authorization_data.begin();
auth_it != key_def.authorization_data.end(); ++auth_it) {
KeyAuthorizationData* auth_data = data->add_authorization_data();
switch (auth_it->type) {
case KeyDefinition::AuthorizationData::TYPE_HMACSHA256:
auth_data->set_type(
KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_HMACSHA256);
break;
case KeyDefinition::AuthorizationData::TYPE_AES256CBC_HMACSHA256:
auth_data->set_type(
KeyAuthorizationData::KEY_AUTHORIZATION_TYPE_AES256CBC_HMACSHA256);
break;
default:
NOTREACHED();
break;
}
for (std::vector<KeyDefinition::AuthorizationData::Secret>::const_iterator
secret_it = auth_it->secrets.begin();
secret_it != auth_it->secrets.end(); ++secret_it) {
KeyAuthorizationSecret* secret = auth_data->add_secrets();
secret->mutable_usage()->set_encrypt(secret_it->encrypt);
secret->mutable_usage()->set_sign(secret_it->sign);
if (!secret_it->symmetric_key.empty())
secret->set_symmetric_key(secret_it->symmetric_key);
if (!secret_it->public_key.empty())
secret->set_public_key(secret_it->public_key);
secret->set_wrapped(secret_it->wrapped);
}
}
for (std::vector<KeyDefinition::ProviderData>::const_iterator it =
key_def.provider_data.begin();
it != key_def.provider_data.end(); ++it) {
KeyProviderData::Entry* entry = data->mutable_provider_data()->add_entry();
entry->set_name(it->name);
if (it->number)
entry->set_number(*it->number);
if (it->bytes)
entry->set_bytes(*it->bytes);
}
}
// static
void HomedirMethods::Initialize() {
if (g_homedir_methods) {
......
......@@ -13,11 +13,16 @@
#include "base/callback_forward.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/cryptohome/cryptohome_parameters.h"
#include "chromeos/dbus/cryptohome/key.pb.h"
#include "chromeos/dbus/cryptohome/rpc.pb.h"
#include "chromeos/dbus/cryptohome_client.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace cryptohome {
// Converts the given KeyDefinition to a Key.
void CHROMEOS_EXPORT KeyDefinitionToKey(const KeyDefinition& key_def, Key* key);
// This class manages calls to Cryptohome service's home directory methods:
// Mount, CheckKey, Add/UpdateKey.
class CHROMEOS_EXPORT HomedirMethods {
......@@ -59,7 +64,7 @@ class CHROMEOS_EXPORT HomedirMethods {
// Otherwise, the normal range of return codes is expected.
virtual void MountEx(const Identification& id,
const Authorization& auth,
const MountParameters& request,
const MountRequest& request,
const MountCallback& callback) = 0;
// Asks cryptohomed to try to add another |key| for user identified by |id|
......
......@@ -32,7 +32,7 @@ class CHROMEOS_EXPORT MockHomedirMethods : public HomedirMethods {
MOCK_METHOD4(MountEx,
void(const Identification& id,
const Authorization& key,
const MountParameters& request,
const MountRequest& request,
const MountCallback& callback));
MOCK_METHOD5(AddKeyEx,
void(const Identification& id,
......
......@@ -176,15 +176,17 @@ void DoMount(const base::WeakPtr<AuthAttemptState>& attempt,
const cryptohome::KeyDefinition auth_key(key->GetSecret(),
std::string(),
cryptohome::PRIV_DEFAULT);
cryptohome::MountParameters mount(ephemeral);
cryptohome::MountRequest mount;
if (ephemeral)
mount.set_require_ephemeral(true);
if (create_if_nonexistent) {
mount.create_keys.push_back(cryptohome::KeyDefinition(
key->GetSecret(),
kCryptohomeGAIAKeyLabel,
cryptohome::PRIV_DEFAULT));
KeyDefinitionToKey(
cryptohome::KeyDefinition(key->GetSecret(), kCryptohomeGAIAKeyLabel,
cryptohome::PRIV_DEFAULT),
mount.mutable_create()->add_keys());
}
mount.force_dircrypto_if_available =
attempt->user_context.IsForcingDircrypto();
if (attempt->user_context.IsForcingDircrypto())
mount.set_force_dircrypto_if_available(true);
cryptohome::HomedirMethods::GetInstance()->MountEx(
cryptohome::Identification(attempt->user_context.GetAccountId()),
......@@ -416,12 +418,15 @@ void MountGuestAndGetHash(const base::WeakPtr<AuthAttemptState>& attempt,
void MountPublic(const base::WeakPtr<AuthAttemptState>& attempt,
scoped_refptr<CryptohomeAuthenticator> resolver,
bool force_dircrypto_if_available) {
cryptohome::MountParameters mount(false /* ephemeral */);
mount.force_dircrypto_if_available = force_dircrypto_if_available;
mount.public_mount = true;
cryptohome::MountRequest mount;
if (force_dircrypto_if_available)
mount.set_force_dircrypto_if_available(true);
mount.set_public_mount(true);
// Set the request to create a new homedir when missing.
mount.create_keys.push_back(cryptohome::KeyDefinition(
std::string(), kCryptohomePublicMountKeyLabel, cryptohome::PRIV_DEFAULT));
KeyDefinitionToKey(
cryptohome::KeyDefinition(std::string(), kCryptohomePublicMountKeyLabel,
cryptohome::PRIV_DEFAULT),
mount.mutable_create()->add_keys());
// For public mounts, authorization secret is filled by cryptohomed, hence it
// is left empty. Authentication's key label is also set to an empty string,
......
......@@ -89,9 +89,9 @@ void ExtendedAuthenticatorImpl::CreateMount(
cryptohome::Identification id(account_id);
cryptohome::Authorization auth(keys.front());
cryptohome::MountParameters mount(false);
cryptohome::MountRequest mount;
for (size_t i = 0; i < keys.size(); i++) {
mount.create_keys.push_back(keys[i]);
KeyDefinitionToKey(keys[i], mount.mutable_create()->add_keys());
}
UserContext context(account_id);
Key key(keys.front().secret);
......@@ -191,7 +191,7 @@ void ExtendedAuthenticatorImpl::DoAuthenticateToMount(
cryptohome::Identification id(user_context.GetAccountId());
const Key* const key = user_context.GetKey();
cryptohome::Authorization auth(key->GetSecret(), key->GetLabel());
cryptohome::MountParameters mount(false);
cryptohome::MountRequest mount;
cryptohome::HomedirMethods::GetInstance()->MountEx(
id,
......
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