/* Copyright 2021 Google LLC
Licensed 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 "config.h"
#include "syshead.h"

#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#include "fuzz_verify_cert.h"
#include "misc.h"
#include "manage.h"
#include "otime.h"
#include "base64.h"
#include "ssl_verify.h"
#include "ssl_verify_backend.h"

#include "fuzz_randomizer.h"

static void key_ctx_update_implicit_iv(struct key_ctx *ctx, uint8_t *key,
                                       size_t key_len) {
  const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt(ctx->cipher);

  /* Only use implicit IV in AEAD cipher mode, where HMAC key is not used */
  if (cipher_kt_mode_aead(cipher_kt)) {
    size_t impl_iv_len = 0;
    ASSERT(cipher_kt_iv_size(cipher_kt) >= OPENVPN_AEAD_MIN_IV_LEN);
    impl_iv_len = cipher_kt_iv_size(cipher_kt) - sizeof(packet_id_type);
    ASSERT(impl_iv_len <= OPENVPN_MAX_IV_LENGTH);
    ASSERT(impl_iv_len <= key_len);
    memcpy(ctx->implicit_iv, key, impl_iv_len);
    ctx->implicit_iv_len = impl_iv_len;
  }
}

static int init_frame(struct frame *frame) {
  frame->link_mtu = fuzz_randomizer_get_int(100, 1000);
  frame->extra_buffer = fuzz_randomizer_get_int(100, 1000);
  frame->link_mtu_dynamic = fuzz_randomizer_get_int(100, 1000);
  frame->extra_frame = fuzz_randomizer_get_int(100, 1000);
  frame->extra_tun = fuzz_randomizer_get_int(100, 1000);
  frame->extra_link = fuzz_randomizer_get_int(100, 1000);
  frame->align_flags = 0;
  frame->align_adjust = 0;
  if (TUN_MTU_SIZE(frame) <= 0) {
    return -1;
  }
  return 0;
}

int LLVMFuzzerInitialize(int *argc, char ***argv) {
  OPENSSL_malloc_init();
  SSL_library_init();
  ERR_load_crypto_strings();

  OpenSSL_add_all_algorithms();
  OpenSSL_add_ssl_algorithms();

  SSL_load_error_strings();
  return 0;
}

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  fuzz_random_init(data, size);
  fuzz_success = 1;
  bool key_ctx_dec_initialized = false;
  bool key_ctx_enc_initialized = false;
  struct key_ctx key_ctx_dec;
  memset(&key_ctx_dec, 0, sizeof(struct key_ctx));
  struct key_ctx key_ctx_enc;
  memset(&key_ctx_enc, 0, sizeof(struct key_ctx));

  struct gc_arena gc;
  struct tls_session *session = NULL;
  X509 *x509 = NULL;
  gc = gc_new();

  gb_init();

  // Read key file
  struct key2 key2;
  char *keydata = gb_get_random_string();
  read_key_file(&key2, keydata, RKF_INLINE);

  // init key type
  struct key_type kt;
  memset(&kt, 0, sizeof(struct key_type));

  char *ciphername = gb_get_random_string();
  char *authname = gb_get_random_string();
  bool key_type_initialized = false;

  if (strcmp(ciphername, "AES-256-GCM") == 0 ||
      strcmp(ciphername, "AES-128-GCM") == 0 ||
      strcmp(ciphername, "AES-192-GCM") == 0 ||
      strcmp(ciphername, "CAMELLIA-128-CFB128") == 0) {

    int v = fuzz_randomizer_get_int(0, 1);
    if (v == 0) {
      init_key_type(&kt, ciphername, authname, true, 0);
    } else {
      init_key_type(&kt, ciphername, authname, false, 0);
    }
    key_type_initialized = true;
  }

  if (fuzz_success == 0) {
    goto cleanup;
  }

  // Generate key.
  // Identify which one we should do, read or generate a random key.
  int c = fuzz_randomizer_get_int(0, 1);
  const uint8_t d[1024];
  int key_read = 0;
  struct key key;
  if (c == 0) {
    if (fuzz_get_random_data(d, 1024) != 1024) {
      struct buffer buf = alloc_buf(1024);
      buf_write(&buf, d, 1024);
      if (read_key(&key, &kt, &buf) == 1) {
        key_read = 1;
      }
      free_buf(&buf);
    }
  }
  else {
    if (key_type_initialized == true) {
      generate_key_random(&key, &kt);
    }
  }

  if (fuzz_success == 0) {
    goto cleanup;
  }
  key_read = 1;

  // init decryption context
  if (key_type_initialized && key_read) {
    init_key_ctx(&key_ctx_dec, &key, &kt, OPENVPN_OP_DECRYPT, "x");
    key_ctx_update_implicit_iv(&key_ctx_dec, &(key.hmac), MAX_HMAC_KEY_LENGTH);
    key_ctx_dec_initialized = true;
  }

  // init encryption context
  if (key_type_initialized && key_read) {
    init_key_ctx(&key_ctx_enc, &key, &kt, OPENVPN_OP_DECRYPT, "x");
    key_ctx_update_implicit_iv(&key_ctx_enc, &(key.hmac), MAX_HMAC_KEY_LENGTH);
    key_ctx_enc_initialized = true;
  }

  // perform encryption
  struct frame frame;
  memset(&frame, 0, sizeof(struct frame));
  if (key_ctx_enc_initialized == true && key_ctx_dec_initialized == true &&
      init_frame(&frame) == 0) {
    struct crypto_options opt;
    memset(&opt, 0, sizeof(opt));
    opt.pid_persist = NULL;
    opt.key_ctx_bi.encrypt = key_ctx_enc;
    opt.key_ctx_bi.decrypt = key_ctx_dec;
    opt.key_ctx_bi.initialized = true;
    opt.packet_id.rec.initialized = true;
    opt.packet_id.rec.seq_list = NULL;
    opt.packet_id.rec.name = NULL;

    void *buf_p;

    struct buffer encrypt_workspace = alloc_buf_gc(BUF_SIZE(&(frame)), &gc);
    struct buffer work = alloc_buf_gc(BUF_SIZE(&(frame)), &gc);
    struct buffer src = alloc_buf_gc(TUN_MTU_SIZE(&(frame)), &gc);
    struct buffer buf = clear_buf();

    int x = fuzz_randomizer_get_int(1, TUN_MTU_SIZE(&frame));

    ASSERT(buf_init(&work, FRAME_HEADROOM(&(frame))));
    ASSERT(buf_init(&src, 0));
    src.len = x;
    ASSERT(rand_bytes(BPTR(&src), BLEN(&src)));

    buf = work;
    buf_p = buf_write_alloc(&buf, BLEN(&src));
    ASSERT(buf_p);
    memcpy(buf_p, BPTR(&src), BLEN(&src));

    ASSERT(buf_init(&encrypt_workspace, FRAME_HEADROOM(&(frame))));

    openvpn_encrypt(&buf, encrypt_workspace, &opt);
  }

  // perform decryption
  memset(&frame, 0, sizeof(struct frame));
  if (key_ctx_dec_initialized == true && key_ctx_enc_initialized == true &&
      init_frame(&frame) == 0) {
    struct crypto_options opt;
    memset(&opt, 0, sizeof(opt));
    opt.pid_persist = NULL;
    opt.key_ctx_bi.encrypt = key_ctx_enc;
    opt.key_ctx_bi.decrypt = key_ctx_dec;
    opt.key_ctx_bi.initialized = true;
    opt.packet_id.rec.initialized = true;
    opt.packet_id.rec.seq_list = NULL;
    opt.packet_id.rec.name = NULL;

    void *buf_p;

    struct buffer decrypt_workspace = alloc_buf_gc(BUF_SIZE(&(frame)), &gc);
    struct buffer work = alloc_buf_gc(BUF_SIZE(&(frame)), &gc);
    struct buffer src = alloc_buf_gc(TUN_MTU_SIZE(&(frame)), &gc);
    struct buffer buf = clear_buf();

    int x = fuzz_randomizer_get_int(1, TUN_MTU_SIZE(&frame));

    ASSERT(buf_init(&work, FRAME_HEADROOM(&(frame))));
    ASSERT(buf_init(&src, 0));
    src.len = x;
    ASSERT(rand_bytes(BPTR(&src), BLEN(&src)));

    buf = work;
    buf_p = buf_write_alloc(&buf, BLEN(&src));
    ASSERT(buf_p);
    memcpy(buf_p, BPTR(&src), BLEN(&src));

    ASSERT(buf_init(&decrypt_workspace, FRAME_HEADROOM(&(frame))));
    
    openvpn_decrypt(&buf, decrypt_workspace, &opt, &frame, BPTR(&buf));
  }

cleanup:
  // cleanup
  gc_free(&gc);

  if (key_ctx_dec_initialized == true) {
    free_key_ctx(&key_ctx_dec);
  }

  if (key_ctx_enc_initialized == true) {
    free_key_ctx(&key_ctx_enc);
  }
  fuzz_random_destroy();

  gb_cleanup();

  return 0;
}
