/* 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 <assert.h>
#include <limits.h>
#include <string.h>

#include <openssl/asn1t.h>
#include <openssl/mem.h>

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


static int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out,
                                const ASN1_ITEM *it, int tag, int aclass,
                                int optional);
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
                                 const ASN1_ITEM *it, int tag, int aclass,
                                 int optional);
static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *out_omit,
                       int *putype, const ASN1_ITEM *it);
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
                            int skcontlen, const ASN1_ITEM *item, int do_sort);
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
                                const ASN1_TEMPLATE *tt, int tag, int aclass);

// Top level i2d equivalents

int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) {
  if (out && !*out) {
    unsigned char *p, *buf;
    int len = ASN1_item_ex_i2d(&val, NULL, it, /*tag=*/-1, /*aclass=*/0);
    if (len <= 0) {
      return len;
    }
    buf = OPENSSL_malloc(len);
    if (!buf) {
      OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
      return -1;
    }
    p = buf;
    int len2 = ASN1_item_ex_i2d(&val, &p, it, /*tag=*/-1, /*aclass=*/0);
    if (len2 <= 0) {
      return len2;
    }
    assert(len == len2);
    *out = buf;
    return len;
  }

  return ASN1_item_ex_i2d(&val, out, it, /*tag=*/-1, /*aclass=*/0);
}

// Encode an item, taking care of IMPLICIT tagging (if any). This function
// performs the normal item handling: it can be used in external types.

int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
                     const ASN1_ITEM *it, int tag, int aclass) {
  int ret = asn1_item_ex_i2d_opt(pval, out, it, tag, aclass, /*optional=*/0);
  assert(ret != 0);
  return ret;
}

// asn1_item_ex_i2d_opt behaves like |ASN1_item_ex_i2d| but, if |optional| is
// non-zero and |*pval| is omitted, it returns zero and writes no bytes.
int asn1_item_ex_i2d_opt(ASN1_VALUE **pval, unsigned char **out,
                         const ASN1_ITEM *it, int tag, int aclass,
                         int optional) {
  const ASN1_TEMPLATE *tt = NULL;
  int i, seqcontlen, seqlen;

  // Historically, |aclass| was repurposed to pass additional flags into the
  // encoding process.
  assert((aclass & ASN1_TFLG_TAG_CLASS) == aclass);
  // If not overridding the tag, |aclass| is ignored and should be zero.
  assert(tag != -1 || aclass == 0);

  // All fields are pointers, except for boolean |ASN1_ITYPE_PRIMITIVE|s.
  // Optional primitives are handled later.
  if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) {
    if (optional) {
      return 0;
    }
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
    return -1;
  }

  switch (it->itype) {
    case ASN1_ITYPE_PRIMITIVE:
      if (it->templates) {
        if (it->templates->flags & ASN1_TFLG_OPTIONAL) {
          OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
          return -1;
        }
        return asn1_template_ex_i2d(pval, out, it->templates, tag, aclass);
      }
      return asn1_i2d_ex_primitive(pval, out, it, tag, aclass, optional);

    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);
        return -1;
      }
      return asn1_i2d_ex_primitive(pval, out, it, -1, 0, optional);

    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);
        return -1;
      }
      i = asn1_get_choice_selector(pval, it);
      if (i < 0 || i >= it->tcount) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
        return -1;
      }
      const ASN1_TEMPLATE *chtt = it->templates + i;
      if (chtt->flags & ASN1_TFLG_OPTIONAL) {
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
        return -1;
      }
      ASN1_VALUE **pchval = asn1_get_field_ptr(pval, chtt);
      return asn1_template_ex_i2d(pchval, out, chtt, -1, 0);
    }

    case ASN1_ITYPE_EXTERN: {
      // If new style i2d it does all the work
      const ASN1_EXTERN_FUNCS *ef = it->funcs;
      int ret = ef->asn1_ex_i2d(pval, out, it, tag, aclass);
      if (ret == 0) {
        // |asn1_ex_i2d| should never return zero. We have already checked
        // for optional values generically, and |ASN1_ITYPE_EXTERN| fields
        // must be pointers.
        OPENSSL_PUT_ERROR(ASN1, ERR_R_INTERNAL_ERROR);
        return -1;
      }
      return ret;
    }

    case ASN1_ITYPE_SEQUENCE: {
      i = asn1_enc_restore(&seqcontlen, out, pval, it);
      // An error occurred
      if (i < 0) {
        return -1;
      }
      // We have a valid cached encoding...
      if (i > 0) {
        return seqcontlen;
      }
      // Otherwise carry on
      seqcontlen = 0;
      // If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL
      if (tag == -1) {
        tag = V_ASN1_SEQUENCE;
        aclass = V_ASN1_UNIVERSAL;
      }
      // First work out sequence content length
      for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
        const ASN1_TEMPLATE *seqtt;
        ASN1_VALUE **pseqval;
        int tmplen;
        seqtt = asn1_do_adb(pval, tt, 1);
        if (!seqtt) {
          return -1;
        }
        pseqval = asn1_get_field_ptr(pval, seqtt);
        tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, 0);
        if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen)) {
          return -1;
        }
        seqcontlen += tmplen;
      }

      seqlen = ASN1_object_size(/*constructed=*/1, seqcontlen, tag);
      if (!out || seqlen == -1) {
        return seqlen;
      }
      // Output SEQUENCE header
      ASN1_put_object(out, /*constructed=*/1, seqcontlen, tag, aclass);
      for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
        const ASN1_TEMPLATE *seqtt;
        ASN1_VALUE **pseqval;
        seqtt = asn1_do_adb(pval, tt, 1);
        if (!seqtt) {
          return -1;
        }
        pseqval = asn1_get_field_ptr(pval, seqtt);
        if (asn1_template_ex_i2d(pseqval, out, seqtt, -1, 0) < 0) {
          return -1;
        }
      }
      return seqlen;
    }

    default:
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
      return -1;
  }
}

// asn1_template_ex_i2d behaves like |asn1_item_ex_i2d_opt| but uses an
// |ASN1_TEMPLATE| instead of an |ASN1_ITEM|. An |ASN1_TEMPLATE| wraps an
// |ASN1_ITEM| with modifiers such as tagging, SEQUENCE or SET, etc. Instead of
// taking an |optional| parameter, it uses the |ASN1_TFLG_OPTIONAL| flag.
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
                                const ASN1_TEMPLATE *tt, int tag, int iclass) {
  int i, ret, flags, ttag, tclass;
  size_t j;
  flags = tt->flags;

  // Historically, |iclass| was repurposed to pass additional flags into the
  // encoding process.
  assert((iclass & ASN1_TFLG_TAG_CLASS) == iclass);
  // If not overridding the tag, |iclass| is ignored and should be zero.
  assert(tag != -1 || iclass == 0);

  // Work out tag and class to use: tagging may come either from the
  // template or the arguments, not both because this would create
  // ambiguity.
  if (flags & ASN1_TFLG_TAG_MASK) {
    // Error if argument and template tagging
    if (tag != -1) {
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE);
      return -1;
    }
    // Get tagging from template
    ttag = tt->tag;
    tclass = flags & ASN1_TFLG_TAG_CLASS;
  } else if (tag != -1) {
    // No template tagging, get from arguments
    ttag = tag;
    tclass = iclass & ASN1_TFLG_TAG_CLASS;
  } else {
    ttag = -1;
    tclass = 0;
  }

  const int optional = (flags & ASN1_TFLG_OPTIONAL) != 0;

  // At this point 'ttag' contains the outer tag to use, and 'tclass' is the
  // class.

  if (flags & ASN1_TFLG_SK_MASK) {
    // SET OF, SEQUENCE OF
    STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
    int isset, sktag, skaclass;
    int skcontlen, sklen;
    ASN1_VALUE *skitem;

    if (!*pval) {
      if (optional) {
        return 0;
      }
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
      return -1;
    }

    if (flags & ASN1_TFLG_SET_OF) {
      isset = 1;
      // Historically, types with both bits set were mutated when
      // serialized to apply the sort. We no longer support this.
      assert((flags & ASN1_TFLG_SEQUENCE_OF) == 0);
    } else {
      isset = 0;
    }

    // Work out inner tag value: if EXPLICIT or no tagging use underlying
    // type.
    if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
      sktag = ttag;
      skaclass = tclass;
    } else {
      skaclass = V_ASN1_UNIVERSAL;
      if (isset) {
        sktag = V_ASN1_SET;
      } else {
        sktag = V_ASN1_SEQUENCE;
      }
    }

    // Determine total length of items
    skcontlen = 0;
    for (j = 0; j < sk_ASN1_VALUE_num(sk); j++) {
      int tmplen;
      skitem = sk_ASN1_VALUE_value(sk, j);
      tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), -1, 0);
      if (tmplen == -1 || (skcontlen > INT_MAX - tmplen)) {
        return -1;
      }
      skcontlen += tmplen;
    }
    sklen = ASN1_object_size(/*constructed=*/1, skcontlen, sktag);
    if (sklen == -1) {
      return -1;
    }
    // If EXPLICIT need length of surrounding tag
    if (flags & ASN1_TFLG_EXPTAG) {
      ret = ASN1_object_size(/*constructed=*/1, sklen, ttag);
    } else {
      ret = sklen;
    }

    if (!out || ret == -1) {
      return ret;
    }

    // Now encode this lot...
    // EXPLICIT tag
    if (flags & ASN1_TFLG_EXPTAG) {
      ASN1_put_object(out, /*constructed=*/1, sklen, ttag, tclass);
    }
    // SET or SEQUENCE and IMPLICIT tag
    ASN1_put_object(out, /*constructed=*/1, skcontlen, sktag, skaclass);
    // And the stuff itself
    if (!asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), isset)) {
      return -1;
    }
    return ret;
  }

  if (flags & ASN1_TFLG_EXPTAG) {
    // EXPLICIT tagging
    // Find length of tagged item
    i = asn1_item_ex_i2d_opt(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, 0,
                             optional);
    if (i <= 0) {
      return i;
    }
    // Find length of EXPLICIT tag
    ret = ASN1_object_size(/*constructed=*/1, i, ttag);
    if (out && ret != -1) {
      // Output tag and item
      ASN1_put_object(out, /*constructed=*/1, i, ttag, tclass);
      if (ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, 0) < 0) {
        return -1;
      }
    }
    return ret;
  }

  // Either normal or IMPLICIT tagging
  return asn1_item_ex_i2d_opt(pval, out, ASN1_ITEM_ptr(tt->item), ttag, tclass,
                              optional);
}

// Temporary structure used to hold DER encoding of items for SET OF

typedef struct {
  unsigned char *data;
  int length;
} DER_ENC;

static int der_cmp(const void *a, const void *b) {
  const DER_ENC *d1 = a, *d2 = b;
  int cmplen, i;
  cmplen = (d1->length < d2->length) ? d1->length : d2->length;
  i = OPENSSL_memcmp(d1->data, d2->data, cmplen);
  if (i) {
    return i;
  }
  return d1->length - d2->length;
}

// asn1_set_seq_out writes |sk| to |out| under the i2d output convention,
// excluding the tag and length. It returns one on success and zero on error.
// |skcontlen| must be the total encoded size. If |do_sort| is non-zero, the
// elements are sorted for a SET OF type. Each element of |sk| has type
// |item|.
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
                            int skcontlen, const ASN1_ITEM *item, int do_sort) {
  // No need to sort if there are fewer than two items.
  if (!do_sort || sk_ASN1_VALUE_num(sk) < 2) {
    for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
      ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i);
      if (ASN1_item_ex_i2d(&skitem, out, item, -1, 0) < 0) {
        return 0;
      }
    }
    return 1;
  }

  if (sk_ASN1_VALUE_num(sk) > ((size_t)-1) / sizeof(DER_ENC)) {
    OPENSSL_PUT_ERROR(ASN1, ERR_R_OVERFLOW);
    return 0;
  }

  int ret = 0;
  unsigned char *const buf = OPENSSL_malloc(skcontlen);
  DER_ENC *encoded = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) * sizeof(*encoded));
  if (encoded == NULL || buf == NULL) {
    OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
    goto err;
  }

  // Encode all the elements into |buf| and populate |encoded|.
  unsigned char *p = buf;
  for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
    ASN1_VALUE *skitem = sk_ASN1_VALUE_value(sk, i);
    encoded[i].data = p;
    encoded[i].length = ASN1_item_ex_i2d(&skitem, &p, item, -1, 0);
    if (encoded[i].length < 0) {
      goto err;
    }
    assert(p - buf <= skcontlen);
  }

  qsort(encoded, sk_ASN1_VALUE_num(sk), sizeof(*encoded), der_cmp);

  // Output the elements in sorted order.
  p = *out;
  for (size_t i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
    OPENSSL_memcpy(p, encoded[i].data, encoded[i].length);
    p += encoded[i].length;
  }
  *out = p;

  ret = 1;

err:
  OPENSSL_free(encoded);
  OPENSSL_free(buf);
  return ret;
}

// asn1_i2d_ex_primitive behaves like |ASN1_item_ex_i2d| but |item| must be a
// a PRIMITIVE or MSTRING type that is not an |ASN1_ITEM_TEMPLATE|.
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
                                 const ASN1_ITEM *it, int tag, int aclass,
                                 int optional) {
  // Get length of content octets and maybe find out the underlying type.
  int omit;
  int utype = it->utype;
  int len = asn1_ex_i2c(pval, NULL, &omit, &utype, it);
  if (len < 0) {
    return -1;
  }
  if (omit) {
    if (optional) {
      return 0;
    }
    OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
    return -1;
  }

  // If SEQUENCE, SET or OTHER then header is included in pseudo content
  // octets so don't include tag+length. We need to check here because the
  // call to asn1_ex_i2c() could change utype.
  int usetag =
      utype != V_ASN1_SEQUENCE && utype != V_ASN1_SET && utype != V_ASN1_OTHER;

  // If not implicitly tagged get tag from underlying type
  if (tag == -1) {
    tag = utype;
  }

  // Output tag+length followed by content octets
  if (out) {
    if (usetag) {
      ASN1_put_object(out, /*constructed=*/0, len, tag, aclass);
    }
    int len2 = asn1_ex_i2c(pval, *out, &omit, &utype, it);
    if (len2 < 0) {
      return -1;
    }
    assert(len == len2);
    assert(!omit);
    *out += len;
  }

  if (usetag) {
    return ASN1_object_size(/*constructed=*/0, len, tag);
  }
  return len;
}

// asn1_ex_i2c writes the |*pval| to |cout| under the i2d output convention,
// excluding the tag and length. It returns the number of bytes written,
// possibly zero, on success or -1 on error. If |*pval| should be omitted, it
// returns zero and sets |*out_omit| to true.
//
// If |it| is an MSTRING or ANY type, it gets the underlying type from |*pval|,
// which must be an |ASN1_STRING| or |ASN1_TYPE|, respectively. It then updates
// |*putype| with the tag number of type used, or |V_ASN1_OTHER| if it was not a
// universal type. If |*putype| is set to |V_ASN1_SEQUENCE|, |V_ASN1_SET|, or
// |V_ASN1_OTHER|, it additionally outputs the tag and length, so the caller
// must not do so.
//
// Otherwise, |*putype| must contain |it->utype|.
//
// WARNING: Unlike most functions in this file, |asn1_ex_i2c| can return zero
// without omitting the element. ASN.1 values may have empty contents.
static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *out_omit,
                       int *putype, const ASN1_ITEM *it) {
  ASN1_BOOLEAN *tbool = NULL;
  ASN1_STRING *strtmp;
  ASN1_OBJECT *otmp;
  int utype;
  const unsigned char *cont;
  unsigned char c;
  int len;

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

  *out_omit = 0;

  // Should type be omitted?
  if ((it->itype != ASN1_ITYPE_PRIMITIVE) || (it->utype != V_ASN1_BOOLEAN)) {
    if (!*pval) {
      *out_omit = 1;
      return 0;
    }
  }

  if (it->itype == ASN1_ITYPE_MSTRING) {
    // If MSTRING type set the underlying type
    strtmp = (ASN1_STRING *)*pval;
    utype = strtmp->type;
    if (utype < 0 && utype != V_ASN1_OTHER) {
      // MSTRINGs can have type -1 when default-constructed.
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE);
      return -1;
    }
    // Negative INTEGER and ENUMERATED values use |ASN1_STRING| type values
    // that do not match their corresponding utype values. INTEGERs cannot
    // participate in MSTRING types, but ENUMERATEDs can.
    //
    // TODO(davidben): Is this a bug? Although arguably one of the MSTRING
    // types should contain more values, rather than less. See
    // https://crbug.com/boringssl/412. But it is not possible to fit all
    // possible ANY values into an |ASN1_STRING|, so matching the spec here
    // is somewhat hopeless.
    if (utype == V_ASN1_NEG_INTEGER) {
      utype = V_ASN1_INTEGER;
    } else if (utype == V_ASN1_NEG_ENUMERATED) {
      utype = V_ASN1_ENUMERATED;
    }
    *putype = utype;
  } else if (it->utype == V_ASN1_ANY) {
    // If ANY set type and pointer to value
    ASN1_TYPE *typ;
    typ = (ASN1_TYPE *)*pval;
    utype = typ->type;
    if (utype < 0 && utype != V_ASN1_OTHER) {
      // |ASN1_TYPE|s can have type -1 when default-constructed.
      OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE);
      return -1;
    }
    *putype = utype;
    pval = &typ->value.asn1_value;
  } else {
    utype = *putype;
  }

  switch (utype) {
    case V_ASN1_OBJECT:
      otmp = (ASN1_OBJECT *)*pval;
      cont = otmp->data;
      len = otmp->length;
      if (len == 0) {
        // Some |ASN1_OBJECT|s do not have OIDs and cannot be serialized.
        OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT);
        return -1;
      }
      break;

    case V_ASN1_NULL:
      cont = NULL;
      len = 0;
      break;

    case V_ASN1_BOOLEAN:
      tbool = (ASN1_BOOLEAN *)pval;
      if (*tbool == -1) {
        *out_omit = 1;
        return 0;
      }
      if (it->utype != V_ASN1_ANY) {
        // Default handling if value == size field then omit
        if ((*tbool && (it->size > 0)) || (!*tbool && !it->size)) {
          *out_omit = 1;
          return 0;
        }
      }
      c = *tbool ? 0xff : 0x00;
      cont = &c;
      len = 1;
      break;

    case V_ASN1_BIT_STRING: {
      int ret =
          i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, cout ? &cout : NULL);
      // |i2c_ASN1_BIT_STRING| returns zero on error instead of -1.
      return ret <= 0 ? -1 : ret;
    }

    case V_ASN1_INTEGER:
    case V_ASN1_ENUMERATED: {
      // |i2c_ASN1_INTEGER| also handles ENUMERATED.
      int ret = i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL);
      // |i2c_ASN1_INTEGER| returns zero on error instead of -1.
      return ret <= 0 ? -1 : ret;
    }

    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_SEQUENCE:
    case V_ASN1_SET:
    default:
      // All based on ASN1_STRING and handled the same
      strtmp = (ASN1_STRING *)*pval;
      cont = strtmp->data;
      len = strtmp->length;

      break;
  }
  if (cout && len) {
    OPENSSL_memcpy(cout, cont, len);
  }
  return len;
}
