/*
 * Copyright (C) 2002-2016 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA
 */


/*****************************************************/
/* 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>

#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_INDEFINITE: 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_INDEFINITE (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 (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_objectid_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;
  char temp[LTOSTR_MAX_SIZE];
  uint64_t val, val1;

  *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;

  val1 = der[len_len] / 40;
  val = der[len_len] - val1 * 40;

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

  val = 0;
  leading = 1;
  for (k = 1; 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))
                {
	          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_INDEFINITE;

                  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 lenth 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)
	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 definitions, asn1_node * element)
{
  char name[2 * ASN1_MAX_NAME_SIZE + 1],
    value[ASN1_MAX_NAME_SIZE];
  int retCode = ASN1_SUCCESS, result;
  int len, len2, len3;
  asn1_node p, p2, 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 exapand */
			      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 OCTECT 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 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 p2, 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 exapand */
		  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)
{
  *dst = _asn1_realloc(*dst, *dst_size+src_size);
  if (*dst == NULL)
    return ASN1_MEM_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_INDEFINITE) || class == ASN1_CLASS_STRUCTURED) && ETYPE_IS_STRING(etype)) &&
      !(dflags & DECODE_FLAG_LEVEL3))
    {
      len_len = 1;

      DECR_LEN(der_len, len_len);
      if (p[0] != 0x80)
        {
          warn();
          result = ASN1_DER_ERROR;
          goto cleanup;
        }

      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 */

	  if (out_len > 0)
	    {
              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 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);
}
