// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <ctype.h>
#include <string.h>

#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/buf.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>
#include <openssl/stack.h>
#include <openssl/x509.h>
#include <cstdint>

#include "../asn1/internal.h"
#include "../internal.h"
#include "internal.h"


typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY)

// Maximum length of X509_NAME: much larger than anything we should
// ever see in practice.

#define X509_NAME_MAX (1024 * 1024)

static int x509_name_encode(X509_NAME *a);
static int x509_name_canon(X509_NAME *a);
static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
                          unsigned char **in);

ASN1_SEQUENCE(X509_NAME_ENTRY) = {
    ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
    ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_ANY_AS_STRING),
} ASN1_SEQUENCE_END(X509_NAME_ENTRY)

IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X509_NAME_ENTRY)
IMPLEMENT_ASN1_DUP_FUNCTION_const(X509_NAME_ENTRY)

// For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
// declare two template wrappers for this

ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF,
                                                              0, RDNS,
                                                              X509_NAME_ENTRY)
ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)

ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
    ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)

// Normally that's where it would end: we'd have two nested STACK structures
// representing the ASN1. Unfortunately X509_NAME uses a completely different
// form and caches encodings so we have to process the internal form and
// convert to the external form.
//
// TODO(crbug.com/42290417): Rewrite all this with |CBS| and |CBB|.

static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) {
  X509_NAME *ret = NULL;
  ret = reinterpret_cast<X509_NAME *>(OPENSSL_malloc(sizeof(X509_NAME)));
  if (!ret) {
    goto memerr;
  }
  if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) {
    goto memerr;
  }
  if ((ret->bytes = BUF_MEM_new()) == NULL) {
    goto memerr;
  }
  ret->canon_enc = NULL;
  ret->canon_enclen = 0;
  ret->modified = 1;
  *val = (ASN1_VALUE *)ret;
  return 1;

memerr:
  if (ret) {
    if (ret->entries) {
      sk_X509_NAME_ENTRY_free(ret->entries);
    }
    OPENSSL_free(ret);
  }
  return 0;
}

static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) {
  X509_NAME *a;
  if (!pval || !*pval) {
    return;
  }
  a = (X509_NAME *)*pval;

  BUF_MEM_free(a->bytes);
  sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
  if (a->canon_enc) {
    OPENSSL_free(a->canon_enc);
  }
  OPENSSL_free(a);
  *pval = NULL;
}

static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) {
  sk_X509_NAME_ENTRY_free(ne);
}

static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) {
  sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
}

static int x509_name_ex_parse(ASN1_VALUE **val, CBS *cbs, const ASN1_ITEM *it,
                              int opt) {
  if (opt && !CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) {
    return 1;
  }

  CBS elem;
  if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE) ||
      // Bound the size of an X509_NAME we are willing to parse.
      CBS_len(&elem) > X509_NAME_MAX) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
    return 0;
  }

  // TODO(crbug.com/42290417): Rewrite the parser and canonicalization code with
  // CBS and CBB. For now this calls into the original two-layer d2i code.
  long len = static_cast<long>(CBS_len(&elem));
  const unsigned char *p = CBS_data(&elem), *q;
  STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
  X509_NAME *nm = NULL;
  size_t i, j;
  STACK_OF(X509_NAME_ENTRY) *entries;
  X509_NAME_ENTRY *entry;
  q = p;

  // Get internal representation of Name
  ASN1_VALUE *intname_val = NULL;
  if (ASN1_item_ex_d2i(&intname_val, &p, len,
                       ASN1_ITEM_rptr(X509_NAME_INTERNAL), /*tag=*/-1,
                       /*aclass=*/0, /*opt=*/0) <= 0) {
    return 0;
  }
  intname = (STACK_OF(STACK_OF_X509_NAME_ENTRY) *)intname_val;

  if (*val) {
    x509_name_ex_free(val, NULL);
  }
  ASN1_VALUE *nm_val = NULL;
  if (!x509_name_ex_new(&nm_val, NULL)) {
    goto err;
  }
  nm = (X509_NAME *)nm_val;
  // We've decoded it: now cache encoding
  if (!BUF_MEM_grow(nm->bytes, p - q)) {
    goto err;
  }
  OPENSSL_memcpy(nm->bytes->data, q, p - q);

  // Convert internal representation to X509_NAME structure
  for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname); i++) {
    entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname, i);
    for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
      entry = sk_X509_NAME_ENTRY_value(entries, j);
      entry->set = (int)i;
      if (!sk_X509_NAME_ENTRY_push(nm->entries, entry)) {
        goto err;
      }
      (void)sk_X509_NAME_ENTRY_set(entries, j, NULL);
    }
  }
  if (!x509_name_canon(nm)) {
    goto err;
  }
  sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, local_sk_X509_NAME_ENTRY_free);
  nm->modified = 0;
  *val = (ASN1_VALUE *)nm;
  return 1;
err:
  X509_NAME_free(nm);
  sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
                                       local_sk_X509_NAME_ENTRY_pop_free);
  OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
  return 0;
}

static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
                            const ASN1_ITEM *it) {
  X509_NAME *a = (X509_NAME *)*val;
  if (a->modified && (!x509_name_encode(a) || !x509_name_canon(a))) {
    return -1;
  }
  int ret = a->bytes->length;
  if (out != NULL) {
    OPENSSL_memcpy(*out, a->bytes->data, ret);
    *out += ret;
  }
  return ret;
}

static const ASN1_EXTERN_FUNCS x509_name_ff = {
    x509_name_ex_new, x509_name_ex_free, x509_name_ex_parse, x509_name_ex_i2d};
IMPLEMENT_EXTERN_ASN1(X509_NAME, x509_name_ff)
IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)

static int x509_name_encode(X509_NAME *a) {
  int len;
  unsigned char *p;
  STACK_OF(X509_NAME_ENTRY) *entries = NULL;
  X509_NAME_ENTRY *entry;
  int set = -1;
  size_t i;
  STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname =
      sk_STACK_OF_X509_NAME_ENTRY_new_null();

  {
    if (!intname) {
      goto err;
    }
    for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
      entry = sk_X509_NAME_ENTRY_value(a->entries, i);
      if (entry->set != set) {
        entries = sk_X509_NAME_ENTRY_new_null();
        if (!entries) {
          goto err;
        }
        if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) {
          sk_X509_NAME_ENTRY_free(entries);
          goto err;
        }
        set = entry->set;
      }
      if (!sk_X509_NAME_ENTRY_push(entries, entry)) {
        goto err;
      }
    }
    ASN1_VALUE *intname_val = (ASN1_VALUE *)intname;
    len =
        ASN1_item_ex_i2d(&intname_val, NULL, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
                         /*tag=*/-1, /*aclass=*/0);
    if (len <= 0) {
      goto err;
    }
    if (!BUF_MEM_grow(a->bytes, len)) {
      goto err;
    }
    p = (unsigned char *)a->bytes->data;
    if (ASN1_item_ex_i2d(&intname_val, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
                         /*tag=*/-1, /*aclass=*/0) <= 0) {
      goto err;
    }
    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
                                         local_sk_X509_NAME_ENTRY_free);
    a->modified = 0;
    return 1;
  }

err:
  sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, local_sk_X509_NAME_ENTRY_free);
  return 0;
}

// This function generates the canonical encoding of the Name structure. In
// it all strings are converted to UTF8, leading, trailing and multiple
// spaces collapsed, converted to lower case and the leading SEQUENCE header
// removed. In future we could also normalize the UTF8 too. By doing this
// comparison of Name structures can be rapidly perfomed by just using
// OPENSSL_memcmp() of the canonical encoding. By omitting the leading SEQUENCE
// name constraints of type dirName can also be checked with a simple
// OPENSSL_memcmp().

static int x509_name_canon(X509_NAME *a) {
  unsigned char *p;
  STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
  STACK_OF(X509_NAME_ENTRY) *entries = NULL;
  X509_NAME_ENTRY *entry, *tmpentry = NULL;
  int set = -1, ret = 0, len;
  size_t i;

  if (a->canon_enc) {
    OPENSSL_free(a->canon_enc);
    a->canon_enc = NULL;
  }
  // Special case: empty X509_NAME => null encoding
  if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
    a->canon_enclen = 0;
    return 1;
  }
  intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
  if (!intname) {
    goto err;
  }
  for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
    entry = sk_X509_NAME_ENTRY_value(a->entries, i);
    if (entry->set != set) {
      entries = sk_X509_NAME_ENTRY_new_null();
      if (!entries) {
        goto err;
      }
      if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) {
        sk_X509_NAME_ENTRY_free(entries);
        goto err;
      }
      set = entry->set;
    }
    tmpentry = X509_NAME_ENTRY_new();
    if (tmpentry == NULL) {
      goto err;
    }
    tmpentry->object = OBJ_dup(entry->object);
    if (!asn1_string_canon(tmpentry->value, entry->value)) {
      goto err;
    }
    if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) {
      goto err;
    }
    tmpentry = NULL;
  }

  // Finally generate encoding

  len = i2d_name_canon(intname, NULL);
  if (len < 0) {
    goto err;
  }
  a->canon_enclen = len;

  p = reinterpret_cast<uint8_t *>(OPENSSL_malloc(a->canon_enclen));

  if (!p) {
    goto err;
  }

  a->canon_enc = p;

  i2d_name_canon(intname, &p);

  ret = 1;

err:

  if (tmpentry) {
    X509_NAME_ENTRY_free(tmpentry);
  }
  if (intname) {
    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
                                         local_sk_X509_NAME_ENTRY_pop_free);
  }
  return ret;
}

// Bitmap of all the types of string that will be canonicalized.

#define ASN1_MASK_CANON                                            \
  (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING | \
   B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING |  \
   B_ASN1_VISIBLESTRING)

static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) {
  unsigned char *to, *from;
  int len, i;

  // If type not in bitmask just copy string across
  if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
    if (!ASN1_STRING_copy(out, in)) {
      return 0;
    }
    return 1;
  }

  out->type = V_ASN1_UTF8STRING;
  out->length = ASN1_STRING_to_UTF8(&out->data, in);
  if (out->length == -1) {
    return 0;
  }

  to = out->data;
  from = to;

  len = out->length;

  // Convert string in place to canonical form.

  // Ignore leading spaces
  while ((len > 0) && OPENSSL_isspace(*from)) {
    from++;
    len--;
  }

  to = from + len;

  // Ignore trailing spaces
  while ((len > 0) && OPENSSL_isspace(to[-1])) {
    to--;
    len--;
  }

  to = out->data;

  i = 0;
  while (i < len) {
    // Collapse multiple spaces
    if (OPENSSL_isspace(*from)) {
      // Copy one space across
      *to++ = ' ';
      // Ignore subsequent spaces. Note: don't need to check len here
      // because we know the last character is a non-space so we can't
      // overflow.
      do {
        from++;
        i++;
      } while (OPENSSL_isspace(*from));
    } else {
      *to++ = OPENSSL_tolower(*from);
      from++;
      i++;
    }
  }

  out->length = to - out->data;

  return 1;
}

static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname,
                          unsigned char **in) {
  int len, ltmp;
  size_t i;
  ASN1_VALUE *v;
  STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;

  len = 0;
  for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
    v = sk_ASN1_VALUE_value(intname, i);
    ltmp = ASN1_item_ex_i2d(&v, in, ASN1_ITEM_rptr(X509_NAME_ENTRIES),
                            /*tag=*/-1, /*aclass=*/0);
    if (ltmp < 0) {
      return ltmp;
    }
    len += ltmp;
  }
  return len;
}

int X509_NAME_set(X509_NAME **xn, X509_NAME *name) {
  if ((name = X509_NAME_dup(name)) == NULL) {
    return 0;
  }
  X509_NAME_free(*xn);
  *xn = name;
  return 1;
}

int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) { return ne->set; }

int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **out_der,
                       size_t *out_der_len) {
  // Make sure encoding is valid
  if (i2d_X509_NAME(nm, NULL) <= 0) {
    return 0;
  }
  if (out_der != NULL) {
    *out_der = (unsigned char *)nm->bytes->data;
  }
  if (out_der_len != NULL) {
    *out_der_len = nm->bytes->length;
  }
  return 1;
}

int x509_marshal_name(CBB *out, X509_NAME *in) {
  int len = i2d_X509_NAME(in, nullptr);
  if (len <= 0) {
    return 0;
  }
  uint8_t *ptr;
  return CBB_add_space(out, &ptr, len) && i2d_X509_NAME(in, &ptr) == len;
}
