/** @file

  common.cc - Some common functions everyone needs

  @section license License

  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 <cstdio>
#include <cstring>
#include <openssl/ssl.h>
#include <ts/ts.h>
#include <ts/apidefs.h>

#include "common.h"

const unsigned char salt[]      = {115, 97, 108, 117, 0, 85, 137, 229};
const unsigned char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

std::string
hex_str(std::string const &str)
{
  size_t len = str.size() * 2 + 1;
  char hex_str[len];
  for (unsigned long int i = 0; i < str.size(); ++i) {
    unsigned char c    = str.at(i);
    hex_str[i * 2]     = hex_chars[(c & 0xF0) >> 4];
    hex_str[i * 2 + 1] = hex_chars[(c & 0x0F)];
  }
  hex_str[len] = '\0';
  return std::string(hex_str, len);
}

int
encrypt_encode64(const unsigned char *key, int key_length, const unsigned char *in_data, int in_data_len, char *out_data,
                 size_t out_data_size, size_t *out_data_len)
{
  if (!key || !in_data || !out_data || !out_data_len) {
    return -1;
  }

  int cipher_block_size    = 0;
  unsigned char *encrypted = nullptr;
  int encrypted_len        = 0;
  int encrypted_len_extra  = 0;
  int ret                  = -1;

  // Initialize context
  EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new();
  unsigned char iv[EVP_MAX_IV_LENGTH];
  unsigned char gen_key[EVP_MAX_KEY_LENGTH];

  // generate key and iv
  if (EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), salt, key, key_length, 1, gen_key, iv) <= 0) {
    TSDebug(PLUGIN, "Error generating key.");
  }

  // Set context AES128 with the generated key and iv
  if (1 != EVP_EncryptInit_ex(context, EVP_aes_256_cbc(), nullptr, gen_key, iv)) {
    TSDebug(PLUGIN, "EVP_EncryptInit_ex failed.");
    goto Cleanup;
  }

  // https://www.openssl.org/docs/manmaster/man3/EVP_EncryptUpdate.html
  // EVP_EncryptUpdate() needs (inl + cipher_block_size - 1) bytes.
  // EVP_EncryptFinal_ex needs (inl + cipher_block_size) bytes.
  cipher_block_size = EVP_CIPHER_CTX_block_size(context);
  encrypted         = new unsigned char[in_data_len + cipher_block_size * 2];
  if (1 != EVP_EncryptUpdate(context, encrypted, &encrypted_len, in_data, in_data_len)) {
    TSDebug(PLUGIN, "EVP_EncryptUpdate failed.");
    goto Cleanup;
  }

  if (1 != EVP_EncryptFinal_ex(context, encrypted + encrypted_len, &encrypted_len_extra)) {
    TSDebug(PLUGIN, "EVP_EncryptFinal_ex failed.");
    goto Cleanup;
  }

  // We must encode it to base64 here, since the encryption doesn't guarantee that there are no
  // null bytes in the output. Which will cause a problem when sending it through redis since
  // the redis command needs to be formatted to a C string.
  if (TSBase64Encode(reinterpret_cast<char *>(encrypted), encrypted_len + encrypted_len_extra, out_data, out_data_size,
                     out_data_len) != 0) {
    TSDebug(PLUGIN, "Base 64 encoding failed.");
    goto Cleanup;
  }

  TSDebug(PLUGIN, "Encrypted buffer of size %d to buffer of size %lu.", in_data_len, *out_data_len);
  ret = 0;

Cleanup:

  if (encrypted) {
    delete[] encrypted;
  }

  if (context) {
    EVP_CIPHER_CTX_free(context);
  }

  return ret;
}

int
decrypt_decode64(const unsigned char *key, int key_length, const char *in_data, int in_data_len, unsigned char *out_data,
                 size_t out_data_size, size_t *out_data_len)
{
  if (!key || !in_data || !out_data || !out_data_len) {
    return -1;
  }

  size_t decoded_size     = DECODED_LEN(in_data_len);
  size_t decoded_len      = 0;
  unsigned char *decoded  = new unsigned char[decoded_size];
  int decrypted_len       = 0;
  int decrypted_len_extra = 0;
  int ret                 = -1;

  // Initialize context
  EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new();
  unsigned char iv[EVP_MAX_IV_LENGTH];
  unsigned char gen_key[EVP_MAX_KEY_LENGTH];

  // Decode base64
  std::memset(decoded, 0, decoded_size);
  if (TSBase64Decode(in_data, in_data_len, decoded, decoded_size, &decoded_len) != 0) {
    TSDebug(PLUGIN, "Base 64 decoding failed.");
    goto Cleanup;
  }

  // generate key and iv
  if (EVP_BytesToKey(EVP_aes_256_cbc(), EVP_md5(), salt, key, key_length, 1, gen_key, iv) <= 0) {
    TSDebug(PLUGIN, "Error generating key.");
  }
  // set context with the generated key and iv
  if (1 != EVP_DecryptInit_ex(context, EVP_aes_256_cbc(), nullptr, gen_key, iv)) {
    TSDebug(PLUGIN, "EVP_DecryptInit_ex failed.");
    goto Cleanup;
  }

  // https://www.openssl.org/docs/manmaster/man3/EVP_DecryptUpdate.html
  // EVP_DecryptUpdate() and EVP_DecryptFinal_ex() have the exact same requirements as their encrypt counterparts.
  if (1 != EVP_DecryptUpdate(context, out_data, &decrypted_len, decoded, decoded_len)) {
    TSDebug(PLUGIN, "EVP_DecryptUpdate failed.");
    goto Cleanup;
  }

  if (1 != EVP_DecryptFinal_ex(context, out_data + decrypted_len, &decrypted_len_extra)) {
    TSDebug(PLUGIN, "EVP_DecryptFinal_ex failed.");
    goto Cleanup;
  }

  *out_data_len = decrypted_len + decrypted_len_extra;

  TSDebug(PLUGIN, "Decrypted buffer of size %d to buffer of size %lu.", in_data_len, *out_data_len);
  ret = 0;

Cleanup:

  if (decoded) {
    delete[] decoded;
  }

  if (context) {
    EVP_CIPHER_CTX_free(context);
  }

  return ret;
}
