diff options
author | satorux <satorux@chromium.org> | 2014-12-11 17:32:36 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-12-12 01:33:45 +0000 |
commit | 612142321c115cc876e1d5306c22b35f1859ab74 (patch) | |
tree | c4a4944473d3d72c7b281559588dac4114db1b43 /chromeos/tpm/tpm_token_info_getter.cc | |
parent | 1b703ab9a57fe860a017163c0580641ae337cbab (diff) | |
download | chromium_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.cc | 162 |
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 |