blob: 78b5996e5bdc37da92967b4779169399eac67123 [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.
#include "chaps/handle_generator.h"
#include "chaps/slot_manager.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 {
SlotManagerImpl(ChapsFactory* factory,
TPMUtility* tpm_utility,
bool auto_load_system_token);
virtual ~SlotManagerImpl();
// Initializes the slot manager. Returns true on success.
virtual bool Init();
// SlotManager methods.
virtual int GetSlotCount() const;
virtual bool IsTokenAccessible(const chromeos::SecureBlob& isolate_credential,
int slot_id) const;
virtual bool IsTokenPresent(const chromeos::SecureBlob& isolate_credential,
int slot_id) const;
virtual void GetSlotInfo(const chromeos::SecureBlob& isolate_credential,
int slot_id,
CK_SLOT_INFO* slot_info) const;
virtual void GetTokenInfo(const chromeos::SecureBlob& isolate_credential,
int slot_id,
CK_TOKEN_INFO* token_info) const;
virtual const MechanismMap* GetMechanismInfo(
const chromeos::SecureBlob& isolate_credential,
int slot_id) const;
virtual int OpenSession(const chromeos::SecureBlob& isolate_credential,
int slot_id,
bool is_read_only);
virtual bool CloseSession(const chromeos::SecureBlob& isolate_credential,
int session_id);
virtual void CloseAllSessions(const chromeos::SecureBlob& isolate_credential,
int slot_id);
virtual bool GetSession(const chromeos::SecureBlob& isolate_credential,
int session_id, Session** session) const;
// TokenManagerInterface methods.
virtual bool OpenIsolate(chromeos::SecureBlob* isolate_credential,
bool* new_isolate_created);
virtual void CloseIsolate(const chromeos::SecureBlob& isolate_credential);
virtual bool LoadToken(const chromeos::SecureBlob& isolate_credential,
const base::FilePath& path,
const chromeos::SecureBlob& auth_data,
const std::string& label,
int* slot_id);
virtual void UnloadToken(const chromeos::SecureBlob& isolate_credential,
const base::FilePath& path);
virtual void ChangeTokenAuthData(const base::FilePath& path,
const chromeos::SecureBlob& old_auth_data,
const chromeos::SecureBlob& new_auth_data);
virtual bool GetTokenPath(const chromeos::SecureBlob& isolate_credential,
int slot_id,
base::FilePath* path);
// HandleGenerator methods.
virtual int CreateHandle();
// Holds all information associated with a particular isolate.
struct Isolate {
chromeos::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 chromeos::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 chromeos::SecureBlob& isolate_credential,
const base::FilePath& path,
const chromeos::SecureBlob& auth_data,
const std::string& label,
int* slot_id);
// Loads the master key for a software-only token.
bool LoadSoftwareToken(const chromeos::SecureBlob& auth_data,
ObjectPool* object_pool);
// Initializes a new software-only token.
bool InitializeSoftwareToken(const chromeos::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<chromeos::SecureBlob, Isolate> isolate_map_;
TPMUtility* tpm_utility_;
base::Lock handle_generator_lock_;
bool auto_load_system_token_;
bool is_initialized_;
} // namespace chaps