blob: ef9ea7cf27d039002826cdce2893e2b2bf4e6937 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHAPS_SLOT_MANAGER_IMPL_H_
#define CHAPS_SLOT_MANAGER_IMPL_H_
#include "chaps/handle_generator.h"
#include "chaps/slot_manager.h"
#include "chaps/system_shutdown_blocker.h"
#include "chaps/token_manager_interface.h"
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include <base/macros.h>
#include <base/synchronization/lock.h>
#include <base/threading/platform_thread.h>
#include "chaps/chaps_factory.h"
#include "chaps/object_pool.h"
namespace chaps {
class SessionFactory;
class TPMUtility;
// Maintains a list of PKCS #11 slots and modifies the list according to login
// events received. Sample usage:
// SlotManagerImpl slot_manager(&my_factory, &my_tpm);
// if (!slot_manager.Init()) {
// ...
// }
// // Ready for use by SlotManager and LoginEventListener clients.
class SlotManagerImpl : public SlotManager,
public TokenManagerInterface,
public HandleGenerator {
public:
SlotManagerImpl(ChapsFactory* factory,
TPMUtility* tpm_utility,
bool auto_load_system_token,
SystemShutdownBlocker* system_shutdown_blocker);
~SlotManagerImpl() override;
// Initializes the slot manager. Returns true on success.
virtual bool Init();
// SlotManager methods.
int GetSlotCount() override;
bool IsTokenAccessible(const brillo::SecureBlob& isolate_credential,
int slot_id) const override;
bool IsTokenPresent(const brillo::SecureBlob& isolate_credential,
int slot_id) const override;
void GetSlotInfo(const brillo::SecureBlob& isolate_credential,
int slot_id,
CK_SLOT_INFO* slot_info) const override;
void GetTokenInfo(const brillo::SecureBlob& isolate_credential,
int slot_id,
CK_TOKEN_INFO* token_info) const override;
const MechanismMap* GetMechanismInfo(
const brillo::SecureBlob& isolate_credential, int slot_id) const override;
int OpenSession(const brillo::SecureBlob& isolate_credential,
int slot_id,
bool is_read_only) override;
bool CloseSession(const brillo::SecureBlob& isolate_credential,
int session_id) override;
void CloseAllSessions(const brillo::SecureBlob& isolate_credential,
int slot_id) override;
bool GetSession(const brillo::SecureBlob& isolate_credential,
int session_id,
Session** session) const override;
// TokenManagerInterface methods.
bool OpenIsolate(brillo::SecureBlob* isolate_credential,
bool* new_isolate_created) override;
void CloseIsolate(const brillo::SecureBlob& isolate_credential) override;
bool LoadToken(const brillo::SecureBlob& isolate_credential,
const base::FilePath& path,
const brillo::SecureBlob& auth_data,
const std::string& label,
int* slot_id) override;
void UnloadToken(const brillo::SecureBlob& isolate_credential,
const base::FilePath& path) override;
void ChangeTokenAuthData(const base::FilePath& path,
const brillo::SecureBlob& old_auth_data,
const brillo::SecureBlob& new_auth_data) override;
bool GetTokenPath(const brillo::SecureBlob& isolate_credential,
int slot_id,
base::FilePath* path) override;
// HandleGenerator methods.
int CreateHandle() override;
private:
// Holds all information associated with a particular isolate.
struct Isolate {
brillo::SecureBlob credential;
int open_count;
// The set of slots accessible through this isolate.
std::set<int> slot_ids;
};
// Holds all information associated with a particular slot.
struct Slot {
CK_SLOT_INFO slot_info;
CK_TOKEN_INFO token_info;
std::shared_ptr<ObjectPool> token_object_pool;
// Key: A session identifier.
// Value: The associated session object.
std::map<int, std::shared_ptr<Session>> sessions;
std::shared_ptr<base::PlatformThread::Delegate> worker_thread;
base::PlatformThreadHandle worker_thread_handle;
};
// Internal token presence check without isolate_credential check.
bool IsTokenPresent(int slot_id) const;
// Provides default PKCS #11 slot and token information. This method fills
// the given information structures with constant default values formatted to
// be PKCS #11 compliant.
void GetDefaultInfo(CK_SLOT_INFO* slot_info, CK_TOKEN_INFO* token_info);
// Initializes a key hierarchy for a particular token. This will clobber any
// existing key hierarchy for the token. Returns true on success.
// slot_id - The slot of the token to be initialized.
// object_pool - This must be the token's persistent object pool; it will be
// used to store internal blobs related to the key hierarchy.
// auth_data - Authorization data to be used for the key hierarchy. This same
// data will be required to use the key hierarchy in the future.
// master_key - On success will be assigned the new master key for the token.
bool InitializeKeyHierarchy(int slot_id,
ObjectPool* object_pool,
const std::string& auth_data,
std::string* master_key);
// Searches for slot that does not currently contain a token. If no such slot
// exists a new slot is created. The slot identifier of the empty slot is
// returned.
int FindEmptySlot();
// Creates new slots.
// num_slots - The number of slots to be created.
void AddSlots(int num_slots);
// Creates a new isolate with the given isolate credential.
void AddIsolate(const brillo::SecureBlob& isolate_credential);
// Destroy isolate and unload any tokens in that isolate.
void DestroyIsolate(const Isolate& isolate);
// Get the path of the token loaded in the given slot.
bool PathFromSlotId(int slot_id, base::FilePath* path) const;
// Performs initialization tasks that depend on the TPM SRK. If the TPM is
// not owned this cannot succeed. These tasks include seeding the software
// prng and loading the system token.
bool InitStage2();
// LoadToken for internal callers.
bool LoadTokenInternal(const brillo::SecureBlob& isolate_credential,
const base::FilePath& path,
const brillo::SecureBlob& auth_data,
const std::string& label,
int* slot_id);
// Loads the master key for a software-only token.
bool LoadSoftwareToken(const brillo::SecureBlob& auth_data,
ObjectPool* object_pool);
// Initializes a new software-only token.
bool InitializeSoftwareToken(const brillo::SecureBlob& auth_data,
ObjectPool* object_pool);
ChapsFactory* factory_;
int last_handle_;
MechanismMap mechanism_info_;
// Key: A path to a token's storage directory.
// Value: The identifier of the associated slot.
std::map<base::FilePath, int> path_slot_map_;
std::vector<Slot> slot_list_;
// Key: A session identifier.
// Value: The identifier of the associated slot.
std::map<int, int> session_slot_map_;
std::map<brillo::SecureBlob, Isolate> isolate_map_;
TPMUtility* tpm_utility_;
base::Lock handle_generator_lock_;
bool auto_load_system_token_;
bool is_initialized_;
SystemShutdownBlocker* system_shutdown_blocker_;
DISALLOW_COPY_AND_ASSIGN(SlotManagerImpl);
};
} // namespace chaps
#endif // CHAPS_SLOT_MANAGER_IMPL_H_