Commit 44a555b5 authored by Leo Lai's avatar Leo Lai Committed by Commit Bot

use AttestationClient to get/set key payloads.

We are deprecating attestation methods by CryptohomeClient.

BUG=b:158955123
TEST=unit_tests.

Change-Id: I244899c638df91c27f34ee3e5888077d61248c70
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2497903
Commit-Queue: Leo Lai <cylai@google.com>
Reviewed-by: default avatarMaksim Ivanov <emaxx@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821289}
parent 89540fb3
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
#include "chromeos/attestation/attestation_flow.h" #include "chromeos/attestation/attestation_flow.h"
#include "chromeos/cryptohome/async_method_caller.h" #include "chromeos/cryptohome/async_method_caller.h"
#include "chromeos/cryptohome/cryptohome_parameters.h" #include "chromeos/cryptohome/cryptohome_parameters.h"
#include "chromeos/dbus/attestation/attestation_client.h"
#include "chromeos/dbus/attestation/interface.pb.h"
#include "chromeos/dbus/cryptohome/cryptohome_client.h" #include "chromeos/dbus/cryptohome/cryptohome_client.h"
#include "chromeos/dbus/dbus_method_call_status.h" #include "chromeos/dbus/dbus_method_call_status.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
...@@ -266,12 +268,13 @@ void MachineCertificateUploaderImpl::CheckCertificateExpiry( ...@@ -266,12 +268,13 @@ void MachineCertificateUploaderImpl::CheckCertificateExpiry(
if (num_certificates == 0) { if (num_certificates == 0) {
LOG(WARNING) << "Failed to parse certificate chain, cannot check expiry."; LOG(WARNING) << "Failed to parse certificate chain, cannot check expiry.";
} }
// Get the payload and check if the certificate has already been uploaded. ::attestation::GetKeyInfoRequest request;
GetKeyPayload( request.set_username("");
base::BindRepeating(&MachineCertificateUploaderImpl::CheckIfUploaded, request.set_key_label(kEnterpriseMachineKey);
weak_factory_.GetWeakPtr(), pem_certificate_chain), AttestationClient::Get()->GetKeyInfo(
base::BindRepeating(&MachineCertificateUploaderImpl::Reschedule, request,
weak_factory_.GetWeakPtr())); base::BindOnce(&MachineCertificateUploaderImpl::CheckIfUploaded,
weak_factory_.GetWeakPtr(), pem_certificate_chain));
} }
void MachineCertificateUploaderImpl::UploadCertificate( void MachineCertificateUploaderImpl::UploadCertificate(
...@@ -284,9 +287,14 @@ void MachineCertificateUploaderImpl::UploadCertificate( ...@@ -284,9 +287,14 @@ void MachineCertificateUploaderImpl::UploadCertificate(
void MachineCertificateUploaderImpl::CheckIfUploaded( void MachineCertificateUploaderImpl::CheckIfUploaded(
const std::string& pem_certificate_chain, const std::string& pem_certificate_chain,
const std::string& key_payload) { const ::attestation::GetKeyInfoReply& reply) {
if (reply.status() != ::attestation::STATUS_SUCCESS) {
Reschedule();
return;
}
AttestationKeyPayload payload_pb; AttestationKeyPayload payload_pb;
if (!key_payload.empty() && payload_pb.ParseFromString(key_payload) && if (!reply.payload().empty() && payload_pb.ParseFromString(reply.payload()) &&
payload_pb.is_certificate_uploaded()) { payload_pb.is_certificate_uploaded()) {
// Already uploaded... nothing more to do. // Already uploaded... nothing more to do.
return; return;
...@@ -294,45 +302,35 @@ void MachineCertificateUploaderImpl::CheckIfUploaded( ...@@ -294,45 +302,35 @@ void MachineCertificateUploaderImpl::CheckIfUploaded(
UploadCertificate(pem_certificate_chain); UploadCertificate(pem_certificate_chain);
} }
void MachineCertificateUploaderImpl::GetKeyPayload(
base::RepeatingCallback<void(const std::string&)> callback,
base::RepeatingCallback<void()> on_failure) {
cryptohome_client_->TpmAttestationGetKeyPayload(
KEY_DEVICE,
cryptohome::AccountIdentifier(), // Not used.
kEnterpriseMachineKey,
base::BindOnce(DBusStringCallback, callback, on_failure, FROM_HERE));
}
void MachineCertificateUploaderImpl::OnUploadComplete(bool status) { void MachineCertificateUploaderImpl::OnUploadComplete(bool status) {
if (status) { if (status) {
VLOG(1) << "Enterprise Machine Certificate uploaded to DMServer."; VLOG(1) << "Enterprise Machine Certificate uploaded to DMServer.";
GetKeyPayload( ::attestation::GetKeyInfoRequest request;
base::BindRepeating(&MachineCertificateUploaderImpl::MarkAsUploaded, request.set_username("");
weak_factory_.GetWeakPtr()), request.set_key_label(kEnterpriseMachineKey);
base::DoNothing()); AttestationClient::Get()->GetKeyInfo(
request, base::BindOnce(&MachineCertificateUploaderImpl::MarkAsUploaded,
weak_factory_.GetWeakPtr()));
} }
std::move(callback_).Run(status); std::move(callback_).Run(status);
} }
void MachineCertificateUploaderImpl::MarkAsUploaded( void MachineCertificateUploaderImpl::MarkAsUploaded(
const std::string& key_payload) { const ::attestation::GetKeyInfoReply& reply) {
AttestationKeyPayload payload_pb; AttestationKeyPayload payload_pb;
if (!key_payload.empty()) if (!reply.payload().empty())
payload_pb.ParseFromString(key_payload); payload_pb.ParseFromString(reply.payload());
payload_pb.set_is_certificate_uploaded(true); payload_pb.set_is_certificate_uploaded(true);
std::string new_payload; std::string new_payload;
if (!payload_pb.SerializeToString(&new_payload)) { if (!payload_pb.SerializeToString(&new_payload)) {
LOG(WARNING) << "Failed to serialize key payload."; LOG(WARNING) << "Failed to serialize key payload.";
return; return;
} }
cryptohome_client_->TpmAttestationSetKeyPayload( ::attestation::SetKeyPayloadRequest request;
KEY_DEVICE, request.set_username("");
cryptohome::AccountIdentifier(), // Not used. request.set_key_label(kEnterpriseMachineKey);
kEnterpriseMachineKey, new_payload, request.set_payload(new_payload);
base::BindOnce(DBusBoolRedirectCallback, base::RepeatingClosure(), AttestationClient::Get()->SetKeyPayload(request, base::DoNothing());
base::RepeatingClosure(), base::RepeatingClosure(),
FROM_HERE));
} }
void MachineCertificateUploaderImpl::HandleGetCertificateFailure( void MachineCertificateUploaderImpl::HandleGetCertificateFailure(
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chrome/browser/chromeos/attestation/machine_certificate_uploader.h" #include "chrome/browser/chromeos/attestation/machine_certificate_uploader.h"
#include "chromeos/dbus/attestation/interface.pb.h"
#include "chromeos/dbus/constants/attestation_constants.h" #include "chromeos/dbus/constants/attestation_constants.h"
namespace policy { namespace policy {
...@@ -71,19 +72,14 @@ class MachineCertificateUploaderImpl : public MachineCertificateUploader { ...@@ -71,19 +72,14 @@ class MachineCertificateUploaderImpl : public MachineCertificateUploader {
// Checks if a certificate has already been uploaded and, if not, upload. // Checks if a certificate has already been uploaded and, if not, upload.
void CheckIfUploaded(const std::string& pem_certificate_chain, void CheckIfUploaded(const std::string& pem_certificate_chain,
const std::string& key_payload); const ::attestation::GetKeyInfoReply& reply);
// Gets the payload associated with the EMK and sends it to |callback|,
// or call |on_failure| with no arguments if the payload cannot be obtained.
void GetKeyPayload(base::RepeatingCallback<void(const std::string&)> callback,
base::RepeatingCallback<void()> on_failure);
// Called when a certificate upload operation completes. On success, |status| // Called when a certificate upload operation completes. On success, |status|
// will be true. // will be true.
void OnUploadComplete(bool status); void OnUploadComplete(bool status);
// Marks a key as uploaded in the payload proto. // Marks a key as uploaded in the payload proto.
void MarkAsUploaded(const std::string& key_payload); void MarkAsUploaded(const ::attestation::GetKeyInfoReply& reply);
// Handles failure of getting a certificate. // Handles failure of getting a certificate.
void HandleGetCertificateFailure(AttestationStatus status); void HandleGetCertificateFailure(AttestationStatus status);
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "chrome/browser/chromeos/attestation/machine_certificate_uploader_impl.h" #include "chrome/browser/chromeos/attestation/machine_certificate_uploader_impl.h"
#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h" #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
#include "chromeos/attestation/mock_attestation_flow.h" #include "chromeos/attestation/mock_attestation_flow.h"
#include "chromeos/dbus/attestation/fake_attestation_client.h"
#include "chromeos/dbus/cryptohome/fake_cryptohome_client.h" #include "chromeos/dbus/cryptohome/fake_cryptohome_client.h"
#include "chromeos/settings/cros_settings_names.h" #include "chromeos/settings/cros_settings_names.h"
#include "components/policy/core/common/cloud/mock_cloud_policy_client.h" #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
...@@ -38,6 +39,11 @@ const int64_t kCertExpiringSoon = 20; ...@@ -38,6 +39,11 @@ const int64_t kCertExpiringSoon = 20;
const int64_t kCertExpired = -20; const int64_t kCertExpired = -20;
void CertCallbackSuccess(AttestationFlow::CertificateCallback callback) { void CertCallbackSuccess(AttestationFlow::CertificateCallback callback) {
AttestationClient::Get()
->GetTestInterface()
->GetMutableKeyInfoReply(/*username=*/"", kEnterpriseMachineKey)
->set_certificate("fake_cert");
base::ThreadTaskRunnerHandle::Get()->PostTask( base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(std::move(callback), ATTESTATION_SUCCESS, "fake_cert")); base::BindOnce(std::move(callback), ATTESTATION_SUCCESS, "fake_cert"));
...@@ -67,9 +73,11 @@ void StatusCallbackSuccess(policy::CloudPolicyClient::StatusCallback callback) { ...@@ -67,9 +73,11 @@ void StatusCallbackSuccess(policy::CloudPolicyClient::StatusCallback callback) {
class MachineCertificateUploaderTest : public ::testing::TestWithParam<bool> { class MachineCertificateUploaderTest : public ::testing::TestWithParam<bool> {
public: public:
MachineCertificateUploaderTest() { MachineCertificateUploaderTest() {
AttestationClient::InitializeFake();
settings_helper_.ReplaceDeviceSettingsProviderWithStub(); settings_helper_.ReplaceDeviceSettingsProviderWithStub();
policy_client_.SetDMToken("fake_dm_token"); policy_client_.SetDMToken("fake_dm_token");
} }
~MachineCertificateUploaderTest() override { AttestationClient::Shutdown(); }
protected: protected:
enum MockOptions { enum MockOptions {
...@@ -88,12 +96,20 @@ class MachineCertificateUploaderTest : public ::testing::TestWithParam<bool> { ...@@ -88,12 +96,20 @@ class MachineCertificateUploaderTest : public ::testing::TestWithParam<bool> {
if (key_exists) { if (key_exists) {
cryptohome_client_.SetTpmAttestationDeviceCertificate( cryptohome_client_.SetTpmAttestationDeviceCertificate(
kEnterpriseMachineKey, certificate); kEnterpriseMachineKey, certificate);
::attestation::GetKeyInfoReply* key_info =
AttestationClient::Get()->GetTestInterface()->GetMutableKeyInfoReply(
/*username=*/"", kEnterpriseMachineKey);
key_info->set_certificate(certificate);
} }
// Setup expected key payload queries. // Setup expected key payload queries.
bool key_uploaded = refresh || (mock_options & MOCK_KEY_UPLOADED); bool key_uploaded = refresh || (mock_options & MOCK_KEY_UPLOADED);
cryptohome_client_.SetTpmAttestationDeviceKeyPayload( if (key_uploaded) {
kEnterpriseMachineKey, key_uploaded ? CreatePayload() : std::string()); ::attestation::GetKeyInfoReply* key_info =
AttestationClient::Get()->GetTestInterface()->GetMutableKeyInfoReply(
/*username=*/"", kEnterpriseMachineKey);
key_info->set_payload(key_uploaded ? CreatePayload() : std::string());
}
// Setup expected key uploads. Use WillOnce() so StrictMock will trigger an // Setup expected key uploads. Use WillOnce() so StrictMock will trigger an
// error if our expectations are not met exactly. We want to verify that // error if our expectations are not met exactly. We want to verify that
...@@ -165,8 +181,10 @@ TEST_P(MachineCertificateUploaderTest, NewCertificate) { ...@@ -165,8 +181,10 @@ TEST_P(MachineCertificateUploaderTest, NewCertificate) {
SetupMocks(MOCK_NEW_KEY, ""); SetupMocks(MOCK_NEW_KEY, "");
Run(); Run();
EXPECT_EQ(CreatePayload(), EXPECT_EQ(CreatePayload(),
cryptohome_client_.GetTpmAttestationDeviceKeyPayload( AttestationClient::Get()
kEnterpriseMachineKey)); ->GetTestInterface()
->GetMutableKeyInfoReply(/*username=*/"", kEnterpriseMachineKey)
->payload());
} }
TEST_P(MachineCertificateUploaderTest, KeyExistsNotUploaded) { TEST_P(MachineCertificateUploaderTest, KeyExistsNotUploaded) {
...@@ -176,8 +194,10 @@ TEST_P(MachineCertificateUploaderTest, KeyExistsNotUploaded) { ...@@ -176,8 +194,10 @@ TEST_P(MachineCertificateUploaderTest, KeyExistsNotUploaded) {
SetupMocks(MOCK_KEY_EXISTS, certificate); SetupMocks(MOCK_KEY_EXISTS, certificate);
Run(); Run();
EXPECT_EQ(CreatePayload(), EXPECT_EQ(CreatePayload(),
cryptohome_client_.GetTpmAttestationDeviceKeyPayload( AttestationClient::Get()
kEnterpriseMachineKey)); ->GetTestInterface()
->GetMutableKeyInfoReply(/*username=*/"", kEnterpriseMachineKey)
->payload());
} }
TEST_P(MachineCertificateUploaderTest, KeyExistsAlreadyUploaded) { TEST_P(MachineCertificateUploaderTest, KeyExistsAlreadyUploaded) {
...@@ -227,8 +247,10 @@ TEST_P(MachineCertificateUploaderTest, DBusFailureRetry) { ...@@ -227,8 +247,10 @@ TEST_P(MachineCertificateUploaderTest, DBusFailureRetry) {
base::Unretained(&cryptohome_client_))); base::Unretained(&cryptohome_client_)));
Run(); Run();
EXPECT_EQ(CreatePayload(), EXPECT_EQ(CreatePayload(),
cryptohome_client_.GetTpmAttestationDeviceKeyPayload( AttestationClient::Get()
kEnterpriseMachineKey)); ->GetTestInterface()
->GetMutableKeyInfoReply(/*username=*/"", kEnterpriseMachineKey)
->payload());
} }
INSTANTIATE_TEST_SUITE_P(All, INSTANTIATE_TEST_SUITE_P(All,
......
...@@ -126,6 +126,11 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS_ATTESTATION) AttestationClient { ...@@ -126,6 +126,11 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS_ATTESTATION) AttestationClient {
// Sets the returned status of `GetEnrollmentId()` to be D-Bus error for // Sets the returned status of `GetEnrollmentId()` to be D-Bus error for
// `count` times to emulate D-Bus late availability. // `count` times to emulate D-Bus late availability.
virtual void set_enrollment_id_dbus_error_count(int count) = 0; virtual void set_enrollment_id_dbus_error_count(int count) = 0;
// Gets the reply to the key info query as a fake database.
virtual ::attestation::GetKeyInfoReply* GetMutableKeyInfoReply(
const std::string& username,
const std::string& label) = 0;
}; };
// Not copyable or movable. // Not copyable or movable.
......
...@@ -57,7 +57,15 @@ FakeAttestationClient::mutable_certificate_request_reply() { ...@@ -57,7 +57,15 @@ FakeAttestationClient::mutable_certificate_request_reply() {
void FakeAttestationClient::GetKeyInfo( void FakeAttestationClient::GetKeyInfo(
const ::attestation::GetKeyInfoRequest& request, const ::attestation::GetKeyInfoRequest& request,
GetKeyInfoCallback callback) { GetKeyInfoCallback callback) {
NOTIMPLEMENTED(); ::attestation::GetKeyInfoReply reply;
auto iter = key_info_database_.find(request);
if (iter != key_info_database_.end()) {
reply = iter->second;
} else {
reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
}
PostProtoResponse(std::move(callback), reply);
} }
void FakeAttestationClient::GetEndorsementInfo( void FakeAttestationClient::GetEndorsementInfo(
...@@ -228,7 +236,17 @@ void FakeAttestationClient::SignSimpleChallenge( ...@@ -228,7 +236,17 @@ void FakeAttestationClient::SignSimpleChallenge(
void FakeAttestationClient::SetKeyPayload( void FakeAttestationClient::SetKeyPayload(
const ::attestation::SetKeyPayloadRequest& request, const ::attestation::SetKeyPayloadRequest& request,
SetKeyPayloadCallback callback) { SetKeyPayloadCallback callback) {
NOTIMPLEMENTED(); ::attestation::GetKeyInfoRequest get_key_info_request;
get_key_info_request.set_username(request.username());
get_key_info_request.set_key_label(request.key_label());
auto iter = key_info_database_.find(get_key_info_request);
::attestation::SetKeyPayloadReply reply;
if (iter == key_info_database_.end()) {
reply.set_status(::attestation::STATUS_INVALID_PARAMETER);
} else {
iter->second.set_payload(request.payload());
}
PostProtoResponse(std::move(callback), reply);
} }
void FakeAttestationClient::DeleteKeys( void FakeAttestationClient::DeleteKeys(
...@@ -330,6 +348,16 @@ void FakeAttestationClient::set_enrollment_id_dbus_error_count(int count) { ...@@ -330,6 +348,16 @@ void FakeAttestationClient::set_enrollment_id_dbus_error_count(int count) {
enrollment_id_dbus_error_count_ = count; enrollment_id_dbus_error_count_ = count;
} }
::attestation::GetKeyInfoReply* FakeAttestationClient::GetMutableKeyInfoReply(
const std::string& username,
const std::string& label) {
::attestation::GetKeyInfoRequest request;
request.set_username(username);
request.set_key_label(label);
// If there doesn't exist the entry yet, just create a new one.
return &(key_info_database_[request]);
}
AttestationClient::TestInterface* FakeAttestationClient::GetTestInterface() { AttestationClient::TestInterface* FakeAttestationClient::GetTestInterface() {
return this; return this;
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "chromeos/dbus/attestation/attestation_client.h" #include "chromeos/dbus/attestation/attestation_client.h"
#include <deque> #include <deque>
#include <map>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -113,6 +114,9 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS_ATTESTATION) FakeAttestationClient ...@@ -113,6 +114,9 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS_ATTESTATION) FakeAttestationClient
void set_enrollment_id_ignore_cache(const std::string& id) override; void set_enrollment_id_ignore_cache(const std::string& id) override;
void set_cached_enrollment_id(const std::string& id) override; void set_cached_enrollment_id(const std::string& id) override;
void set_enrollment_id_dbus_error_count(int count) override; void set_enrollment_id_dbus_error_count(int count) override;
::attestation::GetKeyInfoReply* GetMutableKeyInfoReply(
const std::string& username,
const std::string& label) override;
AttestationClient::TestInterface* GetTestInterface() override; AttestationClient::TestInterface* GetTestInterface() override;
...@@ -145,6 +149,22 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS_ATTESTATION) FakeAttestationClient ...@@ -145,6 +149,22 @@ class COMPONENT_EXPORT(CHROMEOS_DBUS_ATTESTATION) FakeAttestationClient
std::string enrollment_id_; std::string enrollment_id_;
std::string enrollment_id_ignore_cache_; std::string enrollment_id_ignore_cache_;
int enrollment_id_dbus_error_count_ = 0; int enrollment_id_dbus_error_count_ = 0;
class GetKeyInfoRequestComparator {
public:
bool operator()(const ::attestation::GetKeyInfoRequest& r1,
const ::attestation::GetKeyInfoRequest& r2) const {
return r1.username() == r2.username() ? r1.key_label() < r2.key_label()
: r1.username() < r2.username();
}
};
// The fake key info database. std::map is chosen because we don't have to
// implement the hash function for the `GetKeyInfoRequest`, which could be
// expensive and contributes unreasonable overhead at smaller scale, anyway.
std::map<::attestation::GetKeyInfoRequest,
::attestation::GetKeyInfoReply,
GetKeyInfoRequestComparator>
key_info_database_;
}; };
} // namespace chromeos } // namespace chromeos
......
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