/* 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 "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 unsigned kMaxDepth = 2048;

/* cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found|
 * depending on whether an indefinite length element was found. The value of
 * |in| is not changed. It returns one on success (i.e. |*ber_found| was set)
 * and zero on error. */
static int cbs_find_ber(CBS *orig_in, char *ber_found, unsigned 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;
    unsigned tag;
    size_t header_len;

    if (!CBS_get_any_asn1_element(&in, &contents, &tag, &header_len)) {
      return 0;
    }
    if (CBS_len(&contents) == header_len &&
        header_len > 0 &&
        CBS_data(&contents)[header_len-1] == 0x80) {
      *ber_found = 1;
      return 1;
    }
    if (tag & CBS_ASN1_CONSTRUCTED) {
      if (!CBS_skip(&contents, header_len) ||
          !cbs_find_ber(&contents, ber_found, depth + 1)) {
        return 0;
      }
    }
  }

  return 1;
}

/* is_primitive_type returns true if |tag| likely a primitive type. Normally
 * one can just test the "constructed" bit in the tag but, in BER, even
 * primitive tags can have the constructed bit if they have indefinite
 * length. */
static char is_primitive_type(unsigned tag) {
  return (tag & 0xc0) == 0 &&
         (tag & 0x1f) != (CBS_ASN1_SEQUENCE & 0x1f) &&
         (tag & 0x1f) != (CBS_ASN1_SET & 0x1f);
}

/* is_eoc returns true if |header_len| and |contents|, as returned by
 * |CBS_get_any_asn1_element|, indicate an "end of contents" (EOC) value. */
static char is_eoc(size_t header_len, CBS *contents) {
  return header_len == 2 && CBS_len(contents) == 2 &&
         memcmp(CBS_data(contents), "\x00\x00", 2) == 0;
}

/* cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If
 * |squash_header| is set then the top-level of elements from |in| will not
 * have their headers written. This is used when concatenating the fragments of
 * an indefinite length, primitive value. 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, char squash_header,
                           char looking_for_eoc, unsigned depth) {
  if (depth > kMaxDepth) {
    return 0;
  }

  while (CBS_len(in) > 0) {
    CBS contents;
    unsigned tag;
    size_t header_len;
    CBB *out_contents, out_contents_storage;

    if (!CBS_get_any_asn1_element(in, &contents, &tag, &header_len)) {
      return 0;
    }
    out_contents = out;

    if (CBS_len(&contents) == header_len) {
      if (is_eoc(header_len, &contents)) {
        return looking_for_eoc;
      }

      if (header_len > 0 && CBS_data(&contents)[header_len - 1] == 0x80) {
        CBB out_context_specific;

        /* This is an indefinite length element. If it's a SEQUENCE or SET then
         * we just need to write the out the contents as normal, but with a
         * concrete length prefix.
         *
         * If it's a something else then the contents will be a series of BER
         * elements of the same type which need to be concatenated. */
        const char context_specific = (tag & 0xc0) == 0x80;
        const char simple_type = is_primitive_type(tag);

        if (!squash_header) {
          unsigned out_tag = tag;
          if (simple_type) {
            out_tag &= ~CBS_ASN1_CONSTRUCTED;
          }
          if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) {
            return 0;
          }
          out_contents = &out_contents_storage;
        }

        /* If context specific then we peek at the inner tag and replicate it.
         * This is because NSS produces odd-seeming BER structures where an
         * indefinite length explicit tag doesn't have the expected actual tag
         * inside it. */
        if (context_specific) {
          CBS in_copy, contents;
          unsigned tag;
          size_t header_len;

          CBS_init(&in_copy, CBS_data(in), CBS_len(in));
          if (!CBS_get_any_asn1_element(&in_copy, &contents, &tag, &header_len)) {
            return 0;
          }
          if (is_eoc(header_len, &contents)) {
            /* The indefinite-length value is empty. Unread the EOC and
             * continue. */
            CBS_init(in, CBS_data(&in_copy), CBS_len(&in_copy));
            continue;
          }
          if (is_primitive_type(tag)) {
            tag &= 0x1f;
          }
          if (!CBB_add_asn1(out_contents, &out_context_specific, tag)) {
            return 0;
          }
          out_contents = &out_context_specific;
        }

        if (!cbs_convert_ber(in, out_contents,
                             context_specific || simple_type,
                             1 /* looking for eoc */, depth + 1)) {
          return 0;
        }
        if (out_contents != out && !CBB_flush(out)) {
          return 0;
        }
        continue;
      }
    }

    if (!squash_header) {
      if (!CBB_add_asn1(out, &out_contents_storage, tag)) {
        return 0;
      }
      out_contents = &out_contents_storage;
    }

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

    if (tag & CBS_ASN1_CONSTRUCTED) {
      if (!cbs_convert_ber(&contents, out_contents, 0 /* don't squash header */,
                           0 /* not looking for eoc */, depth + 1)) {
        return 0;
      }
    } else {
      if (!CBB_add_bytes(out_contents, CBS_data(&contents),
                         CBS_len(&contents))) {
        return 0;
      }
    }

    if (out_contents != out && !CBB_flush(out)) {
      return 0;
    }
  }

  return looking_for_eoc == 0;
}

int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) {
  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. */
  char conversion_needed;
  if (!cbs_find_ber(in, &conversion_needed, 0)) {
    return 0;
  }

  if (!conversion_needed) {
    *out = NULL;
    *out_len = 0;
    return 1;
  }

  CBB_init(&cbb, CBS_len(in));
  if (!cbs_convert_ber(in, &cbb, 0, 0, 0)) {
    CBB_cleanup(&cbb);
    return 0;
  }

  return CBB_finish(&cbb, out, out_len);
}
