/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/pool.h>

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

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

// Constructed types with a recursive definition (such as can be found in PKCS7)
// could eventually exceed the stack given malicious input with excessive
// recursion. Therefore we limit the stack depth. This is the maximum number of
// recursive invocations of asn1_item_embed_d2i().
#define ASN1_MAX_CONSTRUCTED_NEST 30

static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
                           char *cst, const unsigned char **in, long len,
                           int exptag, int expclass, char opt);

static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
                                long len, const ASN1_TEMPLATE *tt, char opt,
                                CRYPTO_BUFFER *buf, int depth);
static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in,
                                   long len, const ASN1_TEMPLATE *tt, char opt,
                                   CRYPTO_BUFFER *buf, int depth);
static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len,
                       int utype, const ASN1_ITEM *it);
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in,
                                 long len, const ASN1_ITEM *it, int tag,
                                 int aclass, char opt);
static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
                            long len, const ASN1_ITEM *it, int tag, int aclass,
                            char opt, CRYPTO_BUFFER *buf, int depth);

// Table to convert tags to bit values, used for MSTRING type
static const unsigned long tag2bit[31] = {
    0,  // (reserved)
    0,  // BOOLEAN
    0,  // INTEGER
    B_ASN1_BIT_STRING,
    B_ASN1_OCTET_STRING,
    0,               // NULL
    0,               // OBJECT IDENTIFIER
    B_ASN1_UNKNOWN,  // ObjectDescriptor
    B_ASN1_UNKNOWN,  // EXTERNAL
    B_ASN1_UNKNOWN,  // REAL
    B_ASN1_UNKNOWN,  // ENUMERATED
    B_ASN1_UNKNOWN,  // EMBEDDED PDV
    B_ASN1_UTF8STRING,
    B_ASN1_UNKNOWN,  // RELATIVE-OID
    B_ASN1_UNKNOWN,  // TIME
    B_ASN1_UNKNOWN,  // (reserved)
    B_ASN1_SEQUENCE,
    0,  // SET
    B_ASN1_NUMERICSTRING,
    B_ASN1_PRINTABLESTRING,
    B_ASN1_T61STRING,
    B_ASN1_VIDEOTEXSTRING,
    B_ASN1_IA5STRING,
    B_ASN1_UTCTIME,
    B_ASN1_GENERALIZEDTIME,
    B_ASN1_GRAPHICSTRING,
    B_ASN1_ISO64STRING,
    B_ASN1_GENERALSTRING,
    B_ASN1_UNIVERSALSTRING,
    B_ASN1_UNKNOWN,  // CHARACTER STRING
    B_ASN1_BMPSTRING,
};

unsigned long ASN1_tag2bit(int tag) {
  if (tag < 0 || tag > 30) {
    return 0;
  }
  return tag2bit[tag];
}

static int is_supported_universal_type(int tag, int aclass) {
  if (aclass != V_ASN1_UNIVERSAL) {
    return 0;
  }
  return tag == V_ASN1_OBJECT || tag == V_ASN1_NULL || tag == V_ASN1_BOOLEAN ||
         tag == V_ASN1_BIT_STRING || tag == V_ASN1_INTEGER ||
         tag == V_ASN1_ENUMERATED || tag == V_ASN1_OCTET_STRING ||
         tag == V_ASN1_NUMERICSTRING || tag == V_ASN1_PRINTABLESTRING ||
         tag == V_ASN1_T61STRING || tag == V_ASN1_VIDEOTEXSTRING ||
         tag == V_ASN1_IA5STRING || tag == V_ASN1_UTCTIME ||
         tag == V_ASN1_GENERALIZEDTIME || tag == V_ASN1_GRAPHICSTRING ||
         tag == V_ASN1_VISIBLESTRING || tag == V_ASN1_GENERALSTRING ||
         tag == V_ASN1_UNIVERSALSTRING || tag == V_ASN1_BMPSTRING ||
         tag == V_ASN1_UTF8STRING || tag == V_ASN1_SET ||
         tag == V_ASN1_SEQUENCE;
}

// Macro to initialize and invalidate the cache

// Decode an ASN1 item, this currently behaves just like a standard 'd2i'
// function. 'in' points to a buffer to read the data from, in future we
// will have more advanced versions that can input data a piece at a time and
// this will simply be a special case.

ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
                          const ASN1_ITEM *it) {
  ASN1_VALUE *ret = NULL;
  if (asn1_item_ex_d2i(&ret, in, len, it, /*tag=*/-1, /*aclass=*/0, /*opt=*/0,
                       /*buf=*/NULL, /*depth=*/0) <= 0) {
    // Clean up, in case the caller left a partial object.
    //
    // TODO(davidben): I don't think it can leave one, but the codepaths below
    // are a bit inconsistent. Revisit this when rewriting this function.
    ASN1_item_ex_free(&ret, it);
  }

  // If the caller supplied an output pointer, free the old one and replace it
  // with |ret|. This differs from OpenSSL slightly in that we don't support
  // object reuse. We run this on both success and failure. On failure, even
  // with object reuse, OpenSSL destroys the previous object.
  if (pval != NULL) {
    ASN1_item_ex_free(pval, it);
    *pval = ret;
  }
  return ret;
}

// Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and
// tag mismatch return -1 to handle OPTIONAL
//
// TODO(davidben): Historically, all functions in this file had to account for
// |*pval| containing an arbitrary existing value. This is no longer the case
// because |ASN1_item_d2i| now always starts from NULL. As part of rewriting
// this function, take the simplified assumptions into account. Though we must
// still account for the internal calls to |ASN1_item_ex_new|.

static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
                            long len, const ASN1_ITEM *it, int tag, int aclass,
                            char opt, CRYPTO_BUFFER *buf, int depth) {
  const ASN1_TEMPLATE *tt, *errtt = NULL;
  const unsigned char *p = NULL, *q;
  unsigned char oclass;
  char cst, isopt;
  int i;
  int otag;
  int ret = 0;
  ASN1_VALUE **pchptr;
  if (!pval) {
    return 0;
  }

  if (buf != NULL) {
    assert(CRYPTO_BUFFER_data(buf) <= *in &&
           *in + len <= CRYPTO_BUFFER_data(buf) + CRYPTO_BUFFER_len(buf));
  }

  // Bound |len| to comfortably fit in an int. Lengths in this module often
  // switch between int and long without overflow checks.
  if (len > INT_MAX / 2) {
    len = INT_MAX / 2;
  }

  if (++depth > ASN1_MAX_CONSTRUCTED_NEST) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_TOO_DEEP);
    goto err;
  }

  switch (it->itype) {
    case ASN1_ITYPE_PRIMITIVE:
      if (it->templates) {
        // tagging or OPTIONAL is currently illegal on an item template
        // because the flags can't get passed down. In practice this
        // isn't a problem: we include the relevant flags from the item
        // template in the template itself.
        if ((tag != -1) || opt) {
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
          goto err;
        }
        return asn1_template_ex_d2i(pval, in, len, it->templates, opt, buf,
                                    depth);
      }
      return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt);
      break;

    case ASN1_ITYPE_MSTRING:
      // It never makes sense for multi-strings to have implicit tagging, so
      // if tag != -1, then this looks like an error in the template.
      if (tag != -1) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
        goto err;
      }

      p = *in;
      // Just read in tag and class
      ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, &p, len, -1, 0, 1);
      if (!ret) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
        goto err;
      }

      // Must be UNIVERSAL class
      if (oclass != V_ASN1_UNIVERSAL) {
        // If OPTIONAL, assume this is OK
        if (opt) {
          return -1;
        }
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL);
        goto err;
      }
      // Check tag matches bit map
      if (!(ASN1_tag2bit(otag) & it->utype)) {
        // If OPTIONAL, assume this is OK
        if (opt) {
          return -1;
        }
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG);
        goto err;
      }
      return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0);

    case ASN1_ITYPE_EXTERN: {
      // We don't support implicit tagging with external types.
      if (tag != -1) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
        goto err;
      }
      const ASN1_EXTERN_FUNCS *ef =
          reinterpret_cast<const ASN1_EXTERN_FUNCS *>(it->funcs);
      return ef->asn1_ex_d2i(pval, in, len, it, opt, NULL);
    }

    case ASN1_ITYPE_CHOICE: {
      // It never makes sense for CHOICE types to have implicit tagging, so if
      // tag != -1, then this looks like an error in the template.
      if (tag != -1) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
        goto err;
      }

      const ASN1_AUX *aux = reinterpret_cast<const ASN1_AUX *>(it->funcs);
      ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
      if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) {
        goto auxerr;
      }

      if (*pval) {
        // Free up and zero CHOICE value if initialised
        i = asn1_get_choice_selector(pval, it);
        if ((i >= 0) && (i < it->tcount)) {
          tt = it->templates + i;
          pchptr = asn1_get_field_ptr(pval, tt);
          ASN1_template_free(pchptr, tt);
          asn1_set_choice_selector(pval, -1, it);
        }
      } else if (!ASN1_item_ex_new(pval, it)) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
        goto err;
      }
      // CHOICE type, try each possibility in turn
      p = *in;
      for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
        pchptr = asn1_get_field_ptr(pval, tt);
        // We mark field as OPTIONAL so its absence can be recognised.
        ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, buf, depth);
        // If field not present, try the next one
        if (ret == -1) {
          continue;
        }
        // If positive return, read OK, break loop
        if (ret > 0) {
          break;
        }
        // Otherwise must be an ASN1 parsing error
        errtt = tt;
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
        goto err;
      }

      // Did we fall off the end without reading anything?
      if (i == it->tcount) {
        // If OPTIONAL, this is OK
        if (opt) {
          // Free and zero it
          ASN1_item_ex_free(pval, it);
          return -1;
        }
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
        goto err;
      }

      asn1_set_choice_selector(pval, i, it);
      if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) {
        goto auxerr;
      }
      *in = p;
      return 1;
    }

    case ASN1_ITYPE_SEQUENCE: {
      p = *in;

      // If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL
      if (tag == -1) {
        tag = V_ASN1_SEQUENCE;
        aclass = V_ASN1_UNIVERSAL;
      }
      // Get SEQUENCE length and update len, p
      ret = asn1_check_tlen(&len, NULL, NULL, &cst, &p, len, tag, aclass, opt);
      if (!ret) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
        goto err;
      } else if (ret == -1) {
        return -1;
      }
      if (!cst) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
        goto err;
      }

      if (!*pval && !ASN1_item_ex_new(pval, it)) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
        goto err;
      }

      const ASN1_AUX *aux = reinterpret_cast<const ASN1_AUX *>(it->funcs);
      ASN1_aux_cb *asn1_cb = aux != NULL ? aux->asn1_cb : NULL;
      if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) {
        goto auxerr;
      }

      // Free up and zero any ADB found
      for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
        if (tt->flags & ASN1_TFLG_ADB_MASK) {
          const ASN1_TEMPLATE *seqtt;
          ASN1_VALUE **pseqval;
          seqtt = asn1_do_adb(pval, tt, 0);
          if (seqtt == NULL) {
            continue;
          }
          pseqval = asn1_get_field_ptr(pval, seqtt);
          ASN1_template_free(pseqval, seqtt);
        }
      }

      // Get each field entry
      for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
        const ASN1_TEMPLATE *seqtt;
        ASN1_VALUE **pseqval;
        seqtt = asn1_do_adb(pval, tt, 1);
        if (seqtt == NULL) {
          goto err;
        }
        pseqval = asn1_get_field_ptr(pval, seqtt);
        // Have we ran out of data?
        if (!len) {
          break;
        }
        q = p;
        // This determines the OPTIONAL flag value. The field cannot be
        // omitted if it is the last of a SEQUENCE and there is still
        // data to be read. This isn't strictly necessary but it
        // increases efficiency in some cases.
        if (i == (it->tcount - 1)) {
          isopt = 0;
        } else {
          isopt = (seqtt->flags & ASN1_TFLG_OPTIONAL) != 0;
        }
        // attempt to read in field, allowing each to be OPTIONAL

        ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, buf, depth);
        if (!ret) {
          errtt = seqtt;
          goto err;
        } else if (ret == -1) {
          // OPTIONAL component absent. Free and zero the field.
          ASN1_template_free(pseqval, seqtt);
          continue;
        }
        // Update length
        len -= p - q;
      }

      // Check all data read
      if (len) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
        goto err;
      }

      // If we get here we've got no more data in the SEQUENCE, however we
      // may not have read all fields so check all remaining are OPTIONAL
      // and clear any that are.
      for (; i < it->tcount; tt++, i++) {
        const ASN1_TEMPLATE *seqtt;
        seqtt = asn1_do_adb(pval, tt, 1);
        if (seqtt == NULL) {
          goto err;
        }
        if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
          ASN1_VALUE **pseqval;
          pseqval = asn1_get_field_ptr(pval, seqtt);
          ASN1_template_free(pseqval, seqtt);
        } else {
          errtt = seqtt;
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING);
          goto err;
        }
      }
      // Save encoding
      if (!asn1_enc_save(pval, *in, p - *in, it, buf)) {
        goto auxerr;
      }
      if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) {
        goto auxerr;
      }
      *in = p;
      return 1;
    }

    default:
      return 0;
  }
auxerr:
  OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
err:
  ASN1_item_ex_free(pval, it);
  if (errtt) {
    ERR_add_error_data(4, "Field=", errtt->field_name, ", Type=", it->sname);
  } else {
    ERR_add_error_data(2, "Type=", it->sname);
  }
  return 0;
}

int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
                     const ASN1_ITEM *it, int tag, int aclass, char opt,
                     CRYPTO_BUFFER *buf) {
  return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, buf,
                          /*depth=*/0);
}

// Templates are handled with two separate functions. One handles any
// EXPLICIT tag and the other handles the rest.

static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
                                long inlen, const ASN1_TEMPLATE *tt, char opt,
                                CRYPTO_BUFFER *buf, int depth) {
  int aclass;
  int ret;
  long len;
  const unsigned char *p, *q;
  if (!val) {
    return 0;
  }
  uint32_t flags = tt->flags;
  aclass = flags & ASN1_TFLG_TAG_CLASS;

  p = *in;

  // Check if EXPLICIT tag expected
  if (flags & ASN1_TFLG_EXPTAG) {
    char cst;
    // Need to work out amount of data available to the inner content and
    // where it starts: so read in EXPLICIT header to get the info.
    ret = asn1_check_tlen(&len, NULL, NULL, &cst, &p, inlen, tt->tag, aclass,
                          opt);
    q = p;
    if (!ret) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
      return 0;
    } else if (ret == -1) {
      return -1;
    }
    if (!cst) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
      return 0;
    }
    // We've found the field so it can't be OPTIONAL now
    ret = asn1_template_noexp_d2i(val, &p, len, tt, /*opt=*/0, buf, depth);
    if (!ret) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
      return 0;
    }
    // We read the field in OK so update length
    len -= p - q;
    // Check for trailing data.
    if (len) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
      goto err;
    }
  } else {
    return asn1_template_noexp_d2i(val, in, inlen, tt, opt, buf, depth);
  }

  *in = p;
  return 1;

err:
  ASN1_template_free(val, tt);
  return 0;
}

static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in,
                                   long len, const ASN1_TEMPLATE *tt, char opt,
                                   CRYPTO_BUFFER *buf, int depth) {
  int aclass;
  int ret;
  const unsigned char *p;
  if (!val) {
    return 0;
  }
  uint32_t flags = tt->flags;
  aclass = flags & ASN1_TFLG_TAG_CLASS;

  p = *in;

  if (flags & ASN1_TFLG_SK_MASK) {
    // SET OF, SEQUENCE OF
    int sktag, skaclass;
    // First work out expected inner tag value
    if (flags & ASN1_TFLG_IMPTAG) {
      sktag = tt->tag;
      skaclass = aclass;
    } else {
      skaclass = V_ASN1_UNIVERSAL;
      if (flags & ASN1_TFLG_SET_OF) {
        sktag = V_ASN1_SET;
      } else {
        sktag = V_ASN1_SEQUENCE;
      }
    }
    // Get the tag
    ret =
        asn1_check_tlen(&len, NULL, NULL, NULL, &p, len, sktag, skaclass, opt);
    if (!ret) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
      return 0;
    } else if (ret == -1) {
      return -1;
    }
    if (!*val) {
      *val = (ASN1_VALUE *)sk_ASN1_VALUE_new_null();
    } else {
      // We've got a valid STACK: free up any items present
      STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val;
      ASN1_VALUE *vtmp;
      while (sk_ASN1_VALUE_num(sktmp) > 0) {
        vtmp = sk_ASN1_VALUE_pop(sktmp);
        ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item));
      }
    }

    if (!*val) {
      goto err;
    }

    // Read as many items as we can
    while (len > 0) {
      ASN1_VALUE *skfield;
      const unsigned char *q = p;
      skfield = NULL;
      if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item),
                            /*tag=*/-1, /*aclass=*/0, /*opt=*/0, buf, depth)) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
        goto err;
      }
      len -= p - q;
      if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
        ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item));
        goto err;
      }
    }
  } else if (flags & ASN1_TFLG_IMPTAG) {
    // IMPLICIT tagging
    ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag,
                           aclass, opt, buf, depth);
    if (!ret) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
      goto err;
    } else if (ret == -1) {
      return -1;
    }
  } else {
    // Nothing special
    ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), /*tag=*/-1,
                           /*aclass=*/0, opt, buf, depth);
    if (!ret) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
      goto err;
    } else if (ret == -1) {
      return -1;
    }
  }

  *in = p;
  return 1;

err:
  ASN1_template_free(val, tt);
  return 0;
}

static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in,
                                 long inlen, const ASN1_ITEM *it, int tag,
                                 int aclass, char opt) {
  int ret = 0, utype;
  long plen;
  char cst;
  const unsigned char *p;
  const unsigned char *cont = NULL;
  long len;
  if (!pval) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL);
    return 0;  // Should never happen
  }

  if (it->itype == ASN1_ITYPE_MSTRING) {
    utype = tag;
    tag = -1;
  } else {
    utype = it->utype;
  }

  if (utype == V_ASN1_ANY) {
    // If type is ANY need to figure out type from tag
    unsigned char oclass;
    if (tag >= 0) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY);
      return 0;
    }
    if (opt) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY);
      return 0;
    }
    p = *in;
    ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, &p, inlen, -1, 0, 0);
    if (!ret) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
      return 0;
    }
    if (!is_supported_universal_type(utype, oclass)) {
      utype = V_ASN1_OTHER;
    }
  }
  if (tag == -1) {
    tag = utype;
    aclass = V_ASN1_UNIVERSAL;
  }
  p = *in;
  // Check header
  ret = asn1_check_tlen(&plen, NULL, NULL, &cst, &p, inlen, tag, aclass, opt);
  if (!ret) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
    return 0;
  } else if (ret == -1) {
    return -1;
  }
  ret = 0;
  // SEQUENCE, SET and "OTHER" are left in encoded form
  if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
      (utype == V_ASN1_OTHER)) {
    // SEQUENCE and SET must be constructed
    if (utype != V_ASN1_OTHER && !cst) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED);
      return 0;
    }

    cont = *in;
    len = p - cont + plen;
    p += plen;
  } else if (cst) {
    // This parser historically supported BER constructed strings. We no
    // longer do and will gradually tighten this parser into a DER
    // parser. BER types should use |CBS_asn1_ber_to_der|.
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE);
    return 0;
  } else {
    cont = p;
    len = plen;
    p += plen;
  }

  // We now have content length and type: translate into a structure
  if (!asn1_ex_c2i(pval, cont, len, utype, it)) {
    goto err;
  }

  *in = p;
  ret = 1;
err:
  return ret;
}

// Translate ASN1 content octets into a structure

static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len,
                       int utype, const ASN1_ITEM *it) {
  ASN1_VALUE **opval = NULL;
  ASN1_STRING *stmp;
  ASN1_TYPE *typ = NULL;
  int ret = 0;
  ASN1_INTEGER **tint;

  // Historically, |it->funcs| for primitive types contained an
  // |ASN1_PRIMITIVE_FUNCS| table of callbacks.
  assert(it->funcs == NULL);

  // If ANY type clear type and set pointer to internal value
  if (it->utype == V_ASN1_ANY) {
    if (!*pval) {
      typ = ASN1_TYPE_new();
      if (typ == NULL) {
        goto err;
      }
      *pval = (ASN1_VALUE *)typ;
    } else {
      typ = (ASN1_TYPE *)*pval;
    }

    if (utype != typ->type) {
      ASN1_TYPE_set(typ, utype, NULL);
    }
    opval = pval;
    pval = &typ->value.asn1_value;
  }
  switch (utype) {
    case V_ASN1_OBJECT:
      if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) {
        goto err;
      }
      break;

    case V_ASN1_NULL:
      if (len) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH);
        goto err;
      }
      *pval = (ASN1_VALUE *)1;
      break;

    case V_ASN1_BOOLEAN:
      if (len != 1) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
        goto err;
      } else {
        ASN1_BOOLEAN *tbool;
        tbool = (ASN1_BOOLEAN *)pval;
        *tbool = *cont;
      }
      break;

    case V_ASN1_BIT_STRING:
      if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) {
        goto err;
      }
      break;

    case V_ASN1_INTEGER:
    case V_ASN1_ENUMERATED:
      tint = (ASN1_INTEGER **)pval;
      if (!c2i_ASN1_INTEGER(tint, &cont, len)) {
        goto err;
      }
      // Fixup type to match the expected form
      (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
      break;

    case V_ASN1_OCTET_STRING:
    case V_ASN1_NUMERICSTRING:
    case V_ASN1_PRINTABLESTRING:
    case V_ASN1_T61STRING:
    case V_ASN1_VIDEOTEXSTRING:
    case V_ASN1_IA5STRING:
    case V_ASN1_UTCTIME:
    case V_ASN1_GENERALIZEDTIME:
    case V_ASN1_GRAPHICSTRING:
    case V_ASN1_VISIBLESTRING:
    case V_ASN1_GENERALSTRING:
    case V_ASN1_UNIVERSALSTRING:
    case V_ASN1_BMPSTRING:
    case V_ASN1_UTF8STRING:
    case V_ASN1_OTHER:
    case V_ASN1_SET:
    case V_ASN1_SEQUENCE:
    // TODO(crbug.com/boringssl/412): This default case should be removed, now
    // that we've resolved https://crbug.com/boringssl/561. However, it is still
    // needed to support some edge cases in |ASN1_PRINTABLE|. |ASN1_PRINTABLE|
    // broadly doesn't tolerate unrecognized universal tags, but except for
    // eight values that map to |B_ASN1_UNKNOWN| instead of zero. See the
    // X509Test.NameAttributeValues test.
    default: {
      CBS cbs;
      CBS_init(&cbs, cont, (size_t)len);
      if (utype == V_ASN1_BMPSTRING) {
        while (CBS_len(&cbs) != 0) {
          uint32_t c;
          if (!CBS_get_ucs2_be(&cbs, &c)) {
            OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING);
            goto err;
          }
        }
      }
      if (utype == V_ASN1_UNIVERSALSTRING) {
        while (CBS_len(&cbs) != 0) {
          uint32_t c;
          if (!CBS_get_utf32_be(&cbs, &c)) {
            OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING);
            goto err;
          }
        }
      }
      if (utype == V_ASN1_UTF8STRING) {
        while (CBS_len(&cbs) != 0) {
          uint32_t c;
          if (!CBS_get_utf8(&cbs, &c)) {
            OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING);
            goto err;
          }
        }
      }
      if (utype == V_ASN1_UTCTIME) {
        if (!CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/1)) {
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
          goto err;
        }
      }
      if (utype == V_ASN1_GENERALIZEDTIME) {
        if (!CBS_parse_generalized_time(&cbs, NULL,
                                        /*allow_timezone_offset=*/0)) {
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
          goto err;
        }
      }
      // TODO(https://crbug.com/boringssl/427): Check other string types.

      // All based on ASN1_STRING and handled the same
      if (!*pval) {
        stmp = ASN1_STRING_type_new(utype);
        if (!stmp) {
          goto err;
        }
        *pval = (ASN1_VALUE *)stmp;
      } else {
        stmp = (ASN1_STRING *)*pval;
        stmp->type = utype;
      }
      if (!ASN1_STRING_set(stmp, cont, len)) {
        ASN1_STRING_free(stmp);
        *pval = NULL;
        goto err;
      }
      break;
    }
  }
  // If ASN1_ANY and NULL type fix up value
  if (typ && (utype == V_ASN1_NULL)) {
    typ->value.ptr = NULL;
  }

  ret = 1;
err:
  if (!ret) {
    ASN1_TYPE_free(typ);
    if (opval) {
      *opval = NULL;
    }
  }
  return ret;
}

// Check an ASN1 tag and length: a bit like ASN1_get_object but it
// checks the expected tag.

static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
                           char *cst, const unsigned char **in, long len,
                           int exptag, int expclass, char opt) {
  int i;
  int ptag, pclass;
  long plen;
  const unsigned char *p;
  p = *in;

  i = ASN1_get_object(&p, &plen, &ptag, &pclass, len);
  if (i & 0x80) {
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER);
    return 0;
  }
  if (exptag >= 0) {
    if ((exptag != ptag) || (expclass != pclass)) {
      // If type is OPTIONAL, not an error: indicate missing type.
      if (opt) {
        return -1;
      }
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG);
      return 0;
    }
  }

  if (cst) {
    *cst = i & V_ASN1_CONSTRUCTED;
  }

  if (olen) {
    *olen = plen;
  }

  if (oclass) {
    *oclass = pclass;
  }

  if (otag) {
    *otag = ptag;
  }

  *in = p;
  return 1;
}
