blob: ec21c7081920bad0d81491c2cb44f61a27aadd2a [file] [log] [blame]
// Copyright 2022 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SHILL_STORE_PKCS11_SLOT_GETTER_H_
#define SHILL_STORE_PKCS11_SLOT_GETTER_H_
#include <chaps/pkcs11/cryptoki.h>
#include <memory>
#include <string>
#include <string_view>
#include <base/functional/callback.h>
#include <base/memory/weak_ptr.h>
#include <base/time/time.h>
#include <chaps/threading_mode.h>
#include <chaps/token_manager_client.h>
#include <gtest/gtest_prod.h>
#include <shill/store/pkcs11_util.h>
namespace shill {
// The initial, maximum, and multiplier for the delay of getting the TPM token
// slot ID. Timeout happens when the current delay exceeds the maximum delay
// |kPkcs11TokenMaxRequestDelay|.
constexpr base::TimeDelta kPkcs11TokenInitialRequestDelay =
base::Milliseconds(100);
constexpr base::TimeDelta kPkcs11TokenMaxRequestDelay = base::Minutes(5);
constexpr int kPkcs11TokenDelayMultiplier = 2;
// This class handles getting the user or the system slot ID from chaps.
class Pkcs11SlotGetter {
public:
explicit Pkcs11SlotGetter(
std::string_view user_hash = "",
chaps::TokenManagerClient* test_chaps_client_ = nullptr);
Pkcs11SlotGetter(const Pkcs11SlotGetter&) = delete;
Pkcs11SlotGetter& operator=(const Pkcs11SlotGetter&) = delete;
virtual ~Pkcs11SlotGetter() = default;
// Get PKCS#11 slot ID value of |slot|. |slot| can either be user slot or
// system slot. Upon failure, this will return pkcs11::kInvalidSlot. The slot
// ID might not be ready when calling this method. Use this method only when
// the synchronous call is necessary (e.g. when the TPM token is about to get
// removed).
virtual CK_SLOT_ID GetPkcs11SlotId(pkcs11::Slot slot);
// The asynchronous version of GetPkcs11SlotId. Upon failure, this method
// will retry to get the slot ID value. On timeout, this will return
// pkcs11::kInvalidSlot. The retry is necessary as the TPM token might not
// yet be ready.
virtual void GetPkcs11SlotIdWithRetries(
pkcs11::Slot slot,
base::OnceCallback<void(CK_SLOT_ID)> callback,
base::TimeDelta delay = kPkcs11TokenInitialRequestDelay);
// Returns the user slot ID if |user_hash_| is valid, otherwise it returns the
// system slot ID. Upon failure, pkcs11::kInvalidSlot is returned.
virtual CK_SLOT_ID GetPkcs11DefaultSlotId();
// Get the slot type (user or system) of |slot_id|.
virtual pkcs11::Slot GetSlotType(CK_SLOT_ID slot_id);
private:
FRIEND_TEST(Pkcs11SlotGetterTest, GetInvalidUserSlot);
FRIEND_TEST(Pkcs11SlotGetterTest, GetDefaultSlot_SystemSlot);
// Get the slot ID value of slot type |slot|. |user_hash_| needs to be valid
// in order to grab the user type slot.
CK_SLOT_ID GetSlotId(pkcs11::Slot slot);
// Cached user and system slot ID.
CK_SLOT_ID user_slot_id_;
CK_SLOT_ID system_slot_id_;
// The hash of the currently active user.
std::string user_hash_;
// The default token manager client for accessing chapsd's Pkcs#11 interface
chaps::TokenManagerClient default_chaps_client_{
chaps::ThreadingMode::kCurrentThread};
// The actual token manager client used by this class, usually set to
// default_chaps_client_, but can be overridden for testing.
chaps::TokenManagerClient* chaps_client_;
base::WeakPtrFactory<Pkcs11SlotGetter> weak_factory_{this};
};
} // namespace shill
#endif // SHILL_STORE_PKCS11_SLOT_GETTER_H_