/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "DHImpl.hpp"

#include <openssl/objects.h>
#include <openssl/stack.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/rsa.h>
#include <cstring>
#include <cctype>
#include <cstdint>

static DH *m_dh = nullptr;
static std::string m_skAlgo;
static int m_keySize = 0;
static BIGNUM *m_pubKeyOther = nullptr;
static unsigned char m_key[128] = {0};
static std::vector<X509 *> m_serverCerts;

static const char *dhP =
    "13528702063991073999718992897071702177131142188276542919088770094024269"
    "73079899070080419278066109785292538223079165925365098181867673946"
    "34756714063947534092593553024224277712367371302394452615862654308"
    "11180902979719649450105660478776364198726078338308557022096810447"
    "3500348898008043285865193451061481841186553";

static const int dhL = 1023;

static int DH_PUBKEY_set(DH_PUBKEY **x, EVP_PKEY *pkey);
static EVP_PKEY *DH_PUBKEY_get(DH_PUBKEY *key);
static const EVP_CIPHER *getCipherFunc();
static int setSkAlgo(const char *skalgo);

ASN1_SEQUENCE(
    DH_PUBKEY) = {ASN1_SIMPLE(DH_PUBKEY, algor, X509_ALGOR),
                  ASN1_SIMPLE(DH_PUBKEY, public_key,
                              ASN1_BIT_STRING)} ASN1_SEQUENCE_END(DH_PUBKEY)

    // This gives us the i2d/d2i x.509 (ASN1 DER) encode/decode functions
    IMPLEMENT_ASN1_FUNCTIONS(DH_PUBKEY)

    // Returns Error code
    int gf_initDhKeys(const char *dhAlgo, const char *ksPath) {
  int errorCode = DH_ERR_NO_ERROR;  // No error;

  // ksPath can be null
  if (m_dh || !dhAlgo || strlen(dhAlgo) == 0) {
    return errorCode;
  }

  // set the symmetric cipher algorithm name
  errorCode = setSkAlgo(dhAlgo);
  if (errorCode != DH_ERR_NO_ERROR) {
    return errorCode;
  }

  // do add-all here or outside in DS::connect?
  OpenSSL_add_all_algorithms();
  ERR_load_crypto_strings();

  m_dh = DH_new();

  BIGNUM* pbn = nullptr;
  BIGNUM* gbn = nullptr;
  DH_get0_pqg(m_dh, const_cast<const BIGNUM**>(&pbn), nullptr, const_cast<const BIGNUM**>(&gbn));
  BN_dec2bn(&pbn, dhP);

  LOGDH(" DHInit: P ptr is %p", pbn);
  LOGDH(" DHInit: G ptr is %p", gbn);
  LOGDH(" DHInit: length is %d", DH_get_length(m_dh));

  BN_dec2bn(&gbn, dhP);

  DH_set_length(m_dh, dhL);

  DH_generate_key(m_dh);

  const BIGNUM *pub_key, *priv_key;
  DH_get0_key(m_dh, &pub_key, &priv_key);

  int codes = 0;
  DH_check(m_dh, &codes);
  LOGDH(" DHInit: DH_check codes is 0x%04X", codes);
  LOGDH(" DHInit: DH_size is %d", DH_size(m_dh));

  // load the server's RSA public key for server authentication
  // note that OpenSSL 0.9.8g has a bug where it can read only the first one in
  // the keystore

  LOGDH(" Loading keystore...");

  if (ksPath == nullptr || strlen(ksPath) == 0) {
    LOGDH("Property \"security-client-kspath\" 's value is nullptr.");
    return errorCode;
  }
  FILE *keyStoreFP = nullptr;
  keyStoreFP = fopen(ksPath, "r");

  LOGDH(" kspath is [%s]", ksPath);
  LOGDH(" keystore FILE ptr is %p", keyStoreFP);

  // Read from pem file and put into.
  X509 *cert = nullptr;
  do {
    cert = PEM_read_X509(keyStoreFP, nullptr, nullptr, nullptr);

    if (cert != nullptr) {
      m_serverCerts.push_back(cert);
    }
  } while (cert != nullptr);

  LOGDH(" Total certificats imported # %zd", m_serverCerts.size());

  fclose(keyStoreFP);

  return errorCode;
}

void gf_clearDhKeys(void) {
  if (m_dh != nullptr) {
    DH_free(m_dh);
    m_dh = nullptr;
  }

  std::vector<X509 *>::const_iterator iter;
  for (iter = m_serverCerts.begin(); iter != m_serverCerts.end(); ++iter) {
    X509_free(*iter);
  }

  m_serverCerts.clear();

  if (m_pubKeyOther != nullptr) {
    BN_free(m_pubKeyOther);
    m_pubKeyOther = nullptr;
  }

  memset(m_key, 0, 128);

  EVP_cleanup();
}

unsigned char *gf_getPublicKey(int *pLen) {
  const BIGNUM *pub_key, *priv_key;
  DH_get0_key(m_dh, &pub_key, &priv_key);

  if (pub_key == nullptr || pLen == nullptr) {
    return nullptr;
  }

  int numBytes = BN_num_bytes(pub_key);

  if (numBytes <= 0) {
    return nullptr;
  }

  EVP_PKEY *evppubkey = EVP_PKEY_new();
  LOGDH(" before assign DH ptr is %p", m_dh);
  EVP_PKEY_assign_DH(evppubkey, m_dh);
  LOGDH(" after assign DH ptr is %p", m_dh);
  DH_PUBKEY *dhpubkey = nullptr;
  DH_PUBKEY_set(&dhpubkey, evppubkey);
  int len = i2d_DH_PUBKEY(dhpubkey, nullptr);
  unsigned char *pubkey = new unsigned char[len];
  unsigned char *temp = pubkey;
  //
  //  Note, this temp pointer is needed because OpenSSL increments the pointer
  //  passed in
  // so that following encoding can be done at the current output location,
  // this will cause a problem if we try to free the pointer which has been
  // moved by OpenSSL.
  //
  i2d_DH_PUBKEY(dhpubkey, &temp);

  //  TODO: uncomment this - causing problem in computeSecret?
  // DH_PUBKEY_free(dhpubkey);
  // EVP_PKEY_free(evppubkey);

  LOGDH(" after evp free DH ptr is %p", m_dh);
  *pLen = len;
  return pubkey;
}

void gf_setPublicKeyOther(const unsigned char *pubkey, int length) {
  if (m_pubKeyOther != nullptr) {
    BN_free(m_pubKeyOther);
    m_pubKeyOther = nullptr;
  }

  const unsigned char *temp = pubkey;
  DH_PUBKEY *dhpubkey = d2i_DH_PUBKEY(nullptr, &temp, length);
  LOGDH(" setPubKeyOther: after d2i_dhpubkey ptr is %p", dhpubkey);
  EVP_PKEY *evppkey = DH_PUBKEY_get(dhpubkey);
  LOGDH(" setPubKeyOther: after dhpubkey get evp ptr is %p", evppkey);
  LOGDH(" setPubKeyOther: before BNdup ptr is %p", m_pubKeyOther);

  const BIGNUM *pub_key, *priv_key;
  DH *dh = EVP_PKEY_get1_DH(evppkey);
  DH_get0_key(dh, &pub_key, &priv_key);
  m_pubKeyOther = BN_dup(pub_key);
  LOGDH(" setPubKeyOther: after BNdup ptr is %p", m_pubKeyOther);
  EVP_PKEY_free(evppkey);
  DH_PUBKEY_free(dhpubkey);

#ifdef _DEBUG
  int codes = 0;
  int ret = DH_check_pub_key(m_dh, m_pubKeyOther, &codes);
  LOGDH(" DHInit: DH_check_pub_key ret %d", ret);
  LOGDH(" DHInit: DH check_pub_key codes is 0x%04X", codes);
#endif
}

void gf_computeSharedSecret() {
  LOGDH("COMPUTE: DH ptr %p, pubkeyOther ptr %p", m_dh, m_pubKeyOther);

  LOGDH("DHcomputeKey DHSize is %d", DH_size(m_dh));
#ifdef _DEBUG
  int ret = DH_compute_key(m_key, m_pubKeyOther, m_dh);
  LOGDH("DHcomputeKey ret %d : Compute err(%d): %s", ret, ERR_get_error(),
        ERR_error_string(ERR_get_error(), nullptr));
#endif
}

int setSkAlgo(const char *skalgo) {
  int errCode = DH_ERR_NO_ERROR;

  std::string inAlgo(skalgo);
  size_t colIdx = inAlgo.find(':');
  std::string algoStr =
      (colIdx == std::string::npos) ? inAlgo : inAlgo.substr(0, colIdx);
  int keySize = 0;

  // Convert input algo to lower case to support case insensitivity
  for (unsigned int i = 0; i < algoStr.size(); i++) {
    algoStr[i] = tolower(algoStr[i]);
  }

  if (algoStr == "aes") {
    keySize = (colIdx == std::string::npos)
                  ? 128
                  : atoi(inAlgo.substr(colIdx + 1).c_str());
    if (keySize == 128 || keySize == 192 || keySize == 256) {
      m_skAlgo = "AES";
      m_keySize = keySize;
    } else {
      return DH_ERR_ILLEGAL_KEYSIZE;
    }
  } else if (algoStr == "blowfish") {
    keySize = (colIdx == std::string::npos)
                  ? 128
                  : atoi(inAlgo.substr(colIdx + 1).c_str());
    if (keySize >= 128 && keySize <= 448) {
      m_skAlgo = "Blowfish";
      m_keySize = keySize;
    } else {
      return DH_ERR_ILLEGAL_KEYSIZE;
    }
  } else if (algoStr == "desede") {  // No keysize should be given
    if (colIdx == std::string::npos) {
      m_skAlgo = "DESede";
      m_keySize = 192;
    } else {
      return DH_ERR_ILLEGAL_KEYSIZE;
    }
  } else {
    return DH_ERR_UNSUPPORTED_ALGO;
  }

  LOGDH(" DH: Got SK algo as %s", m_skAlgo.c_str());
  LOGDH(" DH: Got keySize as %d", m_keySize);

  return errCode;
}

const EVP_CIPHER *getCipherFunc() {
  if (m_skAlgo == "AES") {
    if (m_keySize == 192) {
      return EVP_aes_192_cbc();
    } else if (m_keySize == 256) {
      return EVP_aes_256_cbc();
    } else {  // Default
      return EVP_aes_128_cbc();
    }
  } else if (m_skAlgo == "Blowfish") {
    return EVP_bf_cbc();
  } else if (m_skAlgo == "DESede") {
    return EVP_des_ede3_cbc();
  } else {
    LOGDH("ERROR: Unsupported DH Algorithm");
    return nullptr;
  }
}

unsigned char *gf_encryptDH(const unsigned char *cleartext, int len,
                            int *retLen) {
  // Validation
  if (cleartext == nullptr || len < 1 || retLen == nullptr) {
    return nullptr;
  }

  LOGDH(" DH: gf_encryptDH using sk algo: %s, Keysize: %d", m_skAlgo.c_str(),
        m_keySize);

  unsigned char *ciphertext =
      new unsigned char[len + 50];  // give enough room for padding
  int outlen, tmplen;
  EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();

  const EVP_CIPHER *cipherFunc = getCipherFunc();

  // init openssl cipher context
  if (m_skAlgo == "AES") {
    int keySize = m_keySize > 128 ? m_keySize / 8 : 16;
    EVP_EncryptInit_ex(ctx, cipherFunc, nullptr, (unsigned char *)m_key,
                       (unsigned char *)m_key + keySize);
  } else if (m_skAlgo == "Blowfish") {
    int keySize = m_keySize > 128 ? m_keySize / 8 : 16;
    EVP_EncryptInit_ex(ctx, cipherFunc, nullptr, nullptr,
                       (unsigned char *)m_key + keySize);
    EVP_CIPHER_CTX_set_key_length(ctx, keySize);
    LOGDH("DHencrypt: BF keysize is %d", keySize);
    EVP_EncryptInit_ex(ctx, nullptr, nullptr, (unsigned char *)m_key, nullptr);
  } else if (m_skAlgo == "DESede") {
    EVP_EncryptInit_ex(ctx, cipherFunc, nullptr, (unsigned char *)m_key,
                       (unsigned char *)m_key + 24);
  }

  if (!EVP_EncryptUpdate(ctx, ciphertext, &outlen, cleartext, len)) {
    LOGDH(" DHencrypt: enc update ret nullptr");
    return nullptr;
  }
  /* Buffer passed to EVP_EncryptFinal() must be after data just
   * encrypted to avoid overwriting it.
   */
  tmplen = 0;

  if (!EVP_EncryptFinal_ex(ctx, ciphertext + outlen, &tmplen)) {
    LOGDH("DHencrypt: enc final ret nullptr");
    return nullptr;
  }

  outlen += tmplen;

  EVP_CIPHER_CTX_cleanup(ctx);

  LOGDH("DHencrypt: in len is %d, out len is %d", len, outlen);

  *retLen = outlen;
  return ciphertext;
}

// std::shared_ptr<CacheableBytes> decrypt(const uint8_t * ciphertext, int
// len)
// {
//  LOGDH("DH: Used unimplemented decrypt!");
//  return nullptr;
//}

bool gf_verifyDH(const char *subject, const unsigned char *challenge,
                 int challengeLen, const unsigned char *response,
                 int responseLen, int *reason) {
  LOGDH(" In Verify - looking for subject %s", subject);

  EVP_PKEY *evpkey = nullptr;
  X509 *cert = nullptr;

  char *certsubject = nullptr;

  int32_t count = static_cast<int32_t>(m_serverCerts.size());
  if (count == 0) {
    *reason = DH_ERR_NO_CERTIFICATES;
    return false;
  }

  for (int item = 0; item < count; item++) {
    certsubject =
        X509_NAME_oneline(X509_get_subject_name(m_serverCerts[item]), nullptr, 0);

    // Ignore first letter for comparision, openssl adds / before subject name
    // e.g. /CN=geode1
    if (strcmp((const char *)certsubject + 1, subject) == 0) {
      evpkey = X509_get_pubkey(m_serverCerts[item]);
      cert = m_serverCerts[item];
      LOGDH("Found subject [%s] in stored certificates", certsubject);
      break;
    }
  }

  if (evpkey == nullptr || cert == nullptr) {
    *reason = DH_ERR_SUBJECT_NOT_FOUND;
    LOGDH("Certificate not found!");
    return false;
  }

  const ASN1_OBJECT *macobj;
  const X509_ALGOR *algorithm = nullptr;
  X509_ALGOR_get0(&macobj, nullptr, nullptr, algorithm);

  const EVP_MD *signatureDigest = EVP_get_digestbyobj(macobj);
  EVP_MD_CTX *signatureCtx = EVP_MD_CTX_new();

  int result1 = EVP_VerifyInit_ex(signatureCtx, signatureDigest, nullptr);
  LOGDH(" Result of VerifyInit is %d", result1);

  int result2 = EVP_VerifyUpdate(signatureCtx, challenge, challengeLen);
  LOGDH(" Result of VerifyUpdate is %d", result2);

  int result3 = EVP_VerifyFinal(signatureCtx, response, responseLen, evpkey);
  LOGDH(" Result of VerifyFinal is %d", result3);

  bool result = (result1 == 1 && result2 == 1 && result3 == 1);

  EVP_MD_CTX_free(signatureCtx);

  if (result == false) {
    *reason = DH_ERR_INVALID_SIGN;
  }

  return result;
}

int DH_PUBKEY_set(DH_PUBKEY **x, EVP_PKEY *pkey) {
  DH_PUBKEY *pk = nullptr;
  X509_ALGOR *a;
  ASN1_OBJECT *o;
  unsigned char *s, *p = nullptr;
  int i;
  ASN1_INTEGER *asn1int = nullptr;
  DH *dh = EVP_PKEY_get1_DH(pkey);

  if (x == nullptr) return (0);

  if ((pk = DH_PUBKEY_new()) == nullptr) goto err;
  a = pk->algor;

  LOGDH(" key type for OBJ NID is %d", EVP_PKEY_base_id(pkey));

  /* set the algorithm id */
  if ((o = OBJ_nid2obj(EVP_PKEY_base_id(pkey))) == nullptr) goto err;
  ASN1_OBJECT_free(a->algorithm);
  a->algorithm = o;

  /* Set the parameter list */
  if (EVP_PKEY_base_id(pkey) == EVP_PKEY_RSA) {
    if ((a->parameter == nullptr) || (a->parameter->type != V_ASN1_NULL)) {
      ASN1_TYPE_free(a->parameter);
      if (!(a->parameter = ASN1_TYPE_new())) {
        X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
        goto err;
      }
      a->parameter->type = V_ASN1_NULL;
    }
  } else if (EVP_PKEY_base_id(pkey) == EVP_PKEY_DH) {
    unsigned char *pp;

    const BIGNUM *pub_key, *priv_key;
    DH_get0_key(dh, &pub_key, &priv_key);
    ASN1_TYPE_free(a->parameter);
    if ((i = i2d_DHparams(dh, nullptr)) <= 0) goto err;
    if (!(p = reinterpret_cast<unsigned char *>(OPENSSL_malloc(i)))) {
      X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
      goto err;
    }
    pp = p;
    i2d_DHparams(dh, &pp);
    if (!(a->parameter = ASN1_TYPE_new())) {
      OPENSSL_free(p);
      X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
      goto err;
    }
    a->parameter->type = V_ASN1_SEQUENCE;
    if (!(a->parameter->value.sequence = ASN1_STRING_new())) {
      OPENSSL_free(p);
      X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
      goto err;
    }
    if (!ASN1_STRING_set(a->parameter->value.sequence, p, i)) {
      OPENSSL_free(p);
      X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
      goto err;
    }
    OPENSSL_free(p);
  } else if (1) {
    X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM);
    goto err;
  }

  const BIGNUM *pub_key, *priv_key;
  DH_get0_key(dh, &pub_key, &priv_key);

  asn1int = BN_to_ASN1_INTEGER(pub_key, nullptr);
  if ((i = i2d_ASN1_INTEGER(asn1int, nullptr)) <= 0) goto err;
  if ((s = reinterpret_cast<unsigned char *>(OPENSSL_malloc(i + 1))) == nullptr) {
    X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
    goto err;
  }
  p = s;
  i2d_ASN1_INTEGER(asn1int, &p);
  if (!ASN1_BIT_STRING_set(pk->public_key, s, i)) {
    X509err(X509_F_X509_PUBKEY_SET, ERR_R_MALLOC_FAILURE);
    goto err;
  }
  /* Set number of unused bits to zero */
  pk->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
  pk->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;

  OPENSSL_free(s);

  if (*x != nullptr) DH_PUBKEY_free(*x);

  *x = pk;

  return 1;
err:
  if (asn1int != nullptr) ASN1_INTEGER_free(asn1int);
  if (pk != nullptr) DH_PUBKEY_free(pk);
  return 0;
}

EVP_PKEY *DH_PUBKEY_get(DH_PUBKEY *key) {
  EVP_PKEY *ret = nullptr;
  decltype(asn1_string_st::length) j;
  const unsigned char *p;
  const unsigned char *cp;
  X509_ALGOR *a;
  ASN1_INTEGER *asn1int = nullptr;

  if (key == nullptr) {
    EVP_PKEY_up_ref(key->pkey);
    return (key->pkey);
  }

  if (key->pkey != nullptr) {
    EVP_PKEY_up_ref(key->pkey);
    return (key->pkey);
  }

  if (key->public_key == nullptr) {
    if (asn1int != nullptr) ASN1_INTEGER_free(asn1int);
    if (ret != nullptr) EVP_PKEY_free(ret);
    return (nullptr);
  }

  if ((ret = EVP_PKEY_new()) == nullptr) {
    X509err(X509_F_X509_PUBKEY_DECODE, ERR_R_MALLOC_FAILURE);
    if (asn1int != nullptr) ASN1_INTEGER_free(asn1int);
    if (ret != nullptr) EVP_PKEY_free(ret);
    return (nullptr);
  }

  LOGDH(" DHPUBKEY evppkey type is %d", EVP_PKEY_base_id(ret));

  /* the parameters must be extracted before the public key */

  a = key->algor;

  if (EVP_PKEY_base_id(ret) == EVP_PKEY_DH) {
    if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) {
      if ((EVP_PKEY_set1_DH(ret, DH_new())) == 0) {
        X509err(X509_F_X509_PUBKEY_DECODE, ERR_R_MALLOC_FAILURE);
        if (asn1int != nullptr) ASN1_INTEGER_free(asn1int);
        if (ret != nullptr) EVP_PKEY_free(ret);
        return (nullptr);
      }
      cp = p = a->parameter->value.sequence->data;
      j = a->parameter->value.sequence->length;
      DH *dh = EVP_PKEY_get1_DH(ret);
      if (!d2i_DHparams(&dh, &cp, j)) {
        if (asn1int != nullptr) ASN1_INTEGER_free(asn1int);
        if (ret != nullptr) EVP_PKEY_free(ret);
        return (nullptr);
      }
    }
  }

  p = key->public_key->data;
  j = key->public_key->length;

  asn1int = d2i_ASN1_INTEGER(nullptr, &p, j);
  LOGDH("after d2i asn1 integer ptr is %p", asn1int);

  DH *dh = EVP_PKEY_get1_DH(ret);
  DH_set0_key(dh, ASN1_INTEGER_to_BN(asn1int, nullptr), nullptr);

  key->pkey = ret;
  EVP_PKEY_up_ref(key->pkey);

  if (asn1int) {
    ASN1_INTEGER_free(asn1int);
  }
  return (ret);
}
