/*
 * Copyright (C) 2002-2025 Free Software Foundation, Inc.
 *
 * This file is part of LIBTASN1.
 *
 * The LIBTASN1 library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see
 * <https://www.gnu.org/licenses/>.
 */

#include <config.h>

/*****************************************************/
/* File: decoding.c                                  */
/* Description: Functions to manage DER decoding     */
/*****************************************************/

#include <int.h>
#include <parser_aux.h>
#include <gstr.h>
#include <structure.h>
#include <element.h>
#include <limits.h>
#include <intprops.h>
#include "c-ctype.h"

#ifdef DEBUG
# define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__)
#else
# define warn()
#endif

#define IS_ERR(len, flags) (len < -1 || ((flags & ASN1_DECODE_FLAG_STRICT_DER) && len < 0))

#define HAVE_TWO(x) (x>=2?1:0)

/* Decoding flags (dflags) used in several decoding functions.
 *  DECODE_FLAG_HAVE_TAG: The provided buffer includes a tag
 *  DECODE_FLAG_CONSTRUCTED: The provided buffer is of indefinite encoding (useful
 *                           when no tags are present).
 *  DECODE_FLAG_LEVEL1: Internal flag to indicate a level of recursion for BER strings.
 *  DECODE_FLAG_LEVEL2: Internal flag to indicate two levels of recursion for BER strings.
 *  DECODE_FLAG_LEVEL3: Internal flag to indicate three levels of recursion for BER strings.
 *                      This is the maximum levels of recursion possible to prevent stack
 *                      exhaustion.
 */

#define DECODE_FLAG_HAVE_TAG 1
#define DECODE_FLAG_CONSTRUCTED (1<<1)
#define DECODE_FLAG_LEVEL1 (1<<2)
#define DECODE_FLAG_LEVEL2 (1<<3)
#define DECODE_FLAG_LEVEL3 (1<<4)

#define DECR_LEN(l, s) do { \
	  l -= s; \
	  if (l < 0) { \
	    warn(); \
	    result = ASN1_DER_ERROR; \
	    goto cleanup; \
	  } \
	} while (0)

static int
_asn1_get_indefinite_length_string (const unsigned char *der, int der_len,
				    int *len);

static int
_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
			 unsigned int _der_len, unsigned char **str,
			 unsigned int *str_len, unsigned int *ber_len,
			 unsigned dflags);

static int
_asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
			 unsigned int _der_len, const unsigned char **str,
			 unsigned int *str_len, unsigned dflags);

static void
_asn1_error_description_tag_error (asn1_node node, char *ErrorDescription)
{

  Estrcpy (ErrorDescription, ":: tag error near element '");
  _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
			   ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
  Estrcat (ErrorDescription, "'");

}

/**
 * asn1_get_length_der:
 * @der: DER data to decode.
 * @der_len: Length of DER data to decode.
 * @len: Output variable containing the length of the DER length field.
 *
 * Extract a length field from DER data.
 *
 * Returns: Return the decoded length value, or -1 on indefinite
 *   length, or -2 when the value was too big to fit in a int, or -4
 *   when the decoded length value plus @len would exceed @der_len.
 **/
long
asn1_get_length_der (const unsigned char *der, int der_len, int *len)
{
  unsigned int ans;
  int k, punt, sum;

  *len = 0;
  if (der_len <= 0)
    return 0;

  if (!(der[0] & 128))
    {
      /* short form */
      *len = 1;
      ans = der[0];
    }
  else
    {
      /* Long form */
      k = der[0] & 0x7F;
      punt = 1;
      if (k)
	{			/* definite length method */
	  ans = 0;
	  while (punt <= k && punt < der_len)
	    {
	      if (INT_MULTIPLY_OVERFLOW (ans, 256))
		return -2;
	      ans *= 256;

	      if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt])))
		return -2;
	      ans += der[punt];
	      punt++;
	    }
	}
      else
	{			/* indefinite length method */
	  *len = punt;
	  return -1;
	}

      *len = punt;
    }

  sum = ans;
  if (ans >= INT_MAX || INT_ADD_OVERFLOW (sum, (*len)))
    return -2;
  sum += *len;

  if (sum > der_len)
    return -4;

  return ans;
}

/**
 * asn1_get_tag_der:
 * @der: DER data to decode.
 * @der_len: Length of DER data to decode.
 * @cls: Output variable containing decoded class.
 * @len: Output variable containing the length of the DER TAG data.
 * @tag: Output variable containing the decoded tag (may be %NULL).
 *
 * Decode the class and TAG from DER code.
 *
 * Returns: Returns %ASN1_SUCCESS on success, or an error.
 **/
int
asn1_get_tag_der (const unsigned char *der, int der_len,
		  unsigned char *cls, int *len, unsigned long *tag)
{
  unsigned int ris;
  int punt;

  if (der == NULL || der_len < 2 || len == NULL)
    return ASN1_DER_ERROR;

  *cls = der[0] & 0xE0;
  if ((der[0] & 0x1F) != 0x1F)
    {
      /* short form */
      *len = 1;
      ris = der[0] & 0x1F;
    }
  else
    {
      /* Long form */
      punt = 1;
      ris = 0;
      while (punt < der_len && der[punt] & 128)
	{

	  if (INT_MULTIPLY_OVERFLOW (ris, 128))
	    return ASN1_DER_ERROR;
	  ris *= 128;

	  if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
	    return ASN1_DER_ERROR;
	  ris += (der[punt] & 0x7F);
	  punt++;
	}

      if (punt >= der_len)
	return ASN1_DER_ERROR;

      if (INT_MULTIPLY_OVERFLOW (ris, 128))
	return ASN1_DER_ERROR;
      ris *= 128;

      if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
	return ASN1_DER_ERROR;
      ris += (der[punt] & 0x7F);
      punt++;

      *len = punt;
    }

  if (tag)
    *tag = ris;
  return ASN1_SUCCESS;
}

/**
 * asn1_get_length_ber:
 * @ber: BER data to decode.
 * @ber_len: Length of BER data to decode.
 * @len: Output variable containing the length of the BER length field.
 *
 * Extract a length field from BER data.  The difference to
 * asn1_get_length_der() is that this function will return a length
 * even if the value has indefinite encoding.
 *
 * Returns: Return the decoded length value, or negative value when
 *   the value was too big.
 *
 * Since: 2.0
 **/
long
asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len)
{
  int ret;
  long err;

  ret = asn1_get_length_der (ber, ber_len, len);

  if (ret == -1 && ber_len > 1)
    {				/* indefinite length method */
      err = _asn1_get_indefinite_length_string (ber + 1, ber_len - 1, &ret);
      if (err != ASN1_SUCCESS)
	return -3;
    }

  return ret;
}

/**
 * asn1_get_octet_der:
 * @der: DER data to decode containing the OCTET SEQUENCE.
 * @der_len: The length of the @der data to decode.
 * @ret_len: Output variable containing the encoded length of the DER data.
 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
 * @str_size: Length of pre-allocated output buffer.
 * @str_len: Output variable containing the length of the contents of the OCTET SEQUENCE.
 *
 * Extract an OCTET SEQUENCE from DER data. Note that this function
 * expects the DER data past the tag field, i.e., the length and
 * content octets.
 *
 * Returns: Returns %ASN1_SUCCESS on success, or an error.
 **/
int
asn1_get_octet_der (const unsigned char *der, int der_len,
		    int *ret_len, unsigned char *str, int str_size,
		    int *str_len)
{
  int len_len = 0;

  if (der_len <= 0)
    return ASN1_GENERIC_ERROR;

  *str_len = asn1_get_length_der (der, der_len, &len_len);

  if (*str_len < 0)
    return ASN1_DER_ERROR;

  *ret_len = *str_len + len_len;
  if (str_size >= *str_len)
    {
      if (*str_len > 0 && str != NULL)
	memcpy (str, der + len_len, *str_len);
    }
  else
    {
      return ASN1_MEM_ERROR;
    }

  return ASN1_SUCCESS;
}


/*-
 * _asn1_get_time_der:
 * @type: %ASN1_ETYPE_GENERALIZED_TIME or %ASN1_ETYPE_UTC_TIME
 * @der: DER data to decode containing the time
 * @der_len: Length of DER data to decode.
 * @ret_len: Output variable containing the length of the DER data.
 * @str: Pre-allocated output buffer to put the textual time in.
 * @str_size: Length of pre-allocated output buffer.
 * @flags: Zero or %ASN1_DECODE_FLAG_STRICT_DER
 *
 * Performs basic checks in the DER encoded time object and returns its textual form.
 * The textual form will be in the YYYYMMDD000000Z format for GeneralizedTime
 * and YYMMDD000000Z for UTCTime.
 *
 * Returns: %ASN1_SUCCESS on success, or an error.
 -*/
static int
_asn1_get_time_der (unsigned type, const unsigned char *der, int der_len,
		    int *ret_len, char *str, int str_size, unsigned flags)
{
  int len_len, str_len;
  unsigned i;
  unsigned sign_count = 0;
  unsigned dot_count = 0;
  const unsigned char *p;

  if (der_len <= 0 || str == NULL)
    return ASN1_DER_ERROR;

  str_len = asn1_get_length_der (der, der_len, &len_len);
  if (str_len <= 0 || str_size < str_len)
    return ASN1_DER_ERROR;

  /* perform some sanity checks on the data */
  if (str_len < 8)
    {
      warn ();
      return ASN1_TIME_ENCODING_ERROR;
    }

  if ((flags & ASN1_DECODE_FLAG_STRICT_DER)
      && !(flags & ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME))
    {
      p = &der[len_len];
      for (i = 0; i < (unsigned) (str_len - 1); i++)
	{
	  if (c_isdigit (p[i]) == 0)
	    {
	      if (type == ASN1_ETYPE_GENERALIZED_TIME)
		{
		  /* tolerate lax encodings */
		  if (p[i] == '.' && dot_count == 0)
		    {
		      dot_count++;
		      continue;
		    }

		  /* This is not really valid DER, but there are
		   * structures using that */
		  if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) &&
		      (p[i] == '+' || p[i] == '-') && sign_count == 0)
		    {
		      sign_count++;
		      continue;
		    }
		}

	      warn ();
	      return ASN1_TIME_ENCODING_ERROR;
	    }
	}

      if (sign_count == 0 && p[str_len - 1] != 'Z')
	{
	  warn ();
	  return ASN1_TIME_ENCODING_ERROR;
	}
    }
  memcpy (str, der + len_len, str_len);
  str[str_len] = 0;
  *ret_len = str_len + len_len;

  return ASN1_SUCCESS;
}

/**
 * asn1_get_object_id_der:
 * @der: DER data to decode containing the OBJECT IDENTIFIER
 * @der_len: Length of DER data to decode.
 * @ret_len: Output variable containing the length of the DER data.
 * @str: Pre-allocated output buffer to put the textual object id in.
 * @str_size: Length of pre-allocated output buffer.
 *
 * Converts a DER encoded object identifier to its textual form. This
 * function expects the DER object identifier without the tag.
 *
 * Returns: %ASN1_SUCCESS on success, or an error.
 **/
int
asn1_get_object_id_der (const unsigned char *der, int der_len, int *ret_len,
			char *str, int str_size)
{
  int len_len, len, k;
  int leading, parsed;
  char temp[LTOSTR_MAX_SIZE];
  uint64_t val, val1, val0;

  *ret_len = 0;
  if (str && str_size > 0)
    str[0] = 0;			/* no oid */

  if (str == NULL || der_len <= 0)
    return ASN1_GENERIC_ERROR;

  len = asn1_get_length_der (der, der_len, &len_len);

  if (len <= 0 || len + len_len > der_len)
    return ASN1_DER_ERROR;

  /* leading octet can never be 0x80 */
  if (der[len_len] == 0x80)
    return ASN1_DER_ERROR;

  val0 = 0;

  for (k = 0; k < len; k++)
    {
      if (INT_LEFT_SHIFT_OVERFLOW (val0, 7))
	return ASN1_DER_ERROR;

      val0 <<= 7;
      val0 |= der[len_len + k] & 0x7F;
      if (!(der[len_len + k] & 0x80))
	break;
    }
  parsed = ++k;

  /* val0 = (X*40) + Y, X={0,1,2}, Y<=39 when X={0,1} */
  /* X = val, Y = val1 */

  /* check if X == 0  */
  val = 0;
  val1 = val0;
  if (val1 > 39)
    {
      val = 1;
      val1 = val0 - 40;
      if (val1 > 39)
	{
	  val = 2;
	  val1 = val0 - 80;
	}
    }

  _asn1_str_cpy (str, str_size, _asn1_ltostr (val, temp));
  _asn1_str_cat (str, str_size, ".");
  _asn1_str_cat (str, str_size, _asn1_ltostr (val1, temp));

  val = 0;
  leading = 1;
  for (k = parsed; k < len; k++)
    {
      /* X.690 mandates that the leading byte must never be 0x80
       */
      if (leading != 0 && der[len_len + k] == 0x80)
	return ASN1_DER_ERROR;
      leading = 0;

      /* check for wrap around */
      if (INT_LEFT_SHIFT_OVERFLOW (val, 7))
	return ASN1_DER_ERROR;

      val = val << 7;
      val |= der[len_len + k] & 0x7F;

      if (!(der[len_len + k] & 0x80))
	{
	  _asn1_str_cat (str, str_size, ".");
	  _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
	  val = 0;
	  leading = 1;
	}
    }

  if (INT_ADD_OVERFLOW (len, len_len))
    return ASN1_DER_ERROR;

  *ret_len = len + len_len;

  return ASN1_SUCCESS;
}

/**
 * asn1_get_bit_der:
 * @der: DER data to decode containing the BIT SEQUENCE.
 * @der_len: Length of DER data to decode.
 * @ret_len: Output variable containing the length of the DER data.
 * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
 * @str_size: Length of pre-allocated output buffer.
 * @bit_len: Output variable containing the size of the BIT SEQUENCE.
 *
 * Extract a BIT SEQUENCE from DER data.
 *
 * Returns: %ASN1_SUCCESS on success, or an error.
 **/
int
asn1_get_bit_der (const unsigned char *der, int der_len,
		  int *ret_len, unsigned char *str, int str_size,
		  int *bit_len)
{
  int len_len = 0, len_byte;

  if (der_len <= 0)
    return ASN1_GENERIC_ERROR;

  len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
  if (len_byte < 0)
    return ASN1_DER_ERROR;

  *ret_len = len_byte + len_len + 1;
  *bit_len = len_byte * 8 - der[len_len];

  if (*bit_len < 0)
    return ASN1_DER_ERROR;

  if (str_size >= len_byte)
    {
      if (len_byte > 0 && str)
	memcpy (str, der + len_len + 1, len_byte);
    }
  else
    {
      return ASN1_MEM_ERROR;
    }

  return ASN1_SUCCESS;
}

/* tag_len: the total tag length (explicit+inner)
 * inner_tag_len: the inner_tag length
 */
static int
_asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
		       int *tag_len, int *inner_tag_len, unsigned flags)
{
  asn1_node p;
  int counter, len2, len3, is_tag_implicit;
  int result;
  unsigned long tag, tag_implicit = 0;
  unsigned char class, class2, class_implicit = 0;

  if (der_len <= 0)
    return ASN1_GENERIC_ERROR;

  counter = is_tag_implicit = 0;

  if (node->type & CONST_TAG)
    {
      p = node->down;
      while (p)
	{
	  if (type_field (p->type) == ASN1_ETYPE_TAG)
	    {
	      if (p->type & CONST_APPLICATION)
		class2 = ASN1_CLASS_APPLICATION;
	      else if (p->type & CONST_UNIVERSAL)
		class2 = ASN1_CLASS_UNIVERSAL;
	      else if (p->type & CONST_PRIVATE)
		class2 = ASN1_CLASS_PRIVATE;
	      else
		class2 = ASN1_CLASS_CONTEXT_SPECIFIC;

	      if (p->type & CONST_EXPLICIT)
		{
		  if (asn1_get_tag_der
		      (der + counter, der_len, &class, &len2,
		       &tag) != ASN1_SUCCESS)
		    return ASN1_DER_ERROR;

		  DECR_LEN (der_len, len2);
		  counter += len2;

		  if (flags & ASN1_DECODE_FLAG_STRICT_DER)
		    len3 =
		      asn1_get_length_der (der + counter, der_len, &len2);
		  else
		    len3 =
		      asn1_get_length_ber (der + counter, der_len, &len2);
		  if (len3 < 0)
		    return ASN1_DER_ERROR;

		  DECR_LEN (der_len, len2);
		  counter += len2;

		  if (!is_tag_implicit)
		    {
		      if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
			  (tag != strtoul ((char *) p->value, NULL, 10)))
			return ASN1_TAG_ERROR;
		    }
		  else
		    {		/* ASN1_TAG_IMPLICIT */
		      if ((class != class_implicit) || (tag != tag_implicit))
			return ASN1_TAG_ERROR;
		    }
		  is_tag_implicit = 0;
		}
	      else
		{		/* ASN1_TAG_IMPLICIT */
		  if (!is_tag_implicit)
		    {
		      if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
			  (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF)
			  || (type_field (node->type) == ASN1_ETYPE_SET)
			  || (type_field (node->type) == ASN1_ETYPE_SET_OF))
			class2 |= ASN1_CLASS_STRUCTURED;
		      class_implicit = class2;
		      tag_implicit = strtoul ((char *) p->value, NULL, 10);
		      is_tag_implicit = 1;
		    }
		}
	    }
	  p = p->right;
	}
    }

  if (is_tag_implicit)
    {
      if (asn1_get_tag_der
	  (der + counter, der_len, &class, &len2, &tag) != ASN1_SUCCESS)
	return ASN1_DER_ERROR;

      DECR_LEN (der_len, len2);

      if ((class != class_implicit) || (tag != tag_implicit))
	{
	  if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING)
	    {
	      class_implicit |= ASN1_CLASS_STRUCTURED;
	      if ((class != class_implicit) || (tag != tag_implicit))
		return ASN1_TAG_ERROR;
	    }
	  else
	    return ASN1_TAG_ERROR;
	}
    }
  else
    {
      unsigned type = type_field (node->type);
      if (type == ASN1_ETYPE_TAG)
	{
	  *tag_len = 0;
	  if (inner_tag_len)
	    *inner_tag_len = 0;
	  return ASN1_SUCCESS;
	}

      if (asn1_get_tag_der
	  (der + counter, der_len, &class, &len2, &tag) != ASN1_SUCCESS)
	return ASN1_DER_ERROR;

      DECR_LEN (der_len, len2);

      switch (type)
	{
	case ASN1_ETYPE_NULL:
	case ASN1_ETYPE_BOOLEAN:
	case ASN1_ETYPE_INTEGER:
	case ASN1_ETYPE_ENUMERATED:
	case ASN1_ETYPE_OBJECT_ID:
	case ASN1_ETYPE_GENERALSTRING:
	case ASN1_ETYPE_NUMERIC_STRING:
	case ASN1_ETYPE_IA5_STRING:
	case ASN1_ETYPE_TELETEX_STRING:
	case ASN1_ETYPE_PRINTABLE_STRING:
	case ASN1_ETYPE_UNIVERSAL_STRING:
	case ASN1_ETYPE_BMP_STRING:
	case ASN1_ETYPE_UTF8_STRING:
	case ASN1_ETYPE_VISIBLE_STRING:
	case ASN1_ETYPE_BIT_STRING:
	case ASN1_ETYPE_SEQUENCE:
	case ASN1_ETYPE_SEQUENCE_OF:
	case ASN1_ETYPE_SET:
	case ASN1_ETYPE_SET_OF:
	case ASN1_ETYPE_GENERALIZED_TIME:
	case ASN1_ETYPE_UTC_TIME:
	  if ((class != _asn1_tags[type].class)
	      || (tag != _asn1_tags[type].tag))
	    return ASN1_DER_ERROR;
	  break;

	case ASN1_ETYPE_OCTET_STRING:
	  /* OCTET STRING is handled differently to allow
	   * BER encodings (structured class). */
	  if (((class != ASN1_CLASS_UNIVERSAL)
	       && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
	      || (tag != ASN1_TAG_OCTET_STRING))
	    return ASN1_DER_ERROR;
	  break;
	case ASN1_ETYPE_ANY:
	  counter -= len2;
	  break;
	case ASN1_ETYPE_CHOICE:
	  counter -= len2;
	  break;
	default:
	  return ASN1_DER_ERROR;
	  break;
	}
    }

  counter += len2;
  *tag_len = counter;
  if (inner_tag_len)
    *inner_tag_len = len2;
  return ASN1_SUCCESS;

cleanup:
  return result;
}

static int
extract_tag_der_recursive (asn1_node node, const unsigned char *der,
			   int der_len, int *ret_len, int *inner_len,
			   unsigned flags)
{
  asn1_node p;
  int ris = ASN1_DER_ERROR;

  if (type_field (node->type) == ASN1_ETYPE_CHOICE)
    {
      p = node->down;
      while (p)
	{
	  ris =
	    _asn1_extract_tag_der (p, der, der_len, ret_len, inner_len,
				   flags);
	  if (ris == ASN1_SUCCESS)
	    break;
	  p = p->right;
	}

      *ret_len = 0;
      return ris;
    }
  else
    return _asn1_extract_tag_der (node, der, der_len, ret_len, inner_len,
				  flags);
}

static int
_asn1_delete_not_used (asn1_node node)
{
  asn1_node p, p2;

  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  p = node;
  while (p)
    {
      if (p->type & CONST_NOT_USED)
	{
	  p2 = NULL;
	  if (p != node)
	    {
	      p2 = _asn1_find_left (p);
	      if (!p2)
		p2 = _asn1_find_up (p);
	    }
	  asn1_delete_structure (&p);
	  p = p2;
	}

      if (!p)
	break;			/* reach node */

      if (p->down)
	{
	  p = p->down;
	}
      else
	{
	  if (p == node)
	    p = NULL;
	  else if (p->right)
	    p = p->right;
	  else
	    {
	      while (1)
		{
		  p = _asn1_find_up (p);
		  if (p == node)
		    {
		      p = NULL;
		      break;
		    }
		  if (p->right)
		    {
		      p = p->right;
		      break;
		    }
		}
	    }
	}
    }
  return ASN1_SUCCESS;
}

static int
_asn1_get_indefinite_length_string (const unsigned char *der,
				    int der_len, int *len)
{
  int len2, len3, counter, indefinite;
  int result;
  unsigned long tag;
  unsigned char class;

  counter = indefinite = 0;

  while (1)
    {
      if (HAVE_TWO (der_len) && (der[counter] == 0)
	  && (der[counter + 1] == 0))
	{
	  counter += 2;
	  DECR_LEN (der_len, 2);

	  indefinite--;
	  if (indefinite <= 0)
	    break;
	  else
	    continue;
	}

      if (asn1_get_tag_der
	  (der + counter, der_len, &class, &len2, &tag) != ASN1_SUCCESS)
	return ASN1_DER_ERROR;

      DECR_LEN (der_len, len2);
      counter += len2;

      len2 = asn1_get_length_der (der + counter, der_len, &len3);
      if (len2 < -1)
	return ASN1_DER_ERROR;

      if (len2 == -1)
	{
	  indefinite++;
	  counter += 1;
	  DECR_LEN (der_len, 1);
	}
      else
	{
	  counter += len2 + len3;
	  DECR_LEN (der_len, len2 + len3);
	}
    }

  *len = counter;
  return ASN1_SUCCESS;

cleanup:
  return result;
}

static void
delete_unneeded_choice_fields (asn1_node p)
{
  asn1_node p2;

  while (p->right)
    {
      p2 = p->right;
      asn1_delete_structure (&p2);
    }
}


/**
 * asn1_der_decoding2
 * @element: pointer to an ASN1 structure.
 * @ider: vector that contains the DER encoding.
 * @max_ider_len: pointer to an integer giving the information about the
 *   maximal number of bytes occupied by *@ider. The real size of the DER
 *   encoding is returned through this pointer.
 * @flags: flags controlling the behaviour of the function.
 * @errorDescription: null-terminated string contains details when an
 *   error occurred.
 *
 * Fill the structure *@element with values of a DER encoding string. The
 * structure must just be created with function asn1_create_element().
 *
 * If %ASN1_DECODE_FLAG_ALLOW_PADDING flag is set then the function will ignore
 * padding after the decoded DER data. Upon a successful return the value of
 * *@max_ider_len will be set to the number of bytes decoded.
 *
 * If %ASN1_DECODE_FLAG_STRICT_DER flag is set then the function will
 * not decode any BER-encoded elements.
 *
 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
 *   if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or
 *   %ASN1_DER_ERROR if the der encoding doesn't match the structure
 *   name (*@ELEMENT deleted).
 **/
int
asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len,
		    unsigned int flags, char *errorDescription)
{
  asn1_node node, p, p2, p3;
  char temp[128];
  int counter, len2, len3, len4, move, ris, tlen;
  struct node_tail_cache_st tcache = { NULL, NULL };
  unsigned char class;
  unsigned long tag;
  int tag_len;
  int indefinite, result, total_len = *max_ider_len, ider_len = *max_ider_len;
  int inner_tag_len;
  unsigned char *ptmp;
  const unsigned char *ptag;
  const unsigned char *der = ider;

  node = *element;

  if (errorDescription != NULL)
    errorDescription[0] = 0;

  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  if (node->type & CONST_OPTION)
    {
      result = ASN1_GENERIC_ERROR;
      warn ();
      goto cleanup;
    }

  counter = 0;
  move = DOWN;
  p = node;
  while (1)
    {
      tag_len = 0;
      inner_tag_len = 0;
      ris = ASN1_SUCCESS;
      if (move != UP)
	{
	  if (p->type & CONST_SET)
	    {
	      p2 = _asn1_find_up (p);
	      len2 = p2->tmp_ival;
	      if (len2 == -1)
		{
		  if (HAVE_TWO (ider_len) && !der[counter]
		      && !der[counter + 1])
		    {
		      p = p2;
		      move = UP;
		      counter += 2;
		      DECR_LEN (ider_len, 2);
		      continue;
		    }
		}
	      else if (counter == len2)
		{
		  p = p2;
		  move = UP;
		  continue;
		}
	      else if (counter > len2)
		{
		  result = ASN1_DER_ERROR;
		  warn ();
		  goto cleanup;
		}
	      p2 = p2->down;
	      while (p2)
		{
		  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
		    {
		      ris =
			extract_tag_der_recursive (p2, der + counter,
						   ider_len, &len2, NULL,
						   flags);
		      if (ris == ASN1_SUCCESS)
			{
			  p2->type &= ~CONST_NOT_USED;
			  p = p2;
			  break;
			}
		    }
		  p2 = p2->right;
		}
	      if (p2 == NULL)
		{
		  result = ASN1_DER_ERROR;
		  warn ();
		  goto cleanup;
		}
	    }

	  /* the position in the DER structure this starts */
	  p->start = counter;
	  p->end = total_len - 1;

	  if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
	    {
	      p2 = _asn1_find_up (p);
	      len2 = p2->tmp_ival;
	      if (counter == len2)
		{
		  if (p->right)
		    {
		      p2 = p->right;
		      move = RIGHT;
		    }
		  else
		    move = UP;

		  if (p->type & CONST_OPTION)
		    asn1_delete_structure (&p);

		  p = p2;
		  continue;
		}
	    }

	  if (type_field (p->type) == ASN1_ETYPE_CHOICE)
	    {
	      while (p->down)
		{
		  ris =
		    extract_tag_der_recursive (p->down, der + counter,
					       ider_len, &len2, NULL, flags);

		  if (ris == ASN1_SUCCESS)
		    {
		      delete_unneeded_choice_fields (p->down);
		      break;
		    }
		  else if (ris == ASN1_ERROR_TYPE_ANY)
		    {
		      result = ASN1_ERROR_TYPE_ANY;
		      warn ();
		      goto cleanup;
		    }
		  else
		    {
		      p2 = p->down;
		      asn1_delete_structure (&p2);
		    }
		}

	      if (p->down == NULL)
		{
		  if (!(p->type & CONST_OPTION))
		    {
		      result = ASN1_DER_ERROR;
		      warn ();
		      goto cleanup;
		    }
		}
	      else if (type_field (p->type) != ASN1_ETYPE_CHOICE)
		p = p->down;

	      p->start = counter;
	    }

	  if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
	    {
	      p2 = _asn1_find_up (p);
	      len2 = p2->tmp_ival;

	      if ((len2 != -1) && (counter > len2))
		ris = ASN1_TAG_ERROR;
	    }

	  if (ris == ASN1_SUCCESS)
	    ris =
	      extract_tag_der_recursive (p, der + counter, ider_len,
					 &tag_len, &inner_tag_len, flags);

	  if (ris != ASN1_SUCCESS)
	    {
	      if (p->type & CONST_OPTION)
		{
		  p->type |= CONST_NOT_USED;
		  move = RIGHT;
		}
	      else if (p->type & CONST_DEFAULT)
		{
		  _asn1_set_value (p, NULL, 0);
		  move = RIGHT;
		}
	      else
		{
		  if (errorDescription != NULL)
		    _asn1_error_description_tag_error (p, errorDescription);

		  result = ASN1_TAG_ERROR;
		  warn ();
		  goto cleanup;
		}
	    }
	  else
	    {
	      DECR_LEN (ider_len, tag_len);
	      counter += tag_len;
	    }
	}

      if (ris == ASN1_SUCCESS)
	{
	  switch (type_field (p->type))
	    {
	    case ASN1_ETYPE_NULL:
	      DECR_LEN (ider_len, 1);
	      if (der[counter])
		{
		  result = ASN1_DER_ERROR;
		  warn ();
		  goto cleanup;
		}
	      counter++;
	      move = RIGHT;
	      break;
	    case ASN1_ETYPE_BOOLEAN:
	      DECR_LEN (ider_len, 2);

	      if (der[counter++] != 1)
		{
		  result = ASN1_DER_ERROR;
		  warn ();
		  goto cleanup;
		}
	      if (der[counter++] == 0)
		_asn1_set_value (p, "F", 1);
	      else
		_asn1_set_value (p, "T", 1);
	      move = RIGHT;
	      break;
	    case ASN1_ETYPE_INTEGER:
	    case ASN1_ETYPE_ENUMERATED:
	      len2 = asn1_get_length_der (der + counter, ider_len, &len3);
	      if (len2 < 0)
		{
		  result = ASN1_DER_ERROR;
		  warn ();
		  goto cleanup;
		}

	      DECR_LEN (ider_len, len3 + len2);

	      _asn1_set_value (p, der + counter, len3 + len2);
	      counter += len3 + len2;
	      move = RIGHT;
	      break;
	    case ASN1_ETYPE_OBJECT_ID:
	      result =
		asn1_get_object_id_der (der + counter, ider_len, &len2,
					temp, sizeof (temp));
	      if (result != ASN1_SUCCESS)
		{
		  warn ();
		  goto cleanup;
		}

	      DECR_LEN (ider_len, len2);

	      tlen = strlen (temp);
	      if (tlen > 0)
		_asn1_set_value (p, temp, tlen + 1);

	      counter += len2;
	      move = RIGHT;
	      break;
	    case ASN1_ETYPE_GENERALIZED_TIME:
	    case ASN1_ETYPE_UTC_TIME:
	      result =
		_asn1_get_time_der (type_field (p->type), der + counter,
				    ider_len, &len2, temp, sizeof (temp) - 1,
				    flags);
	      if (result != ASN1_SUCCESS)
		{
		  warn ();
		  goto cleanup;
		}

	      DECR_LEN (ider_len, len2);

	      tlen = strlen (temp);
	      if (tlen > 0)
		_asn1_set_value (p, temp, tlen);

	      counter += len2;
	      move = RIGHT;
	      break;
	    case ASN1_ETYPE_OCTET_STRING:
	      if (counter < inner_tag_len)
		{
		  result = ASN1_DER_ERROR;
		  warn ();
		  goto cleanup;
		}

	      ptag = der + counter - inner_tag_len;
	      if ((flags & ASN1_DECODE_FLAG_STRICT_DER)
		  || !(ptag[0] & ASN1_CLASS_STRUCTURED))
		{
		  if (ptag[0] & ASN1_CLASS_STRUCTURED)
		    {
		      result = ASN1_DER_ERROR;
		      warn ();
		      goto cleanup;
		    }

		  len2 = asn1_get_length_der (der + counter, ider_len, &len3);
		  if (len2 < 0)
		    {
		      result = ASN1_DER_ERROR;
		      warn ();
		      goto cleanup;
		    }

		  DECR_LEN (ider_len, len3 + len2);

		  _asn1_set_value (p, der + counter, len3 + len2);
		  counter += len3 + len2;
		}
	      else
		{
		  unsigned dflags = 0, vlen, ber_len;

		  if (ptag[0] & ASN1_CLASS_STRUCTURED)
		    dflags |= DECODE_FLAG_CONSTRUCTED;

		  result =
		    _asn1_decode_simple_ber (type_field (p->type),
					     der + counter, ider_len, &ptmp,
					     &vlen, &ber_len, dflags);
		  if (result != ASN1_SUCCESS)
		    {
		      warn ();
		      goto cleanup;
		    }

		  DECR_LEN (ider_len, ber_len);

		  _asn1_set_value_lv (p, ptmp, vlen);

		  counter += ber_len;
		  free (ptmp);
		}
	      move = RIGHT;
	      break;
	    case ASN1_ETYPE_GENERALSTRING:
	    case ASN1_ETYPE_NUMERIC_STRING:
	    case ASN1_ETYPE_IA5_STRING:
	    case ASN1_ETYPE_TELETEX_STRING:
	    case ASN1_ETYPE_PRINTABLE_STRING:
	    case ASN1_ETYPE_UNIVERSAL_STRING:
	    case ASN1_ETYPE_BMP_STRING:
	    case ASN1_ETYPE_UTF8_STRING:
	    case ASN1_ETYPE_VISIBLE_STRING:
	    case ASN1_ETYPE_BIT_STRING:
	      len2 = asn1_get_length_der (der + counter, ider_len, &len3);
	      if (len2 < 0)
		{
		  result = ASN1_DER_ERROR;
		  warn ();
		  goto cleanup;
		}

	      DECR_LEN (ider_len, len3 + len2);

	      _asn1_set_value (p, der + counter, len3 + len2);
	      counter += len3 + len2;
	      move = RIGHT;
	      break;
	    case ASN1_ETYPE_SEQUENCE:
	    case ASN1_ETYPE_SET:
	      if (move == UP)
		{
		  len2 = p->tmp_ival;
		  p->tmp_ival = 0;
		  if (len2 == -1)
		    {		/* indefinite length method */
		      DECR_LEN (ider_len, 2);
		      if ((der[counter]) || der[counter + 1])
			{
			  result = ASN1_DER_ERROR;
			  warn ();
			  goto cleanup;
			}
		      counter += 2;
		    }
		  else
		    {		/* definite length method */
		      if (len2 != counter)
			{
			  result = ASN1_DER_ERROR;
			  warn ();
			  goto cleanup;
			}
		    }
		  move = RIGHT;
		}
	      else
		{		/* move==DOWN || move==RIGHT */
		  len3 = asn1_get_length_der (der + counter, ider_len, &len2);
		  if (IS_ERR (len3, flags))
		    {
		      result = ASN1_DER_ERROR;
		      warn ();
		      goto cleanup;
		    }

		  DECR_LEN (ider_len, len2);
		  counter += len2;

		  if (len3 > 0)
		    {
		      p->tmp_ival = counter + len3;
		      move = DOWN;
		    }
		  else if (len3 == 0)
		    {
		      p2 = p->down;
		      while (p2)
			{
			  if (type_field (p2->type) != ASN1_ETYPE_TAG)
			    {
			      p3 = p2->right;
			      asn1_delete_structure (&p2);
			      p2 = p3;
			    }
			  else
			    p2 = p2->right;
			}
		      move = RIGHT;
		    }
		  else
		    {		/* indefinite length method */
		      p->tmp_ival = -1;
		      move = DOWN;
		    }
		}
	      break;
	    case ASN1_ETYPE_SEQUENCE_OF:
	    case ASN1_ETYPE_SET_OF:
	      if (move == UP)
		{
		  len2 = p->tmp_ival;
		  if (len2 == -1)
		    {		/* indefinite length method */
		      if (!HAVE_TWO (ider_len)
			  || ((der[counter]) || der[counter + 1]))
			{
			  result = _asn1_append_sequence_set (p, &tcache);
			  if (result != 0)
			    {
			      warn ();
			      goto cleanup;
			    }
			  p = tcache.tail;
			  move = RIGHT;
			  continue;
			}

		      p->tmp_ival = 0;
		      tcache.tail = NULL;	/* finished decoding this structure */
		      tcache.head = NULL;
		      DECR_LEN (ider_len, 2);
		      counter += 2;
		    }
		  else
		    {		/* definite length method */
		      if (len2 > counter)
			{
			  result = _asn1_append_sequence_set (p, &tcache);
			  if (result != 0)
			    {
			      warn ();
			      goto cleanup;
			    }
			  p = tcache.tail;
			  move = RIGHT;
			  continue;
			}

		      p->tmp_ival = 0;
		      tcache.tail = NULL;	/* finished decoding this structure */
		      tcache.head = NULL;

		      if (len2 != counter)
			{
			  result = ASN1_DER_ERROR;
			  warn ();
			  goto cleanup;
			}
		    }
		}
	      else
		{		/* move==DOWN || move==RIGHT */
		  len3 = asn1_get_length_der (der + counter, ider_len, &len2);
		  if (IS_ERR (len3, flags))
		    {
		      result = ASN1_DER_ERROR;
		      warn ();
		      goto cleanup;
		    }

		  DECR_LEN (ider_len, len2);
		  counter += len2;
		  if (len3)
		    {
		      if (len3 > 0)
			{	/* definite length method */
			  p->tmp_ival = counter + len3;
			}
		      else
			{	/* indefinite length method */
			  p->tmp_ival = -1;
			}

		      p2 = p->down;
		      if (p2 == NULL)
			{
			  result = ASN1_DER_ERROR;
			  warn ();
			  goto cleanup;
			}

		      while ((type_field (p2->type) == ASN1_ETYPE_TAG)
			     || (type_field (p2->type) == ASN1_ETYPE_SIZE))
			p2 = p2->right;
		      if (p2->right == NULL)
			{
			  result = _asn1_append_sequence_set (p, &tcache);
			  if (result != 0)
			    {
			      warn ();
			      goto cleanup;
			    }
			}
		      p = p2;
		    }
		}
	      move = RIGHT;
	      break;
	    case ASN1_ETYPE_ANY:
	      /* Check indefinite length method in an EXPLICIT TAG */

	      if (!(flags & ASN1_DECODE_FLAG_STRICT_DER)
		  && (p->type & CONST_TAG) && tag_len == 2
		  && (der[counter - 1] == 0x80))
		indefinite = 1;
	      else
		indefinite = 0;

	      if (asn1_get_tag_der
		  (der + counter, ider_len, &class, &len2,
		   &tag) != ASN1_SUCCESS)
		{
		  result = ASN1_DER_ERROR;
		  warn ();
		  goto cleanup;
		}

	      DECR_LEN (ider_len, len2);

	      len4 =
		asn1_get_length_der (der + counter + len2, ider_len, &len3);
	      if (IS_ERR (len4, flags))
		{
		  result = ASN1_DER_ERROR;
		  warn ();
		  goto cleanup;
		}
	      if (len4 != -1)	/* definite */
		{
		  len2 += len4;

		  DECR_LEN (ider_len, len4 + len3);
		  _asn1_set_value_lv (p, der + counter, len2 + len3);
		  counter += len2 + len3;
		}
	      else		/* == -1 */
		{		/* indefinite length */
		  ider_len += len2;	/* undo DECR_LEN */

		  if (counter == 0)
		    {
		      result = ASN1_DER_ERROR;
		      warn ();
		      goto cleanup;
		    }

		  result =
		    _asn1_get_indefinite_length_string (der + counter,
							ider_len, &len2);
		  if (result != ASN1_SUCCESS)
		    {
		      warn ();
		      goto cleanup;
		    }

		  DECR_LEN (ider_len, len2);
		  _asn1_set_value_lv (p, der + counter, len2);
		  counter += len2;

		}

	      /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
	         an indefinite length method. */
	      if (indefinite)
		{
		  DECR_LEN (ider_len, 2);
		  if (!der[counter] && !der[counter + 1])
		    {
		      counter += 2;
		    }
		  else
		    {
		      result = ASN1_DER_ERROR;
		      warn ();
		      goto cleanup;
		    }
		}

	      move = RIGHT;
	      break;
	    default:
	      move = (move == UP) ? RIGHT : DOWN;
	      break;
	    }
	}

      if (p)
	{
	  p->end = counter - 1;
	}

      if (p == node && move != DOWN)
	break;

      if (move == DOWN)
	{
	  if (p->down)
	    p = p->down;
	  else
	    move = RIGHT;
	}
      if ((move == RIGHT) && !(p->type & CONST_SET))
	{
	  if (p->right)
	    p = p->right;
	  else
	    move = UP;
	}
      if (move == UP)
	{
	  /* If we are parsing a sequence or set and p is a direct
	     child of it, no need to traverse the list back to the leftmost node. */
	  if (tcache.tail == p)
	    p = tcache.head;
	  else
	    p = _asn1_find_up (p);
	}
    }

  _asn1_delete_not_used (*element);

  if ((ider_len < 0) ||
      (!(flags & ASN1_DECODE_FLAG_ALLOW_PADDING) && (ider_len != 0)))
    {
      warn ();
      result = ASN1_DER_ERROR;
      goto cleanup;
    }

  *max_ider_len = total_len - ider_len;

  return ASN1_SUCCESS;

cleanup:
  asn1_delete_structure (element);
  return result;
}


/**
 * asn1_der_decoding:
 * @element: pointer to an ASN1 structure.
 * @ider: vector that contains the DER encoding.
 * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1].
 * @errorDescription: null-terminated string contains details when an
 *   error occurred.
 *
 * Fill the structure *@element with values of a DER encoding
 * string. The structure must just be created with function
 * asn1_create_element().
 *
 * Note that the *@element variable is provided as a pointer for
 * historical reasons.
 *
 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
 *   if @ELEMENT is %NULL, and %ASN1_TAG_ERROR or
 *   %ASN1_DER_ERROR if the der encoding doesn't match the structure
 *   name (*@ELEMENT deleted).
 **/
int
asn1_der_decoding (asn1_node *element, const void *ider, int ider_len,
		   char *errorDescription)
{
  return asn1_der_decoding2 (element, ider, &ider_len, 0, errorDescription);
}

/**
 * asn1_der_decoding_element:
 * @structure: pointer to an ASN1 structure
 * @elementName: name of the element to fill
 * @ider: vector that contains the DER encoding of the whole structure.
 * @len: number of bytes of *der: der[0]..der[len-1]
 * @errorDescription: null-terminated string contains details when an
 *   error occurred.
 *
 * Fill the element named @ELEMENTNAME with values of a DER encoding
 * string.  The structure must just be created with function
 * asn1_create_element().  The DER vector must contain the encoding
 * string of the whole @STRUCTURE.  If an error occurs during the
 * decoding procedure, the *@STRUCTURE is deleted and set equal to
 * %NULL.
 *
 * This function is deprecated and may just be an alias to asn1_der_decoding
 * in future versions. Use asn1_der_decoding() instead.
 *
 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
 *   if ELEMENT is %NULL or @elementName == NULL, and
 *   %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding doesn't
 *   match the structure @structure (*ELEMENT deleted).
 **/
int
asn1_der_decoding_element (asn1_node *structure, const char *elementName,
			   const void *ider, int len, char *errorDescription)
{
  return asn1_der_decoding (structure, ider, len, errorDescription);
}

/**
 * asn1_der_decoding_startEnd:
 * @element: pointer to an ASN1 element
 * @ider: vector that contains the DER encoding.
 * @ider_len: number of bytes of *@ider: @ider[0]..@ider[len-1]
 * @name_element: an element of NAME structure.
 * @start: the position of the first byte of NAME_ELEMENT decoding
 *   (@ider[*start])
 * @end: the position of the last byte of NAME_ELEMENT decoding
 *  (@ider[*end])
 *
 * Find the start and end point of an element in a DER encoding
 * string. I mean that if you have a der encoding and you have already
 * used the function asn1_der_decoding() to fill a structure, it may
 * happen that you want to find the piece of string concerning an
 * element of the structure.
 *
 * One example is the sequence "tbsCertificate" inside an X509
 * certificate.
 *
 * Note that since libtasn1 3.7 the @ider and @ider_len parameters
 * can be omitted, if the element is already decoded using asn1_der_decoding().
 *
 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
 *   if ELEMENT is %asn1_node EMPTY or @name_element is not a valid
 *   element, %ASN1_TAG_ERROR or %ASN1_DER_ERROR if the der encoding
 *   doesn't match the structure ELEMENT.
 **/
int
asn1_der_decoding_startEnd (asn1_node element, const void *ider, int ider_len,
			    const char *name_element, int *start, int *end)
{
  asn1_node node, node_to_find;
  int result = ASN1_DER_ERROR;

  node = element;

  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  node_to_find = asn1_find_node (node, name_element);

  if (node_to_find == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  *start = node_to_find->start;
  *end = node_to_find->end;

  if (*start == 0 && *end == 0)
    {
      if (ider == NULL || ider_len == 0)
	return ASN1_GENERIC_ERROR;

      /* it seems asn1_der_decoding() wasn't called before. Do it now */
      result = asn1_der_decoding (&node, ider, ider_len, NULL);
      if (result != ASN1_SUCCESS)
	{
	  warn ();
	  return result;
	}

      node_to_find = asn1_find_node (node, name_element);
      if (node_to_find == NULL)
	return ASN1_ELEMENT_NOT_FOUND;

      *start = node_to_find->start;
      *end = node_to_find->end;
    }

  if (*end < *start)
    return ASN1_GENERIC_ERROR;

  return ASN1_SUCCESS;
}

/**
 * asn1_expand_any_defined_by:
 * @definitions: ASN1 definitions
 * @element: pointer to an ASN1 structure
 *
 * Expands every "ANY DEFINED BY" element of a structure created from
 * a DER decoding process (asn1_der_decoding function). The element
 * ANY must be defined by an OBJECT IDENTIFIER. The type used to
 * expand the element ANY is the first one following the definition of
 * the actual value of the OBJECT IDENTIFIER.
 *
 * Returns: %ASN1_SUCCESS if Substitution OK, %ASN1_ERROR_TYPE_ANY if
 *   some "ANY DEFINED BY" element couldn't be expanded due to a
 *   problem in OBJECT_ID -> TYPE association, or other error codes
 *   depending on DER decoding.
 **/
int
asn1_expand_any_defined_by (asn1_node_const definitions, asn1_node *element)
{
  char name[2 * ASN1_MAX_NAME_SIZE + 2], value[ASN1_MAX_NAME_SIZE];
  int retCode = ASN1_SUCCESS, result;
  int len, len2, len3;
  asn1_node_const p2;
  asn1_node p, p3, aux = NULL;
  char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
  const char *definitionsName;

  if ((definitions == NULL) || (*element == NULL))
    return ASN1_ELEMENT_NOT_FOUND;

  definitionsName = definitions->name;

  p = *element;
  while (p)
    {

      switch (type_field (p->type))
	{
	case ASN1_ETYPE_ANY:
	  if ((p->type & CONST_DEFINED_BY) && (p->value))
	    {
	      /* search the "DEF_BY" element */
	      p2 = p->down;
	      while ((p2) && (type_field (p2->type) != ASN1_ETYPE_CONSTANT))
		p2 = p2->right;

	      if (!p2)
		{
		  retCode = ASN1_ERROR_TYPE_ANY;
		  break;
		}

	      p3 = _asn1_find_up (p);

	      if (!p3)
		{
		  retCode = ASN1_ERROR_TYPE_ANY;
		  break;
		}

	      p3 = p3->down;
	      while (p3)
		{
		  if (!(strcmp (p3->name, p2->name)))
		    break;
		  p3 = p3->right;
		}

	      if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
		  (p3->value == NULL))
		{

		  p3 = _asn1_find_up (p);
		  p3 = _asn1_find_up (p3);

		  if (!p3)
		    {
		      retCode = ASN1_ERROR_TYPE_ANY;
		      break;
		    }

		  p3 = p3->down;

		  while (p3)
		    {
		      if (!(strcmp (p3->name, p2->name)))
			break;
		      p3 = p3->right;
		    }

		  if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
		      || (p3->value == NULL))
		    {
		      retCode = ASN1_ERROR_TYPE_ANY;
		      break;
		    }
		}

	      /* search the OBJECT_ID into definitions */
	      p2 = definitions->down;
	      while (p2)
		{
		  if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
		      (p2->type & CONST_ASSIGN))
		    {
		      snprintf (name, sizeof (name), "%s.%s", definitionsName,
				p2->name);

		      len = ASN1_MAX_NAME_SIZE;
		      result =
			asn1_read_value (definitions, name, value, &len);

		      if ((result == ASN1_SUCCESS)
			  && (!_asn1_strcmp (p3->value, value)))
			{
			  p2 = p2->right;	/* pointer to the structure to
						   use for expansion */
			  while ((p2) && (p2->type & CONST_ASSIGN))
			    p2 = p2->right;

			  if (p2)
			    {
			      snprintf (name, sizeof (name), "%s.%s",
					definitionsName, p2->name);

			      result =
				asn1_create_element (definitions, name, &aux);
			      if (result == ASN1_SUCCESS)
				{
				  _asn1_cpy_name (aux, p);
				  len2 =
				    asn1_get_length_der (p->value,
							 p->value_len, &len3);
				  if (len2 < 0)
				    return ASN1_DER_ERROR;

				  result =
				    asn1_der_decoding (&aux, p->value + len3,
						       len2,
						       errorDescription);
				  if (result == ASN1_SUCCESS)
				    {

				      _asn1_set_right (aux, p->right);
				      _asn1_set_right (p, aux);

				      result = asn1_delete_structure (&p);
				      if (result == ASN1_SUCCESS)
					{
					  p = aux;
					  aux = NULL;
					  break;
					}
				      else
					{	/* error with asn1_delete_structure */
					  asn1_delete_structure (&aux);
					  retCode = result;
					  break;
					}
				    }
				  else
				    {	/* error with asn1_der_decoding */
				      retCode = result;
				      break;
				    }
				}
			      else
				{	/* error with asn1_create_element */
				  retCode = result;
				  break;
				}
			    }
			  else
			    {	/* error with the pointer to the structure to expand */
			      retCode = ASN1_ERROR_TYPE_ANY;
			      break;
			    }
			}
		    }
		  p2 = p2->right;
		}		/* end while */

	      if (!p2)
		{
		  retCode = ASN1_ERROR_TYPE_ANY;
		  break;
		}

	    }
	  break;
	default:
	  break;
	}


      if (p->down)
	{
	  p = p->down;
	}
      else if (p == *element)
	{
	  p = NULL;
	  break;
	}
      else if (p->right)
	p = p->right;
      else
	{
	  while (1)
	    {
	      p = _asn1_find_up (p);
	      if (p == *element)
		{
		  p = NULL;
		  break;
		}
	      if (p->right)
		{
		  p = p->right;
		  break;
		}
	    }
	}
    }

  return retCode;
}

/**
 * asn1_expand_octet_string:
 * @definitions: ASN1 definitions
 * @element: pointer to an ASN1 structure
 * @octetName: name of the OCTET STRING field to expand.
 * @objectName: name of the OBJECT IDENTIFIER field to use to define
 *    the type for expansion.
 *
 * Expands an "OCTET STRING" element of a structure created from a DER
 * decoding process (the asn1_der_decoding() function).  The type used
 * for expansion is the first one following the definition of the
 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
 *
 * Returns: %ASN1_SUCCESS if substitution OK, %ASN1_ELEMENT_NOT_FOUND
 *   if @objectName or @octetName are not correct,
 *   %ASN1_VALUE_NOT_VALID if it wasn't possible to find the type to
 *   use for expansion, or other errors depending on DER decoding.
 **/
int
asn1_expand_octet_string (asn1_node_const definitions, asn1_node *element,
			  const char *octetName, const char *objectName)
{
  char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
  int retCode = ASN1_SUCCESS, result;
  int len, len2, len3;
  asn1_node_const p2;
  asn1_node aux = NULL;
  asn1_node octetNode = NULL, objectNode = NULL;
  char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];

  if ((definitions == NULL) || (*element == NULL))
    return ASN1_ELEMENT_NOT_FOUND;

  octetNode = asn1_find_node (*element, octetName);
  if (octetNode == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING)
    return ASN1_ELEMENT_NOT_FOUND;
  if (octetNode->value == NULL)
    return ASN1_VALUE_NOT_FOUND;

  objectNode = asn1_find_node (*element, objectName);
  if (objectNode == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID)
    return ASN1_ELEMENT_NOT_FOUND;

  if (objectNode->value == NULL)
    return ASN1_VALUE_NOT_FOUND;


  /* search the OBJECT_ID into definitions */
  p2 = definitions->down;
  while (p2)
    {
      if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
	  (p2->type & CONST_ASSIGN))
	{
	  strcpy (name, definitions->name);
	  strcat (name, ".");
	  strcat (name, p2->name);

	  len = sizeof (value);
	  result = asn1_read_value (definitions, name, value, &len);

	  if ((result == ASN1_SUCCESS)
	      && (!_asn1_strcmp (objectNode->value, value)))
	    {

	      p2 = p2->right;	/* pointer to the structure to
				   use for expansion */
	      while ((p2) && (p2->type & CONST_ASSIGN))
		p2 = p2->right;

	      if (p2)
		{
		  strcpy (name, definitions->name);
		  strcat (name, ".");
		  strcat (name, p2->name);

		  result = asn1_create_element (definitions, name, &aux);
		  if (result == ASN1_SUCCESS)
		    {
		      _asn1_cpy_name (aux, octetNode);
		      len2 =
			asn1_get_length_der (octetNode->value,
					     octetNode->value_len, &len3);
		      if (len2 < 0)
			return ASN1_DER_ERROR;

		      result =
			asn1_der_decoding (&aux, octetNode->value + len3,
					   len2, errorDescription);
		      if (result == ASN1_SUCCESS)
			{

			  _asn1_set_right (aux, octetNode->right);
			  _asn1_set_right (octetNode, aux);

			  result = asn1_delete_structure (&octetNode);
			  if (result == ASN1_SUCCESS)
			    {
			      aux = NULL;
			      break;
			    }
			  else
			    {	/* error with asn1_delete_structure */
			      asn1_delete_structure (&aux);
			      retCode = result;
			      break;
			    }
			}
		      else
			{	/* error with asn1_der_decoding */
			  retCode = result;
			  break;
			}
		    }
		  else
		    {		/* error with asn1_create_element */
		      retCode = result;
		      break;
		    }
		}
	      else
		{		/* error with the pointer to the structure to expand */
		  retCode = ASN1_VALUE_NOT_VALID;
		  break;
		}
	    }
	}

      p2 = p2->right;

    }

  if (!p2)
    retCode = ASN1_VALUE_NOT_VALID;

  return retCode;
}

/*-
 * _asn1_decode_simple_der:
 * @etype: The type of the string to be encoded (ASN1_ETYPE_)
 * @der: the encoded string
 * @_der_len: the bytes of the encoded string
 * @str: a pointer to the data
 * @str_len: the length of the data
 * @dflags: DECODE_FLAG_*
 *
 * Decodes a simple DER encoded type (e.g. a string, which is not constructed).
 * The output is a pointer inside the @der.
 *
 * Returns: %ASN1_SUCCESS if successful or an error value.
 -*/
static int
_asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
			 unsigned int _der_len, const unsigned char **str,
			 unsigned int *str_len, unsigned dflags)
{
  int tag_len, len_len;
  const unsigned char *p;
  int der_len = _der_len;
  unsigned char class;
  unsigned long tag;
  long ret;

  if (der == NULL || der_len == 0)
    return ASN1_VALUE_NOT_VALID;

  if (ETYPE_OK (etype) == 0 || ETYPE_IS_STRING (etype) == 0)
    return ASN1_VALUE_NOT_VALID;

  /* doesn't handle constructed classes */
  class = ETYPE_CLASS (etype);
  if (class != ASN1_CLASS_UNIVERSAL)
    return ASN1_VALUE_NOT_VALID;

  p = der;

  if (dflags & DECODE_FLAG_HAVE_TAG)
    {
      ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
      if (ret != ASN1_SUCCESS)
	return ret;

      if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype))
	{
	  warn ();
	  return ASN1_DER_ERROR;
	}

      p += tag_len;
      der_len -= tag_len;
      if (der_len <= 0)
	return ASN1_DER_ERROR;
    }

  ret = asn1_get_length_der (p, der_len, &len_len);
  if (ret < 0)
    return ASN1_DER_ERROR;

  p += len_len;
  der_len -= len_len;
  if (der_len <= 0)
    return ASN1_DER_ERROR;

  *str_len = ret;
  *str = p;

  return ASN1_SUCCESS;
}

/**
 * asn1_decode_simple_der:
 * @etype: The type of the string to be encoded (ASN1_ETYPE_)
 * @der: the encoded string
 * @_der_len: the bytes of the encoded string
 * @str: a pointer to the data
 * @str_len: the length of the data
 *
 * Decodes a simple DER encoded type (e.g. a string, which is not constructed).
 * The output is a pointer inside the @der.
 *
 * Returns: %ASN1_SUCCESS if successful or an error value.
 **/
int
asn1_decode_simple_der (unsigned int etype, const unsigned char *der,
			unsigned int _der_len, const unsigned char **str,
			unsigned int *str_len)
{
  return _asn1_decode_simple_der (etype, der, _der_len, str, str_len,
				  DECODE_FLAG_HAVE_TAG);
}

static int
append (uint8_t **dst, unsigned *dst_size, const unsigned char *src,
	unsigned src_size)
{
  if (src_size == 0)
    return ASN1_SUCCESS;

  *dst = _asn1_realloc (*dst, *dst_size + src_size);
  if (*dst == NULL)
    return ASN1_MEM_ALLOC_ERROR;
  memcpy (*dst + *dst_size, src, src_size);
  *dst_size += src_size;
  return ASN1_SUCCESS;
}

/*-
 * _asn1_decode_simple_ber:
 * @etype: The type of the string to be encoded (ASN1_ETYPE_)
 * @der: the encoded string
 * @_der_len: the bytes of the encoded string
 * @str: a pointer to the data
 * @str_len: the length of the data
 * @ber_len: the total length occupied by BER (may be %NULL)
 * @have_tag: whether a DER tag is included
 *
 * Decodes a BER encoded type. The output is an allocated value
 * of the data. This decodes BER STRINGS only. Other types are
 * decoded as DER.
 *
 * Returns: %ASN1_SUCCESS if successful or an error value.
 -*/
static int
_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
			 unsigned int _der_len, unsigned char **str,
			 unsigned int *str_len, unsigned int *ber_len,
			 unsigned dflags)
{
  int tag_len, len_len;
  const unsigned char *p;
  int der_len = _der_len;
  uint8_t *total = NULL;
  unsigned total_size = 0;
  unsigned char class;
  unsigned long tag;
  unsigned char *out = NULL;
  const unsigned char *cout = NULL;
  unsigned out_len;
  long result;

  if (ber_len)
    *ber_len = 0;

  if (der == NULL || der_len == 0)
    {
      warn ();
      return ASN1_VALUE_NOT_VALID;
    }

  if (ETYPE_OK (etype) == 0)
    {
      warn ();
      return ASN1_VALUE_NOT_VALID;
    }

  /* doesn't handle constructed + definite classes */
  class = ETYPE_CLASS (etype);
  if (class != ASN1_CLASS_UNIVERSAL)
    {
      warn ();
      return ASN1_VALUE_NOT_VALID;
    }

  p = der;

  if (dflags & DECODE_FLAG_HAVE_TAG)
    {
      result = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
      if (result != ASN1_SUCCESS)
	{
	  warn ();
	  return result;
	}

      if (tag != ETYPE_TAG (etype))
	{
	  warn ();
	  return ASN1_DER_ERROR;
	}

      p += tag_len;

      DECR_LEN (der_len, tag_len);

      if (ber_len)
	*ber_len += tag_len;
    }

  /* indefinite constructed */
  if ((((dflags & DECODE_FLAG_CONSTRUCTED) || class == ASN1_CLASS_STRUCTURED)
       && ETYPE_IS_STRING (etype)) && !(dflags & DECODE_FLAG_LEVEL3))
    {
      if (der_len == 0)
	{
	  warn ();
	  result = ASN1_DER_ERROR;
	  goto cleanup;
	}

      if (der_len > 0 && p[0] == 0x80)	/* indefinite */
	{
	  len_len = 1;
	  DECR_LEN (der_len, len_len);
	  p += len_len;

	  if (ber_len)
	    *ber_len += len_len;

	  /* decode the available octet strings */
	  do
	    {
	      unsigned tmp_len;
	      unsigned flags = DECODE_FLAG_HAVE_TAG;

	      if (dflags & DECODE_FLAG_LEVEL1)
		flags |= DECODE_FLAG_LEVEL2;
	      else if (dflags & DECODE_FLAG_LEVEL2)
		flags |= DECODE_FLAG_LEVEL3;
	      else
		flags |= DECODE_FLAG_LEVEL1;

	      result =
		_asn1_decode_simple_ber (etype, p, der_len, &out, &out_len,
					 &tmp_len, flags);
	      if (result != ASN1_SUCCESS)
		{
		  warn ();
		  goto cleanup;
		}

	      p += tmp_len;
	      DECR_LEN (der_len, tmp_len);

	      if (ber_len)
		*ber_len += tmp_len;

	      DECR_LEN (der_len, 2);	/* we need the EOC */

	      result = append (&total, &total_size, out, out_len);
	      if (result != ASN1_SUCCESS)
		{
		  warn ();
		  goto cleanup;
		}

	      free (out);
	      out = NULL;

	      if (p[0] == 0 && p[1] == 0)	/* EOC */
		{
		  if (ber_len)
		    *ber_len += 2;
		  break;
		}

	      /* no EOC */
	      der_len += 2;

	      if (der_len == 2)
		{
		  warn ();
		  result = ASN1_DER_ERROR;
		  goto cleanup;
		}
	    }
	  while (1);
	}
      else			/* constructed */
	{
	  long const_len;

	  result = asn1_get_length_ber (p, der_len, &len_len);
	  if (result < 0)
	    {
	      warn ();
	      result = ASN1_DER_ERROR;
	      goto cleanup;
	    }

	  DECR_LEN (der_len, len_len);
	  p += len_len;

	  const_len = result;

	  if (ber_len)
	    *ber_len += len_len;

	  /* decode the available octet strings */
	  while (const_len > 0)
	    {
	      unsigned tmp_len;
	      unsigned flags = DECODE_FLAG_HAVE_TAG;

	      if (dflags & DECODE_FLAG_LEVEL1)
		flags |= DECODE_FLAG_LEVEL2;
	      else if (dflags & DECODE_FLAG_LEVEL2)
		flags |= DECODE_FLAG_LEVEL3;
	      else
		flags |= DECODE_FLAG_LEVEL1;

	      result =
		_asn1_decode_simple_ber (etype, p, der_len, &out, &out_len,
					 &tmp_len, flags);
	      if (result != ASN1_SUCCESS)
		{
		  warn ();
		  goto cleanup;
		}

	      p += tmp_len;
	      DECR_LEN (der_len, tmp_len);
	      DECR_LEN (const_len, tmp_len);

	      if (ber_len)
		*ber_len += tmp_len;

	      result = append (&total, &total_size, out, out_len);
	      if (result != ASN1_SUCCESS)
		{
		  warn ();
		  goto cleanup;
		}

	      free (out);
	      out = NULL;
	    }
	}
    }
  else if (class == ETYPE_CLASS (etype))
    {
      if (ber_len)
	{
	  result = asn1_get_length_der (p, der_len, &len_len);
	  if (result < 0)
	    {
	      warn ();
	      result = ASN1_DER_ERROR;
	      goto cleanup;
	    }
	  *ber_len += result + len_len;
	}

      /* non-string values are decoded as DER */
      result =
	_asn1_decode_simple_der (etype, der, _der_len, &cout, &out_len,
				 dflags);
      if (result != ASN1_SUCCESS)
	{
	  warn ();
	  goto cleanup;
	}

      result = append (&total, &total_size, cout, out_len);
      if (result != ASN1_SUCCESS)
	{
	  warn ();
	  goto cleanup;
	}
    }
  else
    {
      warn ();
      result = ASN1_DER_ERROR;
      goto cleanup;
    }

  *str = total;
  *str_len = total_size;

  return ASN1_SUCCESS;
cleanup:
  free (out);
  free (total);
  return result;
}

/**
 * asn1_decode_simple_ber:
 * @etype: The type of the string to be encoded (ASN1_ETYPE_)
 * @der: the encoded string
 * @_der_len: the bytes of the encoded string
 * @str: a pointer to the data
 * @str_len: the length of the data
 * @ber_len: the total length occupied by BER (may be %NULL)
 *
 * Decodes a BER encoded type. The output is an allocated value
 * of the data. This decodes BER STRINGS only. Other types are
 * decoded as DER.
 *
 * Returns: %ASN1_SUCCESS if successful or an error value.
 **/
int
asn1_decode_simple_ber (unsigned int etype, const unsigned char *der,
			unsigned int _der_len, unsigned char **str,
			unsigned int *str_len, unsigned int *ber_len)
{
  return _asn1_decode_simple_ber (etype, der, _der_len, str, str_len, ber_len,
				  DECODE_FLAG_HAVE_TAG);
}
