1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "tpm_password_fetcher.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/cryptohome_client.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chromeos {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Interval between TPM password checks.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kTpmCheckIntervalMs = 500;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TpmPasswordFetcher::TpmPasswordFetcher(TpmPasswordFetcherDelegate* delegate)
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : delegate_(delegate), weak_factory_(this) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(delegate_);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TpmPasswordFetcher::~TpmPasswordFetcher() {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TpmPasswordFetcher::Fetch() {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Since this method is also called directly.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  weak_factory_.InvalidateWeakPtrs();
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DBusThreadManager::Get()->GetCryptohomeClient()->TpmIsReady(base::Bind(
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      &TpmPasswordFetcher::OnTpmIsReady, weak_factory_.GetWeakPtr()));
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TpmPasswordFetcher::OnTpmIsReady(DBusMethodCallStatus call_status,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      bool tpm_is_ready) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (call_status == DBUS_METHOD_CALL_SUCCESS && tpm_is_ready) {
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    DBusThreadManager::Get()->GetCryptohomeClient()->TpmGetPassword(base::Bind(
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        &TpmPasswordFetcher::OnTpmGetPassword, weak_factory_.GetWeakPtr()));
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Password hasn't been acquired, reschedule fetch.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RescheduleFetch();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TpmPasswordFetcher::OnTpmGetPassword(DBusMethodCallStatus call_status,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const std::string& password) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (call_status == DBUS_METHOD_CALL_SUCCESS) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (password.empty()) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // For a fresh OOBE flow TPM is uninitialized,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // ownership process is started at the EULA screen,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // password is cleared after EULA is accepted.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "TPM returned an empty password.";
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delegate_->OnPasswordFetched(password);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Password hasn't been acquired, reschedule fetch.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RescheduleFetch();
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TpmPasswordFetcher::RescheduleFetch() {
6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  base::MessageLoop::current()->PostDelayedTask(
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FROM_HERE,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&TpmPasswordFetcher::Fetch, weak_factory_.GetWeakPtr()),
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(kTpmCheckIntervalMs));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chromeos
73