/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2013-2018 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 "tpm.hpp"
#include "../transform/private-key.hpp"
#include "../../encoding/buffer-stream.hpp"
#include "../../util/cf-string-osx.hpp"

#include <Security/Security.h>
#include <cstring>

namespace ndn {
namespace security {
namespace tpm {

namespace cfstring = util::cfstring;
using util::CFReleaser;

class BackEndOsx::Impl
{
public:
  SecKeychainRef keyChainRef;
  bool isTerminalMode = false;
};

static CFReleaser<CFDataRef>
makeCFDataNoCopy(const uint8_t* buf, size_t buflen)
{
  return CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, buf, buflen, kCFAllocatorNull);
}

static CFReleaser<CFMutableDictionaryRef>
makeCFMutableDictionary()
{
  return CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                   &kCFTypeDictionaryKeyCallBacks,
                                   &kCFTypeDictionaryValueCallBacks);
}

static std::string
getErrorMessage(OSStatus status)
{
  CFReleaser<CFStringRef> msg = SecCopyErrorMessageString(status, nullptr);
  if (msg != nullptr)
    return cfstring::toStdString(msg.get());
  else
    return "<no error message>";
}

static std::string
getFailureReason(CFErrorRef err)
{
  CFReleaser<CFStringRef> reason = CFErrorCopyFailureReason(err);
  if (reason != nullptr)
    return cfstring::toStdString(reason.get());
  else
    return "<unknown reason>";
}

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::SHA224:
  case DigestAlgorithm::SHA256:
  case DigestAlgorithm::SHA384:
  case DigestAlgorithm::SHA512:
    return kSecDigestSHA2;
  default:
    return nullptr;
  }
}

static int
getDigestSize(DigestAlgorithm digestAlgo)
{
  switch (digestAlgo) {
  case DigestAlgorithm::SHA224:
    return 224;
  case DigestAlgorithm::SHA256:
    return 256;
  case DigestAlgorithm::SHA384:
    return 384;
  case DigestAlgorithm::SHA512:
    return 512;
  default:
    return -1;
  }
}

/**
 * @brief Get reference to private key with name @p keyName.
 */
static KeyRefOsx
getKeyRef(const Name& keyName)
{
  auto keyLabel = cfstring::fromStdString(keyName.toUri());

  auto query = makeCFMutableDictionary();
  CFDictionaryAddValue(query.get(), kSecClass, kSecClassKey);
  CFDictionaryAddValue(query.get(), kSecAttrKeyClass, kSecAttrKeyClassPrivate);
  CFDictionaryAddValue(query.get(), kSecAttrLabel, keyLabel.get());
  CFDictionaryAddValue(query.get(), kSecReturnRef, kCFBooleanTrue);

  KeyRefOsx keyRef;
  // C-style cast is used as per Apple convention
  OSStatus res = SecItemCopyMatching(query.get(), (CFTypeRef*)&keyRef.get());
  keyRef.retain();

  if (res == errSecSuccess) {
    return keyRef;
  }
  else if (res == errSecItemNotFound) {
    return nullptr;
  }
  else {
    BOOST_THROW_EXCEPTION(BackEnd::Error("Key lookup in keychain failed: " + getErrorMessage(res)));
  }
}

/**
 * @brief Export a private key from the Keychain to @p outKey
 */
static void
exportItem(const KeyRefOsx& keyRef, transform::PrivateKey& outKey)
{
  // use a temporary password for PKCS8 encoding
  const char pw[] = "correct horse battery staple";
  auto passphrase = cfstring::fromBuffer(reinterpret_cast<const uint8_t*>(pw), std::strlen(pw));

  SecItemImportExportKeyParameters keyParams;
  std::memset(&keyParams, 0, sizeof(keyParams));
  keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
  keyParams.passphrase = passphrase.get();

  CFReleaser<CFDataRef> exportedKey;
  OSStatus res = SecItemExport(keyRef.get(),           // secItemOrArray
                               kSecFormatWrappedPKCS8, // outputFormat
                               0,                      // flags
                               &keyParams,             // keyParams
                               &exportedKey.get());    // exportedData

  if (res != errSecSuccess) {
    BOOST_THROW_EXCEPTION(BackEnd::Error("Failed to export private key: "s + getErrorMessage(res)));
  }

  outKey.loadPkcs8(CFDataGetBytePtr(exportedKey.get()), CFDataGetLength(exportedKey.get()),
                   pw, std::strlen(pw));
}

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

  OSStatus res = SecKeychainCopyDefault(&m_impl->keyChainRef);
  if (res == errSecNoDefaultKeychain) {
    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 digestAlgo, const uint8_t* buf, size_t size)
{
  CFReleaser<CFErrorRef> error;
  CFReleaser<SecTransformRef> signer = SecSignTransformCreate(key.get(), &error.get());
  if (signer == nullptr) {
    BOOST_THROW_EXCEPTION(Error("Failed to create sign transform: " + getFailureReason(error.get())));
  }

  // Set input
  auto data = makeCFDataNoCopy(buf, size);
  SecTransformSetAttribute(signer.get(), kSecTransformInputAttributeName, data.get(), &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Failed to configure input of sign transform: " +
                                getFailureReason(error.get())));
  }

  // Enable use of padding
  SecTransformSetAttribute(signer.get(), kSecPaddingKey, kSecPaddingPKCS1Key, &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Failed to configure padding of sign transform: " +
                                getFailureReason(error.get())));
  }

  // Set digest type
  SecTransformSetAttribute(signer.get(), kSecDigestTypeAttribute, getDigestAlgorithm(digestAlgo), &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Failed to configure digest type of sign transform: " +
                                getFailureReason(error.get())));
  }

  // Set digest length
  int digestSize = getDigestSize(digestAlgo);
  CFReleaser<CFNumberRef> cfDigestSize = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &digestSize);
  SecTransformSetAttribute(signer.get(), kSecDigestLengthAttribute, cfDigestSize.get(), &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Failed to configure digest length of sign transform: " +
                                getFailureReason(error.get())));
  }

  // Actually sign
  // C-style cast is used as per Apple convention
  CFReleaser<CFDataRef> signature = (CFDataRef)SecTransformExecute(signer.get(), &error.get());
  if (signature == nullptr) {
    BOOST_THROW_EXCEPTION(Error("Failed to sign data: " + getFailureReason(error.get())));
  }

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

ConstBufferPtr
BackEndOsx::decrypt(const KeyRefOsx& key, const uint8_t* cipherText, size_t cipherSize)
{
  CFReleaser<CFErrorRef> error;
  CFReleaser<SecTransformRef> decryptor = SecDecryptTransformCreate(key.get(), &error.get());
  if (decryptor == nullptr) {
    BOOST_THROW_EXCEPTION(Error("Failed to create decrypt transform: " + getFailureReason(error.get())));
  }

  auto data = makeCFDataNoCopy(cipherText, cipherSize);
  SecTransformSetAttribute(decryptor.get(), kSecTransformInputAttributeName, data.get(), &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Failed to configure input of decrypt transform: " +
                                getFailureReason(error.get())));
  }

  SecTransformSetAttribute(decryptor.get(), kSecPaddingKey, kSecPaddingOAEPKey, &error.get());
  if (error != nullptr) {
    BOOST_THROW_EXCEPTION(Error("Failed to configure padding of decrypt transform: " +
                                getFailureReason(error.get())));
  }

  // C-style cast is used as per Apple convention
  CFReleaser<CFDataRef> plainText = (CFDataRef)SecTransformExecute(decryptor.get(), &error.get());
  if (plainText == nullptr) {
    BOOST_THROW_EXCEPTION(Error("Failed to decrypt data: " + getFailureReason(error.get())));
  }

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

ConstBufferPtr
BackEndOsx::derivePublicKey(const KeyRefOsx& key)
{
  transform::PrivateKey privateKey;
  exportItem(key, privateKey);
  return privateKey.derivePublicKey();
}

bool
BackEndOsx::doHasKey(const Name& keyName) const
{
  return getKeyRef(keyName) != nullptr;
}

unique_ptr<KeyHandle>
BackEndOsx::doGetKeyHandle(const Name& keyName) const
{
  KeyRefOsx keyRef = getKeyRef(keyName);
  if (keyRef == nullptr) {
    return nullptr;
  }

  return make_unique<KeyHandleOsx>(keyRef.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("Failed to generate key pair: Unsupported key type"));
    }
  }
  CFReleaser<CFNumberRef> cfKeySize = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &keySize);

  auto attrDict = makeCFMutableDictionary();
  CFDictionaryAddValue(attrDict.get(), kSecAttrKeyType, getAsymKeyType(keyType));
  CFDictionaryAddValue(attrDict.get(), kSecAttrKeySizeInBits, cfKeySize.get());

  KeyRefOsx publicKey, privateKey;
  OSStatus res = SecKeyGeneratePair(attrDict.get(), &publicKey.get(), &privateKey.get());
  publicKey.retain();
  privateKey.retain();

  if (res != errSecSuccess) {
    BOOST_THROW_EXCEPTION(Error("Failed to generate key pair: " + getErrorMessage(res)));
  }

  unique_ptr<KeyHandle> keyHandle = make_unique<KeyHandleOsx>(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)
{
  auto keyLabel = cfstring::fromStdString(keyName.toUri());

  auto query = makeCFMutableDictionary();
  CFDictionaryAddValue(query.get(), kSecClass, kSecClassKey);
  CFDictionaryAddValue(query.get(), kSecAttrLabel, keyLabel.get());
  CFDictionaryAddValue(query.get(), kSecMatchLimit, kSecMatchLimitAll);

  OSStatus res = SecItemDelete(query.get());

  if (res != errSecSuccess && res != errSecItemNotFound) {
    BOOST_THROW_EXCEPTION(Error("Failed to delete key pair: " + getErrorMessage(res)));
  }
}

ConstBufferPtr
BackEndOsx::doExportKey(const Name& keyName, const char* pw, size_t pwLen)
{
  KeyRefOsx keychainItem = getKeyRef(keyName);
  if (keychainItem == nullptr) {
    BOOST_THROW_EXCEPTION(Error("Failed to export private key: " + getErrorMessage(errSecItemNotFound)));
  }

  transform::PrivateKey exportedKey;
  OBufferStream pkcs8;
  try {
    exportItem(keychainItem, exportedKey);
    exportedKey.savePkcs8(pkcs8, pw, pwLen);
  }
  catch (const transform::PrivateKey::Error& e) {
    BOOST_THROW_EXCEPTION(Error("Failed to export private key: "s + e.what()));
  }
  return pkcs8.buf();
}

void
BackEndOsx::doImportKey(const Name& keyName, const uint8_t* buf, size_t size,
                        const char* pw, size_t pwLen)
{
  transform::PrivateKey privKey;
  OBufferStream pkcs1;
  try {
    // do the PKCS8 decoding ourselves, see bug #4450
    privKey.loadPkcs8(buf, size, pw, pwLen);
    privKey.savePkcs1(pkcs1);
  }
  catch (const transform::PrivateKey::Error& e) {
    BOOST_THROW_EXCEPTION(Error("Failed to import private key: "s + e.what()));
  }
  auto keyToImport = makeCFDataNoCopy(pkcs1.buf()->data(), pkcs1.buf()->size());

  SecExternalFormat externalFormat = kSecFormatOpenSSL;
  SecExternalItemType externalType = kSecItemTypePrivateKey;

  auto keyUri = keyName.toUri();
  auto keyLabel = cfstring::fromStdString(keyUri);
  CFReleaser<SecAccessRef> access;
  OSStatus res = SecAccessCreate(keyLabel.get(), // descriptor
                                 nullptr,        // trustedlist (null == trust only the calling app)
                                 &access.get()); // accessRef

  if (res != errSecSuccess) {
    BOOST_THROW_EXCEPTION(Error("Failed to import private key: " + getErrorMessage(res)));
  }

  SecItemImportExportKeyParameters keyParams;
  std::memset(&keyParams, 0, sizeof(keyParams));
  keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
  keyParams.accessRef = access.get();

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

  if (res != errSecSuccess) {
    BOOST_THROW_EXCEPTION(Error("Failed to import private key: " + getErrorMessage(res)));
  }

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

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