Commit ab4931b6 authored by Maksim Ivanov's avatar Maksim Ivanov Committed by Commit Bot

Pass chall-resp keys to cryptohome in CryptohomeAuthenticator

Add the support of the challenge-response keys to the code that makes
MountEx requests to the cryptohomed daemon from the
CryptohomeAuthenticator class.

This completes the implementation of the most basic scenario of the
online smart card based user login.

Bug: 826417
Change-Id: I1e543d6521ea9b204b56127634250986b53a6cb7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1678561Reviewed-by: default avatarDenis Kuznetsov <antrim@chromium.org>
Reviewed-by: default avatarRoman Sorokin [CET] <rsorokin@chromium.org>
Reviewed-by: default avatarAchuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Maksim Ivanov <emaxx@chromium.org>
Cr-Commit-Position: refs/heads/master@{#673279}
parent 350f3eb9
...@@ -138,6 +138,7 @@ ...@@ -138,6 +138,7 @@
#include "chromeos/cryptohome/cryptohome_parameters.h" #include "chromeos/cryptohome/cryptohome_parameters.h"
#include "chromeos/cryptohome/homedir_methods.h" #include "chromeos/cryptohome/homedir_methods.h"
#include "chromeos/cryptohome/system_salt_getter.h" #include "chromeos/cryptohome/system_salt_getter.h"
#include "chromeos/dbus/constants/cryptohome_key_delegate_constants.h"
#include "chromeos/dbus/cryptohome/cryptohome_client.h" #include "chromeos/dbus/cryptohome/cryptohome_client.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power/power_manager_client.h" #include "chromeos/dbus/power/power_manager_client.h"
...@@ -357,8 +358,8 @@ class DBusServices { ...@@ -357,8 +358,8 @@ class DBusServices {
std::make_unique<DriveFileStreamServiceProvider>())); std::make_unique<DriveFileStreamServiceProvider>()));
cryptohome_key_delegate_service_ = CrosDBusService::Create( cryptohome_key_delegate_service_ = CrosDBusService::Create(
system_bus, CryptohomeKeyDelegateServiceProvider::kServiceName, system_bus, cryptohome::kCryptohomeKeyDelegateServiceName,
dbus::ObjectPath(CryptohomeKeyDelegateServiceProvider::kServicePath), dbus::ObjectPath(cryptohome::kCryptohomeKeyDelegateServicePath),
CrosDBusService::CreateServiceProviderList( CrosDBusService::CreateServiceProviderList(
std::make_unique<CryptohomeKeyDelegateServiceProvider>())); std::make_unique<CryptohomeKeyDelegateServiceProvider>()));
......
...@@ -26,11 +26,6 @@ ...@@ -26,11 +26,6 @@
namespace chromeos { namespace chromeos {
const char CryptohomeKeyDelegateServiceProvider::kServiceName[] =
"org.chromium.CryptohomeKeyDelegate";
const char CryptohomeKeyDelegateServiceProvider::kServicePath[] =
"/org/chromium/CryptohomeKeyDelegate";
namespace { namespace {
// Converts the cryptohome challenge algorithm enum into the TLS 1.3 // Converts the cryptohome challenge algorithm enum into the TLS 1.3
......
...@@ -27,11 +27,6 @@ namespace chromeos { ...@@ -27,11 +27,6 @@ namespace chromeos {
class CryptohomeKeyDelegateServiceProvider final class CryptohomeKeyDelegateServiceProvider final
: public CrosDBusService::ServiceProviderInterface { : public CrosDBusService::ServiceProviderInterface {
public: public:
// Name of the provided D-Bus service.
static const char kServiceName[];
// Path of the provided D-Bus service.
static const char kServicePath[];
CryptohomeKeyDelegateServiceProvider(); CryptohomeKeyDelegateServiceProvider();
~CryptohomeKeyDelegateServiceProvider() override; ~CryptohomeKeyDelegateServiceProvider() override;
......
...@@ -13,6 +13,8 @@ component("constants") { ...@@ -13,6 +13,8 @@ component("constants") {
sources = [ sources = [
"attestation_constants.cc", "attestation_constants.cc",
"attestation_constants.h", "attestation_constants.h",
"cryptohome_key_delegate_constants.cc",
"cryptohome_key_delegate_constants.h",
"dbus_paths.cc", "dbus_paths.cc",
"dbus_paths.h", "dbus_paths.h",
"dbus_switches.cc", "dbus_switches.cc",
......
// Copyright 2019 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 "chromeos/dbus/constants/cryptohome_key_delegate_constants.h"
namespace cryptohome {
const char kCryptohomeKeyDelegateServiceName[] =
"org.chromium.CryptohomeKeyDelegate";
const char kCryptohomeKeyDelegateServicePath[] =
"/org/chromium/CryptohomeKeyDelegate";
} // namespace cryptohome
// Copyright 2019 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 CHROMEOS_DBUS_CONSTANTS_CRYPTOHOME_KEY_DELEGATE_CONSTANTS_H_
#define CHROMEOS_DBUS_CONSTANTS_CRYPTOHOME_KEY_DELEGATE_CONSTANTS_H_
#include "base/component_export.h"
namespace cryptohome {
// Name and path of the D-Bus service that is run by Chrome and implements the
// org.chromium.CryptohomeKeyDelegateInterface interface. See the interface
// definition in the Chrome OS repo in
// src/platform2/cryptohome/dbus_bindings/
// org.chromium.CryptohomeKeyDelegateInterface.xml .
COMPONENT_EXPORT(CHROMEOS_DBUS_CONSTANTS)
extern const char kCryptohomeKeyDelegateServiceName[];
COMPONENT_EXPORT(CHROMEOS_DBUS_CONSTANTS)
extern const char kCryptohomeKeyDelegateServicePath[];
} // namespace cryptohome
#endif // CHROMEOS_DBUS_CONSTANTS_CRYPTOHOME_KEY_DELEGATE_CONSTANTS_H_
...@@ -19,6 +19,7 @@ component("auth") { ...@@ -19,6 +19,7 @@ component("auth") {
"//chromeos/cryptohome", "//chromeos/cryptohome",
"//chromeos/dbus/auth_policy", "//chromeos/dbus/auth_policy",
"//chromeos/dbus/auth_policy:authpolicy_proto", "//chromeos/dbus/auth_policy:authpolicy_proto",
"//chromeos/dbus/constants",
"//chromeos/dbus/cryptohome", "//chromeos/dbus/cryptohome",
"//chromeos/dbus/cryptohome:cryptohome_proto", "//chromeos/dbus/cryptohome:cryptohome_proto",
"//chromeos/dbus/session_manager", "//chromeos/dbus/session_manager",
...@@ -47,6 +48,8 @@ component("auth") { ...@@ -47,6 +48,8 @@ component("auth") {
"authenticator.h", "authenticator.h",
"challenge_response/cert_utils.cc", "challenge_response/cert_utils.cc",
"challenge_response/cert_utils.h", "challenge_response/cert_utils.h",
"challenge_response/key_label_utils.cc",
"challenge_response/key_label_utils.h",
"cryptohome_authenticator.cc", "cryptohome_authenticator.cc",
"cryptohome_authenticator.h", "cryptohome_authenticator.h",
"extended_authenticator.cc", "extended_authenticator.cc",
......
// Copyright 2019 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 "chromeos/login/auth/challenge_response/key_label_utils.h"
#include "base/logging.h"
#include "base/strings/string_number_conversions.h"
#include "crypto/sha2.h"
namespace chromeos {
namespace {
// Prefix to be used in the cryptohome key labels for challenge-response keys.
// Prefixing allows to avoid accidental clashes between different keys (labels
// are used to uniquely identify the needed key in requests to cryptohomed).
constexpr char kKeyLabelPrefix[] = "challenge-response-";
// Given a DER-encoded X.509 Subject Public Key Info, returns its hashed
// representation that is suitable for inclusion into cryptohome key labels. The
// label built this way is, practically, unique (short of a SHA-256 collision).
std::string GenerateLabelSpkiPart(const std::string& public_key_spki_der) {
DCHECK(!public_key_spki_der.empty());
const std::string hash = crypto::SHA256HashString(public_key_spki_der);
return base::HexEncode(hash.data(), hash.size());
}
} // namespace
std::string GenerateChallengeResponseKeyLabel(
const std::vector<ChallengeResponseKey>& challenge_response_keys) {
// For now, only a single challenge-response key is supported.
DCHECK_EQ(challenge_response_keys.size(), 1ull);
return kKeyLabelPrefix +
GenerateLabelSpkiPart(
challenge_response_keys[0].public_key_spki_der());
}
} // namespace chromeos
// Copyright 2019 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 CHROMEOS_LOGIN_AUTH_CHALLENGE_RESPONSE_KEY_LABEL_UTILS_H_
#define CHROMEOS_LOGIN_AUTH_CHALLENGE_RESPONSE_KEY_LABEL_UTILS_H_
#include <string>
#include <vector>
#include "chromeos/login/auth/challenge_response_key.h"
namespace chromeos {
// Generates the cryptohome user key label for the given challenge-response key
// information. Currently the constraint is that |challenge_response_keys| must
// contain exactly one item.
std::string GenerateChallengeResponseKeyLabel(
const std::vector<ChallengeResponseKey>& challenge_response_keys);
} // namespace chromeos
#endif // CHROMEOS_LOGIN_AUTH_CHALLENGE_RESPONSE_KEY_LABEL_UTILS_H_
...@@ -20,8 +20,10 @@ ...@@ -20,8 +20,10 @@
#include "chromeos/cryptohome/cryptohome_util.h" #include "chromeos/cryptohome/cryptohome_util.h"
#include "chromeos/cryptohome/homedir_methods.h" #include "chromeos/cryptohome/homedir_methods.h"
#include "chromeos/cryptohome/system_salt_getter.h" #include "chromeos/cryptohome/system_salt_getter.h"
#include "chromeos/dbus/constants/cryptohome_key_delegate_constants.h"
#include "chromeos/dbus/cryptohome/cryptohome_client.h" #include "chromeos/dbus/cryptohome/cryptohome_client.h"
#include "chromeos/login/auth/auth_status_consumer.h" #include "chromeos/login/auth/auth_status_consumer.h"
#include "chromeos/login/auth/challenge_response/key_label_utils.h"
#include "chromeos/login/auth/key.h" #include "chromeos/login/auth/key.h"
#include "chromeos/login/auth/login_event_recorder.h" #include "chromeos/login/auth/login_event_recorder.h"
#include "chromeos/login/auth/user_context.h" #include "chromeos/login/auth/user_context.h"
...@@ -227,31 +229,50 @@ void DoMount(const base::WeakPtr<AuthAttemptState>& attempt, ...@@ -227,31 +229,50 @@ void DoMount(const base::WeakPtr<AuthAttemptState>& attempt,
// that returns directly would not generate 2 OnLoginSucces() calls. // that returns directly would not generate 2 OnLoginSucces() calls.
attempt->UsernameHashRequested(); attempt->UsernameHashRequested();
cryptohome::KeyDefinition key_definition;
cryptohome::AuthorizationRequest auth;
cryptohome::Key* auth_key = auth.mutable_key();
if (!attempt->user_context.GetChallengeResponseKeys().empty()) {
// For the challenge-response key, no secret is passed, only public-key
// information. The authorization request consists of the same key as the
// persisted key, plus the additional KeyDelegate information that allows
// cryptohomed to call back to Chrome to perform challenges.
key_definition = cryptohome::KeyDefinition::CreateForChallengeResponse(
attempt->user_context.GetChallengeResponseKeys(),
GenerateChallengeResponseKeyLabel(
attempt->user_context.GetChallengeResponseKeys()),
cryptohome::PRIV_DEFAULT);
cryptohome::KeyDefinitionToKey(key_definition, auth_key);
auth.mutable_key_delegate()->set_dbus_service_name(
cryptohome::kCryptohomeKeyDelegateServiceName);
auth.mutable_key_delegate()->set_dbus_object_path(
cryptohome::kCryptohomeKeyDelegateServicePath);
} else {
key_definition = cryptohome::KeyDefinition::CreateForPassword(
key->GetSecret(), kCryptohomeGAIAKeyLabel, cryptohome::PRIV_DEFAULT);
// Don't set the authorization's key label, implicitly setting it to an
// empty string, which is a wildcard allowing any key to match. This is
// necessary because cryptohomes created by Chrome OS M38 and older will
// have a legacy key with no label while those created by Chrome OS M39 and
// newer will have a key with the label kCryptohomeGAIAKeyLabel.
//
// This logic does not apply to PIN and weak keys in general, as those do
// not authenticate against a wildcard label.
if (attempt->user_context.IsUsingPin())
auth_key->mutable_data()->set_label(key->GetLabel());
auth_key->set_secret(key->GetSecret());
}
cryptohome::MountRequest mount; cryptohome::MountRequest mount;
if (ephemeral) if (ephemeral)
mount.set_require_ephemeral(true); mount.set_require_ephemeral(true);
if (create_if_nonexistent) { if (create_if_nonexistent) {
cryptohome::KeyDefinitionToKey( cryptohome::KeyDefinitionToKey(key_definition,
cryptohome::KeyDefinition::CreateForPassword(key->GetSecret(), mount.mutable_create()->add_keys());
kCryptohomeGAIAKeyLabel,
cryptohome::PRIV_DEFAULT),
mount.mutable_create()->add_keys());
} }
if (attempt->user_context.IsForcingDircrypto()) if (attempt->user_context.IsForcingDircrypto())
mount.set_force_dircrypto_if_available(true); mount.set_force_dircrypto_if_available(true);
cryptohome::AuthorizationRequest auth;
cryptohome::Key* auth_key = auth.mutable_key();
// Don't set the authorization's key label, implicitly setting it to an
// empty string, which is a wildcard allowing any key to match. This is
// necessary because cryptohomes created by Chrome OS M38 and older will have
// a legacy key with no label while those created by Chrome OS M39 and newer
// will have a key with the label kCryptohomeGAIAKeyLabel.
//
// This logic does not apply to PIN and weak keys in general, as those do not
// authenticate against a wildcard label.
if (attempt->user_context.IsUsingPin())
auth_key->mutable_data()->set_label(key->GetLabel());
auth_key->set_secret(key->GetSecret());
CryptohomeClient::Get()->MountEx( CryptohomeClient::Get()->MountEx(
cryptohome::CreateAccountIdentifierFromAccountId( cryptohome::CreateAccountIdentifierFromAccountId(
attempt->user_context.GetAccountId()), attempt->user_context.GetAccountId()),
......
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