/* Copyright (c) 2014, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <openssl/bytestring.h>

#include <assert.h>
#include <string.h>

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


// kMaxDepth is a just a sanity limit. The code should be such that the length
// of the input being processes always decreases. None the less, a very large
// input could otherwise cause the stack to overflow.
static const uint32_t kMaxDepth = 2048;

// is_string_type returns one if |tag| is a string type and zero otherwise. It
// ignores the constructed bit.
static int is_string_type(CBS_ASN1_TAG tag) {
  // While BER supports constructed BIT STRINGS, OpenSSL misparses them. To
  // avoid acting on an ambiguous input, we do not support constructed BIT
  // STRINGS. See https://github.com/openssl/openssl/issues/12810.
  switch (tag & ~CBS_ASN1_CONSTRUCTED) {
    case CBS_ASN1_OCTETSTRING:
    case CBS_ASN1_UTF8STRING:
    case CBS_ASN1_NUMERICSTRING:
    case CBS_ASN1_PRINTABLESTRING:
    case CBS_ASN1_T61STRING:
    case CBS_ASN1_VIDEOTEXSTRING:
    case CBS_ASN1_IA5STRING:
    case CBS_ASN1_GRAPHICSTRING:
    case CBS_ASN1_VISIBLESTRING:
    case CBS_ASN1_GENERALSTRING:
    case CBS_ASN1_UNIVERSALSTRING:
    case CBS_ASN1_BMPSTRING:
      return 1;
    default:
      return 0;
  }
}

// cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found|
// depending on whether an indefinite length element or constructed string was
// found. The value of |orig_in| is not changed. It returns one on success (i.e.
// |*ber_found| was set) and zero on error.
static int cbs_find_ber(const CBS *orig_in, int *ber_found, uint32_t depth) {
  CBS in;

  if (depth > kMaxDepth) {
    return 0;
  }

  CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in));
  *ber_found = 0;

  while (CBS_len(&in) > 0) {
    CBS contents;
    CBS_ASN1_TAG tag;
    size_t header_len;
    int indefinite;
    if (!CBS_get_any_ber_asn1_element(&in, &contents, &tag, &header_len,
                                      ber_found, &indefinite)) {
      return 0;
    }
    if (*ber_found) {
      return 1;
    }
    if (tag & CBS_ASN1_CONSTRUCTED) {
      if (is_string_type(tag)) {
        // Constructed strings are only legal in BER and require conversion.
        *ber_found = 1;
        return 1;
      }
      if (!CBS_skip(&contents, header_len) ||
          !cbs_find_ber(&contents, ber_found, depth + 1)) {
        return 0;
      }
    }
  }

  return 1;
}

// cbs_get_eoc returns one if |cbs| begins with an "end of contents" (EOC) value
// and zero otherwise. If an EOC was found, it advances |cbs| past it.
static int cbs_get_eoc(CBS *cbs) {
  if (CBS_len(cbs) >= 2 &&
      CBS_data(cbs)[0] == 0 && CBS_data(cbs)[1] == 0) {
    return CBS_skip(cbs, 2);
  }
  return 0;
}

// cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If
// |string_tag| is non-zero, then all elements must match |string_tag| up to the
// constructed bit and primitive element bodies are written to |out| without
// element headers. This is used when concatenating the fragments of a
// constructed string. If |looking_for_eoc| is set then any EOC elements found
// will cause the function to return after consuming it. It returns one on
// success and zero on error.
static int cbs_convert_ber(CBS *in, CBB *out, CBS_ASN1_TAG string_tag,
                           int looking_for_eoc, uint32_t depth) {
  assert(!(string_tag & CBS_ASN1_CONSTRUCTED));

  if (depth > kMaxDepth) {
    return 0;
  }

  while (CBS_len(in) > 0) {
    if (looking_for_eoc && cbs_get_eoc(in)) {
      return 1;
    }

    CBS contents;
    CBS_ASN1_TAG tag, child_string_tag = string_tag;
    size_t header_len;
    int indefinite;
    CBB *out_contents, out_contents_storage;
    if (!CBS_get_any_ber_asn1_element(in, &contents, &tag, &header_len,
                                      /*out_ber_found=*/NULL, &indefinite)) {
      return 0;
    }

    if (string_tag != 0) {
      // This is part of a constructed string. All elements must match
      // |string_tag| up to the constructed bit and get appended to |out|
      // without a child element.
      if ((tag & ~CBS_ASN1_CONSTRUCTED) != string_tag) {
        return 0;
      }
      out_contents = out;
    } else {
      CBS_ASN1_TAG out_tag = tag;
      if ((tag & CBS_ASN1_CONSTRUCTED) && is_string_type(tag)) {
        // If a constructed string, clear the constructed bit and inform
        // children to concatenate bodies.
        out_tag &= ~CBS_ASN1_CONSTRUCTED;
        child_string_tag = out_tag;
      }
      if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) {
        return 0;
      }
      out_contents = &out_contents_storage;
    }

    if (indefinite) {
      if (!cbs_convert_ber(in, out_contents, child_string_tag,
                           /*looking_for_eoc=*/1, depth + 1) ||
          !CBB_flush(out)) {
        return 0;
      }
      continue;
    }

    if (!CBS_skip(&contents, header_len)) {
      return 0;
    }

    if (tag & CBS_ASN1_CONSTRUCTED) {
      // Recurse into children.
      if (!cbs_convert_ber(&contents, out_contents, child_string_tag,
                           /*looking_for_eoc=*/0, depth + 1)) {
        return 0;
      }
    } else {
      // Copy primitive contents as-is.
      if (!CBB_add_bytes(out_contents, CBS_data(&contents),
                         CBS_len(&contents))) {
        return 0;
      }
    }

    if (!CBB_flush(out)) {
      return 0;
    }
  }

  return looking_for_eoc == 0;
}

int CBS_asn1_ber_to_der(CBS *in, CBS *out, uint8_t **out_storage) {
  CBB cbb;

  // First, do a quick walk to find any indefinite-length elements. Most of the
  // time we hope that there aren't any and thus we can quickly return.
  int conversion_needed;
  if (!cbs_find_ber(in, &conversion_needed, 0)) {
    return 0;
  }

  if (!conversion_needed) {
    if (!CBS_get_any_asn1_element(in, out, NULL, NULL)) {
      return 0;
    }
    *out_storage = NULL;
    return 1;
  }

  size_t len;
  if (!CBB_init(&cbb, CBS_len(in)) ||
      !cbs_convert_ber(in, &cbb, 0, 0, 0) ||
      !CBB_finish(&cbb, out_storage, &len)) {
    CBB_cleanup(&cbb);
    return 0;
  }

  CBS_init(out, *out_storage, len);
  return 1;
}

int CBS_get_asn1_implicit_string(CBS *in, CBS *out, uint8_t **out_storage,
                                 CBS_ASN1_TAG outer_tag,
                                 CBS_ASN1_TAG inner_tag) {
  assert(!(outer_tag & CBS_ASN1_CONSTRUCTED));
  assert(!(inner_tag & CBS_ASN1_CONSTRUCTED));
  assert(is_string_type(inner_tag));

  if (CBS_peek_asn1_tag(in, outer_tag)) {
    // Normal implicitly-tagged string.
    *out_storage = NULL;
    return CBS_get_asn1(in, out, outer_tag);
  }

  // Otherwise, try to parse an implicitly-tagged constructed string.
  // |CBS_asn1_ber_to_der| is assumed to have run, so only allow one level deep
  // of nesting.
  CBB result;
  CBS child;
  if (!CBB_init(&result, CBS_len(in)) ||
      !CBS_get_asn1(in, &child, outer_tag | CBS_ASN1_CONSTRUCTED)) {
    goto err;
  }

  while (CBS_len(&child) > 0) {
    CBS chunk;
    if (!CBS_get_asn1(&child, &chunk, inner_tag) ||
        !CBB_add_bytes(&result, CBS_data(&chunk), CBS_len(&chunk))) {
      goto err;
    }
  }

  uint8_t *data;
  size_t len;
  if (!CBB_finish(&result, &data, &len)) {
    goto err;
  }

  CBS_init(out, data, len);
  *out_storage = data;
  return 1;

err:
  CBB_cleanup(&result);
  return 0;
}
