Commit 54ff9dd3 authored by Andreea Costinas's avatar Andreea Costinas Committed by Commit Bot

enterprise.platformKeys api: Register machine key

As part of a feature to side-load machine keys verified by remote
attestation into the system-wide token using the
enterprise.platformKeys.challengeMachineKey API, the
SignEnterpriseChallenge method needs another argument that specifies the
key name used for SignedPublicKeyAndChallenge.

When challenging machine key with register = true, the EMK cannot be
registered as that would relinquish it and the DMServer relies on it to
remain stable.

This CL generates a new machine key to side-load into the system-wide
token in this case. The key will be used for SignedPublicKeyAndChallenge
but the challenge response will still be singed using the stable EMK.

Depends on CL:1714597.

BUG=b:35580115
TEST=manually tested,
unit_tests --gtest_filter=EPKChallengeMachineKeyTest.KeyRegisteredSuccess

Change-Id: I4c426f06d1ff32333bf1383a54d4840f119aeeeb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1708948
Commit-Queue: Andreea-Elena Costinas <acostinas@google.com>
Reviewed-by: default avatarYves Arrouye <drcrash@chromium.org>
Reviewed-by: default avatarPavol Marko <pmarko@chromium.org>
Reviewed-by: default avatarRyo Hashimoto <hashimoto@chromium.org>
Reviewed-by: default avatarMattias Nissler <mnissler@chromium.org>
Cr-Commit-Position: refs/heads/master@{#686730}
parent 923b834d
......@@ -119,6 +119,7 @@ void EnrollmentCertificateUploaderImpl::GetCertificate() {
EmptyAccountId(), // Not used.
std::string(), // Not used.
false, // Do not force a new key to be generated.
std::string(), // Leave key name empty to generate a default name.
base::BindRepeating(
[](const base::RepeatingCallback<void(const std::string&)> on_success,
const base::RepeatingCallback<void(AttestationStatus)> on_failure,
......
......@@ -80,8 +80,8 @@ class EnrollmentCertificateUploaderTest : public ::testing::Test {
// Setup expected cert generations. Again use WillOnce(). Cert generation
// is another costly operation and if it gets triggered more than once
// during a single pass this indicates a logical problem in the uploader.
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _))
.WillOnce(WithArgs<4>(Invoke(CertCallbackSuccess)));
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillOnce(WithArgs<5>(Invoke(CertCallbackSuccess)));
}
void Run(bool expected_status) {
......@@ -111,14 +111,14 @@ TEST_F(EnrollmentCertificateUploaderTest, UnregisteredPolicyClient) {
}
TEST_F(EnrollmentCertificateUploaderTest, GetCertificateUnspecifiedFailure) {
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _))
.WillRepeatedly(WithArgs<4>(Invoke(CertCallbackUnspecifiedFailure)));
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillRepeatedly(WithArgs<5>(Invoke(CertCallbackUnspecifiedFailure)));
Run(false /* expected_status */);
}
TEST_F(EnrollmentCertificateUploaderTest, GetCertificateBadRequestFailure) {
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _))
.WillOnce(WithArgs<4>(Invoke(CertCallbackBadRequestFailure)));
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillOnce(WithArgs<5>(Invoke(CertCallbackBadRequestFailure)));
Run(false /* expected_status */);
}
......
......@@ -204,6 +204,7 @@ void MachineCertificateUploaderImpl::GetNewCertificate() {
EmptyAccountId(), // Not used.
std::string(), // Not used.
true, // Force a new key to be generated.
std::string(), // Leave key name empty to generate a default name.
base::BindRepeating(
[](const base::RepeatingCallback<void(const std::string&)> on_success,
const base::RepeatingCallback<void(AttestationStatus)> on_failure,
......
......@@ -110,8 +110,8 @@ class MachineCertificateUploaderTest : public ::testing::TestWithParam<bool> {
// another costly operation and if it gets triggered more than once during
// a single pass this indicates a logical problem in the observer.
if (new_key) {
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _))
.WillOnce(WithArgs<4>(Invoke(CertCallbackSuccess)));
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillOnce(WithArgs<5>(Invoke(CertCallbackSuccess)));
}
}
......@@ -149,14 +149,14 @@ TEST_P(MachineCertificateUploaderTest, UnregisteredPolicyClient) {
}
TEST_P(MachineCertificateUploaderTest, GetCertificateUnspecifiedFailure) {
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _))
.WillRepeatedly(WithArgs<4>(Invoke(CertCallbackUnspecifiedFailure)));
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillRepeatedly(WithArgs<5>(Invoke(CertCallbackUnspecifiedFailure)));
Run();
}
TEST_P(MachineCertificateUploaderTest, GetCertificateBadRequestFailure) {
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _))
.WillOnce(WithArgs<4>(Invoke(CertCallbackBadRequestFailure)));
EXPECT_CALL(attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillOnce(WithArgs<5>(Invoke(CertCallbackBadRequestFailure)));
Run();
}
......
......@@ -265,9 +265,9 @@ void PlatformVerificationFlow::GetCertificate(const ChallengeContext& context,
AttestationFlow::CertificateCallback certificate_callback =
base::Bind(&PlatformVerificationFlow::OnCertificateReady, this, context,
account_id, base::Passed(&timer));
attestation_flow_->GetCertificate(PROFILE_CONTENT_PROTECTION_CERTIFICATE,
account_id, context.service_id,
force_new_key, certificate_callback);
attestation_flow_->GetCertificate(
PROFILE_CONTENT_PROTECTION_CERTIFICATE, account_id, context.service_id,
force_new_key, std::string() /*key_name*/, certificate_callback);
}
void PlatformVerificationFlow::OnCertificateReady(
......@@ -341,10 +341,12 @@ void PlatformVerificationFlow::OnChallengeReady(
AttestationFlow::CertificateCallback renew_callback =
base::Bind(&PlatformVerificationFlow::RenewCertificateCallback, this,
certificate_chain);
attestation_flow_->GetCertificate(PROFILE_CONTENT_PROTECTION_CERTIFICATE,
account_id, context.service_id,
true, // force_new_key
renew_callback);
attestation_flow_->GetCertificate(
PROFILE_CONTENT_PROTECTION_CERTIFICATE, account_id, context.service_id,
true, // force_new_key
std::string(), // key_name, empty means a default one will be
// generated.
renew_callback);
}
}
......
......@@ -128,8 +128,8 @@ class PlatformVerificationFlowTest : public ::testing::Test {
// Configure the mock AttestationFlow to call FakeGetCertificate.
EXPECT_CALL(mock_attestation_flow_,
GetCertificate(PROFILE_CONTENT_PROTECTION_CERTIFICATE,
account_id, kTestID, _, _))
.WillRepeatedly(WithArgs<4>(
account_id, kTestID, _, _, _))
.WillRepeatedly(WithArgs<5>(
Invoke(this, &PlatformVerificationFlowTest::FakeGetCertificate)));
// Configure the mock AsyncMethodCaller to call FakeSignChallenge.
......
......@@ -216,8 +216,8 @@ class DeviceCloudPolicyManagerChromeOSTest
CreateAttestationFlow() {
mock_ = new StrictMock<chromeos::attestation::MockAttestationFlow>();
if (ShouldRegisterWithCert()) {
EXPECT_CALL(*mock_, GetCertificate(_, _, _, _, _))
.WillOnce(WithArgs<4>(Invoke(CertCallbackSuccess)));
EXPECT_CALL(*mock_, GetCertificate(_, _, _, _, _, _))
.WillOnce(WithArgs<5>(Invoke(CertCallbackSuccess)));
}
return mock_;
}
......@@ -876,7 +876,7 @@ TEST_P(DeviceCloudPolicyManagerChromeOSEnrollmentTest, DisableMachineCertReq) {
EXPECT_CALL(*mock_, GetCertificate(
chromeos::attestation::AttestationCertificateProfile::
PROFILE_ENTERPRISE_MACHINE_CERTIFICATE,
_, _, _, _))
_, _, _, _, _))
.Times(0);
RunTest();
......
......@@ -457,7 +457,8 @@ void EnrollmentHandlerChromeOS::StartAttestationBasedEnrollmentFlow() {
weak_ptr_factory_.GetWeakPtr());
attestation_flow_->GetCertificate(
chromeos::attestation::PROFILE_ENTERPRISE_ENROLLMENT_CERTIFICATE,
EmptyAccountId(), "" /* request_origin */, false /* force_new_key */,
EmptyAccountId(), std::string() /* request_origin */,
false /* force_new_key */, std::string(), /* key_name */
callback);
}
......
......@@ -85,6 +85,7 @@ void SignChallengeCallbackTrue(
const std::string& device_id,
chromeos::attestation::AttestationChallengeOptions options,
const std::string& challenge,
const std::string& key_name_for_spkac,
const cryptohome::AsyncMethodCaller::DataCallback& callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(callback, true, "response"));
......@@ -98,6 +99,7 @@ void SignChallengeCallbackFalse(
const std::string& device_id,
chromeos::attestation::AttestationChallengeOptions options,
const std::string& challenge,
const std::string& key_name_for_spkac,
const cryptohome::AsyncMethodCaller::DataCallback& callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(callback, false, ""));
......@@ -108,6 +110,7 @@ void GetCertificateCallbackTrue(
const AccountId& account_id,
const std::string& request_origin,
bool force_new_key,
const std::string& key_name,
const chromeos::attestation::AttestationFlow::CertificateCallback&
callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
......@@ -121,6 +124,7 @@ void GetCertificateCallbackFalse(
const AccountId& account_id,
const std::string& request_origin,
bool force_new_key,
const std::string& key_name,
const chromeos::attestation::AttestationFlow::CertificateCallback&
callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
......@@ -141,9 +145,9 @@ class EPKChallengeKeyTestBase : public BrowserWithTestWindowTest {
ON_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _))
.WillByDefault(Invoke(RegisterKeyCallbackTrue));
ON_CALL(mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _))
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _))
.WillByDefault(Invoke(SignChallengeCallbackTrue));
ON_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
ON_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillByDefault(Invoke(GetCertificateCallbackTrue));
stub_install_attributes_.SetCloudManaged("google.com", "device_id");
......@@ -297,7 +301,7 @@ TEST_F(EPKChallengeMachineKeyTest, DoesKeyExistDbusFailed) {
}
TEST_F(EPKChallengeMachineKeyTest, GetCertificateFailed) {
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillRepeatedly(Invoke(GetCertificateCallbackFalse));
EXPECT_EQ(GetCertificateError(kGetCertificateFailed),
......@@ -306,7 +310,7 @@ TEST_F(EPKChallengeMachineKeyTest, GetCertificateFailed) {
TEST_F(EPKChallengeMachineKeyTest, SignChallengeFailed) {
EXPECT_CALL(mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _))
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _))
.WillRepeatedly(Invoke(SignChallengeCallbackFalse));
EXPECT_EQ(EPKPChallengeKeyBase::kSignChallengeFailedError,
......@@ -327,7 +331,8 @@ TEST_F(EPKChallengeMachineKeyTest, KeyExists) {
std::string());
// GetCertificate must not be called if the key exists.
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _)).Times(0);
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _))
.Times(0);
EXPECT_TRUE(utils::RunFunction(func_.get(), CreateArgs(), browser(),
extensions::api_test_utils::NONE));
......@@ -354,14 +359,14 @@ TEST_F(EPKChallengeMachineKeyTest, Success) {
EXPECT_CALL(mock_attestation_flow_,
GetCertificate(
chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE,
_, _, _, _))
_, _, _, _, _))
.Times(1);
// SignEnterpriseChallenge must be called exactly once.
EXPECT_CALL(
mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(
chromeos::attestation::KEY_DEVICE, cryptohome::Identification(),
"attest-ent-machine", "google.com", "device_id", _, "challenge", _))
EXPECT_CALL(mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(
chromeos::attestation::KEY_DEVICE,
cryptohome::Identification(), "attest-ent-machine",
"google.com", "device_id", _, "challenge", _, _))
.Times(1);
std::unique_ptr<base::Value> value(
......@@ -373,24 +378,26 @@ TEST_F(EPKChallengeMachineKeyTest, Success) {
}
TEST_F(EPKChallengeMachineKeyTest, KeyRegisteredSuccess) {
std::string key_name_for_spkac = "attest-ent-machine-" + extension_->id();
// GetCertificate must be called exactly once.
EXPECT_CALL(mock_attestation_flow_,
GetCertificate(
chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE,
_, _, _, _))
_, _, _, _, _))
.Times(1);
// TpmAttestationRegisterKey must be called exactly once.
EXPECT_CALL(mock_async_method_caller_,
TpmAttestationRegisterKey(chromeos::attestation::KEY_DEVICE,
_ /* Unused by the API. */,
"attest-ent-machine", _))
key_name_for_spkac, _))
.Times(1);
// SignEnterpriseChallenge must be called exactly once.
EXPECT_CALL(
mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(
chromeos::attestation::KEY_DEVICE, cryptohome::Identification(),
"attest-ent-machine", "google.com", "device_id", _, "challenge", _))
"attest-ent-machine", "google.com", "device_id", _, "challenge",
key_name_for_spkac, _))
.Times(1);
std::unique_ptr<base::Value> value(RunFunctionAndReturnSingleResult(
......@@ -488,7 +495,7 @@ TEST_F(EPKChallengeUserKeyTest, DoesKeyExistDbusFailed) {
}
TEST_F(EPKChallengeUserKeyTest, GetCertificateFailed) {
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillRepeatedly(Invoke(GetCertificateCallbackFalse));
EXPECT_EQ(GetCertificateError(kGetCertificateFailed),
......@@ -497,7 +504,7 @@ TEST_F(EPKChallengeUserKeyTest, GetCertificateFailed) {
TEST_F(EPKChallengeUserKeyTest, SignChallengeFailed) {
EXPECT_CALL(mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _))
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _))
.WillRepeatedly(Invoke(SignChallengeCallbackFalse));
EXPECT_EQ(EPKPChallengeKeyBase::kSignChallengeFailedError,
......@@ -518,7 +525,8 @@ TEST_F(EPKChallengeUserKeyTest, KeyExists) {
AccountId::FromUserEmail(kUserEmail)),
"attest-ent-user", std::string());
// GetCertificate must not be called if the key exists.
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _)).Times(0);
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _))
.Times(0);
EXPECT_TRUE(utils::RunFunction(func_.get(), CreateArgs(), browser(),
extensions::api_test_utils::NONE));
......@@ -545,7 +553,7 @@ TEST_F(EPKChallengeUserKeyTest, Success) {
EXPECT_CALL(
mock_attestation_flow_,
GetCertificate(chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE,
_, _, _, _))
_, _, _, _, _))
.Times(1);
const cryptohome::Identification cryptohome_id(
AccountId::FromUserEmail(kUserEmail));
......@@ -554,7 +562,7 @@ TEST_F(EPKChallengeUserKeyTest, Success) {
mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(
chromeos::attestation::KEY_USER, cryptohome_id, "attest-ent-user",
kUserEmail, "device_id", _, "challenge", _))
kUserEmail, "device_id", _, "challenge", _, _))
.Times(1);
// RegisterKey must be called exactly once.
EXPECT_CALL(mock_async_method_caller_,
......
......@@ -43,6 +43,12 @@
#include "google_apis/gaia/gaia_auth_util.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace {
// Prefix for naming machine keys used for SignedPublicKeyAndChallenge when
// challenging the EMK with register=true.
const char kEnterpriseMachineKeyForSpkacPrefix[] = "attest-ent-machine-";
} // namespace
namespace extensions {
namespace api_epkp = api::enterprise_platform_keys_private;
......@@ -68,12 +74,14 @@ EPKPChallengeKeyBase::PrepareKeyContext::PrepareKeyContext(
const std::string& key_name,
chromeos::attestation::AttestationCertificateProfile certificate_profile,
bool require_user_consent,
const std::string& key_name_for_spkac,
const base::Callback<void(PrepareKeyResult)>& callback)
: key_type(key_type),
account_id(account_id),
key_name(key_name),
certificate_profile(certificate_profile),
require_user_consent(require_user_consent),
key_name_for_spkac(key_name_for_spkac),
callback(callback) {}
EPKPChallengeKeyBase::PrepareKeyContext::PrepareKeyContext(
......@@ -199,13 +207,11 @@ void EPKPChallengeKeyBase::PrepareKey(
const std::string& key_name,
chromeos::attestation::AttestationCertificateProfile certificate_profile,
bool require_user_consent,
const std::string& key_name_for_spkac,
const base::Callback<void(PrepareKeyResult)>& callback) {
const PrepareKeyContext context = PrepareKeyContext(key_type,
account_id,
key_name,
certificate_profile,
require_user_consent,
callback);
const PrepareKeyContext context =
PrepareKeyContext(key_type, account_id, key_name, certificate_profile,
require_user_consent, key_name_for_spkac, callback);
cryptohome_client_->TpmAttestationIsPrepared(
base::BindOnce(&EPKPChallengeKeyBase::IsAttestationPreparedCallback,
base::Unretained(this), context));
......@@ -224,6 +230,18 @@ void EPKPChallengeKeyBase::IsAttestationPreparedCallback(
base::Unretained(this), context));
return;
}
if (!context.key_name_for_spkac.empty()) {
// Generate a new key and have it signed by PCA.
attestation_flow_->GetCertificate(
context.certificate_profile, context.account_id,
std::string(), // Not used.
true, // Force a new key to be generated.
context.key_name_for_spkac,
base::Bind(&EPKPChallengeKeyBase::GetCertificateCallback,
base::Unretained(this), context.callback));
return;
}
// Attestation is available, see if the key we need already exists.
cryptohome_client_->TpmAttestationDoesKeyExist(
context.key_type,
......@@ -295,6 +313,7 @@ void EPKPChallengeKeyBase::AskForUserConsentCallback(
context.certificate_profile, context.account_id,
std::string(), // Not used.
true, // Force a new key to be generated.
std::string(), // Leave key name empty to generate a default name.
base::Bind(&EPKPChallengeKeyBase::GetCertificateCallback,
base::Unretained(this), context.callback));
}
......@@ -392,18 +411,31 @@ void EPKPChallengeMachineKey::GetDeviceAttestationEnabledCallback(
return;
}
// The EMK cannot be registered as that would relinquish it and the DMServer
// relies on it to remain stable. If register_key = true, generate a new
// machine key to side-load into the system-wide token. This key will be
// used for SignedPublicKeyAndChallenge but the challenge response will still
// be singed using the stable EMK.
std::string key_name_for_spkac;
if (register_key) {
key_name_for_spkac = kEnterpriseMachineKeyForSpkacPrefix + extension_->id();
}
PrepareKey(chromeos::attestation::KEY_DEVICE,
EmptyAccountId(), // Not used.
chromeos::attestation::kEnterpriseMachineKey,
chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE,
false, // user consent is not required.
key_name_for_spkac,
base::Bind(&EPKPChallengeMachineKey::PrepareKeyCallback,
base::Unretained(this), challenge, register_key));
base::Unretained(this), challenge, register_key,
key_name_for_spkac));
}
void EPKPChallengeMachineKey::PrepareKeyCallback(const std::string& challenge,
bool register_key,
PrepareKeyResult result) {
void EPKPChallengeMachineKey::PrepareKeyCallback(
const std::string& challenge,
bool register_key,
const std::string& key_name_for_spkac,
PrepareKeyResult result) {
if (result != PREPARE_KEY_OK) {
callback_.Run(false,
base::StringPrintf(kGetCertificateFailedError, result));
......@@ -418,7 +450,7 @@ void EPKPChallengeMachineKey::PrepareKeyCallback(const std::string& challenge,
GetDeviceId(),
register_key ? chromeos::attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY
: chromeos::attestation::CHALLENGE_OPTION_NONE,
challenge,
challenge, key_name_for_spkac,
base::Bind(&EPKPChallengeMachineKey::SignChallengeCallback,
base::Unretained(this), register_key));
}
......@@ -432,10 +464,12 @@ void EPKPChallengeMachineKey::SignChallengeCallback(
return;
}
if (register_key) {
std::string key_name_for_spkac =
kEnterpriseMachineKeyForSpkacPrefix + extension_->id();
async_caller_->TpmAttestationRegisterKey(
chromeos::attestation::KEY_DEVICE,
cryptohome::Identification(), // Not used.
chromeos::attestation::kEnterpriseMachineKey,
key_name_for_spkac,
base::Bind(&EPKPChallengeMachineKey::RegisterKeyCallback,
base::Unretained(this), response));
} else {
......@@ -559,7 +593,7 @@ void EPKPChallengeUserKey::GetDeviceAttestationEnabledCallback(
PrepareKey(chromeos::attestation::KEY_USER, GetAccountId(),
chromeos::attestation::kEnterpriseUserKey,
chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE,
require_user_consent,
require_user_consent, std::string() /* key_name_for_spkac */,
base::Bind(&EPKPChallengeUserKey::PrepareKeyCallback,
base::Unretained(this), challenge, register_key));
}
......@@ -580,7 +614,7 @@ void EPKPChallengeUserKey::PrepareKeyCallback(const std::string& challenge,
chromeos::attestation::kEnterpriseUserKey, GetUserEmail(), GetDeviceId(),
register_key ? chromeos::attestation::CHALLENGE_INCLUDE_SIGNED_PUBLIC_KEY
: chromeos::attestation::CHALLENGE_OPTION_NONE,
challenge,
challenge, std::string() /* key_name_for_spkac */,
base::Bind(&EPKPChallengeUserKey::SignChallengeCallback,
base::Unretained(this), register_key));
}
......
......@@ -100,16 +100,18 @@ class EPKPChallengeKeyBase {
// Returns the enterprise virtual device ID.
std::string GetDeviceId() const;
// Prepares the key for signing. It will first check if the key exists. If
// the key does not exist, it will call AttestationFlow::GetCertificate() to
// get a new one. If require_user_consent is true, it will explicitly ask for
// user consent before calling GetCertificate().
// Prepares the key for signing. It will first check if a new key should be
// generated, i.e. |key_name_for_spkac| is not empty or the key doesn't
// exist and, if necessary, call AttestationFlow::GetCertificate() to get a
// new one. If require_user_consent is true, it will explicitly ask for user
// consent before calling GetCertificate().
void PrepareKey(
chromeos::attestation::AttestationKeyType key_type,
const AccountId& account_id,
const std::string& key_name,
chromeos::attestation::AttestationCertificateProfile certificate_profile,
bool require_user_consent,
const std::string& key_name_for_spkac,
const base::Callback<void(PrepareKeyResult)>& callback);
chromeos::CryptohomeClient* cryptohome_client_;
......@@ -130,6 +132,7 @@ class EPKPChallengeKeyBase {
chromeos::attestation::AttestationCertificateProfile
certificate_profile,
bool require_user_consent,
const std::string& key_name_for_spkac,
const base::Callback<void(PrepareKeyResult)>& callback);
PrepareKeyContext(const PrepareKeyContext& other);
~PrepareKeyContext();
......@@ -139,6 +142,7 @@ class EPKPChallengeKeyBase {
const std::string key_name;
chromeos::attestation::AttestationCertificateProfile certificate_profile;
bool require_user_consent;
std::string key_name_for_spkac;
const base::Callback<void(PrepareKeyResult)> callback;
};
......@@ -195,6 +199,7 @@ class EPKPChallengeMachineKey : public EPKPChallengeKeyBase {
bool enabled);
void PrepareKeyCallback(const std::string& challenge,
bool register_key,
const std::string& key_name_for_spkac,
PrepareKeyResult result);
void SignChallengeCallback(bool register_key,
bool success,
......
......@@ -88,6 +88,7 @@ void SignChallengeCallbackTrue(
const std::string& device_id,
chromeos::attestation::AttestationChallengeOptions options,
const std::string& challenge,
const std::string& key_name_for_spkac,
const cryptohome::AsyncMethodCaller::DataCallback& callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(callback, true, "response"));
......@@ -101,6 +102,7 @@ void SignChallengeCallbackFalse(
const std::string& device_id,
chromeos::attestation::AttestationChallengeOptions options,
const std::string& challenge,
const std::string& key_name_for_spkac,
const cryptohome::AsyncMethodCaller::DataCallback& callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(callback, false, ""));
......@@ -111,6 +113,7 @@ void GetCertificateCallbackTrue(
const AccountId& account_id,
const std::string& request_origin,
bool force_new_key,
const std::string& key_name,
const chromeos::attestation::AttestationFlow::CertificateCallback&
callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
......@@ -124,6 +127,7 @@ void GetCertificateCallbackUnspecifiedFailure(
const AccountId& account_id,
const std::string& request_origin,
bool force_new_key,
const std::string& key_name,
const chromeos::attestation::AttestationFlow::CertificateCallback&
callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
......@@ -138,6 +142,7 @@ void GetCertificateCallbackBadRequestFailure(
const AccountId& account_id,
const std::string& request_origin,
bool force_new_key,
const std::string& key_name,
const chromeos::attestation::AttestationFlow::CertificateCallback&
callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
......@@ -164,9 +169,9 @@ class EPKPChallengeKeyTestBase : public BrowserWithTestWindowTest {
ON_CALL(mock_async_method_caller_, TpmAttestationRegisterKey(_, _, _, _))
.WillByDefault(Invoke(RegisterKeyCallbackTrue));
ON_CALL(mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _))
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _))
.WillByDefault(Invoke(SignChallengeCallbackTrue));
ON_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
ON_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillByDefault(Invoke(GetCertificateCallbackTrue));
stub_install_attributes_.SetCloudManaged("google.com", "device_id");
......@@ -301,7 +306,7 @@ TEST_F(EPKPChallengeMachineKeyTest, DoesKeyExistDbusFailed) {
}
TEST_F(EPKPChallengeMachineKeyTest, GetCertificateFailed) {
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillRepeatedly(Invoke(GetCertificateCallbackUnspecifiedFailure));
EXPECT_EQ(GetCertificateError(kGetCertificateFailed),
......@@ -310,7 +315,7 @@ TEST_F(EPKPChallengeMachineKeyTest, GetCertificateFailed) {
TEST_F(EPKPChallengeMachineKeyTest, SignChallengeFailed) {
EXPECT_CALL(mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _))
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _))
.WillRepeatedly(Invoke(SignChallengeCallbackFalse));
EXPECT_EQ(EPKPChallengeKeyBase::kSignChallengeFailedError,
......@@ -321,7 +326,7 @@ TEST_F(EPKPChallengeMachineKeyTest, KeyExists) {
cryptohome_client_.SetTpmAttestationDeviceCertificate("attest-ent-machine",
std::string());
// GetCertificate must not be called if the key exists.
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _))
.Times(0);
EXPECT_TRUE(utils::RunFunction(func_.get(), kArgs, browser(),
......@@ -366,14 +371,14 @@ TEST_P(EPKPChallengeMachineKeyAllProfilesTest, Success) {
EXPECT_CALL(mock_attestation_flow_,
GetCertificate(
chromeos::attestation::PROFILE_ENTERPRISE_MACHINE_CERTIFICATE,
_, _, _, _))
_, _, _, _, _))
.Times(1);
// SignEnterpriseChallenge must be called exactly once.
EXPECT_CALL(
mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(
chromeos::attestation::KEY_DEVICE, cryptohome::Identification(),
"attest-ent-machine", "google.com", "device_id", _, "challenge", _))
EXPECT_CALL(mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(
chromeos::attestation::KEY_DEVICE,
cryptohome::Identification(), "attest-ent-machine",
"google.com", "device_id", _, "challenge", _, _))
.Times(1);
std::unique_ptr<base::Value> value(utils::RunFunctionAndReturnSingleResult(
......@@ -464,7 +469,7 @@ TEST_F(EPKPChallengeUserKeyTest, DoesKeyExistDbusFailed) {
}
TEST_F(EPKPChallengeUserKeyTest, GetCertificateFailedWithUnspecifiedFailure) {
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillRepeatedly(Invoke(GetCertificateCallbackUnspecifiedFailure));
EXPECT_EQ(GetCertificateError(kGetCertificateFailed),
......@@ -472,7 +477,7 @@ TEST_F(EPKPChallengeUserKeyTest, GetCertificateFailedWithUnspecifiedFailure) {
}
TEST_F(EPKPChallengeUserKeyTest, GetCertificateFailedWithBadRequestFailure) {
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _))
.WillRepeatedly(Invoke(GetCertificateCallbackBadRequestFailure));
EXPECT_EQ(GetCertificateError(kGetCertificateFailed),
......@@ -481,7 +486,7 @@ TEST_F(EPKPChallengeUserKeyTest, GetCertificateFailedWithBadRequestFailure) {
TEST_F(EPKPChallengeUserKeyTest, SignChallengeFailed) {
EXPECT_CALL(mock_async_method_caller_,
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _))
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _))
.WillRepeatedly(Invoke(SignChallengeCallbackFalse));
EXPECT_EQ(EPKPChallengeKeyBase::kSignChallengeFailedError,
......@@ -502,7 +507,7 @@ TEST_F(EPKPChallengeUserKeyTest, KeyExists) {
AccountId::FromUserEmail(kUserEmail)),
"attest-ent-user", std::string());
// GetCertificate must not be called if the key exists.
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _))
EXPECT_CALL(mock_attestation_flow_, GetCertificate(_, _, _, _, _, _))
.Times(0);
EXPECT_TRUE(utils::RunFunction(func_.get(), kArgs, browser(),
......@@ -527,10 +532,10 @@ TEST_F(EPKPChallengeUserKeyTest, PersonalDevice) {
TEST_F(EPKPChallengeUserKeyTest, Success) {
// GetCertificate must be called exactly once.
EXPECT_CALL(mock_attestation_flow_,
GetCertificate(
chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE,
_, _, _, _))
EXPECT_CALL(
mock_attestation_flow_,
GetCertificate(chromeos::attestation::PROFILE_ENTERPRISE_USER_CERTIFICATE,
_, _, _, _, _))
.Times(1);
const AccountId account_id = AccountId::FromUserEmail(kUserEmail);
// SignEnterpriseChallenge must be called exactly once.
......@@ -539,7 +544,7 @@ TEST_F(EPKPChallengeUserKeyTest, Success) {
chromeos::attestation::KEY_USER,
cryptohome::Identification(account_id), "attest-ent-user",
cryptohome::Identification(account_id).id(), "device_id", _,
"challenge", _))
"challenge", _, _))
.Times(1);
// RegisterKey must be called exactly once.
EXPECT_CALL(mock_async_method_caller_,
......
......@@ -121,12 +121,14 @@ void AttestationFlow::GetCertificate(
const AccountId& account_id,
const std::string& request_origin,
bool force_new_key,
const std::string& key_name,
const CertificateCallback& callback) {
// If this device has not enrolled with the Privacy CA, we need to do that
// first. Once enrolled we can proceed with the certificate request.
const base::Closure do_cert_request = base::Bind(
&AttestationFlow::StartCertificateRequest, weak_factory_.GetWeakPtr(),
certificate_profile, account_id, request_origin, force_new_key, callback);
const base::Closure do_cert_request =
base::Bind(&AttestationFlow::StartCertificateRequest,
weak_factory_.GetWeakPtr(), certificate_profile, account_id,
request_origin, force_new_key, key_name, callback);
const base::RepeatingClosure on_failure =
base::BindRepeating(callback, ATTESTATION_UNSPECIFIED_FAILURE, "");
const base::Closure initiate_enroll = base::Bind(
......@@ -220,31 +222,35 @@ void AttestationFlow::StartCertificateRequest(
const AccountId& account_id,
const std::string& request_origin,
bool generate_new_key,
const std::string& key_name,
const CertificateCallback& callback) {
AttestationKeyType key_type = GetKeyTypeForProfile(certificate_profile);
std::string key_name =
GetKeyNameForProfile(certificate_profile, request_origin);
std::string attestation_key_name =
!key_name.empty()
? key_name
: GetKeyNameForProfile(certificate_profile, request_origin);
if (generate_new_key) {
// Get the attestation service to create a Privacy CA certificate request.
async_caller_->AsyncTpmAttestationCreateCertRequest(
server_proxy_->GetType(), certificate_profile,
cryptohome::Identification(account_id), request_origin,
base::Bind(&AttestationFlow::SendCertificateRequestToPCA,
weak_factory_.GetWeakPtr(), key_type, account_id, key_name,
callback));
weak_factory_.GetWeakPtr(), key_type, account_id,
attestation_key_name, callback));
} else {
// If the key already exists, query the existing certificate.
const base::Closure on_key_exists = base::Bind(
&AttestationFlow::GetExistingCertificate, weak_factory_.GetWeakPtr(),
key_type, account_id, key_name, callback);
key_type, account_id, attestation_key_name, callback);
// If the key does not exist, call this method back with |generate_new_key|
// set to true.
const base::Closure on_key_not_exists = base::Bind(
&AttestationFlow::StartCertificateRequest, weak_factory_.GetWeakPtr(),
certificate_profile, account_id, request_origin, true, callback);
const base::Closure on_key_not_exists =
base::Bind(&AttestationFlow::StartCertificateRequest,
weak_factory_.GetWeakPtr(), certificate_profile, account_id,
request_origin, true, attestation_key_name, callback);
cryptohome_client_->TpmAttestationDoesKeyExist(
key_type, cryptohome::CreateAccountIdentifierFromAccountId(account_id),
key_name,
attestation_key_name,
base::BindOnce(
&DBusBoolRedirectCallback, on_key_exists, on_key_not_exists,
base::BindRepeating(callback, ATTESTATION_UNSPECIFIED_FAILURE, ""),
......
......@@ -119,6 +119,8 @@ class COMPONENT_EXPORT(CHROMEOS_ATTESTATION) AttestationFlow {
// force_new_key - If set to true, a new key will be generated even if a key
// already exists for the profile. The new key will replace
// the existing key on success.
// key_name - The name of the key. If left empty, a default name derived
// from the |certiifcate_profile| and |account_id| will be used.
// callback - A callback which will be called when the operation completes.
// On success |result| will be true and |data| will contain the
// PCA-issued certificate chain in PEM format.
......@@ -126,6 +128,7 @@ class COMPONENT_EXPORT(CHROMEOS_ATTESTATION) AttestationFlow {
const AccountId& account_id,
const std::string& request_origin,
bool force_new_key,
const std::string& key_name,
const CertificateCallback& callback);
private:
......@@ -199,12 +202,15 @@ class COMPONENT_EXPORT(CHROMEOS_ATTESTATION) AttestationFlow {
// account_id - Identifies the active user.
// request_origin - An identifier for the origin of this request.
// generate_new_key - If set to true a new key is generated.
// key_name - The name of the key. If left empty, a default name derived
// from the |certiifcate_profile| and |account_id| will be used.
// callback - Called when the operation completes.
void StartCertificateRequest(
const AttestationCertificateProfile certificate_profile,
const AccountId& account_id,
const std::string& request_origin,
bool generate_new_key,
const std::string& key_name,
const CertificateCallback& callback);
// Called when the attestation daemon has finished creating a certificate
......
......@@ -142,7 +142,8 @@ TEST_F(AttestationFlowTest, GetCertificate) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, account_id,
"fake_origin", true, mock_callback);
"fake_origin", true, std::string() /* key_name */,
mock_callback);
RunUntilIdle();
}
......@@ -231,7 +232,8 @@ TEST_F(AttestationFlowTest, GetCertificate_Attestation_Not_Prepared) {
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.set_retry_delay(base::TimeDelta::FromMilliseconds(30));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, account_id,
"fake_origin", true, callback);
"fake_origin", true, std::string() /* key_name */,
callback);
Run();
}
......@@ -263,7 +265,8 @@ TEST_F(AttestationFlowTest, GetCertificate_Attestation_Never_Prepared) {
flow.set_ready_timeout(base::TimeDelta::FromMilliseconds(20));
flow.set_retry_delay(base::TimeDelta::FromMilliseconds(6));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(),
"fake_origin", true, callback);
"fake_origin", true, std::string() /* key_name */,
callback);
Run();
}
......@@ -292,7 +295,7 @@ TEST_F(AttestationFlowTest, GetCertificate_NoEK) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "",
true, mock_callback);
true, std::string() /* key_name */, mock_callback);
RunUntilIdle();
}
......@@ -325,7 +328,7 @@ TEST_F(AttestationFlowTest, GetCertificate_EKRejected) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "",
true, mock_callback);
true, std::string() /* key_name */, mock_callback);
RunUntilIdle();
}
......@@ -364,7 +367,7 @@ TEST_F(AttestationFlowTest, GetCertificate_FailEnroll) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "",
true, mock_callback);
true, std::string() /* key_name */, mock_callback);
RunUntilIdle();
}
......@@ -407,7 +410,7 @@ TEST_F(AttestationFlowTest, GetMachineCertificateAlreadyEnrolled) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_MACHINE_CERTIFICATE, EmptyAccountId(),
"", true, mock_callback);
"", true, std::string() /* key_name */, mock_callback);
RunUntilIdle();
}
......@@ -450,7 +453,8 @@ TEST_F(AttestationFlowTest, GetEnrollmentCertificateAlreadyEnrolled) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_ENROLLMENT_CERTIFICATE,
EmptyAccountId(), "", true, mock_callback);
EmptyAccountId(), "", true, std::string() /* key_name */,
mock_callback);
RunUntilIdle();
}
......@@ -478,7 +482,7 @@ TEST_F(AttestationFlowTest, GetCertificate_FailCreateCertRequest) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "",
true, mock_callback);
true, std::string() /* key_name */, mock_callback);
RunUntilIdle();
}
......@@ -511,7 +515,7 @@ TEST_F(AttestationFlowTest, GetCertificate_CertRequestRejected) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "",
true, mock_callback);
true, std::string() /* key_name */, mock_callback);
RunUntilIdle();
}
......@@ -550,7 +554,7 @@ TEST_F(AttestationFlowTest, GetCertificate_CertRequestBadRequest) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "",
true, mock_callback);
true, std::string() /* key_name */, mock_callback);
RunUntilIdle();
}
......@@ -575,7 +579,7 @@ TEST_F(AttestationFlowTest, GetCertificate_FailIsEnrolled) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "",
true, mock_callback);
true, std::string() /* key_name */, mock_callback);
RunUntilIdle();
}
......@@ -618,7 +622,7 @@ TEST_F(AttestationFlowTest, GetCertificate_CheckExisting) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "",
false, mock_callback);
false, std::string() /* key_name */, mock_callback);
RunUntilIdle();
}
......@@ -644,7 +648,7 @@ TEST_F(AttestationFlowTest, GetCertificate_AlreadyExists) {
std::unique_ptr<ServerProxy> proxy_interface(proxy.release());
AttestationFlow flow(&async_caller, &client, std::move(proxy_interface));
flow.GetCertificate(PROFILE_ENTERPRISE_USER_CERTIFICATE, EmptyAccountId(), "",
false, mock_callback);
false, std::string() /* key_name */, mock_callback);
RunUntilIdle();
}
......
......@@ -69,11 +69,12 @@ class MockAttestationFlow : public AttestationFlow {
MockAttestationFlow();
virtual ~MockAttestationFlow();
MOCK_METHOD5(GetCertificate,
MOCK_METHOD6(GetCertificate,
void(AttestationCertificateProfile,
const AccountId& account_id,
const std::string&,
bool,
const std::string&, /* key_name */
const CertificateCallback&));
};
......
......@@ -104,10 +104,11 @@ class AsyncMethodCallerImpl : public AsyncMethodCaller,
const std::string& device_id,
chromeos::attestation::AttestationChallengeOptions options,
const std::string& challenge,
const std::string& key_name_for_spkac,
const DataCallback& callback) override {
CryptohomeClient::Get()->TpmAttestationSignEnterpriseChallenge(
key_type, CreateAccountIdentifierFromIdentification(cryptohome_id),
key_name, domain, device_id, options, challenge,
key_name, domain, device_id, options, challenge, key_name_for_spkac,
base::BindOnce(
&AsyncMethodCallerImpl::RegisterAsyncDataCallback,
weak_ptr_factory_.GetWeakPtr(), callback,
......
......@@ -94,6 +94,9 @@ class COMPONENT_EXPORT(CHROMEOS_CRYPTOHOME) AsyncMethodCaller {
// the challenge response. If |key_type| is KEY_USER, a |user_id| must be
// provided. Otherwise |user_id| is ignored. For normal GAIA users the
// |user_id| is an AccountaId-derived string (see AccountId::GetAccountIdKey).
// If |key_name_for_spkac| is not empty, then the corresponding key will be
// used for SignedPublicKeyAndChallenge, but the challenge response will still
// be signed by the key specified by |key_name| (EMK or EUK).
virtual void TpmAttestationSignEnterpriseChallenge(
chromeos::attestation::AttestationKeyType key_type,
const Identification& user_id,
......@@ -102,6 +105,7 @@ class COMPONENT_EXPORT(CHROMEOS_CRYPTOHOME) AsyncMethodCaller {
const std::string& device_id,
chromeos::attestation::AttestationChallengeOptions options,
const std::string& challenge,
const std::string& key_name_for_spkac,
const DataCallback& callback) = 0;
// Asks cryptohomed to asynchronously sign a simple challenge with the key
......
......@@ -41,10 +41,10 @@ void MockAsyncMethodCaller::SetUp(bool success, MountError return_code) {
.WillByDefault(
WithArgs<4>(Invoke(this,
&MockAsyncMethodCaller::FakeFinishCertRequest)));
ON_CALL(*this, TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _))
.WillByDefault(
WithArgs<7>(Invoke(this,
&MockAsyncMethodCaller::FakeEnterpriseChallenge)));
ON_CALL(*this,
TpmAttestationSignEnterpriseChallenge(_, _, _, _, _, _, _, _, _))
.WillByDefault(WithArgs<8>(
Invoke(this, &MockAsyncMethodCaller::FakeEnterpriseChallenge)));
ON_CALL(*this, TpmAttestationRegisterKey(_, _, _, _))
.WillByDefault(
WithArgs<3>(Invoke(this, &MockAsyncMethodCaller::DoCallback)));
......
......@@ -53,7 +53,7 @@ class MockAsyncMethodCaller : public AsyncMethodCaller {
const Identification& user_id,
const std::string& key_name,
const Callback& callback));
MOCK_METHOD8(TpmAttestationSignEnterpriseChallenge,
MOCK_METHOD9(TpmAttestationSignEnterpriseChallenge,
void(chromeos::attestation::AttestationKeyType key_type,
const Identification& user_id,
const std::string& key_name,
......@@ -61,6 +61,7 @@ class MockAsyncMethodCaller : public AsyncMethodCaller {
const std::string& device_id,
chromeos::attestation::AttestationChallengeOptions options,
const std::string& challenge,
const std::string& key_name_for_spkac,
const DataCallback& callback));
MOCK_METHOD5(TpmAttestationSignSimpleChallenge,
void(chromeos::attestation::AttestationKeyType key_type,
......
......@@ -673,10 +673,11 @@ class CryptohomeClientImpl : public CryptohomeClient {
const std::string& device_id,
attestation::AttestationChallengeOptions options,
const std::string& challenge,
const std::string& key_name_for_spkac,
AsyncMethodCallback callback) override {
dbus::MethodCall method_call(
cryptohome::kCryptohomeInterface,
cryptohome::kCryptohomeTpmAttestationSignEnterpriseVaChallenge);
cryptohome::kCryptohomeTpmAttestationSignEnterpriseVaChallengeV2);
dbus::MessageWriter writer(&method_call);
writer.AppendInt32(GetVerifiedAccessType());
bool is_user_specific = (key_type == attestation::KEY_USER);
......@@ -691,6 +692,7 @@ class CryptohomeClientImpl : public CryptohomeClient {
writer.AppendBool(include_signed_public_key);
writer.AppendArrayOfBytes(
reinterpret_cast<const uint8_t*>(challenge.data()), challenge.size());
writer.AppendString(key_name_for_spkac);
proxy_->CallMethod(
&method_call, kTpmDBusTimeoutMs,
base::BindOnce(&CryptohomeClientImpl::OnAsyncMethodCall,
......
......@@ -423,7 +423,10 @@ class COMPONENT_EXPORT(CRYPTOHOME_CLIENT) CryptohomeClient {
// The |callback| will be called when the dbus call completes. When the
// operation completes, the AsyncCallStatusWithDataHandler signal handler is
// called. If |key_type| is KEY_USER, a |id| must be provided.
// Otherwise |id| is ignored.
// Otherwise |id| is ignored. If |key_name_for_spkac| is not empty, then the
// corresponding key will be used for SignedPublicKeyAndChallenge, but the
// challenge response will still be signed by the key specified by |key_name|
// (EMK or EUK).
virtual void TpmAttestationSignEnterpriseChallenge(
attestation::AttestationKeyType key_type,
const cryptohome::AccountIdentifier& id,
......@@ -432,6 +435,7 @@ class COMPONENT_EXPORT(CRYPTOHOME_CLIENT) CryptohomeClient {
const std::string& device_id,
attestation::AttestationChallengeOptions options,
const std::string& challenge,
const std::string& key_name_for_spkac,
AsyncMethodCallback callback) = 0;
// Asynchronously signs a simple challenge with the key specified by
......
......@@ -472,6 +472,7 @@ void FakeCryptohomeClient::TpmAttestationSignEnterpriseChallenge(
const std::string& device_id,
attestation::AttestationChallengeOptions options,
const std::string& challenge,
const std::string& key_name_for_spkac,
AsyncMethodCallback callback) {
ReturnAsyncMethodData(std::move(callback), std::string());
}
......
......@@ -150,6 +150,7 @@ class COMPONENT_EXPORT(CRYPTOHOME_CLIENT) FakeCryptohomeClient
const std::string& device_id,
attestation::AttestationChallengeOptions options,
const std::string& challenge,
const std::string& key_name_for_spkac,
AsyncMethodCallback callback) override;
void TpmAttestationSignSimpleChallenge(
attestation::AttestationKeyType key_type,
......
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