/*
 * Copyright (C) 2000-2021 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: element.c                                   */
/* Description: Functions with the read and write    */
/*   functions.                                      */
/*****************************************************/


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

void
_asn1_hierarchical_name (asn1_node_const node, char *name, int name_size)
{
  asn1_node_const p;
  char tmp_name[64];

  p = node;

  name[0] = 0;

  while (p != NULL)
    {
      if (p->name[0] != 0)
	{
	  _asn1_str_cpy (tmp_name, sizeof (tmp_name), name),
	    _asn1_str_cpy (name, name_size, p->name);
	  _asn1_str_cat (name, name_size, ".");
	  _asn1_str_cat (name, name_size, tmp_name);
	}
      p = _asn1_find_up (p);
    }

  if (name[0] == 0)
    _asn1_str_cpy (name, name_size, "ROOT");
}


/******************************************************************/
/* Function : _asn1_convert_integer                               */
/* Description: converts an integer from a null terminated string */
/*              to der decoding. The convertion from a null       */
/*              terminated string to an integer is made with      */
/*              the 'strtol' function.                            */
/* Parameters:                                                    */
/*   value: null terminated string to convert.                    */
/*   value_out: convertion result (memory must be already         */
/*              allocated).                                       */
/*   value_out_size: number of bytes of value_out.                */
/*   len: number of significant byte of value_out.                */
/* Return: ASN1_MEM_ERROR or ASN1_SUCCESS                         */
/******************************************************************/
int
_asn1_convert_integer (const unsigned char *value, unsigned char *value_out,
		       int value_out_size, int *len)
{
  char negative;
  unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
  long valtmp;
  int k, k2;

  valtmp = _asn1_strtol (value, NULL, 10);

  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
    {
      val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
    }

  if (val[0] & 0x80)
    negative = 1;
  else
    negative = 0;

  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
    {
      if (negative && (val[k] != 0xFF))
	break;
      else if (!negative && val[k])
	break;
    }

  if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
    k--;

  *len = SIZEOF_UNSIGNED_LONG_INT - k;

  if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
    /* VALUE_OUT is too short to contain the value conversion */
    return ASN1_MEM_ERROR;

  if (value_out != NULL)
    {
      for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
        value_out[k2 - k] = val[k2];
    }

#if 0
  printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
    printf (", vOut[%d]=%d", k, value_out[k]);
  printf ("\n");
#endif

  return ASN1_SUCCESS;
}

/* Appends a new element into the sequence (or set) defined by this
 * node. The new element will have a name of '?number', where number
 * is a monotonically increased serial number.
 *
 * The last element in the list may be provided in @pcache, to avoid
 * traversing the list, an expensive operation in long lists.
 *
 * On success it returns in @pcache the added element (which is the
 * tail in the list of added elements).
 */
int
_asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache)
{
  asn1_node p, p2;
  char temp[LTOSTR_MAX_SIZE+1];
  long n;

  if (!node || !(node->down))
    return ASN1_GENERIC_ERROR;

  p = node->down;
  while ((type_field (p->type) == ASN1_ETYPE_TAG)
	 || (type_field (p->type) == ASN1_ETYPE_SIZE))
    p = p->right;

  p2 = _asn1_copy_structure3 (p);
  if (p2 == NULL)
    return ASN1_GENERIC_ERROR;

  if (pcache == NULL || pcache->tail == NULL || pcache->head != node)
    {
      while (p->right)
        {
          p = p->right;
        }
    }
  else
    {
      p = pcache->tail;
    }

  _asn1_set_right (p, p2);
  if (pcache)
    {
      pcache->head = node;
      pcache->tail = p2;
    }

  if (p->name[0] == 0)
    _asn1_str_cpy (temp, sizeof (temp), "?1");
  else
    {
      n = strtol (p->name + 1, NULL, 0);
      n++;
      temp[0] = '?';
      _asn1_ltostr (n, temp + 1);
    }
  _asn1_set_name (p2, temp);
  /*  p2->type |= CONST_OPTION; */

  return ASN1_SUCCESS;
}


/**
 * asn1_write_value:
 * @node_root: pointer to a structure
 * @name: the name of the element inside the structure that you want to set.
 * @ivalue: vector used to specify the value to set. If len is >0,
 *   VALUE must be a two's complement form integer.  if len=0 *VALUE
 *   must be a null terminated string with an integer value.
 * @len: number of bytes of *value to use to set the value:
 *   value[0]..value[len-1] or 0 if value is a null terminated string
 *
 * Set the value of one element inside a structure.
 *
 * If an element is OPTIONAL and you want to delete it, you must use
 * the value=NULL and len=0.  Using "pkix.asn":
 *
 * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
 * NULL, 0);
 *
 * Description for each type:
 *
 * INTEGER: VALUE must contain a two's complement form integer.
 *
 *            value[0]=0xFF ,               len=1 -> integer=-1.
 *            value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1.
 *            value[0]=0x01 ,               len=1 -> integer= 1.
 *            value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1.
 *            value="123"                 , len=0 -> integer= 123.
 *
 * ENUMERATED: As INTEGER (but only with not negative numbers).
 *
 * BOOLEAN: VALUE must be the null terminated string "TRUE" or
 *   "FALSE" and LEN != 0.
 *
 *            value="TRUE" , len=1 -> boolean=TRUE.
 *            value="FALSE" , len=1 -> boolean=FALSE.
 *
 * OBJECT IDENTIFIER: VALUE must be a null terminated string with
 *   each number separated by a dot (e.g. "1.2.3.543.1").  LEN != 0.
 *
 *            value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
 *
 * UTCTime: VALUE must be a null terminated string in one of these
 *   formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ",
 *   "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'",
 *   "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'".  LEN != 0.
 *
 *            value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
 *            at 12h 00m Greenwich Mean Time
 *
 * GeneralizedTime: VALUE must be in one of this format:
 *   "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ",
 *   "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'",
 *   "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s
 *   indicates the seconds with any precision like "10.1" or "01.02".
 *   LEN != 0
 *
 *            value="2001010112001.12-0700" , len=1 -> time=Jannuary
 *            1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
 *
 * OCTET STRING: VALUE contains the octet string and LEN is the
 *   number of octets.
 *
 *            value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
 *            len=3 -> three bytes octet string
 *
 * GeneralString: VALUE contains the generalstring and LEN is the
 *   number of octets.
 *
 *            value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
 *            len=3 -> three bytes generalstring
 *
 * BIT STRING: VALUE contains the bit string organized by bytes and
 *   LEN is the number of bits.
 *
 *   value="$\backslash$xCF" , len=6 -> bit string="110011" (six
 *   bits)
 *
 * CHOICE: if NAME indicates a choice type, VALUE must specify one of
 *   the alternatives with a null terminated string. LEN != 0. Using
 *   "pkix.asn"\:
 *
 *           result=asn1_write_value(cert,
 *           "certificate1.tbsCertificate.subject", "rdnSequence",
 *           1);
 *
 * ANY: VALUE indicates the der encoding of a structure.  LEN != 0.
 *
 * SEQUENCE OF: VALUE must be the null terminated string "NEW" and
 *   LEN != 0. With this instruction another element is appended in
 *   the sequence. The name of this element will be "?1" if it's the
 *   first one, "?2" for the second and so on.
 *
 *   Using "pkix.asn"\:
 *
 *   result=asn1_write_value(cert,
 *   "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
 *
 * SET OF: the same as SEQUENCE OF.  Using "pkix.asn":
 *
 *           result=asn1_write_value(cert,
 *           "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
 *
 * Returns: %ASN1_SUCCESS if the value was set,
 *   %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element, and
 *   %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format.
 **/
int
asn1_write_value (asn1_node node_root, const char *name,
		  const void *ivalue, int len)
{
  asn1_node node, p, p2;
  unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
  int len2, k, k2, negative;
  size_t i;
  const unsigned char *value = ivalue;
  unsigned int type;

  node = asn1_find_node (node_root, name);
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
    {
      asn1_delete_structure (&node);
      return ASN1_SUCCESS;
    }

  type = type_field (node->type);

  if ((type == ASN1_ETYPE_SEQUENCE_OF || type == ASN1_ETYPE_SET_OF) && (value == NULL) && (len == 0))
    {
      p = node->down;
      while ((type_field (p->type) == ASN1_ETYPE_TAG)
	     || (type_field (p->type) == ASN1_ETYPE_SIZE))
	p = p->right;

      while (p->right)
	asn1_delete_structure (&p->right);

      return ASN1_SUCCESS;
    }

  /* Don't allow element deletion for other types */
  if (value == NULL)
    {
      return ASN1_VALUE_NOT_VALID;
    }

  switch (type)
    {
    case ASN1_ETYPE_BOOLEAN:
      if (!_asn1_strcmp (value, "TRUE"))
	{
	  if (node->type & CONST_DEFAULT)
	    {
	      p = node->down;
	      while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
		p = p->right;
	      if (p->type & CONST_TRUE)
		_asn1_set_value (node, NULL, 0);
	      else
		_asn1_set_value (node, "T", 1);
	    }
	  else
	    _asn1_set_value (node, "T", 1);
	}
      else if (!_asn1_strcmp (value, "FALSE"))
	{
	  if (node->type & CONST_DEFAULT)
	    {
	      p = node->down;
	      while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
		p = p->right;
	      if (p->type & CONST_FALSE)
		_asn1_set_value (node, NULL, 0);
	      else
		_asn1_set_value (node, "F", 1);
	    }
	  else
	    _asn1_set_value (node, "F", 1);
	}
      else
	return ASN1_VALUE_NOT_VALID;
      break;
    case ASN1_ETYPE_INTEGER:
    case ASN1_ETYPE_ENUMERATED:
      if (len == 0)
	{
	  if ((c_isdigit (value[0])) || (value[0] == '-'))
	    {
	      value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
	      if (value_temp == NULL)
		return ASN1_MEM_ALLOC_ERROR;

	      _asn1_convert_integer (value, value_temp,
				     SIZEOF_UNSIGNED_LONG_INT, &len);
	    }
	  else
	    {			/* is an identifier like v1 */
	      if (!(node->type & CONST_LIST))
		return ASN1_VALUE_NOT_VALID;
	      p = node->down;
	      while (p)
		{
		  if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
		    {
		      if (!_asn1_strcmp (p->name, value))
			{
			  value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
			  if (value_temp == NULL)
			    return ASN1_MEM_ALLOC_ERROR;

			  _asn1_convert_integer (p->value,
						 value_temp,
						 SIZEOF_UNSIGNED_LONG_INT,
						 &len);
			  break;
			}
		    }
		  p = p->right;
		}
	      if (p == NULL)
		return ASN1_VALUE_NOT_VALID;
	    }
	}
      else
	{			/* len != 0 */
	  value_temp = malloc (len);
	  if (value_temp == NULL)
	    return ASN1_MEM_ALLOC_ERROR;
	  memcpy (value_temp, value, len);
	}

      if (value_temp[0] & 0x80)
	negative = 1;
      else
	negative = 0;

      if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED))
	{
	  free (value_temp);
	  return ASN1_VALUE_NOT_VALID;
	}

      for (k = 0; k < len - 1; k++)
	if (negative && (value_temp[k] != 0xFF))
	  break;
	else if (!negative && value_temp[k])
	  break;

      if ((negative && !(value_temp[k] & 0x80)) ||
	  (!negative && (value_temp[k] & 0x80)))
	k--;

      _asn1_set_value_lv (node, value_temp + k, len - k);

      if (node->type & CONST_DEFAULT)
	{
	  p = node->down;
	  while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
	    p = p->right;
	  if ((c_isdigit (p->value[0])) || (p->value[0] == '-'))
	    {
	      default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
	      if (default_temp == NULL)
		{
		  free (value_temp);
		  return ASN1_MEM_ALLOC_ERROR;
		}

	      _asn1_convert_integer (p->value, default_temp,
				     SIZEOF_UNSIGNED_LONG_INT, &len2);
	    }
	  else
	    {			/* is an identifier like v1 */
	      if (!(node->type & CONST_LIST))
		{
		  free (value_temp);
		  return ASN1_VALUE_NOT_VALID;
		}
	      p2 = node->down;
	      while (p2)
		{
		  if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
		    {
		      if (!_asn1_strcmp (p2->name, p->value))
			{
			  default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
			  if (default_temp == NULL)
			    {
			      free (value_temp);
			      return ASN1_MEM_ALLOC_ERROR;
			    }

			  _asn1_convert_integer (p2->value,
						 default_temp,
						 SIZEOF_UNSIGNED_LONG_INT,
						 &len2);
			  break;
			}
		    }
		  p2 = p2->right;
		}
	      if (p2 == NULL)
		{
		  free (value_temp);
		  return ASN1_VALUE_NOT_VALID;
		}
	    }


	  if ((len - k) == len2)
	    {
	      for (k2 = 0; k2 < len2; k2++)
		if (value_temp[k + k2] != default_temp[k2])
		  {
		    break;
		  }
	      if (k2 == len2)
		_asn1_set_value (node, NULL, 0);
	    }
	  free (default_temp);
	}
      free (value_temp);
      break;
    case ASN1_ETYPE_OBJECT_ID:
      for (i = 0; i < _asn1_strlen (value); i++)
	if ((!c_isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
	  return ASN1_VALUE_NOT_VALID;
      if (node->type & CONST_DEFAULT)
	{
	  p = node->down;
	  while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
	    p = p->right;
	  if (!_asn1_strcmp (value, p->value))
	    {
	      _asn1_set_value (node, NULL, 0);
	      break;
	    }
	}
      _asn1_set_value (node, value, _asn1_strlen (value) + 1);
      break;
    case ASN1_ETYPE_UTC_TIME:
      {
	len = _asn1_strlen (value);
	if (len < 11)
	  return ASN1_VALUE_NOT_VALID;
	for (k = 0; k < 10; k++)
	  if (!c_isdigit (value[k]))
	    return ASN1_VALUE_NOT_VALID;
	switch (len)
	  {
	  case 11:
	    if (value[10] != 'Z')
	      return ASN1_VALUE_NOT_VALID;
	    break;
	  case 13:
	    if ((!c_isdigit (value[10])) || (!c_isdigit (value[11])) ||
		(value[12] != 'Z'))
	      return ASN1_VALUE_NOT_VALID;
	    break;
	  case 15:
	    if ((value[10] != '+') && (value[10] != '-'))
	      return ASN1_VALUE_NOT_VALID;
	    for (k = 11; k < 15; k++)
	      if (!c_isdigit (value[k]))
		return ASN1_VALUE_NOT_VALID;
	    break;
	  case 17:
	    if ((!c_isdigit (value[10])) || (!c_isdigit (value[11])))
	      return ASN1_VALUE_NOT_VALID;
	    if ((value[12] != '+') && (value[12] != '-'))
	      return ASN1_VALUE_NOT_VALID;
	    for (k = 13; k < 17; k++)
	      if (!c_isdigit (value[k]))
		return ASN1_VALUE_NOT_VALID;
	    break;
	  default:
	    return ASN1_VALUE_NOT_FOUND;
	  }
	_asn1_set_value (node, value, len);
      }
      break;
    case ASN1_ETYPE_GENERALIZED_TIME:
      len = _asn1_strlen (value);
      _asn1_set_value (node, value, len);
      break;
    case ASN1_ETYPE_OCTET_STRING:
    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:
      if (len == 0)
	len = _asn1_strlen (value);
      _asn1_set_value_lv (node, value, len);
      break;
    case ASN1_ETYPE_BIT_STRING:
      if (len == 0)
	len = _asn1_strlen (value);
      asn1_length_der ((len >> 3) + 2, NULL, &len2);
      temp = malloc ((len >> 3) + 2 + len2);
      if (temp == NULL)
	return ASN1_MEM_ALLOC_ERROR;

      asn1_bit_der (value, len, temp, &len2);
      _asn1_set_value_m (node, temp, len2);
      temp = NULL;
      break;
    case ASN1_ETYPE_CHOICE:
      p = node->down;
      while (p)
	{
	  if (!_asn1_strcmp (p->name, value))
	    {
	      p2 = node->down;
	      while (p2)
		{
		  if (p2 != p)
		    {
		      asn1_delete_structure (&p2);
		      p2 = node->down;
		    }
		  else
		    p2 = p2->right;
		}
	      break;
	    }
	  p = p->right;
	}
      if (!p)
	return ASN1_ELEMENT_NOT_FOUND;
      break;
    case ASN1_ETYPE_ANY:
      _asn1_set_value_lv (node, value, len);
      break;
    case ASN1_ETYPE_SEQUENCE_OF:
    case ASN1_ETYPE_SET_OF:
      if (_asn1_strcmp (value, "NEW"))
	return ASN1_VALUE_NOT_VALID;
      _asn1_append_sequence_set (node, NULL);
      break;
    default:
      return ASN1_ELEMENT_NOT_FOUND;
      break;
    }

  return ASN1_SUCCESS;
}


#define PUT_VALUE( ptr, ptr_size, data, data_size) \
	*len = data_size; \
	if (ptr_size < data_size) { \
		return ASN1_MEM_ERROR; \
	} else { \
		if (ptr && data_size > 0) \
		  memcpy (ptr, data, data_size); \
	}

#define PUT_STR_VALUE( ptr, ptr_size, data) \
	*len = _asn1_strlen (data) + 1; \
	if (ptr_size < *len) { \
		return ASN1_MEM_ERROR; \
	} else { \
		/* this strcpy is checked */ \
		if (ptr) { \
		  _asn1_strcpy (ptr, data); \
		} \
	}

#define PUT_AS_STR_VALUE( ptr, ptr_size, data, data_size) \
	*len = data_size + 1; \
	if (ptr_size < *len) { \
		return ASN1_MEM_ERROR; \
	} else { \
		/* this strcpy is checked */ \
		if (ptr) { \
		  if (data_size > 0) \
		    memcpy (ptr, data, data_size); \
		  ptr[data_size] = 0; \
		} \
	}

#define ADD_STR_VALUE( ptr, ptr_size, data) \
        *len += _asn1_strlen(data); \
        if (ptr_size < (int) *len) { \
                (*len)++; \
                return ASN1_MEM_ERROR; \
        } else { \
                /* this strcat is checked */ \
                if (ptr) _asn1_strcat (ptr, data); \
        }

/**
 * asn1_read_value:
 * @root: pointer to a structure.
 * @name: the name of the element inside a structure that you want to read.
 * @ivalue: vector that will contain the element's content, must be a
 *   pointer to memory cells already allocated (may be %NULL).
 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
 *   holds the sizeof value.
 *
 * Returns the value of one element inside a structure.
 * If an element is OPTIONAL and this returns
 * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
 * in the der encoding that created the structure.  The first element
 * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
 * so on. If the @root provided is a node to specific sequence element,
 * then the keyword "?CURRENT" is also acceptable and indicates the
 * current sequence element of this node.
 *
 * Note that there can be valid values with length zero. In these case
 * this function will succeed and @len will be zero.
 *
 * INTEGER: VALUE will contain a two's complement form integer.
 *
 *            integer=-1  -> value[0]=0xFF , len=1.
 *            integer=1   -> value[0]=0x01 , len=1.
 *
 * ENUMERATED: As INTEGER (but only with not negative numbers).
 *
 * BOOLEAN: VALUE will be the null terminated string "TRUE" or
 *   "FALSE" and LEN=5 or LEN=6.
 *
 * OBJECT IDENTIFIER: VALUE will be a null terminated string with
 *   each number separated by a dot (i.e. "1.2.3.543.1").
 *
 *                      LEN = strlen(VALUE)+1
 *
 * UTCTime: VALUE will be a null terminated string in one of these
 *   formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
 *   LEN=strlen(VALUE)+1.
 *
 * GeneralizedTime: VALUE will be a null terminated string in the
 *   same format used to set the value.
 *
 * OCTET STRING: VALUE will contain the octet string and LEN will be
 *   the number of octets.
 *
 * GeneralString: VALUE will contain the generalstring and LEN will
 *   be the number of octets.
 *
 * BIT STRING: VALUE will contain the bit string organized by bytes
 *   and LEN will be the number of bits.
 *
 * CHOICE: If NAME indicates a choice type, VALUE will specify the
 *   alternative selected.
 *
 * ANY: If NAME indicates an any type, VALUE will indicate the DER
 *   encoding of the structure actually used.
 *
 * Returns: %ASN1_SUCCESS if value is returned,
 *   %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
 *   %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
 *   selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
 *   to store the result, and in this case @len will contain the number of
 *   bytes needed. On the occasion that the stored data are of zero-length
 *   this function may return %ASN1_SUCCESS even if the provided @len is zero.
 **/
int
asn1_read_value (asn1_node_const root, const char *name, void *ivalue, int *len)
{
  return asn1_read_value_type (root, name, ivalue, len, NULL);
}

/**
 * asn1_read_value_type:
 * @root: pointer to a structure.
 * @name: the name of the element inside a structure that you want to read.
 * @ivalue: vector that will contain the element's content, must be a
 *   pointer to memory cells already allocated (may be %NULL).
 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
 *   holds the sizeof value.
 * @etype: The type of the value read (ASN1_ETYPE)
 *
 * Returns the type and value of one element inside a structure.
 * If an element is OPTIONAL and this returns
 * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
 * in the der encoding that created the structure.  The first element
 * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
 * so on. If the @root provided is a node to specific sequence element,
 * then the keyword "?CURRENT" is also acceptable and indicates the
 * current sequence element of this node.
 *
 * Note that there can be valid values with length zero. In these case
 * this function will succeed and @len will be zero.
 *
 *
 * INTEGER: VALUE will contain a two's complement form integer.
 *
 *            integer=-1  -> value[0]=0xFF , len=1.
 *            integer=1   -> value[0]=0x01 , len=1.
 *
 * ENUMERATED: As INTEGER (but only with not negative numbers).
 *
 * BOOLEAN: VALUE will be the null terminated string "TRUE" or
 *   "FALSE" and LEN=5 or LEN=6.
 *
 * OBJECT IDENTIFIER: VALUE will be a null terminated string with
 *   each number separated by a dot (i.e. "1.2.3.543.1").
 *
 *                      LEN = strlen(VALUE)+1
 *
 * UTCTime: VALUE will be a null terminated string in one of these
 *   formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
 *   LEN=strlen(VALUE)+1.
 *
 * GeneralizedTime: VALUE will be a null terminated string in the
 *   same format used to set the value.
 *
 * OCTET STRING: VALUE will contain the octet string and LEN will be
 *   the number of octets.
 *
 * GeneralString: VALUE will contain the generalstring and LEN will
 *   be the number of octets.
 *
 * BIT STRING: VALUE will contain the bit string organized by bytes
 *   and LEN will be the number of bits.
 *
 * CHOICE: If NAME indicates a choice type, VALUE will specify the
 *   alternative selected.
 *
 * ANY: If NAME indicates an any type, VALUE will indicate the DER
 *   encoding of the structure actually used.
 *
 * Returns: %ASN1_SUCCESS if value is returned,
 *   %ASN1_ELEMENT_NOT_FOUND if @name is not a valid element,
 *   %ASN1_VALUE_NOT_FOUND if there isn't any value for the element
 *   selected, and %ASN1_MEM_ERROR if The value vector isn't big enough
 *   to store the result, and in this case @len will contain the number of
 *   bytes needed. On the occasion that the stored data are of zero-length
 *   this function may return %ASN1_SUCCESS even if the provided @len is zero.
 **/
int
asn1_read_value_type (asn1_node_const root, const char *name, void *ivalue,
		      int *len, unsigned int *etype)
{
  asn1_node_const node, p, p2;
  int len2, len3, result;
  int value_size = *len;
  unsigned char *value = ivalue;
  unsigned type;

  node = asn1_find_node (root, name);
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  type = type_field (node->type);

  if ((type != ASN1_ETYPE_NULL) &&
      (type != ASN1_ETYPE_CHOICE) &&
      !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
      (node->value == NULL))
    return ASN1_VALUE_NOT_FOUND;

  if (etype)
    *etype = type;
  switch (type)
    {
    case ASN1_ETYPE_NULL:
      PUT_STR_VALUE (value, value_size, "NULL");
      break;
    case ASN1_ETYPE_BOOLEAN:
      if ((node->type & CONST_DEFAULT) && (node->value == NULL))
	{
	  p = node->down;
	  while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
	    p = p->right;
	  if (p->type & CONST_TRUE)
	    {
	      PUT_STR_VALUE (value, value_size, "TRUE");
	    }
	  else
	    {
	      PUT_STR_VALUE (value, value_size, "FALSE");
	    }
	}
      else if (node->value[0] == 'T')
	{
	  PUT_STR_VALUE (value, value_size, "TRUE");
	}
      else
	{
	  PUT_STR_VALUE (value, value_size, "FALSE");
	}
      break;
    case ASN1_ETYPE_INTEGER:
    case ASN1_ETYPE_ENUMERATED:
      if ((node->type & CONST_DEFAULT) && (node->value == NULL))
	{
	  p = node->down;
	  while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
	    p = p->right;
	  if ((c_isdigit (p->value[0])) || (p->value[0] == '-')
	      || (p->value[0] == '+'))
	    {
	      result = _asn1_convert_integer
		  (p->value, value, value_size, len);
              if (result != ASN1_SUCCESS)
		return result;
	    }
	  else
	    {			/* is an identifier like v1 */
	      p2 = node->down;
	      while (p2)
		{
		  if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
		    {
		      if (!_asn1_strcmp (p2->name, p->value))
			{
			  result = _asn1_convert_integer
			      (p2->value, value, value_size,
			       len);
			  if (result != ASN1_SUCCESS)
			    return result;
			  break;
			}
		    }
		  p2 = p2->right;
		}
	    }
	}
      else
	{
	  len2 = -1;
	  result = asn1_get_octet_der
	      (node->value, node->value_len, &len2, value, value_size,
	       len);
          if (result != ASN1_SUCCESS)
	    return result;
	}
      break;
    case ASN1_ETYPE_OBJECT_ID:
      if (node->type & CONST_ASSIGN)
	{
	  *len = 0;
	  if (value)
	    value[0] = 0;
	  p = node->down;
	  while (p)
	    {
	      if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
		{
		  ADD_STR_VALUE (value, value_size, p->value);
		  if (p->right)
		    {
		      ADD_STR_VALUE (value, value_size, ".");
		    }
		}
	      p = p->right;
	    }
	  (*len)++;
	}
      else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
	{
	  p = node->down;
	  while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
	    p = p->right;
	  PUT_STR_VALUE (value, value_size, p->value);
	}
      else
	{
	  PUT_STR_VALUE (value, value_size, node->value);
	}
      break;
    case ASN1_ETYPE_GENERALIZED_TIME:
    case ASN1_ETYPE_UTC_TIME:
      PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len);
      break;
    case ASN1_ETYPE_OCTET_STRING:
    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:
      len2 = -1;
      result = asn1_get_octet_der
	  (node->value, node->value_len, &len2, value, value_size,
	   len);
      if (result != ASN1_SUCCESS)
	return result;
      break;
    case ASN1_ETYPE_BIT_STRING:
      len2 = -1;
      result = asn1_get_bit_der
	  (node->value, node->value_len, &len2, value, value_size,
	   len);
      if (result != ASN1_SUCCESS)
	return result;
      break;
    case ASN1_ETYPE_CHOICE:
      PUT_STR_VALUE (value, value_size, node->down->name);
      break;
    case ASN1_ETYPE_ANY:
      len3 = -1;
      len2 = asn1_get_length_der (node->value, node->value_len, &len3);
      if (len2 < 0)
	return ASN1_DER_ERROR;
      PUT_VALUE (value, value_size, node->value + len3, len2);
      break;
    default:
      return ASN1_ELEMENT_NOT_FOUND;
      break;
    }
  return ASN1_SUCCESS;
}


/**
 * asn1_read_tag:
 * @root: pointer to a structure
 * @name: the name of the element inside a structure.
 * @tagValue:  variable that will contain the TAG value.
 * @classValue: variable that will specify the TAG type.
 *
 * Returns the TAG and the CLASS of one element inside a structure.
 * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
 * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
 * %ASN1_CLASS_CONTEXT_SPECIFIC.
 *
 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
 *   @name is not a valid element.
 **/
int
asn1_read_tag (asn1_node_const root, const char *name, int *tagValue,
	       int *classValue)
{
  asn1_node node, p, pTag;

  node = asn1_find_node (root, name);
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  p = node->down;

  /* pTag will points to the IMPLICIT TAG */
  pTag = NULL;
  if (node->type & CONST_TAG)
    {
      while (p)
	{
	  if (type_field (p->type) == ASN1_ETYPE_TAG)
	    {
	      if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
		pTag = p;
	      else if (p->type & CONST_EXPLICIT)
		pTag = NULL;
	    }
	  p = p->right;
	}
    }

  if (pTag)
    {
      *tagValue = _asn1_strtoul (pTag->value, NULL, 10);

      if (pTag->type & CONST_APPLICATION)
	*classValue = ASN1_CLASS_APPLICATION;
      else if (pTag->type & CONST_UNIVERSAL)
	*classValue = ASN1_CLASS_UNIVERSAL;
      else if (pTag->type & CONST_PRIVATE)
	*classValue = ASN1_CLASS_PRIVATE;
      else
	*classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
    }
  else
    {
      unsigned type = type_field (node->type);
      *classValue = ASN1_CLASS_UNIVERSAL;

      switch (type)
	{
	CASE_HANDLED_ETYPES:
	  *tagValue = _asn1_tags[type].tag;
	  break;
	case ASN1_ETYPE_TAG:
	case ASN1_ETYPE_CHOICE:
	case ASN1_ETYPE_ANY:
	  *tagValue = -1;
	  break;
	default:
	  break;
	}
    }

  return ASN1_SUCCESS;
}

/**
 * asn1_read_node_value:
 * @node: pointer to a node.
 * @data: a point to a asn1_data_node_st
 *
 * Returns the value a data node inside a asn1_node structure.
 * The data returned should be handled as constant values.
 *
 * Returns: %ASN1_SUCCESS if the node exists.
 **/
int
asn1_read_node_value (asn1_node_const node, asn1_data_node_st * data)
{
  data->name = node->name;
  data->value = node->value;
  data->value_len = node->value_len;
  data->type = type_field (node->type);

  return ASN1_SUCCESS;
}
