/*
  This file is part of libmicrohttpd
  Copyright (C) 2013, 2016 Christian Grothoff
  Copyright (C) 2016-2022 Evgeny Grin (Karlson2k)

  libmicrohttpd is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published
  by the Free Software Foundation; either version 3, or (at your
  option) any later version.

  libmicrohttpd 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 libmicrohttpd; see the file COPYING.  If not, write to the
  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  Boston, MA 02110-1301, USA.
*/

/**
 * @file test_https_sni.c
 * @brief  Testcase for libmicrohttpd HTTPS with SNI operations
 * @author Christian Grothoff
 * @author Karlson2k (Evgeny Grin)
 */
#include "platform.h"
#include "microhttpd.h"
#include <limits.h>
#include <sys/stat.h>
#include <curl/curl.h>
#ifdef MHD_HTTPS_REQUIRE_GCRYPT
#include <gcrypt.h>
#endif /* MHD_HTTPS_REQUIRE_GCRYPT */
#include "tls_test_common.h"
#include <gnutls/gnutls.h>

/* This test only works with GnuTLS >= 3.0 */
#if GNUTLS_VERSION_MAJOR >= 3

#include <gnutls/abstract.h>

/**
 * A hostname, server key and certificate.
 */
struct Hosts
{
  struct Hosts *next;
  const char *hostname;
  gnutls_pcert_st pcrt;
  gnutls_privkey_t key;
};


/**
 * Linked list of supported TLDs and respective certificates.
 */
static struct Hosts *hosts;

/* Load the certificate and the private key.
 * (This code is largely taken from GnuTLS).
 */
static void
load_keys (const char *hostname,
           const char *CERT_FILE,
           const char *KEY_FILE)
{
  int ret;
  gnutls_datum_t data;
  struct Hosts *host;

  host = malloc (sizeof (struct Hosts));
  if (NULL == host)
    abort ();
  host->hostname = hostname;
  host->next = hosts;
  hosts = host;

  ret = gnutls_load_file (CERT_FILE, &data);
  if (ret < 0)
  {
    fprintf (stderr,
             "*** Error loading certificate file %s.\n",
             CERT_FILE);
    exit (1);
  }
  ret =
    gnutls_pcert_import_x509_raw (&host->pcrt, &data, GNUTLS_X509_FMT_PEM,
                                  0);
  if (ret < 0)
  {
    fprintf (stderr,
             "*** Error loading certificate file: %s\n",
             gnutls_strerror (ret));
    exit (1);
  }
  gnutls_free (data.data);

  ret = gnutls_load_file (KEY_FILE, &data);
  if (ret < 0)
  {
    fprintf (stderr,
             "*** Error loading key file %s.\n",
             KEY_FILE);
    exit (1);
  }

  gnutls_privkey_init (&host->key);
  ret =
    gnutls_privkey_import_x509_raw (host->key,
                                    &data, GNUTLS_X509_FMT_PEM,
                                    NULL, 0);
  if (ret < 0)
  {
    fprintf (stderr,
             "*** Error loading key file: %s\n",
             gnutls_strerror (ret));
    exit (1);
  }
  gnutls_free (data.data);
}


/**
 * @param session the session we are giving a cert for
 * @param req_ca_dn NULL on server side
 * @param nreqs length of req_ca_dn, and thus 0 on server side
 * @param pk_algos NULL on server side
 * @param pk_algos_length 0 on server side
 * @param pcert list of certificates (to be set)
 * @param pcert_length length of pcert (to be set)
 * @param pkey the private key (to be set)
 */
static int
sni_callback (gnutls_session_t session,
              const gnutls_datum_t *req_ca_dn,
              int nreqs,
              const gnutls_pk_algorithm_t *pk_algos,
              int pk_algos_length,
              gnutls_pcert_st **pcert,
              unsigned int *pcert_length,
              gnutls_privkey_t *pkey)
{
  char name[256];
  size_t name_len;
  struct Hosts *host;
  unsigned int type;
  (void) req_ca_dn; (void) nreqs; (void) pk_algos; (void) pk_algos_length;   /* Unused. Silent compiler warning. */

  name_len = sizeof (name);
  if (GNUTLS_E_SUCCESS !=
      gnutls_server_name_get (session,
                              name,
                              &name_len,
                              &type,
                              0 /* index */))
    return -1;
  for (host = hosts; NULL != host; host = host->next)
    if (0 == strncmp (name, host->hostname, name_len))
      break;
  if (NULL == host)
  {
    fprintf (stderr,
             "Need certificate for %.*s\n",
             (int) name_len,
             name);
    return -1;
  }
#if 0
  fprintf (stderr,
           "Returning certificate for %.*s\n",
           (int) name_len,
           name);
#endif
  *pkey = host->key;
  *pcert_length = 1;
  *pcert = &host->pcrt;
  return 0;
}


/* perform a HTTP GET request via SSL/TLS */
static int
do_get (const char *url, uint16_t port)
{
  CURL *c;
  struct CBC cbc;
  CURLcode errornum;
  size_t len;
  struct curl_slist *dns_info;
  char buf[256];

  len = strlen (test_data);
  if (NULL == (cbc.buf = malloc (sizeof (char) * len)))
  {
    fprintf (stderr, MHD_E_MEM);
    return -1;
  }
  cbc.size = len;
  cbc.pos = 0;

  c = curl_easy_init ();
#ifdef _DEBUG
  curl_easy_setopt (c, CURLOPT_VERBOSE, 1L);
#endif
  curl_easy_setopt (c, CURLOPT_URL, url);
  curl_easy_setopt (c, CURLOPT_PORT, (long) port);
  curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
  curl_easy_setopt (c, CURLOPT_TIMEOUT, 10L);
  curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 10L);
  curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, &copyBuffer);
  curl_easy_setopt (c, CURLOPT_WRITEDATA, &cbc);
  curl_easy_setopt (c, CURLOPT_CAINFO, SRCDIR "/test-ca.crt");

  /* perform peer authentication */
  /* TODO merge into send_curl_req */
  curl_easy_setopt (c, CURLOPT_SSL_VERIFYPEER, 0L);
  curl_easy_setopt (c, CURLOPT_SSL_VERIFYHOST, 2L);
  sprintf (buf, "mhdhost1:%u:127.0.0.1", (unsigned int) port);
  dns_info = curl_slist_append (NULL, buf);
  sprintf (buf, "mhdhost2:%u:127.0.0.1", (unsigned int) port);
  dns_info = curl_slist_append (dns_info, buf);
  curl_easy_setopt (c, CURLOPT_RESOLVE, dns_info);
  curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);

  /* NOTE: use of CONNECTTIMEOUT without also
     setting NOSIGNAL results in really weird
     crashes on my system! */
  curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
  if (CURLE_OK != (errornum = curl_easy_perform (c)))
  {
    fprintf (stderr, "curl_easy_perform failed: `%s'\n",
             curl_easy_strerror (errornum));
    curl_easy_cleanup (c);
    free (cbc.buf);
    curl_slist_free_all (dns_info);
    return errornum;
  }

  curl_easy_cleanup (c);
  curl_slist_free_all (dns_info);
  if (memcmp (cbc.buf, test_data, len) != 0)
  {
    fprintf (stderr, "Error: local file & received file differ.\n");
    free (cbc.buf);
    return -1;
  }

  free (cbc.buf);
  return 0;
}


int
main (int argc, char *const *argv)
{
  unsigned int error_count = 0;
  struct MHD_Daemon *d;
  uint16_t port;
  const char *tls_backend;
  (void) argc;   /* Unused. Silent compiler warning. */

  if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
    port = 0;
  else
    port = 3065;

#ifdef MHD_HTTPS_REQUIRE_GCRYPT
  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
#ifdef GCRYCTL_INITIALIZATION_FINISHED
  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
#endif
#endif /* MHD_HTTPS_REQUIRE_GCRYPT */
  if (! testsuite_curl_global_init ())
    return 99;
  tls_backend = curl_version_info (CURLVERSION_NOW)->ssl_version;
  if (NULL == tls_backend)
  {
    fprintf (stderr, "Curl does not support SSL.  Cannot run the test.\n");
    curl_global_cleanup ();
    return 77;
  }
  if (! curl_tls_is_gnutls () && ! curl_tls_is_openssl ())
  {
    fprintf (stderr, "This test is reliable only with libcurl with GnuTLS or "
             "OpenSSL backends.\nSkipping the test as libcurl has '%s' "
             "backend.\n", tls_backend);
    curl_global_cleanup ();
    return 77;
  }

  load_keys ("mhdhost1", SRCDIR "/mhdhost1.crt",
             SRCDIR "/mhdhost1.key");
  load_keys ("mhdhost2", SRCDIR "/mhdhost2.crt",
             SRCDIR "/mhdhost2.key");
  d = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION
                        | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_TLS
                        | MHD_USE_ERROR_LOG,
                        port,
                        NULL, NULL,
                        &http_ahc, NULL,
                        MHD_OPTION_HTTPS_CERT_CALLBACK, &sni_callback,
                        MHD_OPTION_END);
  if (d == NULL)
  {
    fprintf (stderr, MHD_E_SERVER_INIT);
    return -1;
  }
  if (0 == port)
  {
    const union MHD_DaemonInfo *dinfo;
    dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
    if ((NULL == dinfo) || (0 == dinfo->port) )
    {
      MHD_stop_daemon (d); return -1;
    }
    port = dinfo->port;
  }
  if (0 != do_get ("https://mhdhost1/", port))
    error_count++;
  if (0 != do_get ("https://mhdhost2/", port))
    error_count++;

  MHD_stop_daemon (d);
  curl_global_cleanup ();
  if (error_count != 0)
    fprintf (stderr, "Failed test: %s, error: %u.\n", argv[0], error_count);
  return (0 != error_count) ? 1 : 0;
}


#else

int
main (void)
{
  fprintf (stderr,
           "SNI not supported by GnuTLS < 3.0\n");
  return 77;
}


#endif
