/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2013-2017 Regents of the University of California.
 *
 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
 *
 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 *
 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more details.
 *
 * You should have received copies of the GNU General Public License and GNU Lesser
 * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
 */

#include "back-end-osx.hpp"
#include "key-handle-osx.hpp"
#include "../transform/private-key.hpp"
#include "tpm.hpp"

#include <CoreServices/CoreServices.h>
#include <Security/Security.h>
#include <Security/SecRandom.h>
#include <Security/SecDigestTransform.h>

namespace ndn {
namespace security {
namespace tpm {

using util::CFReleaser;

class BackEndOsx::Impl
{
public:
  Impl()
    : isTerminalMode(false)
  {
  }

  /**
   * @brief Get private key reference with name @p keyName.
   *
   * @param keyName
   * @returns reference to the key
   */
  CFReleaser<SecKeychainItemRef>
  getKey(const Name& keyName)
  {
    CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(nullptr, keyName.toUri().c_str(), kCFStringEncodingUTF8);

    CFReleaser<CFMutableDictionaryRef> attrDict =
      CFDictionaryCreateMutable(nullptr, 5, &kCFTypeDictionaryKeyCallBacks, nullptr);

    CFDictionaryAddValue(attrDict.get(), kSecClass, kSecClassKey);
    CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
    CFDictionaryAddValue(attrDict.get(), kSecAttrKeyClass, kSecAttrKeyClassPrivate);
    CFDictionaryAddValue(attrDict.get(), kSecReturnRef, kCFBooleanTrue);

    CFReleaser<SecKeychainItemRef> keyItem;
    // C-style cast is used as per Apple convention
    OSStatus res = SecItemCopyMatching((CFDictionaryRef)attrDict.get(), (CFTypeRef*)&keyItem.get());
    keyItem.retain();

    if (res != errSecSuccess) {
      if (res == errSecAuthFailed) {
        BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
      }
      BOOST_THROW_EXCEPTION(std::domain_error("Key does not exist"));
    }

    return keyItem;
  }

public:
  SecKeychainRef keyChainRef;
  bool isTerminalMode;
};


static CFTypeRef
getAsymKeyType(KeyType keyType)
{
  switch (keyType) {
  case KeyType::RSA:
    return kSecAttrKeyTypeRSA;
  case KeyType::EC:
    return kSecAttrKeyTypeECDSA;
  default:
    BOOST_THROW_EXCEPTION(Tpm::Error("Unsupported key type"));
  }
}

static CFTypeRef
getDigestAlgorithm(DigestAlgorithm digestAlgo)
{
  switch (digestAlgo) {
  case DigestAlgorithm::SHA256:
    return kSecDigestSHA2;
  default:
    return 0;
  }
}

static long
getDigestSize(DigestAlgorithm digestAlgo)
{
  switch (digestAlgo) {
  case DigestAlgorithm::SHA256:
    return 256;
  default:
    return -1;
  }
}

BackEndOsx::BackEndOsx(const std::string&)
  : m_impl(new Impl)
{
  SecKeychainSetUserInteractionAllowed(!m_impl->isTerminalMode);

  OSStatus res = SecKeychainCopyDefault(&m_impl->keyChainRef);

  if (res == errSecNoDefaultKeychain) { //If no default key chain, create one.
    BOOST_THROW_EXCEPTION(Error("No default keychain, create one first"));
  }
}

BackEndOsx::~BackEndOsx() = default;

const std::string&
BackEndOsx::getScheme()
{
  static std::string scheme = "tpm-osxkeychain";
  return scheme;
}

bool
BackEndOsx::isTerminalMode() const
{
  return m_impl->isTerminalMode;
}

void
BackEndOsx::setTerminalMode(bool isTerminal) const
{
  m_impl->isTerminalMode = isTerminal;
  SecKeychainSetUserInteractionAllowed(!isTerminal);
}

bool
BackEndOsx::isTpmLocked() const
{
  SecKeychainStatus keychainStatus;

  OSStatus res = SecKeychainGetStatus(m_impl->keyChainRef, &keychainStatus);
  if (res != errSecSuccess)
    return true;
  else
    return ((kSecUnlockStateStatus & keychainStatus) == 0);
}

bool
BackEndOsx::unlockTpm(const char* pw, size_t pwLen) const
{
  // If the default key chain is already unlocked, return immediately.
  if (!isTpmLocked())
    return true;

  if (m_impl->isTerminalMode) {
    // Use the supplied password.
    SecKeychainUnlock(m_impl->keyChainRef, pwLen, pw, true);
  }
  else {
    // If inTerminal is not set, get the password from GUI.
    SecKeychainUnlock(m_impl->keyChainRef, 0, nullptr, false);
  }

  return !isTpmLocked();
}

ConstBufferPtr
BackEndOsx::sign(const KeyRefOsx& key, DigestAlgorithm digestAlgorithm,
                 const uint8_t* buf, size_t size) const
{
  CFReleaser<CFDataRef> dataRef = CFDataCreateWithBytesNoCopy(nullptr, buf, size, kCFAllocatorNull);

  CFReleaser<CFErrorRef> error;
  // C-style cast is used as per Apple convention
  CFReleaser<SecTransformRef> signer = SecSignTransformCreate(key.get(), &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Fail to create signer"));
  }

  // Set input
  SecTransformSetAttribute(signer.get(), kSecTransformInputAttributeName, dataRef.get(), &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Fail to configure input of signer"));
  }

  // Enable use of padding
  SecTransformSetAttribute(signer.get(), kSecPaddingKey, kSecPaddingPKCS1Key, &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Fail to configure digest algorithm of signer"));
  }

  // Set padding type
  SecTransformSetAttribute(signer.get(), kSecDigestTypeAttribute, getDigestAlgorithm(digestAlgorithm), &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Fail to configure digest algorithm of signer"));
  }

  // Set digest attribute
  long digestSize = getDigestSize(digestAlgorithm);
  CFReleaser<CFNumberRef> cfDigestSize = CFNumberCreate(nullptr, kCFNumberLongType, &digestSize);
  SecTransformSetAttribute(signer.get(),
                           kSecDigestLengthAttribute,
                           cfDigestSize.get(),
                           &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Fail to configure digest size of signer"));
  }
  // Actually sign
  // C-style cast is used as per Apple convention
  CFReleaser<CFDataRef> signature = (CFDataRef)SecTransformExecute(signer.get(), &error.get());
  if (error != nullptr) {
    CFShow(error.get());
    BOOST_THROW_EXCEPTION(Error("Fail to sign data"));
  }

  if (signature == nullptr) {
    BOOST_THROW_EXCEPTION(Error("Signature is NULL!\n"));
  }

  return make_shared<Buffer>(CFDataGetBytePtr(signature.get()), CFDataGetLength(signature.get()));
}

ConstBufferPtr
BackEndOsx::decrypt(const KeyRefOsx& key, const uint8_t* cipherText, size_t cipherSize) const
{
  CFReleaser<CFDataRef> dataRef = CFDataCreateWithBytesNoCopy(nullptr, cipherText, cipherSize, kCFAllocatorNull);

  CFReleaser<CFErrorRef> error;
  CFReleaser<SecTransformRef> decryptor = SecDecryptTransformCreate(key.get(), &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Fail to create decrypt"));
  }

  SecTransformSetAttribute(decryptor.get(), kSecTransformInputAttributeName, dataRef.get(), &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Fail to configure decrypt"));
  }

  SecTransformSetAttribute(decryptor.get(), kSecPaddingKey, kSecPaddingOAEPKey, &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Fail to configure decrypt #2"));
  }

  CFReleaser<CFDataRef> output = (CFDataRef)SecTransformExecute(decryptor.get(), &error.get());
  if (error != nullptr) {
    // CFShow(error);
    BOOST_THROW_EXCEPTION(Error("Fail to decrypt data"));
  }

  if (output == nullptr) {
    BOOST_THROW_EXCEPTION(Error("Output is NULL!\n"));
  }
  return make_shared<Buffer>(CFDataGetBytePtr(output.get()), CFDataGetLength(output.get()));
}

ConstBufferPtr
BackEndOsx::derivePublicKey(const KeyRefOsx& key) const
{
  CFReleaser<CFDataRef> exportedKey;
  OSStatus res = SecItemExport(key.get(),           // secItemOrArray
                               kSecFormatOpenSSL,   // outputFormat
                               0,                   // flags
                               nullptr,             // keyParams
                               &exportedKey.get()); // exportedData

  if (res != errSecSuccess) {
    if (res == errSecAuthFailed) {
      BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
    }
    else {
      BOOST_THROW_EXCEPTION(Error("Fail to export private key"));
    }
  }

  transform::PrivateKey privateKey;
  privateKey.loadPkcs1(CFDataGetBytePtr(exportedKey.get()), CFDataGetLength(exportedKey.get()));
  return privateKey.derivePublicKey();
}

bool
BackEndOsx::doHasKey(const Name& keyName) const
{
  CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(nullptr, keyName.toUri().c_str(), kCFStringEncodingUTF8);

  CFReleaser<CFMutableDictionaryRef> attrDict =
    CFDictionaryCreateMutable(nullptr, 4, &kCFTypeDictionaryKeyCallBacks, nullptr);

  CFDictionaryAddValue(attrDict.get(), kSecClass, kSecClassKey);
  CFDictionaryAddValue(attrDict.get(), kSecAttrLabel, keyLabel.get());
  CFDictionaryAddValue(attrDict.get(), kSecReturnRef, kCFBooleanTrue);

  CFReleaser<SecKeychainItemRef> itemRef;
  // C-style cast is used as per Apple convention
  OSStatus res = SecItemCopyMatching((CFDictionaryRef)attrDict.get(), (CFTypeRef*)&itemRef.get());
  itemRef.retain();

  return (res == errSecSuccess);
}

unique_ptr<KeyHandle>
BackEndOsx::doGetKeyHandle(const Name& keyName) const
{
  CFReleaser<SecKeychainItemRef> keyItem;
  try {
    keyItem = m_impl->getKey(keyName);
  }
  catch (const std::domain_error&) {
    return nullptr;
  }

  return make_unique<KeyHandleOsx>(*this, (SecKeyRef)keyItem.get());
}

unique_ptr<KeyHandle>
BackEndOsx::doCreateKey(const Name& identityName, const KeyParams& params)
{
  KeyType keyType = params.getKeyType();
  uint32_t keySize;
  switch (keyType) {
    case KeyType::RSA: {
      const RsaKeyParams& rsaParams = static_cast<const RsaKeyParams&>(params);
      keySize = rsaParams.getKeySize();
      break;
    }
    case KeyType::EC: {
      const EcKeyParams& ecParams = static_cast<const EcKeyParams&>(params);
      keySize = ecParams.getKeySize();
      break;
    }
    default: {
      BOOST_THROW_EXCEPTION(Tpm::Error("Fail to create a key pair: Unsupported key type"));
    }
  }
  CFReleaser<CFNumberRef> cfKeySize = CFNumberCreate(nullptr, kCFNumberIntType, &keySize);

  CFReleaser<CFMutableDictionaryRef> attrDict =
    CFDictionaryCreateMutable(nullptr, 2, &kCFTypeDictionaryKeyCallBacks, nullptr);
  CFDictionaryAddValue(attrDict.get(), kSecAttrKeyType, getAsymKeyType(keyType));
  CFDictionaryAddValue(attrDict.get(), kSecAttrKeySizeInBits, cfKeySize.get());

  KeyRefOsx publicKey, privateKey;
  // C-style cast is used as per Apple convention
  OSStatus res = SecKeyGeneratePair((CFDictionaryRef)attrDict.get(), &publicKey.get(), &privateKey.get());

  BOOST_ASSERT(privateKey != nullptr);

  publicKey.retain();
  privateKey.retain();

  BOOST_ASSERT(privateKey != nullptr);

  if (res != errSecSuccess) {
    if (res == errSecAuthFailed) {
      BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
    }
    else {
      BOOST_THROW_EXCEPTION(Error("Fail to create a key pair"));
    }
  }

  unique_ptr<KeyHandle> keyHandle = make_unique<KeyHandleOsx>(*this, privateKey.get());
  setKeyName(*keyHandle, identityName, params);

  SecKeychainAttribute attrs[1]; // maximum number of attributes
  SecKeychainAttributeList attrList = { 0, attrs };
  std::string keyUri = keyHandle->getKeyName().toUri();
  {
    attrs[attrList.count].tag = kSecKeyPrintName;
    attrs[attrList.count].length = keyUri.size();
    attrs[attrList.count].data = const_cast<char*>(keyUri.data());
    attrList.count++;
  }

  SecKeychainItemModifyAttributesAndData((SecKeychainItemRef)privateKey.get(), &attrList, 0, nullptr);
  SecKeychainItemModifyAttributesAndData((SecKeychainItemRef)publicKey.get(), &attrList, 0, nullptr);

  return keyHandle;
}

void
BackEndOsx::doDeleteKey(const Name& keyName)
{
  CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(nullptr, keyName.toUri().c_str(), kCFStringEncodingUTF8);

  CFReleaser<CFMutableDictionaryRef> searchDict =
    CFDictionaryCreateMutable(nullptr, 5, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

  CFDictionaryAddValue(searchDict.get(), kSecClass, kSecClassKey);
  CFDictionaryAddValue(searchDict.get(), kSecAttrLabel, keyLabel.get());
  CFDictionaryAddValue(searchDict.get(), kSecMatchLimit, kSecMatchLimitAll);
  OSStatus res = SecItemDelete(searchDict.get());

  if (res != errSecSuccess) {
    if (res == errSecAuthFailed) {
      BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
    }
    else if (res != errSecItemNotFound) {
      BOOST_THROW_EXCEPTION(Error("Fail to delete a key pair"));
    }
  }
}

ConstBufferPtr
BackEndOsx::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
{
  CFReleaser<SecKeychainItemRef> privateKey;

  try {
    privateKey = m_impl->getKey(keyName);
  }
  catch (const std::domain_error&) {
    BOOST_THROW_EXCEPTION(Tpm::Error("Private key does not exist in OSX Keychain"));
  }

  CFReleaser<CFDataRef> exportedKey;
  SecItemImportExportKeyParameters keyParams;
  memset(&keyParams, 0, sizeof(keyParams));
  CFReleaser<CFStringRef> passphrase =
    CFStringCreateWithBytes(0, reinterpret_cast<const uint8_t*>(pw), pwLen, kCFStringEncodingUTF8, false);
  keyParams.passphrase = passphrase.get();
  OSStatus res = SecItemExport(privateKey.get(),       // secItemOrArray
                               kSecFormatWrappedPKCS8, // outputFormat
                               0,                      // flags
                               &keyParams,             // keyParams
                               &exportedKey.get());    // exportedData

  if (res != errSecSuccess) {
    if (res == errSecAuthFailed) {
      BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
    }
    else {
      BOOST_THROW_EXCEPTION(Error("Fail to export private key"));
    }
  }

  return make_shared<Buffer>(CFDataGetBytePtr(exportedKey.get()), CFDataGetLength(exportedKey.get()));
}

void
BackEndOsx::doImportKey(const Name& keyName, const uint8_t* buf, size_t size,
                        const char* pw, size_t pwLen)
{
  CFReleaser<CFDataRef> importedKey = CFDataCreateWithBytesNoCopy(nullptr, buf, size, kCFAllocatorNull);

  SecExternalFormat externalFormat = kSecFormatWrappedPKCS8;
  SecExternalItemType externalType = kSecItemTypePrivateKey;

  CFReleaser<CFStringRef> keyLabel = CFStringCreateWithCString(nullptr, keyName.toUri().c_str(), kCFStringEncodingUTF8);
  CFReleaser<CFStringRef> passphrase =
    CFStringCreateWithBytes(nullptr, reinterpret_cast<const uint8_t*>(pw), pwLen, kCFStringEncodingUTF8, false);
  CFReleaser<SecAccessRef> access;
  SecAccessCreate(keyLabel.get(), nullptr, &access.get());

  CFArrayRef attributes = nullptr;

  const SecItemImportExportKeyParameters keyParams{
    SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION, // version
    0, // flags
    passphrase.get(), // passphrase
    nullptr, // alert title
    nullptr, // alert prompt
    access.get(), // access ref
    nullptr, // key usage
    attributes // key attributes
  };

  CFReleaser<CFArrayRef> outItems;
  OSStatus res = SecItemImport(importedKey.get(),   // importedData
                               nullptr,             // fileNameOrExtension
                               &externalFormat,     // inputFormat
                               &externalType,       // itemType
                               0,                   // flags
                               &keyParams,          // keyParams
                               m_impl->keyChainRef, // importKeychain
                               &outItems.get());    // outItems

  if (res != errSecSuccess) {
    if (res == errSecAuthFailed) {
      BOOST_THROW_EXCEPTION(Error("Fail to unlock the keychain"));
    }
    else {
      BOOST_THROW_EXCEPTION(Error("Cannot import the private key"));
    }
  }

  // C-style cast is used as per Apple convention
  SecKeychainItemRef privateKey = (SecKeychainItemRef)CFArrayGetValueAtIndex(outItems.get(), 0);
  SecKeychainAttribute attrs[1]; // maximum number of attributes
  SecKeychainAttributeList attrList = { 0, attrs };
  std::string keyUri = keyName.toUri();
  {
    attrs[attrList.count].tag = kSecKeyPrintName;
    attrs[attrList.count].length = keyUri.size();
    attrs[attrList.count].data = const_cast<char*>(keyUri.c_str());
    attrList.count++;
  }

  res = SecKeychainItemModifyAttributesAndData(privateKey, &attrList, 0, nullptr);
}

} // namespace tpm
} // namespace security
} // namespace ndn
