blob: 366f1c6ce6a316dab130afc0247a5634d7a524ff [file] [log] [blame]
// 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 <memory>
#include <string>
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "chrome/browser/ash/attestation/tpm_challenge_key_result.h"
#include "chrome/browser/ash/attestation/tpm_challenge_key_subtle.h"
#include "chromeos/dbus/constants/attestation_constants.h"
class Profile;
class AttestationFlow;
namespace user_prefs {
class PrefRegistrySyncable;
} // namespace user_prefs
namespace ash {
namespace attestation {
// Prefix for naming machine keys used for SignedPublicKeyAndChallenge when
// challenging the EMK with register=true.
const char kEnterpriseMachineKeyForSpkacPrefix[] = "attest-ent-machine-";
//========================= TpmChallengeKeyFactory =============================
class TpmChallengeKey;
class TpmChallengeKeyFactory final {
static std::unique_ptr<TpmChallengeKey> Create();
static void SetForTesting(std::unique_ptr<TpmChallengeKey> next_result);
static TpmChallengeKey* next_result_for_testing_;
//=========================== TpmChallengeKey ==================================
// Asynchronously runs the flow to challenge a key in the caller context. This
// is a wrapper around TpmChallengeKeySubtle with an easier-to-use interface.
// TpmChallengeKeySubtle can be used directly to get more control over main
// steps to build the response.
class TpmChallengeKey {
TpmChallengeKey(const TpmChallengeKey&) = delete;
TpmChallengeKey& operator=(const TpmChallengeKey&) = delete;
virtual ~TpmChallengeKey() = default;
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Should be called only once for every instance. |TpmChallengeKey| object
// should live as long as response from |BuildResponse| function via
// |callback| is expected. On destruction it stops challenge process and
// silently discards callback.
// The response consists of up to two parts: 1) a response to the challenge
// and optionally 2) an SPKAC. They can be generated using different keys:
// A) KEY_DEVICE && !register_key => 1) Stable device key + 2) Empty
// B) KEY_DEVICE && register_key => 1) Stable device key + 2) Key(key_name)
// C) KEY_USER && !register_key => 1) Key(key_name) + 2) Empty
// D) KEY_USER && register_key => 1) Key(key_name) + 2) Key(key_name)
// In case B) |key_name| cannot be empty. In case C), D) some default name
// will be used if |key_name| is empty.
virtual void BuildResponse(AttestationKeyType key_type,
Profile* profile,
TpmChallengeKeyCallback callback,
const std::string& challenge,
bool register_key,
const std::string& key_name) = 0;
// Use TpmChallengeKeyFactory for creation.
TpmChallengeKey() = default;
//=========================== TpmChallengeKeyImpl ==============================
class TpmChallengeKeyImpl final : public TpmChallengeKey {
// Use TpmChallengeKeyFactory for creation.
// Use only for testing.
explicit TpmChallengeKeyImpl(
AttestationFlow* attestation_flow_for_testing,
MachineCertificateUploader* certificate_uploader_for_testing);
TpmChallengeKeyImpl(const TpmChallengeKeyImpl&) = delete;
TpmChallengeKeyImpl& operator=(const TpmChallengeKeyImpl&) = delete;
~TpmChallengeKeyImpl() override;
// TpmChallengeKey
void BuildResponse(AttestationKeyType key_type,
Profile* profile,
TpmChallengeKeyCallback callback,
const std::string& challenge,
bool register_key,
const std::string& key_name) override;
void OnPrepareKeyDone(const TpmChallengeKeyResult& prepare_key_result);
void OnSignChallengeDone(const TpmChallengeKeyResult& sign_challenge_result);
void OnRegisterKeyDone(const TpmChallengeKeyResult& challenge_response,
const TpmChallengeKeyResult& register_key_result);
bool register_key_ = false;
std::string challenge_;
TpmChallengeKeyResult challenge_response_;
TpmChallengeKeyCallback callback_;
std::unique_ptr<TpmChallengeKeySubtle> tpm_challenge_key_subtle_;
base::WeakPtrFactory<TpmChallengeKeyImpl> weak_factory_{this};
} // namespace attestation
} // namespace ash
// TODO( remove after //chrome/browser/chromeos
// source migration is finished.
namespace chromeos {
namespace attestation {
using ::ash::attestation::TpmChallengeKeyFactory;
using ::ash::attestation::TpmChallengeKeyImpl;
} // namespace attestation
} // namespace chromeos