Skip to content

Commit

Permalink
AuthSession: Implement password changed flow
Browse files Browse the repository at this point in the history
Bug: 1298660
Change-Id: I7900b125a9a2872bc662c3be744b94e99487870a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3473223
Reviewed-by: Alexander Alekseev <alemate@chromium.org>
Reviewed-by: Ryo Hashimoto <hashimoto@chromium.org>
Commit-Queue: Denis Kuznetsov <antrim@chromium.org>
Cr-Commit-Position: refs/heads/main@{#984978}
  • Loading branch information
Denis Kuznetsov authored and Chromium LUCI CQ committed Mar 24, 2022
1 parent 7ff1bce commit 9ca63f9
Show file tree
Hide file tree
Showing 23 changed files with 503 additions and 98 deletions.
123 changes: 55 additions & 68 deletions ash/components/cryptohome/cryptohome_util.cc
Expand Up @@ -75,79 +75,66 @@ void KeyDefProviderDataToKeyProviderDataEntry(

} // namespace

KeyDefinition KeyDataToKeyDefinition(const KeyData& key_data) {
CHECK(key_data.has_type());
KeyDefinition result;
// Extract |type|, |label| and |revision|.
switch (key_data.type()) {
case KeyData::KEY_TYPE_PASSWORD:
result.type = KeyDefinition::TYPE_PASSWORD;
break;
case KeyData::KEY_TYPE_CHALLENGE_RESPONSE:
result.type = KeyDefinition::TYPE_CHALLENGE_RESPONSE;
break;
case KeyData::KEY_TYPE_FINGERPRINT:
// KEY_TYPE_FINGERPRINT means the key is a request for fingerprint auth
// and does not really carry any auth information. KEY_TYPE_FINGERPRINT
// is not expected to be used in GetKeyData.
NOTREACHED();
break;
case KeyData::KEY_TYPE_KIOSK:
result.type = KeyDefinition::TYPE_PUBLIC_MOUNT;
break;
}
result.label = key_data.label();
result.revision = key_data.revision();

// Extract |privileges|.
const KeyPrivileges& privileges = key_data.privileges();
if (privileges.add())
result.privileges |= PRIV_ADD;
if (privileges.remove())
result.privileges |= PRIV_REMOVE;
if (privileges.update())
result.privileges |= PRIV_MIGRATE;

// Extract |policy|.
result.policy.low_entropy_credential =
key_data.policy().low_entropy_credential();
result.policy.auth_locked = key_data.policy().auth_locked();

// Extract |provider_data|.
for (auto& provider_datum : key_data.provider_data().entry()) {
// We have either of two
DCHECK_NE(provider_datum.has_number(), provider_datum.has_bytes());

if (provider_datum.has_number()) {
result.provider_data.push_back(KeyDefinition::ProviderData(
provider_datum.name(), provider_datum.number()));
} else {
result.provider_data.push_back(KeyDefinition::ProviderData(
provider_datum.name(), provider_datum.bytes()));
}
}
return result;
}

std::vector<KeyDefinition> RepeatedKeyDataToKeyDefinitions(
const RepeatedPtrField<KeyData>& key_data) {
std::vector<KeyDefinition> key_definitions;
for (RepeatedPtrField<KeyData>::const_iterator it = key_data.begin();
it != key_data.end(); ++it) {
// Extract |type|, |label| and |revision|.
KeyDefinition key_definition;
CHECK(it->has_type());
switch (it->type()) {
case KeyData::KEY_TYPE_PASSWORD:
key_definition.type = KeyDefinition::TYPE_PASSWORD;
break;
case KeyData::KEY_TYPE_CHALLENGE_RESPONSE:
key_definition.type = KeyDefinition::TYPE_CHALLENGE_RESPONSE;
break;
case KeyData::KEY_TYPE_FINGERPRINT:
// KEY_TYPE_FINGERPRINT means the key is a request for fingerprint auth
// and does not really carry any auth information. KEY_TYPE_FINGERPRINT
// is not expected to be used in GetKeyData.
NOTREACHED();
break;
case KeyData::KEY_TYPE_KIOSK:
key_definition.type = KeyDefinition::TYPE_PUBLIC_MOUNT;
break;
}
key_definition.label = it->label();
key_definition.revision = it->revision();

// Extract |privileges|.
const KeyPrivileges& privileges = it->privileges();
if (privileges.add())
key_definition.privileges |= PRIV_ADD;
if (privileges.remove())
key_definition.privileges |= PRIV_REMOVE;
if (privileges.update())
key_definition.privileges |= PRIV_MIGRATE;

// Extract |policy|.
key_definition.policy.low_entropy_credential =
it->policy().low_entropy_credential();
key_definition.policy.auth_locked = it->policy().auth_locked();

// Extract |provider_data|.
for (RepeatedPtrField<KeyProviderData::Entry>::const_iterator
provider_data_it = it->provider_data().entry().begin();
provider_data_it != it->provider_data().entry().end();
++provider_data_it) {
// Extract |name|.
key_definition.provider_data.push_back(
KeyDefinition::ProviderData(provider_data_it->name()));
KeyDefinition::ProviderData& provider_data =
key_definition.provider_data.back();

int data_items = 0;

// Extract |number|.
if (provider_data_it->has_number()) {
provider_data.number =
std::make_unique<int64_t>(provider_data_it->number());
++data_items;
}

// Extract |bytes|.
if (provider_data_it->has_bytes()) {
provider_data.bytes =
std::make_unique<std::string>(provider_data_it->bytes());
++data_items;
}

DCHECK_EQ(1, data_items);
}

key_definitions.push_back(std::move(key_definition));
key_definitions.push_back(KeyDataToKeyDefinition(*it));
}
return key_definitions;
}
Expand Down
5 changes: 5 additions & 0 deletions ash/components/cryptohome/cryptohome_util.h
Expand Up @@ -22,6 +22,11 @@ namespace cryptohome {
std::vector<KeyDefinition> RepeatedKeyDataToKeyDefinitions(
const google::protobuf::RepeatedPtrField<KeyData>& key_data);

// Converts the single key metadata from cryptohome::KeyData> to
// cryptohome::KeyDefinition format.
COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME)
KeyDefinition KeyDataToKeyDefinition(const KeyData& key_data);

// Creates an AuthorizationRequest from the given secret and label.
COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME)
AuthorizationRequest CreateAuthorizationRequest(const std::string& label,
Expand Down
4 changes: 4 additions & 0 deletions ash/components/cryptohome/userdataauth_util.cc
Expand Up @@ -70,6 +70,10 @@ template COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) CryptohomeErrorCode
ReplyToCryptohomeError(const absl::optional<AddAuthFactorReply>&);
template COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) CryptohomeErrorCode
ReplyToCryptohomeError(const absl::optional<UnmountReply>&);
template COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) CryptohomeErrorCode
ReplyToCryptohomeError(const absl::optional<RemoveReply>&);
template COMPONENT_EXPORT(ASH_COMPONENTS_CRYPTOHOME) CryptohomeErrorCode
ReplyToCryptohomeError(const absl::optional<UpdateCredentialReply>&);

std::vector<cryptohome::KeyDefinition> GetKeyDataReplyToKeyDefinitions(
const absl::optional<GetKeyDataReply>& reply) {
Expand Down
2 changes: 2 additions & 0 deletions ash/components/login/auth/BUILD.gn
Expand Up @@ -41,6 +41,8 @@ component("auth") {
sources = [
"auth_attempt_state.cc",
"auth_attempt_state.h",
"auth_factors_data.cc",
"auth_factors_data.h",
"auth_session_authenticator.cc",
"auth_session_authenticator.h",
"auth_status_consumer.cc",
Expand Down
36 changes: 36 additions & 0 deletions ash/components/login/auth/auth_factors_data.cc
@@ -0,0 +1,36 @@
// Copyright 2022 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 "ash/components/login/auth/auth_factors_data.h"

#include "ash/components/cryptohome/cryptohome_parameters.h"
#include "ash/components/login/auth/cryptohome_key_constants.h"

namespace ash {

AuthFactorsData::AuthFactorsData(std::vector<cryptohome::KeyDefinition> keys)
: keys_(std::move(keys)) {}

AuthFactorsData::AuthFactorsData() = default;
AuthFactorsData::AuthFactorsData(const AuthFactorsData&) = default;
AuthFactorsData::AuthFactorsData(AuthFactorsData&&) = default;
AuthFactorsData::~AuthFactorsData() = default;
AuthFactorsData& AuthFactorsData::operator=(const AuthFactorsData&) = default;

const cryptohome::KeyDefinition* AuthFactorsData::FindOnlinePasswordKey()
const {
for (const cryptohome::KeyDefinition& key_def : keys_) {
if (key_def.label == kCryptohomeGaiaKeyLabel)
return &key_def;
}
for (const cryptohome::KeyDefinition& key_def : keys_) {
// Check if label starts with prefix and has required type.
if ((key_def.label.find(kCryptohomeGaiaKeyLegacyLabelPrefix) == 0) &&
key_def.type == cryptohome::KeyDefinition::TYPE_PASSWORD)
return &key_def;
}
return nullptr;
}

} // namespace ash
42 changes: 42 additions & 0 deletions ash/components/login/auth/auth_factors_data.h
@@ -0,0 +1,42 @@
// Copyright 2022 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.

#ifndef ASH_COMPONENTS_LOGIN_AUTH_AUTH_FACTORS_DATA_H_
#define ASH_COMPONENTS_LOGIN_AUTH_AUTH_FACTORS_DATA_H_

#include <string>

#include "ash/components/cryptohome/cryptohome_parameters.h"

namespace ash {

// Public information about authentication keys configured for particular user.
// This class partially encapsulates implementation details of key definition
// (cryptohome::KeyData vs cryptohome::AuthFactor).
// Note that this information does not contain any key secrets.
class COMPONENT_EXPORT(ASH_LOGIN_AUTH) AuthFactorsData {
public:
explicit AuthFactorsData(std::vector<cryptohome::KeyDefinition> keys);

// Empty constructor is needed so that UserContext can be created.
AuthFactorsData();
// Copy constructor (and operator) are needed because UserContext is copyable.
AuthFactorsData(const AuthFactorsData&);
AuthFactorsData(AuthFactorsData&&);

~AuthFactorsData();

AuthFactorsData& operator=(const AuthFactorsData&);

// Returns metadata for the Password key, so that it can be identified for
// further operations.
const cryptohome::KeyDefinition* FindOnlinePasswordKey() const;

private:
std::vector<cryptohome::KeyDefinition> keys_;
};

} // namespace ash

#endif // ASH_COMPONENTS_LOGIN_AUTH_AUTH_FACTORS_DATA_H_

0 comments on commit 9ca63f9

Please sign in to comment.