Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(387)

Unified Diff: chromeos/attestation/attestation_flow.cc

Issue 2529743002: Wait for the attestation to be ready (TPM being prepared for attestation) before trying to enroll. (Closed)
Patch Set: Changed method names and timeouts/delays. Udated doc. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chromeos/attestation/attestation_flow.h ('k') | chromeos/attestation/attestation_flow_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromeos/attestation/attestation_flow.cc
diff --git a/chromeos/attestation/attestation_flow.cc b/chromeos/attestation/attestation_flow.cc
index c82cbe554008bf6f81cde6267570743de5e8c3b5..c1e5597394e58621be3c6144366c50d7e0d7e5df 100644
--- a/chromeos/attestation/attestation_flow.cc
+++ b/chromeos/attestation/attestation_flow.cc
@@ -4,9 +4,13 @@
#include "chromeos/attestation/attestation_flow.h"
+#include <algorithm>
#include <utility>
#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/timer/timer.h"
#include "chromeos/cryptohome/async_method_caller.h"
#include "chromeos/cryptohome/cryptohome_parameters.h"
#include "chromeos/dbus/cryptohome_client.h"
@@ -17,6 +21,14 @@ namespace attestation {
namespace {
+// A reasonable timeout that gives enough time for attestation to be ready,
+// yet does not make the caller wait too long.
+constexpr uint16_t kReadyTimeoutInSeconds = 60;
+
+// Delay before checking again whether the TPM has been prepared for
+// attestation.
+constexpr uint16_t kRetryDelayInMilliseconds = 300;
+
// Redirects to one of three callbacks based on a boolean value and dbus call
// status.
//
@@ -29,10 +41,11 @@ namespace {
void DBusBoolRedirectCallback(const base::Closure& on_true,
const base::Closure& on_false,
const base::Closure& on_fail,
+ const std::string& on_fail_message,
DBusMethodCallStatus status,
bool value) {
if (status != DBUS_METHOD_CALL_SUCCESS) {
- LOG(ERROR) << "Attestation: Failed to query enrollment state.";
+ LOG(ERROR) << "Attestation: Failed to " << on_fail_message << ".";
if (!on_fail.is_null())
on_fail.Run();
return;
@@ -95,6 +108,9 @@ AttestationFlow::AttestationFlow(cryptohome::AsyncMethodCaller* async_caller,
: async_caller_(async_caller),
cryptohome_client_(cryptohome_client),
server_proxy_(std::move(server_proxy)),
+ ready_timeout_(base::TimeDelta::FromSeconds(kReadyTimeoutInSeconds)),
+ retry_delay_(
+ base::TimeDelta::FromMilliseconds(kRetryDelayInMilliseconds)),
weak_factory_(this) {}
AttestationFlow::~AttestationFlow() {
@@ -108,19 +124,33 @@ void AttestationFlow::GetCertificate(
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.
- base::Closure do_cert_request = base::Bind(
+ const base::Closure do_cert_request = base::Bind(
&AttestationFlow::StartCertificateRequest, weak_factory_.GetWeakPtr(),
certificate_profile, account_id, request_origin, force_new_key, callback);
- base::Closure on_enroll_failure = base::Bind(callback, false, "");
- base::Closure do_enroll = base::Bind(&AttestationFlow::StartEnroll,
- weak_factory_.GetWeakPtr(),
- on_enroll_failure,
- do_cert_request);
- cryptohome_client_->TpmAttestationIsEnrolled(base::Bind(
- &DBusBoolRedirectCallback,
- do_cert_request, // If enrolled, proceed with cert request.
- do_enroll, // If not enrolled, initiate enrollment.
- on_enroll_failure));
+ const base::Closure on_failure = base::Bind(callback, false, "");
+ const base::Closure initiate_enroll = base::Bind(
+ &AttestationFlow::WaitForAttestationReadyAndStartEnroll,
+ weak_factory_.GetWeakPtr(), base::TimeTicks::Now() + ready_timeout_,
+ on_failure,
+ base::Bind(&AttestationFlow::StartEnroll, weak_factory_.GetWeakPtr(),
+ on_failure, do_cert_request));
+ cryptohome_client_->TpmAttestationIsEnrolled(
+ base::Bind(&DBusBoolRedirectCallback,
+ do_cert_request, // If enrolled, proceed with cert request.
+ initiate_enroll, // If not enrolled, initiate enrollment.
+ on_failure, "check enrollment state"));
+}
+
+void AttestationFlow::WaitForAttestationReadyAndStartEnroll(
+ base::TimeTicks end_time,
+ const base::Closure& on_failure,
+ const base::Closure& next_task) {
+ const base::Closure retry_initiate_enroll =
+ base::Bind(&AttestationFlow::CheckAttestationReadyAndReschedule,
+ weak_factory_.GetWeakPtr(), end_time, on_failure, next_task);
+ cryptohome_client_->TpmAttestationIsPrepared(
+ base::Bind(&DBusBoolRedirectCallback, next_task, retry_initiate_enroll,
+ on_failure, "check for attestation readiness"));
}
void AttestationFlow::StartEnroll(const base::Closure& on_failure,
@@ -211,18 +241,19 @@ void AttestationFlow::StartCertificateRequest(
callback));
} else {
// If the key already exists, query the existing certificate.
- base::Closure on_key_exists = base::Bind(
+ const base::Closure on_key_exists = base::Bind(
&AttestationFlow::GetExistingCertificate, weak_factory_.GetWeakPtr(),
key_type, account_id, key_name, callback);
// If the key does not exist, call this method back with |generate_new_key|
// set to true.
- base::Closure on_key_not_exists = base::Bind(
+ const base::Closure on_key_not_exists = base::Bind(
&AttestationFlow::StartCertificateRequest, weak_factory_.GetWeakPtr(),
certificate_profile, account_id, request_origin, true, callback);
cryptohome_client_->TpmAttestationDoesKeyExist(
key_type, cryptohome::Identification(account_id), key_name,
base::Bind(&DBusBoolRedirectCallback, on_key_exists, on_key_not_exists,
- base::Bind(callback, false, "")));
+ base::Bind(callback, false, ""),
+ "check for existence of attestation key"));
}
}
@@ -277,6 +308,25 @@ void AttestationFlow::GetExistingCertificate(
base::Bind(&DBusDataMethodCallback, callback));
}
+void AttestationFlow::CheckAttestationReadyAndReschedule(
+ base::TimeTicks end_time,
+ const base::Closure& on_failure,
+ const base::Closure& next_task) {
+ if (base::TimeTicks::Now() < end_time) {
+ LOG(WARNING) << "Attestation: Not prepared yet."
+ << " Retrying in " << retry_delay_ << ".";
+ base::MessageLoop::current()->task_runner()->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&AttestationFlow::WaitForAttestationReadyAndStartEnroll,
+ weak_factory_.GetWeakPtr(), end_time, on_failure, next_task),
+ retry_delay_);
+ } else {
+ LOG(ERROR) << "Attestation: Not prepared. Giving up on retrying.";
+ if (!on_failure.is_null())
+ on_failure.Run();
+ }
+}
+
ServerProxy::~ServerProxy() {}
PrivacyCAType ServerProxy::GetType() {
« no previous file with comments | « chromeos/attestation/attestation_flow.h ('k') | chromeos/attestation/attestation_flow_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698