/*
  chronyd/chronyc - Programs for keeping computer clocks accurate.

 **********************************************************************
 * Copyright (C) Richard P. Curnow  1997-2003
 * Copyright (C) Miroslav Lichvar  2012-2016, 2019-2020
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 **********************************************************************

  =======================================================================

  Module for managing keys used for authenticating NTP packets and commands

  */

#include "config.h"

#include "sysincl.h"

#include "array.h"
#include "keys.h"
#include "cmac.h"
#include "cmdparse.h"
#include "conf.h"
#include "memory.h"
#include "util.h"
#include "local.h"
#include "logging.h"

/* Consider 80 bits as the absolute minimum for a secure key */
#define MIN_SECURE_KEY_LENGTH 10

typedef enum {
  NTP_MAC,
  CMAC,
} KeyClass;

typedef struct {
  uint32_t id;
  int type;
  int length;
  KeyClass class;
  union {
    struct {
      unsigned char *value;
      int hash_id;
    } ntp_mac;
    CMC_Instance cmac;
  } data;
} Key;

static ARR_Instance keys;

static int cache_valid;
static uint32_t cache_key_id;
static int cache_key_pos;

/* ================================================== */

static void
free_keys(void)
{
  unsigned int i;
  Key *key;

  for (i = 0; i < ARR_GetSize(keys); i++) {
    key = ARR_GetElement(keys, i);
    switch (key->class) {
      case NTP_MAC:
        Free(key->data.ntp_mac.value);
        break;
      case CMAC:
        CMC_DestroyInstance(key->data.cmac);
        break;
      default:
        assert(0);
    }
  }

  ARR_SetSize(keys, 0);
  cache_valid = 0;
}

/* ================================================== */

void
KEY_Initialise(void)
{
  keys = ARR_CreateInstance(sizeof (Key));
  cache_valid = 0;
  KEY_Reload();
}

/* ================================================== */

void
KEY_Finalise(void)
{
  free_keys();
  ARR_DestroyInstance(keys);
}

/* ================================================== */

static Key *
get_key(unsigned int index)
{
  return ((Key *)ARR_GetElements(keys)) + index;
}

/* ================================================== */
/* Decode key encoded in ASCII or HEX */

static int
decode_key(char *key)
{
  int len = strlen(key);

  if (!strncmp(key, "ASCII:", 6)) {
    memmove(key, key + 6, len - 6);
    return len - 6;
  } else if (!strncmp(key, "HEX:", 4)) {
    return UTI_HexToBytes(key + 4, key, len);
  } else {
    /* assume ASCII */
    return len;
  }
}

/* ================================================== */

/* Compare two keys */

static int
compare_keys_by_id(const void *a, const void *b)
{
  const Key *c = (const Key *) a;
  const Key *d = (const Key *) b;

  if (c->id < d->id) {
    return -1;
  } else if (c->id > d->id) {
    return +1;
  } else {
    return 0;
  }

}

/* ================================================== */

void
KEY_Reload(void)
{
  unsigned int i, line_number, key_length, cmac_key_length;
  FILE *in;
  char line[2048], *key_file, *key_value;
  const char *key_type;
  HSH_Algorithm hash_algorithm;
  CMC_Algorithm cmac_algorithm;
  int hash_id;
  Key key;

  free_keys();

  key_file = CNF_GetKeysFile();
  line_number = 0;

  if (!key_file)
    return;

  in = UTI_OpenFile(NULL, key_file, NULL, 'r', 0);
  if (!in) {
    LOG(LOGS_WARN, "Could not open keyfile %s", key_file);
    return;
  }

  while (fgets(line, sizeof (line), in)) {
    line_number++;

    CPS_NormalizeLine(line);
    if (!*line)
      continue;

    memset(&key, 0, sizeof (key));

    if (!CPS_ParseKey(line, &key.id, &key_type, &key_value)) {
      LOG(LOGS_WARN, "Could not parse key at line %u in file %s", line_number, key_file);
      continue;
    }

    key_length = decode_key(key_value);
    if (key_length == 0) {
      LOG(LOGS_WARN, "Could not decode key %"PRIu32, key.id);
      continue;
    }

    hash_algorithm = UTI_HashNameToAlgorithm(key_type);
    cmac_algorithm = UTI_CmacNameToAlgorithm(key_type);

    if (hash_algorithm != 0) {
      hash_id = HSH_GetHashId(hash_algorithm);
      if (hash_id < 0) {
        LOG(LOGS_WARN, "Unsupported %s in key %"PRIu32, "hash function", key.id);
        continue;
      }
      key.class = NTP_MAC;
      key.type = hash_algorithm;
      key.length = key_length;
      key.data.ntp_mac.value = MallocArray(unsigned char, key_length);
      memcpy(key.data.ntp_mac.value, key_value, key_length);
      key.data.ntp_mac.hash_id = hash_id;
    } else if (cmac_algorithm != 0) {
      cmac_key_length = CMC_GetKeyLength(cmac_algorithm);
      if (cmac_key_length == 0) {
        LOG(LOGS_WARN, "Unsupported %s in key %"PRIu32, "cipher", key.id);
        continue;
      } else if (cmac_key_length != key_length) {
        LOG(LOGS_WARN, "Invalid length of %s key %"PRIu32" (expected %u bits)",
            key_type, key.id, 8 * cmac_key_length);
        continue;
      }

      key.class = CMAC;
      key.type = cmac_algorithm;
      key.length = key_length;
      key.data.cmac = CMC_CreateInstance(cmac_algorithm, (unsigned char *)key_value,
                                         key_length);
      assert(key.data.cmac);
    } else {
      LOG(LOGS_WARN, "Invalid type in key %"PRIu32, key.id);
      continue;
    }

    ARR_AppendElement(keys, &key);
  }

  fclose(in);

  /* Sort keys into order.  Note, if there's a duplicate, it is
     arbitrary which one we use later - the user should have been
     more careful! */
  qsort(ARR_GetElements(keys), ARR_GetSize(keys), sizeof (Key), compare_keys_by_id);

  /* Check for duplicates */
  for (i = 1; i < ARR_GetSize(keys); i++) {
    if (get_key(i - 1)->id == get_key(i)->id)
      LOG(LOGS_WARN, "Detected duplicate key %"PRIu32, get_key(i - 1)->id);
  }

  /* Erase any passwords from stack */
  memset(line, 0, sizeof (line));
}

/* ================================================== */

static int
lookup_key(uint32_t id)
{
  Key specimen, *where, *keys_ptr;
  int pos;

  keys_ptr = ARR_GetElements(keys);
  specimen.id = id;
  where = (Key *)bsearch((void *)&specimen, keys_ptr, ARR_GetSize(keys),
                         sizeof (Key), compare_keys_by_id);
  if (!where) {
    return -1;
  } else {
    pos = where - keys_ptr;
    return pos;
  }
}

/* ================================================== */

static Key *
get_key_by_id(uint32_t key_id)
{
  int position;

  if (cache_valid && key_id == cache_key_id)
    return get_key(cache_key_pos);

  position = lookup_key(key_id);

  if (position >= 0) {
    cache_valid = 1;
    cache_key_pos = position;
    cache_key_id = key_id;

    return get_key(position);
  }

  return NULL;
}

/* ================================================== */

int
KEY_KeyKnown(uint32_t key_id)
{
  return get_key_by_id(key_id) != NULL;
}

/* ================================================== */

int
KEY_GetAuthLength(uint32_t key_id)
{
  unsigned char buf[MAX_HASH_LENGTH];
  Key *key;

  key = get_key_by_id(key_id);

  if (!key)
    return 0;

  switch (key->class) {
    case NTP_MAC:
      return HSH_Hash(key->data.ntp_mac.hash_id, buf, 0, buf, 0, buf, sizeof (buf));
    case CMAC:
      return CMC_Hash(key->data.cmac, buf, 0, buf, sizeof (buf));
    default:
      assert(0);
      return 0;
  }
}

/* ================================================== */

int
KEY_CheckKeyLength(uint32_t key_id)
{
  Key *key;

  key = get_key_by_id(key_id);

  if (!key)
    return 0;

  return key->length >= MIN_SECURE_KEY_LENGTH;
}

/* ================================================== */

int
KEY_GetKeyInfo(uint32_t key_id, int *type, int *bits)
{
  Key *key;

  key = get_key_by_id(key_id);

  if (!key)
    return 0;

  *type = key->type;
  *bits = 8 * key->length;

  return 1;
}

/* ================================================== */

static int
generate_auth(Key *key, const void *data, int data_len, unsigned char *auth, int auth_len)
{
  switch (key->class) {
    case NTP_MAC:
      return HSH_Hash(key->data.ntp_mac.hash_id, key->data.ntp_mac.value,
                      key->length, data, data_len, auth, auth_len);
    case CMAC:
      return CMC_Hash(key->data.cmac, data, data_len, auth, auth_len);
    default:
      return 0;
  }
}

/* ================================================== */

static int
check_auth(Key *key, const void *data, int data_len,
           const unsigned char *auth, int auth_len, int trunc_len)
{
  unsigned char buf[MAX_HASH_LENGTH];
  int hash_len;

  hash_len = generate_auth(key, data, data_len, buf, sizeof (buf));

  return MIN(hash_len, trunc_len) == auth_len && !memcmp(buf, auth, auth_len);
}

/* ================================================== */

int
KEY_GenerateAuth(uint32_t key_id, const void *data, int data_len,
                 unsigned char *auth, int auth_len)
{
  Key *key;

  key = get_key_by_id(key_id);

  if (!key)
    return 0;

  return generate_auth(key, data, data_len, auth, auth_len);
}

/* ================================================== */

int
KEY_CheckAuth(uint32_t key_id, const void *data, int data_len,
              const unsigned char *auth, int auth_len, int trunc_len)
{
  Key *key;

  key = get_key_by_id(key_id);

  if (!key)
    return 0;

  return check_auth(key, data, data_len, auth, auth_len, trunc_len);
}
