/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
/**
 * Copyright (c) 2013-2014,  Regents of the University of California.
 * All rights reserved.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 *
 * This file licensed under New BSD License.  See COPYING for detailed information about
 * ndn-cxx library copyright, permissions, and redistribution restrictions.
 *
 * @author Yingdi Yu <http://irl.cs.ucla.edu/~yingdi/>
 */

#ifndef NDN_SECURITY_SEC_TPM_OSX_HPP
#define NDN_SECURITY_SEC_TPM_OSX_HPP

#include "../common.hpp"
#include "sec-tpm.hpp"

namespace ndn {

class SecTpmOsx : public SecTpm
{
public:
  class Error : public SecTpm::Error
  {
  public:
    explicit
    Error(const std::string& what)
      : SecTpm::Error(what)
    {
    }
  };

  SecTpmOsx();

  virtual
  ~SecTpmOsx();


  /******************************
   * From TrustedPlatformModule *
   ******************************/

  virtual void
  setTpmPassword(const uint8_t* password, size_t passwordLength);

  virtual void
  resetTpmPassword();

  virtual void
  setInTerminal(bool inTerminal);

  virtual bool
  getInTerminal();

  virtual bool
  locked();

  virtual bool
  unlockTpm(const char* password, size_t passwordLength, bool usePassword);

  virtual void
  generateKeyPairInTpm(const Name& keyName, KeyType keyType, int keySize)
  {
    generateKeyPairInTpmInternal(keyName, keyType, keySize, false);
  }

  virtual void
  deleteKeyPairInTpm(const Name& keyName)
  {
    deleteKeyPairInTpmInternal(keyName, false);
  }

  virtual shared_ptr<PublicKey>
  getPublicKeyFromTpm(const Name& keyName);

  virtual Block
  signInTpm(const uint8_t* data, size_t dataLength,
            const Name& keyName, DigestAlgorithm digestAlgorithm)
  {
    return signInTpmInternal(data, dataLength, keyName, digestAlgorithm, false);
  }

  virtual ConstBufferPtr
  decryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric);

  virtual ConstBufferPtr
  encryptInTpm(const uint8_t* data, size_t dataLength, const Name& keyName, bool isSymmetric);

  virtual void
  generateSymmetricKeyInTpm(const Name& keyName, KeyType keyType, int keySize);

  virtual bool
  doesKeyExistInTpm(const Name& keyName, KeyClass keyClass);

  virtual bool
  generateRandomBlock(uint8_t* res, size_t size);

  virtual void
  addAppToACL(const Name& keyName, KeyClass keyClass, const std::string& appPath, AclType acl);

protected:
  /******************************
   * From TrustedPlatformModule *
   ******************************/
  virtual ConstBufferPtr
  exportPrivateKeyPkcs8FromTpm(const Name& keyName)
  {
    return exportPrivateKeyPkcs8FromTpmInternal(keyName, false);
  }

  virtual bool
  importPrivateKeyPkcs8IntoTpm(const Name& keyName, const uint8_t* buf, size_t size)
  {
    return importPrivateKeyPkcs8IntoTpmInternal(keyName, buf, size, false);
  }

  virtual bool
  importPublicKeyPkcs1IntoTpm(const Name& keyName, const uint8_t* buf, size_t size);

  /******************************
   *       OSX-specifics        *
   ******************************/
  void
  generateKeyPairInTpmInternal(const Name& keyName, KeyType keyType, int keySize, bool needRetry);

  void
  deleteKeyPairInTpmInternal(const Name& keyName, bool needRetry);

  ConstBufferPtr
  exportPrivateKeyPkcs8FromTpmInternal(const Name& keyName, bool needRetry);

  bool
  importPrivateKeyPkcs8IntoTpmInternal(const Name& keyName,
                                       const uint8_t* buf, size_t size,
                                       bool needRetry);

  Block
  signInTpmInternal(const uint8_t* data, size_t dataLength,
                    const Name& keyName, DigestAlgorithm digestAlgorithm,
                    bool needRetry);

private:
  class Impl;
  shared_ptr<Impl> m_impl;
};

} // namespace ndn

#endif // NDN_SECURITY_SEC_TPM_OSX_HPP
