#include <string.h>
#include "dnsmasq.h"
#include "dnssec-crypto.h"
#include <openssl/evp.h>

typedef struct VACTX_rsasha1
{
  VerifyAlgCtx base;
  unsigned char *sig;
  unsigned siglen;
  union
    {
      EVP_MD_CTX hash;
      unsigned char digest[20];
    };
} VACTX_rsasha1;

typedef struct VACTX_rsasha256
{
  VerifyAlgCtx base;
  unsigned char *sig;
  unsigned siglen;
  union
    {
      EVP_MD_CTX hash;
      unsigned char digest[32];
    };
} VACTX_rsasha256;

#define POOL_SIZE 1
static union _Pool
{
  VACTX_rsasha1 rsasha1;
  VACTX_rsasha256 rsasha256;
} Pool[POOL_SIZE];
static char pool_used = 0;

static int rsasha1_set_signature(VerifyAlgCtx *ctx_, unsigned char *data, unsigned len)
{
  VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
  ctx->sig = data;
  ctx->siglen = len;
  return 1;
}

static int rsasha256_set_signature(VerifyAlgCtx *ctx_, unsigned char *data, unsigned len)
{
  VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
  ctx->sig = data;
  ctx->siglen = len;
  return 1;
}

static void rsasha1_begin_data(VerifyAlgCtx *ctx_)
{
  VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
  EVP_MD_CTX_init(&ctx->hash);
  EVP_DigestInit_ex(&ctx->hash, EVP_sha1(), NULL);
}
static void rsasha256_begin_data(VerifyAlgCtx *ctx_)
{
  VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
  EVP_MD_CTX_init(&ctx->hash);
  EVP_DigestInit_ex(&ctx->hash, EVP_sha256(), NULL);
}

static void rsasha1_add_data(VerifyAlgCtx *ctx_, void *data, unsigned len)
{
  VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
  EVP_DigestUpdate(&ctx->hash, data, len);
}
static void rsasha256_add_data(VerifyAlgCtx *ctx_, void *data, unsigned len)
{
  VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
  EVP_DigestUpdate(&ctx->hash, data, len);
}

static void rsasha1_end_data(VerifyAlgCtx *ctx_)
{
  VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
  unsigned char digest[20];
  EVP_DigestFinal(&ctx->hash, digest, NULL);
  memcpy(ctx->digest, digest, 20);
}
static void rsasha256_end_data(VerifyAlgCtx *ctx_)
{
  VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
  unsigned char digest[32];
  EVP_DigestFinal(&ctx->hash, digest, NULL);
  memcpy(ctx->digest, digest, 32);
}

static int rsasha1_verify(VerifyAlgCtx *ctx_, unsigned char *key, unsigned key_len)
{
  VACTX_rsasha1 *ctx = (VACTX_rsasha1 *)ctx_;
  return 0;
}

static int rsasha256_verify(VerifyAlgCtx *ctx_, unsigned char *key, unsigned key_len)
{
  VACTX_rsasha256 *ctx = (VACTX_rsasha256 *)ctx_;
  return 0;
}

#define DEFINE_VALG(alg) \
  int alg ## _set_signature(VerifyAlgCtx *ctx, unsigned char *data, unsigned len); \
  void alg ## _begin_data(VerifyAlgCtx *ctx); \
  void alg ## _add_data(VerifyAlgCtx *ctx, void *data, unsigned len); \
  void alg ## _end_data(VerifyAlgCtx *ctx); \
  int alg ## _verify(VerifyAlgCtx *ctx, unsigned char *key, unsigned key_len) \
  /**/

#define VALG_VTABLE(alg) { \
  alg ## _set_signature, \
  alg ## _begin_data, \
  alg ## _add_data, \
  alg ## _end_data, \
  alg ## _verify \
  } /**/

DEFINE_VALG(rsasha1);
DEFINE_VALG(rsasha256);

/* Updated registry that merges various RFCs:
   https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xml */
static const VerifyAlg valgs[] =
{
  {0,0,0,0,0},            /*  0: reserved */
  {0,0,0,0,0},            /*  1: RSAMD5 */
  {0,0,0,0,0},            /*  2: DH */
  {0,0,0,0,0},            /*  3: DSA */
  {0,0,0,0,0},            /*  4: ECC */
  VALG_VTABLE(rsasha1),   /*  5: RSASHA1 */
  {0,0,0,0,0},            /*  6: DSA-NSEC3-SHA1 */
  {0,0,0,0,0},            /*  7: RSASHA1-NSEC3-SHA1 */
  VALG_VTABLE(rsasha256), /*  8: RSASHA256 */
  {0,0,0,0,0},            /*  9: unassigned */
  {0,0,0,0,0},            /* 10: RSASHA512 */
  {0,0,0,0,0},            /* 11: unassigned */
  {0,0,0,0,0},            /* 12: ECC-GOST */
  {0,0,0,0,0},            /* 13: ECDSAP256SHA256 */
  {0,0,0,0,0},            /* 14: ECDSAP384SHA384 */
};

static const int valgctx_size[] =
{
  0,                        /*  0: reserved */
  0,                        /*  1: RSAMD5 */
  0,                        /*  2: DH */
  0,                        /*  3: DSA */
  0,                        /*  4: ECC */
  sizeof(VACTX_rsasha1),    /*  5: RSASHA1 */
  0,                        /*  6: DSA-NSEC3-SHA1 */
  0,                        /*  7: RSASHA1-NSEC3-SHA1 */
  sizeof(VACTX_rsasha256),  /*  8: RSASHA256 */
  0,                        /*  9: unassigned */
  0,                        /* 10: RSASHA512 */
  0,                        /* 11: unassigned */
  0,                        /* 12: ECC-GOST */
  0,                        /* 13: ECDSAP256SHA256 */
  0,                        /* 14: ECDSAP384SHA384 */
};

int verifyalg_supported(int algo)
{
  return (algo < countof(valgctx_size) && valgctx_size[algo] != 0);
}

VerifyAlgCtx* verifyalg_alloc(int algo)
{
  int i;
  VerifyAlgCtx *ret = 0;

  if (!verifyalg_supported(algo))
    return 0;

  if (pool_used == (1<<POOL_SIZE)-1)
      ret = whine_malloc(valgctx_size[algo]);
  else
    for (i = 0; i < POOL_SIZE; ++i)
      if (!(pool_used & (1 << i)))
        {
          ret = &Pool[i];
          pool_used |= 1 << i;
          break;
        }

  if (ret)
    ret->vtbl = &valgs[algo];
  return ret;
}

void verifyalg_free(VerifyAlgCtx *a)
{
  int pool_idx = ((char*)a - (char*)&Pool[0]) / sizeof(Pool[0]);
  if (pool_idx < 0 || pool_idx >= POOL_SIZE)
    {
      free(a);
      return;
    }

  pool_used &= ~(1 << pool_idx);
}

int verifyalg_algonum(VerifyAlgCtx *a)
{
  int num = a->vtbl - valgs;
  if (num < 0 || num >= countof(valgs))
    return -1;
  return num;
}
