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

 **********************************************************************
 * Copyright (C) Miroslav Lichvar  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.
 * 
 **********************************************************************

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

  Server NTS-NTP authentication
  */

#include "config.h"

#include "sysincl.h"

#include "nts_ntp_server.h"

#include "conf.h"
#include "logging.h"
#include "memory.h"
#include "ntp.h"
#include "ntp_ext.h"
#include "nts_ke_server.h"
#include "nts_ntp.h"
#include "nts_ntp_auth.h"
#include "siv.h"
#include "util.h"

#define SERVER_SIV AEAD_AES_SIV_CMAC_256

struct NtsServer {
  SIV_Instance siv;
  unsigned char nonce[NTS_MIN_UNPADDED_NONCE_LENGTH];
  NKE_Cookie cookies[NTS_MAX_COOKIES];
  int num_cookies;
  NTP_int64 req_tx;
};

/* The server instance handling all requests */
struct NtsServer *server;

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

void
NNS_Initialise(void)
{
  const char **certs, **keys;

  /* Create an NTS-NTP server instance only if NTS-KE server is enabled */
  if (CNF_GetNtsServerCertAndKeyFiles(&certs, &keys) <= 0) {
    server = NULL;
    return;
  }

  server = Malloc(sizeof (struct NtsServer));
  server->siv = SIV_CreateInstance(SERVER_SIV);
  if (!server->siv)
    LOG_FATAL("Could not initialise SIV cipher");
}

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

void
NNS_Finalise(void)
{
  if (!server)
    return;

  SIV_DestroyInstance(server->siv);
  Free(server);
  server = NULL;
}

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

int
NNS_CheckRequestAuth(NTP_Packet *packet, NTP_PacketInfo *info, uint32_t *kod)
{
  int ef_type, ef_body_length, ef_length, has_uniq_id = 0, has_auth = 0, has_cookie = 0;
  int i, plaintext_length, parsed, requested_cookies, cookie_length = -1, auth_start = 0;
  unsigned char plaintext[NTP_MAX_EXTENSIONS_LENGTH];
  NKE_Context context;
  NKE_Cookie cookie;
  void *ef_body;

  *kod = 0;

  if (!server)
    return 0;

  server->num_cookies = 0;
  server->req_tx = packet->transmit_ts;

  if (info->ext_fields == 0 || info->mode != MODE_CLIENT)
    return 0;

  requested_cookies = 0;

  for (parsed = NTP_HEADER_LENGTH; parsed < info->length; parsed += ef_length) {
    if (!NEF_ParseField(packet, info->length, parsed,
                        &ef_length, &ef_type, &ef_body, &ef_body_length))
      /* This is not expected as the packet already passed NAU_ParsePacket() */
      return 0;

    switch (ef_type) {
      case NTP_EF_NTS_UNIQUE_IDENTIFIER:
        has_uniq_id = 1;
        break;
      case NTP_EF_NTS_COOKIE:
        if (has_cookie || ef_body_length > sizeof (cookie.cookie)) {
          DEBUG_LOG("Unexpected cookie/length");
          return 0;
        }
        cookie.length = ef_body_length;
        memcpy(cookie.cookie, ef_body, ef_body_length);
        has_cookie = 1;
        /* Fall through */
      case NTP_EF_NTS_COOKIE_PLACEHOLDER:
        requested_cookies++;

        if (cookie_length >= 0 && cookie_length != ef_body_length) {
          DEBUG_LOG("Invalid cookie/placeholder length");
          return 0;
        }
        cookie_length = ef_body_length;
        break;
      case NTP_EF_NTS_AUTH_AND_EEF:
        if (parsed + ef_length != info->length) {
          DEBUG_LOG("Auth not last EF");
          return 0;
        }

        auth_start = parsed;
        has_auth = 1;
        break;
      default:
        break;
    }
  }

  if (!has_uniq_id || !has_cookie || !has_auth) {
    DEBUG_LOG("Missing an NTS EF");
    return 0;
  }

  if (!NKS_DecodeCookie(&cookie, &context)) {
    *kod = NTP_KOD_NTS_NAK;
    return 0;
  }

  if (context.algorithm != SERVER_SIV) {
    DEBUG_LOG("Unexpected SIV");
    return 0;
  }

  if (!SIV_SetKey(server->siv, context.c2s.key, context.c2s.length)) {
    DEBUG_LOG("Could not set C2S key");
    return 0;
  }

  if (!NNA_DecryptAuthEF(packet, info, server->siv, auth_start,
                         plaintext, sizeof (plaintext), &plaintext_length)) {
    *kod = NTP_KOD_NTS_NAK;
    return 0;
  }

  for (parsed = 0; parsed < plaintext_length; parsed += ef_length) {
    if (!NEF_ParseSingleField(plaintext, plaintext_length, parsed,
                              &ef_length, &ef_type, &ef_body, &ef_body_length)) {
      DEBUG_LOG("Could not parse encrypted EF");
      return 0;
    }

    switch (ef_type) {
      case NTP_EF_NTS_COOKIE_PLACEHOLDER:
        if (cookie_length != ef_body_length) {
          DEBUG_LOG("Invalid cookie/placeholder length");
          return 0;
        }
        requested_cookies++;
        break;
      default:
        break;
    }
  }

  if (!SIV_SetKey(server->siv, context.s2c.key, context.s2c.length)) {
    DEBUG_LOG("Could not set S2C key");
    return 0;
  }

  /* Prepare data for NNS_GenerateResponseAuth() to minimise the time spent
     there (when the TX timestamp is already set) */

  UTI_GetRandomBytes(server->nonce, sizeof (server->nonce));

  assert(sizeof (server->cookies) / sizeof (server->cookies[0]) == NTS_MAX_COOKIES);
  for (i = 0; i < NTS_MAX_COOKIES && i < requested_cookies; i++)
    if (!NKS_GenerateCookie(&context, &server->cookies[i]))
      return 0;

  server->num_cookies = i;

  return 1;
}

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

int
NNS_GenerateResponseAuth(NTP_Packet *request, NTP_PacketInfo *req_info,
                         NTP_Packet *response, NTP_PacketInfo *res_info,
                         uint32_t kod)
{
  int i, ef_type, ef_body_length, ef_length, parsed;
  void *ef_body;
  unsigned char plaintext[NTP_MAX_EXTENSIONS_LENGTH];
  int plaintext_length;

  if (!server || req_info->mode != MODE_CLIENT || res_info->mode != MODE_SERVER)
    return 0;

  /* Make sure this is a response to the request from the last call
     of NNS_CheckRequestAuth() */
  if (UTI_CompareNtp64(&server->req_tx, &request->transmit_ts) != 0)
    assert(0);

  for (parsed = NTP_HEADER_LENGTH; parsed < req_info->length; parsed += ef_length) {
    if (!NEF_ParseField(request, req_info->length, parsed,
                        &ef_length, &ef_type, &ef_body, &ef_body_length))
      /* This is not expected as the packet already passed parsing */
      return 0;

    switch (ef_type) {
      case NTP_EF_NTS_UNIQUE_IDENTIFIER:
        /* Copy the ID from the request */
        if (!NEF_AddField(response, res_info, ef_type, ef_body, ef_body_length))
          return 0;
      default:
        break;
    }
  }

  /* NTS NAK response does not have any other fields */
  if (kod)
    return 1;

  for (i = 0, plaintext_length = 0; i < server->num_cookies; i++) {
    if (!NEF_SetField(plaintext, sizeof (plaintext), plaintext_length,
                      NTP_EF_NTS_COOKIE, server->cookies[i].cookie,
                      server->cookies[i].length, &ef_length))
      return 0;

    plaintext_length += ef_length;
    assert(plaintext_length <= sizeof (plaintext));
  }

  server->num_cookies = 0;

  /* Generate an authenticator field which will make the length
     of the response equal to the length of the request */
  if (!NNA_GenerateAuthEF(response, res_info, server->siv,
                          server->nonce, sizeof (server->nonce),
                          plaintext, plaintext_length,
                          req_info->length - res_info->length))
    return 0;

  return 1;
}
