// 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/token_manager_interface.h"

#include <map>
#include <set>
#include <string>
#include <tr1/memory>
#include <vector>

#include <base/basictypes.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);
  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();

 private:
  // 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::tr1::shared_ptr<ObjectPool> token_object_pool;
    // Key: A session identifier.
    // Value: The associated session object.
    std::map<int, std::tr1::shared_ptr<Session> > sessions;
    std::tr1::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);

  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_;

  DISALLOW_COPY_AND_ASSIGN(SlotManagerImpl);
};

}  // namespace chaps

#endif  // CHAPS_SLOT_MANAGER_IMPL_H_
