summaryrefslogtreecommitdiffstats
path: root/chromeos/tpm/tpm_token_info_getter.cc
diff options
context:
space:
mode:
authorsatorux <satorux@chromium.org>2014-12-11 17:32:36 -0800
committerCommit bot <commit-bot@chromium.org>2014-12-12 01:33:45 +0000
commit612142321c115cc876e1d5306c22b35f1859ab74 (patch)
treec4a4944473d3d72c7b281559588dac4114db1b43 /chromeos/tpm/tpm_token_info_getter.cc
parent1b703ab9a57fe860a017163c0580641ae337cbab (diff)
downloadchromium_src-612142321c115cc876e1d5306c22b35f1859ab74.zip
chromium_src-612142321c115cc876e1d5306c22b35f1859ab74.tar.gz
chromium_src-612142321c115cc876e1d5306c22b35f1859ab74.tar.bz2
Move chromeos/tpm_* to chromeos/tpm
These files are moved in favor of less files to have in the top-level chromeos directory. BUG=none TEST=builds as before Review URL: https://codereview.chromium.org/738683002 Cr-Commit-Position: refs/heads/master@{#308020}
Diffstat (limited to 'chromeos/tpm/tpm_token_info_getter.cc')
-rw-r--r--chromeos/tpm/tpm_token_info_getter.cc162
1 files changed, 162 insertions, 0 deletions
diff --git a/chromeos/tpm/tpm_token_info_getter.cc b/chromeos/tpm/tpm_token_info_getter.cc
new file mode 100644
index 0000000..6f6dfe7
--- /dev/null
+++ b/chromeos/tpm/tpm_token_info_getter.cc
@@ -0,0 +1,162 @@
+// Copyright 2014 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 "chromeos/tpm/tpm_token_info_getter.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "chromeos/dbus/cryptohome_client.h"
+
+namespace {
+
+const int64 kInitialRequestDelayMs = 100;
+const int64 kMaxRequestDelayMs = 300000; // 5 minutes
+
+// Calculates the delay before running next attempt to initiatialize the TPM
+// token, if |last_delay| was the last or initial delay.
+base::TimeDelta GetNextRequestDelayMs(base::TimeDelta last_delay) {
+ // This implements an exponential backoff, as we don't know in which order of
+ // magnitude the TPM token changes it's state.
+ base::TimeDelta next_delay = last_delay * 2;
+
+ // Cap the delay to prevent an overflow. This threshold is arbitrarily chosen.
+ const base::TimeDelta max_delay =
+ base::TimeDelta::FromMilliseconds(kMaxRequestDelayMs);
+ if (next_delay > max_delay)
+ next_delay = max_delay;
+ return next_delay;
+}
+
+} // namespace
+
+namespace chromeos {
+
+TPMTokenInfo::TPMTokenInfo()
+ : tpm_is_enabled(false),
+ token_slot_id(-1) {
+}
+
+TPMTokenInfo::~TPMTokenInfo() {}
+
+// static
+scoped_ptr<TPMTokenInfoGetter> TPMTokenInfoGetter::CreateForUserToken(
+ const std::string& user_id,
+ CryptohomeClient* cryptohome_client,
+ const scoped_refptr<base::TaskRunner>& delayed_task_runner) {
+ CHECK(!user_id.empty());
+ return scoped_ptr<TPMTokenInfoGetter>(
+ new TPMTokenInfoGetter(
+ TYPE_USER, user_id, cryptohome_client, delayed_task_runner));
+}
+
+// static
+scoped_ptr<TPMTokenInfoGetter> TPMTokenInfoGetter::CreateForSystemToken(
+ CryptohomeClient* cryptohome_client,
+ const scoped_refptr<base::TaskRunner>& delayed_task_runner) {
+ return scoped_ptr<TPMTokenInfoGetter>(
+ new TPMTokenInfoGetter(
+ TYPE_SYSTEM, std::string(), cryptohome_client, delayed_task_runner));
+}
+
+TPMTokenInfoGetter::~TPMTokenInfoGetter() {}
+
+void TPMTokenInfoGetter::Start(const TPMTokenInfoCallback& callback) {
+ CHECK(state_ == STATE_INITIAL);
+ CHECK(!callback.is_null());
+
+ callback_ = callback;
+
+ state_ = STATE_STARTED;
+ Continue();
+}
+
+TPMTokenInfoGetter::TPMTokenInfoGetter(
+ TPMTokenInfoGetter::Type type,
+ const std::string& user_id,
+ CryptohomeClient* cryptohome_client,
+ const scoped_refptr<base::TaskRunner>& delayed_task_runner)
+ : delayed_task_runner_(delayed_task_runner),
+ type_(type),
+ state_(TPMTokenInfoGetter::STATE_INITIAL),
+ user_id_(user_id),
+ tpm_request_delay_(
+ base::TimeDelta::FromMilliseconds(kInitialRequestDelayMs)),
+ cryptohome_client_(cryptohome_client),
+ weak_factory_(this) {
+}
+
+void TPMTokenInfoGetter::Continue() {
+ switch (state_) {
+ case STATE_INITIAL:
+ NOTREACHED();
+ break;
+ case STATE_STARTED:
+ cryptohome_client_->TpmIsEnabled(
+ base::Bind(&TPMTokenInfoGetter::OnTpmIsEnabled,
+ weak_factory_.GetWeakPtr()));
+ break;
+ case STATE_TPM_ENABLED:
+ if (type_ == TYPE_SYSTEM) {
+ cryptohome_client_->Pkcs11GetTpmTokenInfo(
+ base::Bind(&TPMTokenInfoGetter::OnPkcs11GetTpmTokenInfo,
+ weak_factory_.GetWeakPtr()));
+ } else { // if (type_ == TYPE_USER)
+ cryptohome_client_->Pkcs11GetTpmTokenInfoForUser(
+ user_id_,
+ base::Bind(&TPMTokenInfoGetter::OnPkcs11GetTpmTokenInfo,
+ weak_factory_.GetWeakPtr()));
+ }
+ break;
+ case STATE_DONE:
+ NOTREACHED();
+ }
+}
+
+void TPMTokenInfoGetter::RetryLater() {
+ delayed_task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(&TPMTokenInfoGetter::Continue, weak_factory_.GetWeakPtr()),
+ tpm_request_delay_);
+ tpm_request_delay_ = GetNextRequestDelayMs(tpm_request_delay_);
+}
+
+void TPMTokenInfoGetter::OnTpmIsEnabled(DBusMethodCallStatus call_status,
+ bool tpm_is_enabled) {
+ if (call_status != DBUS_METHOD_CALL_SUCCESS) {
+ RetryLater();
+ return;
+ }
+
+ if (!tpm_is_enabled) {
+ state_ = STATE_DONE;
+ callback_.Run(TPMTokenInfo());
+ return;
+ }
+
+ state_ = STATE_TPM_ENABLED;
+ Continue();
+}
+
+void TPMTokenInfoGetter::OnPkcs11GetTpmTokenInfo(
+ DBusMethodCallStatus call_status,
+ const std::string& token_name,
+ const std::string& user_pin,
+ int token_slot_id) {
+ if (call_status == DBUS_METHOD_CALL_FAILURE || token_slot_id == -1) {
+ RetryLater();
+ return;
+ }
+
+ state_ = STATE_DONE;
+
+ TPMTokenInfo token_info;
+ token_info.tpm_is_enabled = true;
+ token_info.token_name = token_name;
+ token_info.user_pin = user_pin;
+ token_info.token_slot_id = token_slot_id;
+
+ callback_.Run(token_info);
+}
+
+} // namespace chromeos