Commit 05e0458c authored by Leo Lai's avatar Leo Lai Committed by Commit Bot

Attestation flow talks to attestationd for preparation status

This CL is part of plan that chromium talks to attestationd and bypass
cryptohomed for attestation-related APIs.

BUG=b:158955123

Change-Id: I7be67f3420fb114ab11203dd44e73bca4aa11574
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2249276
Commit-Queue: Leo Lai <cylai@google.com>
Reviewed-by: default avatarMaksim Ivanov <emaxx@chromium.org>
Cr-Commit-Position: refs/heads/master@{#784399}
parent 2c415f77
......@@ -12,6 +12,8 @@ component("attestation") {
"//base",
"//chromeos/cryptohome",
"//chromeos/dbus:common",
"//chromeos/dbus/attestation",
"//chromeos/dbus/attestation:attestation_proto",
"//chromeos/dbus/cryptohome",
"//chromeos/dbus/cryptohome:cryptohome_proto",
"//components/account_id",
......@@ -28,6 +30,7 @@ source_set("test_support") {
public_deps = [ ":attestation" ]
deps = [
"//base/test:test_support",
"//chromeos/dbus/attestation:attestation_proto",
"//components/account_id",
"//testing/gmock",
]
......@@ -44,6 +47,7 @@ source_set("unit_tests") {
"//base/test:test_support",
"//chromeos/cryptohome:test_support",
"//chromeos/dbus:test_support",
"//chromeos/dbus/attestation",
"//components/account_id",
"//testing/gmock",
"//testing/gtest",
......
......@@ -15,6 +15,8 @@
#include "base/timer/timer.h"
#include "chromeos/cryptohome/async_method_caller.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 "components/account_id/account_id.h"
......@@ -31,6 +33,9 @@ constexpr uint16_t kReadyTimeoutInSeconds = 60;
// attestation.
constexpr uint16_t kRetryDelayInMilliseconds = 300;
constexpr ::attestation::ACAType kDefaultAcaType =
::attestation::ACAType::DEFAULT_ACA;
void DBusCertificateMethodCallback(
AttestationFlow::CertificateCallback callback,
base::Optional<CryptohomeClient::TpmAttestationDataResult> result) {
......@@ -46,6 +51,16 @@ void DBusCertificateMethodCallback(
}
}
bool IsPreparedWith(const ::attestation::GetEnrollmentPreparationsReply& reply,
::attestation::ACAType aca_type) {
for (const auto& preparation : reply.enrollment_preparations()) {
if (preparation.first == aca_type) {
return preparation.second;
}
}
return false;
}
} // namespace
AttestationKeyType AttestationFlow::GetKeyTypeForProfile(
......@@ -84,6 +99,7 @@ AttestationFlow::AttestationFlow(cryptohome::AsyncMethodCaller* async_caller,
std::unique_ptr<ServerProxy> server_proxy)
: async_caller_(async_caller),
cryptohome_client_(cryptohome_client),
attestation_client_(AttestationClient::Get()),
server_proxy_(std::move(server_proxy)),
ready_timeout_(base::TimeDelta::FromSeconds(kReadyTimeoutInSeconds)),
retry_delay_(
......@@ -136,22 +152,20 @@ void AttestationFlow::OnEnrollmentCheckComplete(
void AttestationFlow::WaitForAttestationPrepared(
base::TimeTicks end_time,
base::OnceCallback<void(bool)> callback) {
cryptohome_client_->TpmAttestationIsPrepared(base::BindOnce(
&AttestationFlow::OnPreparedCheckComplete, weak_factory_.GetWeakPtr(),
end_time, std::move(callback)));
::attestation::GetEnrollmentPreparationsRequest request;
request.set_aca_type(kDefaultAcaType);
attestation_client_->GetEnrollmentPreparations(
request, base::BindOnce(&AttestationFlow::OnPreparedCheckComplete,
weak_factory_.GetWeakPtr(), end_time,
std::move(callback)));
}
void AttestationFlow::OnPreparedCheckComplete(
base::TimeTicks end_time,
base::OnceCallback<void(bool)> callback,
base::Optional<bool> result) {
if (!result) {
LOG(ERROR) << "Attestation: Failed to check for attestation readiness";
std::move(callback).Run(false);
return;
}
if (*result) {
const ::attestation::GetEnrollmentPreparationsReply& reply) {
if (reply.status() == ::attestation::STATUS_SUCCESS &&
IsPreparedWith(reply, kDefaultAcaType)) {
// Get the attestation service to create a Privacy CA enrollment request.
async_caller_->AsyncTpmAttestationCreateEnrollRequest(
server_proxy_->GetType(),
......
......@@ -14,6 +14,7 @@
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chromeos/dbus/attestation/interface.pb.h"
#include "chromeos/dbus/constants/attestation_constants.h"
#include "chromeos/dbus/dbus_method_call_status.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
......@@ -29,6 +30,7 @@ class AsyncMethodCaller;
namespace chromeos {
class CryptohomeClient;
class AttestationClient;
namespace attestation {
......@@ -157,10 +159,11 @@ class COMPONENT_EXPORT(CHROMEOS_ATTESTATION) AttestationFlow {
// Parameters
// end_time - Time after which preparation should time out.
// callback - Called with the success or failure of the enrollment.
// result - Result of TpmAttestationIsPrepared().
void OnPreparedCheckComplete(base::TimeTicks end_time,
base::OnceCallback<void(bool)> callback,
base::Optional<bool> result);
// reply - Reply from the attestation service.
void OnPreparedCheckComplete(
base::TimeTicks end_time,
base::OnceCallback<void(bool)> callback,
const ::attestation::GetEnrollmentPreparationsReply& reply);
// Called when the attestation daemon has finished creating an enrollment
// request for the Privacy CA. The request is asynchronously forwarded as-is
......@@ -302,6 +305,7 @@ class COMPONENT_EXPORT(CHROMEOS_ATTESTATION) AttestationFlow {
cryptohome::AsyncMethodCaller* async_caller_;
CryptohomeClient* cryptohome_client_;
AttestationClient* attestation_client_;
std::unique_ptr<ServerProxy> server_proxy_;
base::TimeDelta ready_timeout_;
......
......@@ -16,6 +16,7 @@
#include "chromeos/attestation/mock_attestation_flow.h"
#include "chromeos/cryptohome/cryptohome_parameters.h"
#include "chromeos/cryptohome/mock_async_method_caller.h"
#include "chromeos/dbus/attestation/attestation_client.h"
#include "chromeos/dbus/cryptohome/fake_cryptohome_client.h"
#include "components/account_id/account_id.h"
#include "testing/gmock/include/gmock/gmock.h"
......@@ -44,6 +45,8 @@ void AsyncCallbackFalse(cryptohome::AsyncMethodCaller::Callback callback) {
class AttestationFlowTest : public testing::Test {
public:
AttestationFlowTest() { chromeos::AttestationClient::InitializeFake(); }
~AttestationFlowTest() override { chromeos::AttestationClient::Shutdown(); }
void QuitRunLoopCertificateCallback(
AttestationFlow::CertificateCallback callback,
AttestationStatus status,
......@@ -78,7 +81,9 @@ TEST_F(AttestationFlowTest, GetCertificate) {
// Use DBusCallbackFalse so the full enrollment flow is triggered.
chromeos::FakeCryptohomeClient client;
client.set_tpm_attestation_is_enrolled(false);
client.set_tpm_attestation_is_prepared(true);
chromeos::AttestationClient::Get()
->GetTestInterface()
->ConfigureEnrollmentPreparations(true);
// Use StrictMock when we want to verify invocation frequency.
StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
......@@ -152,21 +157,11 @@ TEST_F(AttestationFlowTest, GetCertificate_Attestation_Not_Prepared) {
// Verify the order of calls in a sequence.
Sequence flow_order;
// Custom FakeCryptohomeClient to emulate a situation where it takes a bit
// for attestation to be prepared.
class FakeCryptohomeClient : public chromeos::FakeCryptohomeClient {
public:
void TpmAttestationIsPrepared(DBusMethodCallback<bool> callback) override {
chromeos::FakeCryptohomeClient::TpmAttestationIsPrepared(
std::move(callback));
// Second call (and later), returns true.
set_tpm_attestation_is_prepared(true);
}
};
FakeCryptohomeClient client;
client.set_tpm_attestation_is_enrolled(false);
client.set_tpm_attestation_is_prepared(false);
chromeos::AttestationClient::Get()
->GetTestInterface()
->ConfigureEnrollmentPreparationsSequence({false, true});
// Use StrictMock when we want to verify invocation frequency.
StrictMock<cryptohome::MockAsyncMethodCaller> async_caller;
......@@ -245,7 +240,9 @@ TEST_F(AttestationFlowTest, GetCertificate_Attestation_Never_Prepared) {
chromeos::FakeCryptohomeClient client;
client.set_tpm_attestation_is_enrolled(false);
client.set_tpm_attestation_is_prepared(false);
chromeos::AttestationClient::Get()
->GetTestInterface()
->ConfigureEnrollmentPreparations(false);
// We're not expecting any server calls in this case; StrictMock will verify.
std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
......@@ -280,7 +277,9 @@ TEST_F(AttestationFlowTest, GetCertificate_NoEK) {
chromeos::FakeCryptohomeClient client;
client.set_tpm_attestation_is_enrolled(false);
client.set_tpm_attestation_is_prepared(true);
chromeos::AttestationClient::Get()
->GetTestInterface()
->ConfigureEnrollmentPreparations(true);
// We're not expecting any server calls in this case; StrictMock will verify.
std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
......@@ -309,7 +308,9 @@ TEST_F(AttestationFlowTest, GetCertificate_EKRejected) {
chromeos::FakeCryptohomeClient client;
client.set_tpm_attestation_is_enrolled(false);
client.set_tpm_attestation_is_prepared(true);
chromeos::AttestationClient::Get()
->GetTestInterface()
->ConfigureEnrollmentPreparations(true);
std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
proxy->DeferToFake(false);
......@@ -349,7 +350,9 @@ TEST_F(AttestationFlowTest, GetCertificate_FailEnroll) {
chromeos::FakeCryptohomeClient client;
client.set_tpm_attestation_is_enrolled(false);
client.set_tpm_attestation_is_prepared(true);
chromeos::AttestationClient::Get()
->GetTestInterface()
->ConfigureEnrollmentPreparations(true);
std::unique_ptr<MockServerProxy> proxy(new StrictMock<MockServerProxy>());
proxy->DeferToFake(true);
......
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