Commit ec96c18c authored by Omar Morsi's avatar Omar Morsi Committed by Commit Bot

Introduce timeout for retrieving system certificate database

This CL handles cases when TPM initialization fails and system token
certificate database was requested. It handles this case by introducing
a five-minutes-timeout for the database request.

Bug: 1068548, 844022
Change-Id: If738218f7816aa9af931fa23c85da39012b86b9c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2410377Reviewed-by: default avatarPavol Marko <pmarko@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarMaksim Ivanov <emaxx@chromium.org>
Commit-Queue: Omar Morsi <omorsi@google.com>
Cr-Commit-Position: refs/heads/master@{#828853}
parent d5193a42
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "base/location.h" #include "base/location.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/time/time.h"
#include "build/branding_buildflags.h" #include "build/branding_buildflags.h"
#include "build/buildflag.h" #include "build/buildflag.h"
#include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/login/startup_utils.h"
...@@ -29,6 +30,12 @@ namespace chromeos { ...@@ -29,6 +30,12 @@ namespace chromeos {
namespace { namespace {
// It is stated in cryptohome implementation that 5 minutes is enough time to
// wait for any TPM operations. For more information, please refer to:
// https://chromium.googlesource.com/chromiumos/platform2/+/master/cryptohome/cryptohome.cc
constexpr base::TimeDelta kMaxCertDbRetrievalDelay =
base::TimeDelta::FromMinutes(5);
// Called on UI Thread when the system slot has been retrieved. // Called on UI Thread when the system slot has been retrieved.
void GotSystemSlotOnUIThread( void GotSystemSlotOnUIThread(
base::OnceCallback<void(crypto::ScopedPK11Slot)> callback_ui_thread, base::OnceCallback<void(crypto::ScopedPK11Slot)> callback_ui_thread,
...@@ -141,8 +148,16 @@ void SystemTokenCertDBInitializer::GetSystemTokenCertDb( ...@@ -141,8 +148,16 @@ void SystemTokenCertDBInitializer::GetSystemTokenCertDb(
if (system_token_cert_database_) { if (system_token_cert_database_) {
std::move(callback).Run(system_token_cert_database_.get()); std::move(callback).Run(system_token_cert_database_.get());
} else if (system_token_cert_db_retrieval_failed_) {
std::move(callback).Run(/*nss_cert_database=*/nullptr);
} else { } else {
get_system_token_cert_db_callback_list_.AddUnsafe(std::move(callback)); get_system_token_cert_db_callback_list_.AddUnsafe(std::move(callback));
if (!system_token_cert_db_retrieval_timer_.IsRunning()) {
system_token_cert_db_retrieval_timer_.Start(
FROM_HERE, kMaxCertDbRetrievalDelay, /*receiver=*/this,
&SystemTokenCertDBInitializer::OnSystemTokenDbRetrievalTimeout);
}
} }
} }
...@@ -228,6 +243,7 @@ void SystemTokenCertDBInitializer::InitializeDatabase( ...@@ -228,6 +243,7 @@ void SystemTokenCertDBInitializer::InitializeDatabase(
database->SetSystemSlot(std::move(system_slot_copy)); database->SetSystemSlot(std::move(system_slot_copy));
system_token_cert_database_ = std::move(database); system_token_cert_database_ = std::move(database);
system_token_cert_db_retrieval_timer_.Stop();
get_system_token_cert_db_callback_list_.Notify( get_system_token_cert_db_callback_list_.Notify(
system_token_cert_database_.get()); system_token_cert_database_.get());
...@@ -236,4 +252,12 @@ void SystemTokenCertDBInitializer::InitializeDatabase( ...@@ -236,4 +252,12 @@ void SystemTokenCertDBInitializer::InitializeDatabase(
NetworkCertLoader::Get()->SetSystemNSSDB(system_token_cert_database_.get()); NetworkCertLoader::Get()->SetSystemNSSDB(system_token_cert_database_.get());
} }
void SystemTokenCertDBInitializer::OnSystemTokenDbRetrievalTimeout() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
system_token_cert_db_retrieval_failed_ = true;
get_system_token_cert_db_callback_list_.Notify(
/*nss_cert_database=*/nullptr);
}
} // namespace chromeos } // namespace chromeos
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/observer_list_types.h" #include "base/observer_list_types.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/sequence_checker.h" #include "base/sequence_checker.h"
#include "base/timer/timer.h"
#include "chromeos/dbus/cryptohome/cryptohome_client.h" #include "chromeos/dbus/cryptohome/cryptohome_client.h"
#include "crypto/scoped_nss_types.h" #include "crypto/scoped_nss_types.h"
...@@ -66,7 +67,7 @@ class SystemTokenCertDBInitializer final : public CryptohomeClient::Observer { ...@@ -66,7 +67,7 @@ class SystemTokenCertDBInitializer final : public CryptohomeClient::Observer {
// To be notified when the returned NSSCertDatabase becomes invalid, callers // To be notified when the returned NSSCertDatabase becomes invalid, callers
// should register as SystemTokenCertDBObserver. // should register as SystemTokenCertDBObserver.
using GetSystemTokenCertDbCallback = using GetSystemTokenCertDbCallback =
base::OnceCallback<void(net::NSSCertDatabase*)>; base::OnceCallback<void(net::NSSCertDatabase* nss_cert_database)>;
void GetSystemTokenCertDb(GetSystemTokenCertDbCallback callback); void GetSystemTokenCertDb(GetSystemTokenCertDbCallback callback);
// Adds |observer| as SystemTokenCertDBObserver. // Adds |observer| as SystemTokenCertDBObserver.
...@@ -91,6 +92,12 @@ class SystemTokenCertDBInitializer final : public CryptohomeClient::Observer { ...@@ -91,6 +92,12 @@ class SystemTokenCertDBInitializer final : public CryptohomeClient::Observer {
// Also starts NetworkCertLoader with the system token database. // Also starts NetworkCertLoader with the system token database.
void InitializeDatabase(crypto::ScopedPK11Slot system_slot); void InitializeDatabase(crypto::ScopedPK11Slot system_slot);
// Called after a delay if the system token certificate database was still not
// initialized when |GetSystemTokenCertDb| was called. This function notifies
// |get_system_token_cert_db_callback_list_| with nullptrs as a way of
// informing callers that the database initialization failed.
void OnSystemTokenDbRetrievalTimeout();
// Whether the database initialization was started. // Whether the database initialization was started.
bool started_initializing_ = false; bool started_initializing_ = false;
...@@ -106,6 +113,10 @@ class SystemTokenCertDBInitializer final : public CryptohomeClient::Observer { ...@@ -106,6 +113,10 @@ class SystemTokenCertDBInitializer final : public CryptohomeClient::Observer {
// NSSCertDatabase is destroyed. // NSSCertDatabase is destroyed.
base::ObserverList<SystemTokenCertDBObserver> observers_; base::ObserverList<SystemTokenCertDBObserver> observers_;
bool system_token_cert_db_retrieval_failed_ = false;
base::OneShotTimer system_token_cert_db_retrieval_timer_;
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<SystemTokenCertDBInitializer> weak_ptr_factory_{this}; base::WeakPtrFactory<SystemTokenCertDBInitializer> weak_ptr_factory_{this};
......
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