/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at https://curl.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * SPDX-License-Identifier: curl
 *
 ***************************************************************************/
#include "curl_setup.h"

#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_HTTPSIG)

#include "urldata.h"
#include "http_httpsig.h"
#include "curl_ed25519.h"
#include "curl_hmac.h"
#include "curl_sha256.h"
#include "http.h"
#include "transfer.h"
#include "curl_trc.h"
#include "slist.h"
#include "curlx/dynbuf.h"
#include "curlx/base64.h"
#include "curlx/strdup.h"
#include "curlx/strparse.h"
#include "strcase.h"

#include <time.h>

#define HTTPSIG_MAX_SIG_BASE   CURL_MAX_HTTP_HEADER
#define HTTPSIG_MAX_COMPONENTS 16
#define HTTPSIG_MAX_RAW_SIG    CURL_ED25519_SIGLEN
#define HTTPSIG_DEFAULT_LABEL  "sig1"

enum httpsig_alg {
  HTTPSIG_ALG_ED25519,
  HTTPSIG_ALG_HMAC_SHA256,
  HTTPSIG_ALG_UNKNOWN
};

static const char *alg_to_str(enum httpsig_alg alg)
{
  switch(alg) {
  case HTTPSIG_ALG_ED25519:
    return "ed25519";
  case HTTPSIG_ALG_HMAC_SHA256:
    return "hmac-sha256";
  default:
    break;
  }
  return NULL;
}

static enum httpsig_alg id_to_alg(uint8_t val)
{
  switch(val) {
  case CURLHTTPSIG_ED25519:
    return HTTPSIG_ALG_ED25519;
  case CURLHTTPSIG_HMAC_SHA256:
    return HTTPSIG_ALG_HMAC_SHA256;
  default:
    break;
  }
  return HTTPSIG_ALG_UNKNOWN;
}

static CURLcode decode_hex_key(struct Curl_easy *data,
                               const char *hexstr,
                               unsigned char **keyout,
                               size_t *keylen)
{
  size_t len, i;
  unsigned char *keybuf;

  *keyout = NULL;
  *keylen = 0;

  len = strlen(hexstr);
  while(len > 0 && ISNEWLINE(hexstr[len - 1]))
    len--;

  if(len == 0 || (len & 1) != 0) {
    failf(data, "httpsig: invalid hex key (length %zu)", len);
    return CURLE_BAD_FUNCTION_ARGUMENT;
  }

  if(len > CURL_MAX_INPUT_LENGTH) {
    failf(data, "httpsig: hex key too long");
    return CURLE_BAD_FUNCTION_ARGUMENT;
  }

  keybuf = curlx_malloc(len / 2);
  if(!keybuf)
    return CURLE_OUT_OF_MEMORY;

  for(i = 0; i < len; i += 2) {
    if(!ISXDIGIT(hexstr[i]) || !ISXDIGIT(hexstr[i + 1])) {
      failf(data, "httpsig: invalid hex at position %zu ('%c%c')",
            i, hexstr[i], hexstr[i + 1]);
      curlx_free(keybuf);
      return CURLE_BAD_FUNCTION_ARGUMENT;
    }
    keybuf[i / 2] = (unsigned char)((curlx_hexval(hexstr[i]) << 4) |
                                     curlx_hexval(hexstr[i + 1]));
  }

  *keyout = keybuf;
  *keylen = len / 2;
  return CURLE_OK;
}

/* @authority matches the Host header field-value when available (RFC 9421).
   data->state.http_host is produced by http_set_aptr_host() before auth. */
static CURLcode httpsig_authority(struct Curl_easy *data,
                                  struct connectdata *conn,
                                  struct dynbuf *authority_buf)
{
  const char *h = data->state.http_host;

  if(h && curl_strnequal(h, "host:", 5)) {
    const char *value = h + 5;
    const char *end;

    while(ISBLANK(*value))
      value++;
    if(*value) {
      CURLcode result;

      end = value;
      while(*end && !ISNEWLINE(*end))
        end++;
      while(end > value && ISBLANK(end[-1]))
        end--;
      result = curlx_dyn_addn(authority_buf, value, (size_t)(end - value));
      if(result)
        return result;
      return CURLE_OK;
    }
  }

  {
    const char *hostname = conn->origin->hostname;
    uint16_t port = conn->origin->port;

    if((conn->origin->scheme->defport != port) && port)
      return curlx_dyn_addf(authority_buf, "%s:%u", hostname, port);
    return curlx_dyn_add(authority_buf, hostname);
  }
}

static CURLcode sf_append_quoted(struct dynbuf *buf, const char *str)
{
  CURLcode result = curlx_dyn_addn(buf, "\"", 1);
  if(result)
    return result;
  while(*str) {
    if(ISCNTRL(*str))
      return CURLE_BAD_FUNCTION_ARGUMENT;
    if(*str == '\\' || *str == '"') {
      result = curlx_dyn_addn(buf, "\\", 1);
      if(result)
        return result;
    }
    result = curlx_dyn_addn(buf, str, 1);
    if(result)
      return result;
    str++;
  }
  return curlx_dyn_addn(buf, "\"", 1);
}

/* base64-encode raw bytes into an RFC 8941 byte sequence (:base64:) */
static CURLcode sf_encode_byte_seq(const unsigned char *raw, size_t rawlen,
                                   struct dynbuf *out)
{
  CURLcode result;
  size_t b64len;
  char *b64;

  result = curlx_base64_encode(raw, rawlen, &b64, &b64len);
  if(result)
    return result;

  result = curlx_dyn_addn(out, ":", 1);
  if(!result)
    result = curlx_dyn_addn(out, b64, b64len);
  if(!result)
    result = curlx_dyn_addn(out, ":", 1);

  curlx_free(b64);
  return result;
}

static CURLcode build_sig_params(struct dynbuf *params,
                                 const char **components, size_t count,
                                 time_t created, const char *keyid,
                                 enum httpsig_alg alg)
{
  CURLcode result;
  size_t i;

  result = curlx_dyn_addn(params, "(", 1);
  if(result)
    return result;

  for(i = 0; i < count; i++) {
    if(i > 0) {
      result = curlx_dyn_addn(params, " ", 1);
      if(result)
        return result;
    }
    result = sf_append_quoted(params, components[i]);
    if(result)
      return result;
  }

  result = curlx_dyn_addn(params, ")", 1);
  if(result)
    return result;

  result = curlx_dyn_addf(params, ";created=%lld", (long long)created);
  if(result)
    return result;

  if(keyid && *keyid) {
    result = curlx_dyn_add(params, ";keyid=");
    if(result)
      return result;
    result = sf_append_quoted(params, keyid);
    if(result)
      return result;
  }

  result = curlx_dyn_addf(params, ";alg=\"%s\"", alg_to_str(alg));
  return result;
}

/* strings defined by RFC 9421 */
#define SIG_METHOD    "@method"
#define SIG_AUTHORITY "@authority"
#define SIG_PATH      "@path"
#define SIG_QUERY     "@query"

/* Resolve a component identifier to its value.
 * For headers, we walk the full user-supplied header list to combine
 * duplicate field values with ", " per RFC 9421 Section 2.1. Each
 * individual value is trimmed of leading/trailing OWS and the trailing
 * \r\n. The combined result is written into the caller-provided buffer. */
static CURLcode resolve_component(const char *name,
                                  const char *method,
                                  const char *authority,
                                  const char *path,
                                  const char *query,
                                  struct Curl_easy *data,
                                  struct dynbuf *valbuf,
                                  const char **out)
{
  *out = NULL;

  if(name[0] == '@') {
    if(curl_strequal(name, SIG_METHOD))
      *out = method;
    else if(curl_strequal(name, SIG_AUTHORITY))
      *out = authority;
    else if(curl_strequal(name, SIG_PATH))
      *out = path;
    else if(curl_strequal(name, SIG_QUERY))
      *out = query;
    else {
      failf(data, "httpsig: unsupported derived component '%s'", name);
      return CURLE_BAD_FUNCTION_ARGUMENT;
    }
    if(!*out) {
      failf(data, "httpsig: derived component '%s' has no value", name);
      return CURLE_BAD_FUNCTION_ARGUMENT;
    }
    return CURLE_OK;
  }
  else {
    /* RFC 9421 Section 2.1: walk all user-supplied headers and combine
       duplicate field values with ", " per HTTP field combination rules. */
    struct curl_slist *head;
    size_t namelen = strlen(name);
    bool found = FALSE;

    curlx_dyn_reset(valbuf);

    for(head = data->set.headers; head; head = head->next) {
      if(curl_strnequal(head->data, name, namelen) &&
         Curl_headersep(head->data[namelen])) {
        const char *p = strchr(head->data, ':');
        if(p) {
          CURLcode result;
          struct Curl_str content;
          curlx_str_assign(&content, p + 1, strlen(p + 1));
          curlx_str_trimblanks(&content);
          if(found) {
            result = curlx_dyn_addn(valbuf, ", ", 2);
            if(result)
              return result;
          }
          result = curlx_dyn_addn(valbuf, curlx_str(&content),
                                  curlx_strlen(&content));
          if(result)
            return result;
          found = TRUE;
        }
      }
    }

    if(found) {
      *out = curlx_dyn_ptr(valbuf);
      return CURLE_OK;
    }
    failf(data, "httpsig: header '%s' not found in request", name);
    return CURLE_BAD_FUNCTION_ARGUMENT;
  }
}

static CURLcode build_sig_base(struct dynbuf *base,
                               const char **components, size_t count,
                               const char *method,
                               const char *authority,
                               const char *path,
                               const char *query,
                               struct Curl_easy *data,
                               const char *sig_params)
{
  CURLcode result;
  size_t i;
  struct dynbuf hdrvalbuf;

  curlx_dyn_init(&hdrvalbuf, CURL_MAX_HTTP_HEADER);

  for(i = 0; i < count; i++) {
    const char *val = NULL;
    result = resolve_component(components[i], method,
                               authority, path, query, data,
                               &hdrvalbuf, &val);
    if(result || !val) {
      failf(data, "httpsig: cannot resolve component '%s'", components[i]);
      curlx_dyn_free(&hdrvalbuf);
      return result ? result : CURLE_BAD_FUNCTION_ARGUMENT;
    }

    result = curlx_dyn_addf(base, "\"%s\": %s\n", components[i], val);
    if(result) {
      curlx_dyn_free(&hdrvalbuf);
      return result;
    }
  }

  curlx_dyn_free(&hdrvalbuf);
  result = curlx_dyn_addf(base, "\"@signature-params\": %s", sig_params);
  return result;
}

static CURLcode parse_components(struct Curl_easy *data,
                                 const char *query,
                                 const char **components,
                                 size_t *ncomp_out,
                                 char **hdrs_copy_out)
{
  const char *hdrs = CURL_EASY_STR(data, STRING_HTTPSIG_HEADERS);
  size_t ncomp = 0;

  *hdrs_copy_out = NULL;
  if(hdrs && *hdrs) {
    char *p;
    char *hdrs_copy = curlx_strdup(hdrs);
    if(!hdrs_copy)
      return CURLE_OUT_OF_MEMORY;
    *hdrs_copy_out = hdrs_copy;
    p = hdrs_copy;
    while(*p && ncomp < HTTPSIG_MAX_COMPONENTS) {
      char *start;
      size_t tlen = 0;
      const char *p2 = p;

      curlx_str_passblanks(&p2);
      if(!*p2)
        break;
      p = start = CURL_UNCONST(p2);
      while(*p && !ISBLANK(*p)) {
        if((*p == '\"') || (*p == '\\'))
          return CURLE_BAD_FUNCTION_ARGUMENT;
        p++;
        tlen++;
      }
      if(*p)
        *p++ = '\0';

      if(tlen && start[tlen - 1] == ':') {
        /* Header field: drop the trailing ':' marker. RFC 9421 field
           names are canonically lowercase (Section 2.1). */
        start[--tlen] = '\0';
        if(!tlen) {
          failf(data, "httpsig: empty header component name");
          return CURLE_BAD_FUNCTION_ARGUMENT;
        }
        Curl_strntolower(start, start, tlen);
        components[ncomp++] = start;
      }
      else {
        /* Derived component: map the bare name to its canonical RFC 9421
           '@'-prefixed identifier (Section 2.2). */
        Curl_strntolower(start, start, tlen);
        if(!strcmp(start, "method"))
          components[ncomp++] = SIG_METHOD;
        else if(!strcmp(start, "authority"))
          components[ncomp++] = SIG_AUTHORITY;
        else if(!strcmp(start, "path"))
          components[ncomp++] = SIG_PATH;
        else if(!strcmp(start, "query"))
          components[ncomp++] = SIG_QUERY;
        else {
          failf(data, "httpsig: unknown component '%s'", start);
          return CURLE_BAD_FUNCTION_ARGUMENT;
        }
      }
    }
    if(!ncomp) {
      failf(data, "httpsig: no signature components specified");
      return CURLE_BAD_FUNCTION_ARGUMENT;
    }
    if(*p) {
      failf(data, "httpsig: too many signature components (max %u)",
            (unsigned int)HTTPSIG_MAX_COMPONENTS);
      return CURLE_BAD_FUNCTION_ARGUMENT;
    }

    /* RFC 9421 Section 2: each covered component MUST occur only once */
    {
      size_t i, j;

      for(i = 0; i < ncomp; i++) {
        for(j = i + 1; j < ncomp; j++) {
          if(!strcmp(components[i], components[j])) {
            failf(data, "httpsig: duplicate signature component '%s'",
                  components[i]);
            return CURLE_BAD_FUNCTION_ARGUMENT;
          }
        }
      }
    }
  }
  else {
    components[ncomp++] = SIG_METHOD;
    components[ncomp++] = SIG_AUTHORITY;
    components[ncomp++] = SIG_PATH;
    if(query)
      components[ncomp++] = SIG_QUERY;
  }

  *ncomp_out = ncomp;
  return CURLE_OK;
}

static time_t httpsig_get_created(void)
{
#ifdef DEBUGBUILD
  char *force = getenv("CURL_FORCETIME");
  if(force && *force) {
    char *sigts = getenv("CURL_HTTPSIG_CREATED");
    if(sigts && *sigts) {
      const char *p = sigts;
      curl_off_t num;
      if(!curlx_str_number(&p, &num, CURL_OFF_T_MAX))
        return (time_t)num;
    }
    return 0;
  }
#endif
  return time(NULL);
}

static CURLcode httpsig_sign_base(struct Curl_easy *data,
                                  enum httpsig_alg alg,
                                  const unsigned char *keybuf,
                                  size_t keylen,
                                  const struct dynbuf *sig_base,
                                  unsigned char *raw_sig,
                                  size_t *raw_sig_len)
{
  CURLcode result;

  switch(alg) {
  case HTTPSIG_ALG_ED25519:
    result = Curl_ed25519_sign(
      keybuf, keylen,
      (const unsigned char *)curlx_dyn_ptr(sig_base),
      curlx_dyn_len(sig_base),
      raw_sig, raw_sig_len);
    break;
  case HTTPSIG_ALG_HMAC_SHA256:
    result = Curl_hmacit(&Curl_HMAC_SHA256, keybuf, keylen,
                         (const unsigned char *)curlx_dyn_ptr(sig_base),
                         curlx_dyn_len(sig_base), raw_sig);
    if(!result)
      *raw_sig_len = CURL_SHA256_DIGEST_LENGTH;
    break;
  default:
    result = CURLE_BAD_FUNCTION_ARGUMENT;
    break;
  }

  if(result && result == CURLE_NOT_BUILT_IN) {
    failf(data, "httpsig: algorithm '%s' not supported by TLS backend",
          alg_to_str(alg));
  }
  return result;
}

CURLcode Curl_output_httpsig(struct Curl_easy *data)
{
  CURLcode result = CURLE_OUT_OF_MEMORY;
  struct connectdata *conn = data->conn;
  const char *path;
  const char *query;
  Curl_HttpReq httpreq;
  const char *method = NULL;
  const char *hexkey = CURL_EASY_STR(data, STRING_HTTPSIG_KEY);
  const char *keyid = CURL_EASY_STR(data, STRING_HTTPSIG_KEYID);
  enum httpsig_alg alg;
  time_t created;
  struct dynbuf sig_params;
  struct dynbuf sig_base;
  struct dynbuf sig_hdr;
  struct dynbuf input_hdr;
  struct dynbuf authority_buf;
  const char *authority;
  const char *components[HTTPSIG_MAX_COMPONENTS];
  size_t ncomp = 0;
  unsigned char *keybuf = NULL;
  size_t keylen = 0;
  unsigned char raw_sig[HTTPSIG_MAX_RAW_SIG];
  size_t raw_sig_len = 0;
  char *auth_headers = NULL;
  char *hdrs_copy = NULL;
  struct dynbuf query_dyn;

  alg = id_to_alg(data->set.httpsig_algorithm);
  if(alg == HTTPSIG_ALG_UNKNOWN) {
    failf(data, "httpsig: CURLOPT_HTTPSIG_ALGORITHM is required");
    return CURLE_BAD_FUNCTION_ARGUMENT;
  }

  if(!hexkey || !*hexkey) {
    failf(data, "httpsig: CURLOPT_HTTPSIG_KEY is required");
    return CURLE_BAD_FUNCTION_ARGUMENT;
  }
  if(!keyid || !*keyid) {
    failf(data, "httpsig: CURLOPT_HTTPSIG_KEYID is required");
    return CURLE_BAD_FUNCTION_ARGUMENT;
  }

  curlx_dyn_init(&sig_params, CURL_MAX_HTTP_HEADER);
  curlx_dyn_init(&sig_base, HTTPSIG_MAX_SIG_BASE);
  curlx_dyn_init(&sig_hdr, CURL_MAX_HTTP_HEADER);
  curlx_dyn_init(&input_hdr, CURL_MAX_HTTP_HEADER);
  curlx_dyn_init(&authority_buf, CURL_MAX_HTTP_HEADER);
  curlx_dyn_init(&query_dyn, CURL_MAX_HTTP_HEADER);

  if(Curl_checkheaders(data, STRCONST("Signature")) ||
     Curl_checkheaders(data, STRCONST("Signature-Input"))) {
    /* user provides their own Signature / Signature-Input headers, consider
       this done */
    goto done;
  }

  result = decode_hex_key(data, hexkey, &keybuf, &keylen);
  if(result)
    goto fail;

  if(alg == HTTPSIG_ALG_ED25519 && keylen != 32) {
    failf(data, "httpsig: ed25519 requires a 32-byte key (got %zu)", keylen);
    result = CURLE_BAD_FUNCTION_ARGUMENT;
    goto fail;
  }

  Curl_http_method(data, &method, &httpreq);

  path = data->state.up.path;
  if(!path || !*path)
    path = "/";

  query = data->state.up.query;

  result = httpsig_authority(data, conn, &authority_buf);
  if(result)
    goto fail;
  authority = curlx_dyn_ptr(&authority_buf);

  /* Build @query value: RFC 9421 Section 2.2.7 - always starts with "?" */
  if(query && *query)
    result = curlx_dyn_addf(&query_dyn, "?%s", query);
  else
    result = curlx_dyn_add(&query_dyn, "?");
  if(result)
    goto fail;

  result = parse_components(data, query, components, &ncomp, &hdrs_copy);
  if(result)
    goto fail;

  created = httpsig_get_created();

  result = build_sig_params(&sig_params, components, ncomp,
                            created, keyid, alg);
  if(result)
    goto fail;

  infof(data, "httpsig: Signature-Input params: %s",
        curlx_dyn_ptr(&sig_params));

  result = build_sig_base(&sig_base, components, ncomp,
                          method, authority, path,
                          curlx_dyn_ptr(&query_dyn),
                          data, curlx_dyn_ptr(&sig_params));
  if(result)
    goto fail;

  infof(data, "httpsig: Signature base: [%s]",
        curlx_dyn_ptr(&sig_base));

  result = httpsig_sign_base(data, alg, keybuf, keylen, &sig_base,
                             raw_sig, &raw_sig_len);
  if(result)
    goto fail;

  result = curlx_dyn_add(&sig_hdr, HTTPSIG_DEFAULT_LABEL "=");
  if(result)
    goto fail;
  result = sf_encode_byte_seq(raw_sig, raw_sig_len, &sig_hdr);
  if(result)
    goto fail;

  result = curlx_dyn_addf(&input_hdr, "%s=%s", HTTPSIG_DEFAULT_LABEL,
                          curlx_dyn_ptr(&sig_params));
  if(result)
    goto fail;

  auth_headers = curl_maprintf("Signature-Input: %s\r\n"
                               "Signature: %s\r\n",
                               curlx_dyn_ptr(&input_hdr),
                               curlx_dyn_ptr(&sig_hdr));
  if(!auth_headers)
    goto fail;

  infof(data, "httpsig: Signature-Input: %s", curlx_dyn_ptr(&input_hdr));
  infof(data, "httpsig: Signature: %s", curlx_dyn_ptr(&sig_hdr));
done:
  curlx_free(data->req.hd_auth);
  data->req.hd_auth = auth_headers;
  data->state.authhost.done = TRUE;
  result = CURLE_OK;

fail:
  if(keybuf) {
    memset(keybuf, 0, keylen);
    curlx_free(keybuf);
  }
  memset(raw_sig, 0, sizeof(raw_sig));
  curlx_free(hdrs_copy);
  curlx_dyn_free(&sig_params);
  curlx_dyn_free(&sig_base);
  curlx_dyn_free(&sig_hdr);
  curlx_dyn_free(&input_hdr);
  curlx_dyn_free(&authority_buf);
  curlx_dyn_free(&query_dyn);
  return result;
}

#endif /* !CURL_DISABLE_HTTP && !CURL_DISABLE_HTTPSIG */
