/*
 * 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.
 */
#pragma once

/**
 * This is to make our code work with openssl both 1.0.x and 1.1.y
 * https://wiki.openssl.org/index.php/OpenSSL_1.1.0_Changes#Compatibility_Layer
 */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#include <openssl/engine.h>
#include <string.h>

static void* OPENSSL_zalloc(size_t num) {
  void* ret = OPENSSL_malloc(num);

  if (ret != NULL)
    memset(ret, 0, num);
  return ret;
}

int RSA_set0_key(RSA* r, BIGNUM* n, BIGNUM* e, BIGNUM* d) {
  /* If the fields n and e in r are NULL, the corresponding input
   * parameters MUST be non-NULL for n and e.  d may be
   * left NULL (in case only the public key is used).
   */
  if ((r->n == NULL && n == NULL) || (r->e == NULL && e == NULL))
    return 0;

  if (n != NULL) {
    BN_free(r->n);
    r->n = n;
  }
  if (e != NULL) {
    BN_free(r->e);
    r->e = e;
  }
  if (d != NULL) {
    BN_free(r->d);
    r->d = d;
  }

  return 1;
}

int RSA_set0_factors(RSA* r, BIGNUM* p, BIGNUM* q) {
  /* If the fields p and q in r are NULL, the corresponding input
   * parameters MUST be non-NULL.
   */
  if ((r->p == NULL && p == NULL) || (r->q == NULL && q == NULL))
    return 0;

  if (p != NULL) {
    BN_free(r->p);
    r->p = p;
  }
  if (q != NULL) {
    BN_free(r->q);
    r->q = q;
  }

  return 1;
}

int RSA_set0_crt_params(RSA* r, BIGNUM* dmp1, BIGNUM* dmq1, BIGNUM* iqmp) {
  /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input
   * parameters MUST be non-NULL.
   */
  if ((r->dmp1 == NULL && dmp1 == NULL) || (r->dmq1 == NULL && dmq1 == NULL) || (r->iqmp == NULL && iqmp == NULL))
    return 0;

  if (dmp1 != NULL) {
    BN_free(r->dmp1);
    r->dmp1 = dmp1;
  }
  if (dmq1 != NULL) {
    BN_free(r->dmq1);
    r->dmq1 = dmq1;
  }
  if (iqmp != NULL) {
    BN_free(r->iqmp);
    r->iqmp = iqmp;
  }

  return 1;
}

void RSA_get0_key(const RSA* r, const BIGNUM** n, const BIGNUM** e, const BIGNUM** d) {
  if (n != NULL)
    *n = r->n;
  if (e != NULL)
    *e = r->e;
  if (d != NULL)
    *d = r->d;
}

void RSA_get0_factors(const RSA* r, const BIGNUM** p, const BIGNUM** q) {
  if (p != NULL)
    *p = r->p;
  if (q != NULL)
    *q = r->q;
}

void RSA_get0_crt_params(const RSA* r, const BIGNUM** dmp1, const BIGNUM** dmq1, const BIGNUM** iqmp) {
  if (dmp1 != NULL)
    *dmp1 = r->dmp1;
  if (dmq1 != NULL)
    *dmq1 = r->dmq1;
  if (iqmp != NULL)
    *iqmp = r->iqmp;
}

void DSA_get0_pqg(const DSA* d, const BIGNUM** p, const BIGNUM** q, const BIGNUM** g) {
  if (p != NULL)
    *p = d->p;
  if (q != NULL)
    *q = d->q;
  if (g != NULL)
    *g = d->g;
}

int DSA_set0_pqg(DSA* d, BIGNUM* p, BIGNUM* q, BIGNUM* g) {
  /* If the fields p, q and g in d are NULL, the corresponding input
   * parameters MUST be non-NULL.
   */
  if ((d->p == NULL && p == NULL) || (d->q == NULL && q == NULL) || (d->g == NULL && g == NULL))
    return 0;

  if (p != NULL) {
    BN_free(d->p);
    d->p = p;
  }
  if (q != NULL) {
    BN_free(d->q);
    d->q = q;
  }
  if (g != NULL) {
    BN_free(d->g);
    d->g = g;
  }

  return 1;
}

void DSA_get0_key(const DSA* d, const BIGNUM** pub_key, const BIGNUM** priv_key) {
  if (pub_key != NULL)
    *pub_key = d->pub_key;
  if (priv_key != NULL)
    *priv_key = d->priv_key;
}

int DSA_set0_key(DSA* d, BIGNUM* pub_key, BIGNUM* priv_key) {
  /* If the field pub_key in d is NULL, the corresponding input
   * parameters MUST be non-NULL.  The priv_key field may
   * be left NULL.
   */
  if (d->pub_key == NULL && pub_key == NULL)
    return 0;

  if (pub_key != NULL) {
    BN_free(d->pub_key);
    d->pub_key = pub_key;
  }
  if (priv_key != NULL) {
    BN_free(d->priv_key);
    d->priv_key = priv_key;
  }

  return 1;
}

void DSA_SIG_get0(const DSA_SIG* sig, const BIGNUM** pr, const BIGNUM** ps) {
  if (pr != NULL)
    *pr = sig->r;
  if (ps != NULL)
    *ps = sig->s;
}

int DSA_SIG_set0(DSA_SIG* sig, BIGNUM* r, BIGNUM* s) {
  if (r == NULL || s == NULL)
    return 0;
  BN_clear_free(sig->r);
  BN_clear_free(sig->s);
  sig->r = r;
  sig->s = s;
  return 1;
}

void ECDSA_SIG_get0(const ECDSA_SIG* sig, const BIGNUM** pr, const BIGNUM** ps) {
  if (pr != NULL)
    *pr = sig->r;
  if (ps != NULL)
    *ps = sig->s;
}

int ECDSA_SIG_set0(ECDSA_SIG* sig, BIGNUM* r, BIGNUM* s) {
  if (r == NULL || s == NULL)
    return 0;
  BN_clear_free(sig->r);
  BN_clear_free(sig->s);
  sig->r = r;
  sig->s = s;
  return 1;
}

void DH_get0_pqg(const DH* dh, const BIGNUM** p, const BIGNUM** q, const BIGNUM** g) {
  if (p != NULL)
    *p = dh->p;
  if (q != NULL)
    *q = dh->q;
  if (g != NULL)
    *g = dh->g;
}

int DH_set0_pqg(DH* dh, BIGNUM* p, BIGNUM* q, BIGNUM* g) {
  /* If the fields p and g in d are NULL, the corresponding input
   * parameters MUST be non-NULL.  q may remain NULL.
   */
  if ((dh->p == NULL && p == NULL) || (dh->g == NULL && g == NULL))
    return 0;

  if (p != NULL) {
    BN_free(dh->p);
    dh->p = p;
  }
  if (q != NULL) {
    BN_free(dh->q);
    dh->q = q;
  }
  if (g != NULL) {
    BN_free(dh->g);
    dh->g = g;
  }

  if (q != NULL) {
    dh->length = BN_num_bits(q);
  }

  return 1;
}

void DH_get0_key(const DH* dh, const BIGNUM** pub_key, const BIGNUM** priv_key) {
  if (pub_key != NULL)
    *pub_key = dh->pub_key;
  if (priv_key != NULL)
    *priv_key = dh->priv_key;
}

int DH_set0_key(DH* dh, BIGNUM* pub_key, BIGNUM* priv_key) {
  /* If the field pub_key in dh is NULL, the corresponding input
   * parameters MUST be non-NULL.  The priv_key field may
   * be left NULL.
   */
  if (dh->pub_key == NULL && pub_key == NULL)
    return 0;

  if (pub_key != NULL) {
    BN_free(dh->pub_key);
    dh->pub_key = pub_key;
  }
  if (priv_key != NULL) {
    BN_free(dh->priv_key);
    dh->priv_key = priv_key;
  }

  return 1;
}

int DH_set_length(DH* dh, long length) {
  dh->length = length;
  return 1;
}

const unsigned char* EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX* ctx) {
  return ctx->iv;
}

unsigned char* EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX* ctx) {
  return ctx->iv;
}

EVP_MD_CTX* EVP_MD_CTX_new(void) {
  return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
}

void EVP_MD_CTX_free(EVP_MD_CTX* ctx) {
  EVP_MD_CTX_cleanup(ctx);
  OPENSSL_free(ctx);
}

RSA_METHOD* RSA_meth_dup(const RSA_METHOD* meth) {
  RSA_METHOD* ret;

  ret = OPENSSL_malloc(sizeof(RSA_METHOD));

  if (ret != NULL) {
    memcpy(ret, meth, sizeof(*meth));
    ret->name = OPENSSL_strdup(meth->name);
    if (ret->name == NULL) {
      OPENSSL_free(ret);
      return NULL;
    }
  }

  return ret;
}

int RSA_meth_set1_name(RSA_METHOD* meth, const char* name) {
  char* tmpname;

  tmpname = OPENSSL_strdup(name);
  if (tmpname == NULL) {
    return 0;
  }

  OPENSSL_free((char*)meth->name);
  meth->name = tmpname;

  return 1;
}

int RSA_meth_set_priv_enc(RSA_METHOD* meth, int (*priv_enc)(int flen, const unsigned char* from, unsigned char* to,
                                                            RSA* rsa, int padding)) {
  meth->rsa_priv_enc = priv_enc;
  return 1;
}

int RSA_meth_set_priv_dec(RSA_METHOD* meth, int (*priv_dec)(int flen, const unsigned char* from, unsigned char* to,
                                                            RSA* rsa, int padding)) {
  meth->rsa_priv_dec = priv_dec;
  return 1;
}

int RSA_meth_set_finish(RSA_METHOD* meth, int (*finish)(RSA* rsa)) {
  meth->finish = finish;
  return 1;
}

void RSA_meth_free(RSA_METHOD* meth) {
  if (meth != NULL) {
    OPENSSL_free((char*)meth->name);
    OPENSSL_free(meth);
  }
}

int RSA_bits(const RSA* r) {
  return (BN_num_bits(r->n));
}

RSA* EVP_PKEY_get0_RSA(EVP_PKEY* pkey) {
  if (pkey->type != EVP_PKEY_RSA) {
    return NULL;
  }
  return pkey->pkey.rsa;
}

HMAC_CTX* HMAC_CTX_new(void) {
  HMAC_CTX* ctx = OPENSSL_malloc(sizeof(*ctx));
  if (ctx != NULL) {
    if (!HMAC_CTX_reset(ctx)) {
      HMAC_CTX_free(ctx);
      return NULL;
    }
  }
  return ctx;
}

void HMAC_CTX_free(HMAC_CTX* ctx) {
  if (ctx != NULL) {
    hmac_ctx_cleanup(ctx);
    EVP_MD_CTX_free(ctx->i_ctx);
    EVP_MD_CTX_free(ctx->o_ctx);
    EVP_MD_CTX_free(ctx->md_ctx);
    OPENSSL_free(ctx);
  }
}
#endif