/*
 * Copyright (C) 2002-2014 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: coding.c                                    */
/* Description: Functions to create a DER coding of  */
/*   an ASN1 type.                                   */
/*****************************************************/

#include <int.h>
#include "parser_aux.h"
#include <gstr.h>
#include "element.h"
#include "minmax.h"
#include <structure.h>

#define MAX_TAG_LEN 16

/******************************************************/
/* Function : _asn1_error_description_value_not_found */
/* Description: creates the ErrorDescription string   */
/* for the ASN1_VALUE_NOT_FOUND error.                */
/* Parameters:                                        */
/*   node: node of the tree where the value is NULL.  */
/*   ErrorDescription: string returned.               */
/* Return:                                            */
/******************************************************/
static void
_asn1_error_description_value_not_found (asn1_node node,
					 char *ErrorDescription)
{

  if (ErrorDescription == NULL)
    return;

  Estrcpy (ErrorDescription, ":: value of element '");
  _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
			   ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40);
  Estrcat (ErrorDescription, "' not found");

}

/**
 * asn1_length_der:
 * @len: value to convert.
 * @der: buffer to hold the returned encoding (may be %NULL).
 * @der_len: number of meaningful bytes of ANS (der[0]..der[der_len-1]).
 *
 * Creates the DER encoding of the provided length value.
 * The @der buffer must have enough room for the output. The maximum
 * length this function will encode is %ASN1_MAX_LENGTH_SIZE.
 *
 * To know the size of the DER encoding use a %NULL value for @der.
 **/
void
asn1_length_der (unsigned long int len, unsigned char *der, int *der_len)
{
  int k;
  unsigned char temp[ASN1_MAX_LENGTH_SIZE];
#if SIZEOF_UNSIGNED_LONG_INT > 8
  len &= 0xFFFFFFFFFFFFFFFF;
#endif

  if (len < 128)
    {
      /* short form */
      if (der != NULL)
	der[0] = (unsigned char) len;
      *der_len = 1;
    }
  else
    {
      /* Long form */
      k = 0;
      while (len)
	{
	  temp[k++] = len & 0xFF;
	  len = len >> 8;
	}
      *der_len = k + 1;
      if (der != NULL)
	{
	  der[0] = ((unsigned char) k & 0x7F) + 128;
	  while (k--)
	    der[*der_len - 1 - k] = temp[k];
	}
    }
}

/******************************************************/
/* Function : _asn1_tag_der                           */
/* Description: creates the DER coding for the CLASS  */
/* and TAG parameters.                                */
/* It is limited by the ASN1_MAX_TAG_SIZE variable    */
/* Parameters:                                        */
/*   class: value to convert.                         */
/*   tag_value: value to convert.                     */
/*   ans: string returned.                            */
/*   ans_len: number of meaningful bytes of ANS       */
/*            (ans[0]..ans[ans_len-1]).               */
/* Return:                                            */
/******************************************************/
static void
_asn1_tag_der (unsigned char class, unsigned int tag_value,
	       unsigned char ans[ASN1_MAX_TAG_SIZE], int *ans_len)
{
  int k;
  unsigned char temp[ASN1_MAX_TAG_SIZE];

  if (tag_value < 31)
    {
      /* short form */
      ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
      *ans_len = 1;
    }
  else
    {
      /* Long form */
      ans[0] = (class & 0xE0) + 31;
      k = 0;
      while (tag_value != 0)
	{
	  temp[k++] = tag_value & 0x7F;
	  tag_value >>= 7;

	  if (k > ASN1_MAX_TAG_SIZE - 1)
	    break;		/* will not encode larger tags */
	}
      *ans_len = k + 1;
      while (k--)
	ans[*ans_len - 1 - k] = temp[k] + 128;
      ans[*ans_len - 1] -= 128;
    }
}

/**
 * asn1_octet_der:
 * @str: the input data.
 * @str_len: STR length (str[0]..str[*str_len-1]).
 * @der: encoded string returned.
 * @der_len: number of meaningful bytes of DER (der[0]..der[der_len-1]).
 *
 * Creates a length-value DER encoding for the input data.
 * The DER encoding of the input data will be placed in the @der variable.
 *
 * Note that the OCTET STRING tag is not included in the output.
 *
 * This function does not return any value because it is expected
 * that @der_len will contain enough bytes to store the string
 * plus the DER encoding. The DER encoding size can be obtained using
 * asn1_length_der().
 **/
void
asn1_octet_der (const unsigned char *str, int str_len,
		unsigned char *der, int *der_len)
{
  int len_len;

  if (der == NULL || str_len < 0)
    return;

  asn1_length_der (str_len, der, &len_len);
  memcpy (der + len_len, str, str_len);
  *der_len = str_len + len_len;
}


/**
 * asn1_encode_simple_der:
 * @etype: The type of the string to be encoded (ASN1_ETYPE_)
 * @str: the string data.
 * @str_len: the string length
 * @tl: the encoded tag and length
 * @tl_len: the bytes of the @tl field
 *
 * Creates the DER encoding for various simple ASN.1 types like strings etc.
 * It stores the tag and length in @tl, which should have space for at least
 * %ASN1_MAX_TL_SIZE bytes. Initially @tl_len should contain the size of @tl.
 *
 * The complete DER encoding should consist of the value in @tl appended
 * with the provided @str.
 *
 * Returns: %ASN1_SUCCESS if successful or an error value.
 **/
int
asn1_encode_simple_der (unsigned int etype, const unsigned char *str,
			unsigned int str_len, unsigned char *tl,
			unsigned int *tl_len)
{
  int tag_len, len_len;
  unsigned tlen;
  unsigned char der_tag[ASN1_MAX_TAG_SIZE];
  unsigned char der_length[ASN1_MAX_LENGTH_SIZE];
  unsigned char *p;

  if (str == NULL)
    return ASN1_VALUE_NOT_VALID;

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

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

  _asn1_tag_der (ETYPE_CLASS (etype), ETYPE_TAG (etype), der_tag, &tag_len);

  asn1_length_der (str_len, der_length, &len_len);

  if (tag_len <= 0 || len_len <= 0)
    return ASN1_VALUE_NOT_VALID;

  tlen = tag_len + len_len;

  if (*tl_len < tlen)
    return ASN1_MEM_ERROR;

  p = tl;
  memcpy (p, der_tag, tag_len);
  p += tag_len;
  memcpy (p, der_length, len_len);

  *tl_len = tlen;

  return ASN1_SUCCESS;
}

/******************************************************/
/* Function : _asn1_time_der                          */
/* Description: creates the DER coding for a TIME     */
/* type (length included).                            */
/* Parameters:                                        */
/*   str: TIME null-terminated string.                */
/*   der: string returned.                            */
/*   der_len: number of meaningful bytes of DER       */
/*            (der[0]..der[ans_len-1]). Initially it  */
/*            if must store the lenght of DER.        */
/* Return:                                            */
/*   ASN1_MEM_ERROR when DER isn't big enough         */
/*   ASN1_SUCCESS otherwise                           */
/******************************************************/
static int
_asn1_time_der (unsigned char *str, int str_len, unsigned char *der,
		int *der_len)
{
  int len_len;
  int max_len;

  if (der == NULL)
    return ASN1_VALUE_NOT_VALID;

  max_len = *der_len;

  asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len);

  if ((len_len + str_len) <= max_len)
    memcpy (der + len_len, str, str_len);
  *der_len = len_len + str_len;

  if ((*der_len) > max_len)
    return ASN1_MEM_ERROR;

  return ASN1_SUCCESS;
}


/*
void
_asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
{
  int len_len,str_len;
  char temp[20];

  if(str==NULL) return;
  str_len=asn1_get_length_der(der,*der_len,&len_len);
  if (str_len<0) return;
  memcpy(temp,der+len_len,str_len);
  *der_len=str_len+len_len;
  switch(str_len)
  {
  case 11:
    temp[10]=0;
    strcat(temp,"00+0000");
    break;
  case 13:
    temp[12]=0;
    strcat(temp,"+0000");
    break;
  case 15:
    temp[15]=0;
    memmove(temp+12,temp+10,6);
    temp[10]=temp[11]='0';
    break;
  case 17:
    temp[17]=0;
    break;
  default:
    return;
  }
  strcpy(str,temp);
}
*/

static
void encode_val(uint64_t val, unsigned char *der, int max_len, int *der_len)
{
  int first, k;
  unsigned char bit7;

  first = 0;
  for (k = sizeof(val); k >= 0; k--)
    {
      bit7 = (val >> (k * 7)) & 0x7F;
      if (bit7 || first || !k)
	{
	  if (k)
	    bit7 |= 0x80;
	  if (max_len > (*der_len))
	    der[*der_len] = bit7;
	  (*der_len)++;
	  first = 1;
	}
    }
}

/******************************************************/
/* Function : _asn1_object_id_der                     */
/* Description: creates the DER coding for an         */
/* OBJECT IDENTIFIER  type (length included).         */
/* Parameters:                                        */
/*   str: OBJECT IDENTIFIER null-terminated string.   */
/*   der: string returned.                            */
/*   der_len: number of meaningful bytes of DER       */
/*            (der[0]..der[ans_len-1]). Initially it  */
/*            must store the length of DER.           */
/* Return:                                            */
/*   ASN1_MEM_ERROR when DER isn't big enough         */
/*   ASN1_SUCCESS if succesful                        */
/*   or an error value.                               */
/******************************************************/
static int
_asn1_object_id_der (const char *str, unsigned char *der, int *der_len)
{
  int len_len, counter, max_len;
  char *temp, *n_end, *n_start;
  uint64_t val, val1 = 0;
  int str_len = _asn1_strlen (str);

  max_len = *der_len;
  *der_len = 0;

  if (der == NULL && max_len > 0)
    return ASN1_VALUE_NOT_VALID;

  temp = malloc (str_len + 2);
  if (temp == NULL)
    return ASN1_MEM_ALLOC_ERROR;

  memcpy (temp, str, str_len);
  temp[str_len] = '.';
  temp[str_len + 1] = 0;

  counter = 0;
  n_start = temp;
  while ((n_end = strchr (n_start, '.')))
    {
      *n_end = 0;
      val = _asn1_strtou64 (n_start, NULL, 10);
      counter++;

      if (counter == 1)
        {
	  val1 = val;
	}
      else if (counter == 2)
	{
	  uint64_t val0;

          if (val1 > 2)
            {
              free(temp);
              return ASN1_VALUE_NOT_VALID;
            }
          else if ((val1 == 0 || val1 == 1) && val > 39)
            {
              free(temp);
              return ASN1_VALUE_NOT_VALID;
            }

	  val0 = 40 * val1 + val;
	  encode_val(val0, der, max_len, der_len);
	}
      else
	{
	  encode_val(val, der, max_len, der_len);
	}
      n_start = n_end + 1;
    }

  asn1_length_der (*der_len, NULL, &len_len);
  if (max_len >= (*der_len + len_len))
    {
      memmove (der + len_len, der, *der_len);
      asn1_length_der (*der_len, der, &len_len);
    }
  *der_len += len_len;

  free (temp);

  if (max_len < (*der_len))
    return ASN1_MEM_ERROR;

  return ASN1_SUCCESS;
}

/**
 * asn1_object_id_der:
 * @str: An object identifier in numeric, dot format.
 * @der: buffer to hold the returned encoding (may be %NULL).
 * @der_len: initially the size of @der; will hold the final size.
 * @flags: must be zero
 *
 * Creates the DER encoding of the provided object identifier.
 *
 * Returns: %ASN1_SUCCESS if DER encoding was OK, %ASN1_VALUE_NOT_VALID
 *   if @str is not a valid OID, %ASN1_MEM_ERROR if the @der
 *   vector isn't big enough and in this case @der_len will contain the
 *   length needed.
 **/
int asn1_object_id_der(const char *str, unsigned char *der, int *der_len, unsigned flags)
{
  unsigned char tag_der[MAX_TAG_LEN];
  int tag_len = 0, r;
  int max_len = *der_len;

  *der_len = 0;

  _asn1_tag_der (ETYPE_CLASS (ASN1_ETYPE_OBJECT_ID), ETYPE_TAG (ASN1_ETYPE_OBJECT_ID),
                 tag_der, &tag_len);

  if (max_len > tag_len)
    {
      memcpy(der, tag_der, tag_len);
    }
  max_len -= tag_len;
  der += tag_len;

  r = _asn1_object_id_der (str, der, &max_len);
  if (r == ASN1_MEM_ERROR || r == ASN1_SUCCESS)
    {
      *der_len = max_len + tag_len;
    }

  return r;
}

static const unsigned char bit_mask[] =
  { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };

/**
 * asn1_bit_der:
 * @str: BIT string.
 * @bit_len: number of meaningful bits in STR.
 * @der: string returned.
 * @der_len: number of meaningful bytes of DER
 *   (der[0]..der[ans_len-1]).
 *
 * Creates a length-value DER encoding for the input data
 * as it would have been for a BIT STRING.
 * The DER encoded data will be copied in @der.
 *
 * Note that the BIT STRING tag is not included in the output.
 *
 * This function does not return any value because it is expected
 * that @der_len will contain enough bytes to store the string
 * plus the DER encoding. The DER encoding size can be obtained using
 * asn1_length_der().
 **/
void
asn1_bit_der (const unsigned char *str, int bit_len,
	      unsigned char *der, int *der_len)
{
  int len_len, len_byte, len_pad;

  if (der == NULL)
    return;

  len_byte = bit_len >> 3;
  len_pad = 8 - (bit_len & 7);
  if (len_pad == 8)
    len_pad = 0;
  else
    len_byte++;
  asn1_length_der (len_byte + 1, der, &len_len);
  der[len_len] = len_pad;

  if (str)
    memcpy (der + len_len + 1, str, len_byte);
  der[len_len + len_byte] &= bit_mask[len_pad];
  *der_len = len_byte + len_len + 1;
}


/******************************************************/
/* Function : _asn1_complete_explicit_tag             */
/* Description: add the length coding to the EXPLICIT */
/* tags.                                              */
/* Parameters:                                        */
/*   node: pointer to the tree element.               */
/*   der: string with the DER coding of the whole tree*/
/*   counter: number of meaningful bytes of DER       */
/*            (der[0]..der[*counter-1]).              */
/*   max_len: size of der vector                      */
/* Return:                                            */
/*   ASN1_MEM_ERROR if der vector isn't big enough,   */
/*   otherwise ASN1_SUCCESS.                          */
/******************************************************/
static int
_asn1_complete_explicit_tag (asn1_node node, unsigned char *der,
			     int *counter, int *max_len)
{
  asn1_node p;
  int is_tag_implicit, len2, len3;
  unsigned char temp[SIZEOF_UNSIGNED_INT];

  if (der == NULL && *max_len > 0)
    return ASN1_VALUE_NOT_VALID;

  is_tag_implicit = 0;

  if (node->type & CONST_TAG)
    {
      p = node->down;
      if (p == NULL)
        return ASN1_DER_ERROR;
      /* When there are nested tags we must complete them reverse to
         the order they were created. This is because completing a tag
         modifies all data within it, including the incomplete tags
         which store buffer positions -- simon@josefsson.org 2002-09-06
       */
      while (p->right)
	p = p->right;
      while (p && p != node->down->left)
	{
	  if (type_field (p->type) == ASN1_ETYPE_TAG)
	    {
	      if (p->type & CONST_EXPLICIT)
		{
		  len2 = strtol (p->name, NULL, 10);
		  _asn1_set_name (p, NULL);

		  asn1_length_der (*counter - len2, temp, &len3);
		  if (len3 <= (*max_len))
		    {
		      memmove (der + len2 + len3, der + len2,
			       *counter - len2);
		      memcpy (der + len2, temp, len3);
		    }
		  *max_len -= len3;
		  *counter += len3;
		  is_tag_implicit = 0;
		}
	      else
		{		/* CONST_IMPLICIT */
		  if (!is_tag_implicit)
		    {
		      is_tag_implicit = 1;
		    }
		}
	    }
	  p = p->left;
	}
    }

  if (*max_len < 0)
    return ASN1_MEM_ERROR;

  return ASN1_SUCCESS;
}

const tag_and_class_st _asn1_tags[] = {
  [ASN1_ETYPE_GENERALSTRING] =
    {ASN1_TAG_GENERALSTRING, ASN1_CLASS_UNIVERSAL, "type:GENERALSTRING"},
  [ASN1_ETYPE_NUMERIC_STRING] =
    {ASN1_TAG_NUMERIC_STRING, ASN1_CLASS_UNIVERSAL, "type:NUMERIC_STR"},
  [ASN1_ETYPE_IA5_STRING] =
    {ASN1_TAG_IA5_STRING, ASN1_CLASS_UNIVERSAL, "type:IA5_STR"},
  [ASN1_ETYPE_TELETEX_STRING] =
    {ASN1_TAG_TELETEX_STRING, ASN1_CLASS_UNIVERSAL, "type:TELETEX_STR"},
  [ASN1_ETYPE_PRINTABLE_STRING] =
    {ASN1_TAG_PRINTABLE_STRING, ASN1_CLASS_UNIVERSAL, "type:PRINTABLE_STR"},
  [ASN1_ETYPE_UNIVERSAL_STRING] =
    {ASN1_TAG_UNIVERSAL_STRING, ASN1_CLASS_UNIVERSAL, "type:UNIVERSAL_STR"},
  [ASN1_ETYPE_BMP_STRING] =
    {ASN1_TAG_BMP_STRING, ASN1_CLASS_UNIVERSAL, "type:BMP_STR"},
  [ASN1_ETYPE_UTF8_STRING] =
    {ASN1_TAG_UTF8_STRING, ASN1_CLASS_UNIVERSAL, "type:UTF8_STR"},
  [ASN1_ETYPE_VISIBLE_STRING] =
    {ASN1_TAG_VISIBLE_STRING, ASN1_CLASS_UNIVERSAL, "type:VISIBLE_STR"},
  [ASN1_ETYPE_OCTET_STRING] =
    {ASN1_TAG_OCTET_STRING, ASN1_CLASS_UNIVERSAL, "type:OCT_STR"},
  [ASN1_ETYPE_BIT_STRING] =
    {ASN1_TAG_BIT_STRING, ASN1_CLASS_UNIVERSAL, "type:BIT_STR"},
  [ASN1_ETYPE_OBJECT_ID] =
    {ASN1_TAG_OBJECT_ID, ASN1_CLASS_UNIVERSAL, "type:OBJ_ID"},
  [ASN1_ETYPE_NULL] = {ASN1_TAG_NULL, ASN1_CLASS_UNIVERSAL, "type:NULL"},
  [ASN1_ETYPE_BOOLEAN] =
    {ASN1_TAG_BOOLEAN, ASN1_CLASS_UNIVERSAL, "type:BOOLEAN"},
  [ASN1_ETYPE_INTEGER] =
    {ASN1_TAG_INTEGER, ASN1_CLASS_UNIVERSAL, "type:INTEGER"},
  [ASN1_ETYPE_ENUMERATED] =
    {ASN1_TAG_ENUMERATED, ASN1_CLASS_UNIVERSAL, "type:ENUMERATED"},
  [ASN1_ETYPE_SEQUENCE] =
    {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
     "type:SEQUENCE"},
  [ASN1_ETYPE_SEQUENCE_OF] =
    {ASN1_TAG_SEQUENCE, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
     "type:SEQ_OF"},
  [ASN1_ETYPE_SET] =
    {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, "type:SET"},
  [ASN1_ETYPE_SET_OF] =
    {ASN1_TAG_SET, ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
     "type:SET_OF"},
  [ASN1_ETYPE_GENERALIZED_TIME] =
    {ASN1_TAG_GENERALIZEDTime, ASN1_CLASS_UNIVERSAL, "type:GENERALIZED_TIME"},
  [ASN1_ETYPE_UTC_TIME] =
    {ASN1_TAG_UTCTime, ASN1_CLASS_UNIVERSAL, "type:UTC_TIME"},
};

unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]);

/******************************************************/
/* Function : _asn1_insert_tag_der                    */
/* Description: creates the DER coding of tags of one */
/* NODE.                                              */
/* Parameters:                                        */
/*   node: pointer to the tree element.               */
/*   der: string returned                             */
/*   counter: number of meaningful bytes of DER       */
/*            (counter[0]..der[*counter-1]).          */
/*   max_len: size of der vector                      */
/* Return:                                            */
/*   ASN1_GENERIC_ERROR if the type is unknown,       */
/*   ASN1_MEM_ERROR if der vector isn't big enough,   */
/*   otherwise ASN1_SUCCESS.                          */
/******************************************************/
static int
_asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
		      int *max_len)
{
  asn1_node p;
  int tag_len, is_tag_implicit;
  unsigned char class, class_implicit = 0, temp[MAX(SIZEOF_UNSIGNED_INT * 3 + 1, LTOSTR_MAX_SIZE)];
  unsigned long tag_implicit = 0;
  unsigned char tag_der[MAX_TAG_LEN];

  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)
		class = ASN1_CLASS_APPLICATION;
	      else if (p->type & CONST_UNIVERSAL)
		class = ASN1_CLASS_UNIVERSAL;
	      else if (p->type & CONST_PRIVATE)
		class = ASN1_CLASS_PRIVATE;
	      else
		class = ASN1_CLASS_CONTEXT_SPECIFIC;

	      if (p->type & CONST_EXPLICIT)
		{
		  if (is_tag_implicit)
		    _asn1_tag_der (class_implicit, tag_implicit, tag_der,
				   &tag_len);
		  else
		    _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
				   _asn1_strtoul (p->value, NULL, 10),
				   tag_der, &tag_len);

		  *max_len -= tag_len;
		  if (der && *max_len >= 0)
		    memcpy (der + *counter, tag_der, tag_len);
		  *counter += tag_len;

		  _asn1_ltostr (*counter, (char *) temp);
		  _asn1_set_name (p, (const char *) temp);

		  is_tag_implicit = 0;
		}
	      else
		{		/* CONST_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))
			class |= ASN1_CLASS_STRUCTURED;
		      class_implicit = class;
		      tag_implicit = _asn1_strtoul (p->value, NULL, 10);
		      is_tag_implicit = 1;
		    }
		}
	    }
	  p = p->right;
	}
    }

  if (is_tag_implicit)
    {
      _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
    }
  else
    {
      unsigned type = type_field (node->type);
      switch (type)
	{
	CASE_HANDLED_ETYPES:
	  _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag,
			 tag_der, &tag_len);
	  break;
	case ASN1_ETYPE_TAG:
	case ASN1_ETYPE_CHOICE:
	case ASN1_ETYPE_ANY:
	  tag_len = 0;
	  break;
	default:
	  return ASN1_GENERIC_ERROR;
	}
    }

  *max_len -= tag_len;
  if (der && *max_len >= 0)
    memcpy (der + *counter, tag_der, tag_len);
  *counter += tag_len;

  if (*max_len < 0)
    return ASN1_MEM_ERROR;

  return ASN1_SUCCESS;
}

/******************************************************/
/* Function : _asn1_ordering_set                      */
/* Description: puts the elements of a SET type in    */
/* the correct order according to DER rules.          */
/* Parameters:                                        */
/*   der: string with the DER coding.                 */
/*   node: pointer to the SET element.                */
/* Return:                                            */
/*    ASN1_SUCCESS if successful                      */
/*    or an error value.                              */
/******************************************************/
static int
_asn1_ordering_set (unsigned char *der, int der_len, asn1_node node)
{
  struct vet
  {
    int end;
    unsigned long value;
    struct vet *next, *prev;
  };

  int counter, len, len2;
  struct vet *first, *last, *p_vet, *p2_vet;
  asn1_node p;
  unsigned char class, *temp;
  unsigned long tag, t;
  int err;

  counter = 0;

  if (type_field (node->type) != ASN1_ETYPE_SET)
    return ASN1_VALUE_NOT_VALID;

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

  if ((p == NULL) || (p->right == NULL))
    return ASN1_SUCCESS;

  first = last = NULL;
  while (p)
    {
      p_vet = malloc (sizeof (struct vet));
      if (p_vet == NULL)
        {
	  err = ASN1_MEM_ALLOC_ERROR;
	  goto error;
	}

      p_vet->next = NULL;
      p_vet->prev = last;
      if (first == NULL)
	first = p_vet;
      else
	last->next = p_vet;
      last = p_vet;

      /* tag value calculation */
      err = asn1_get_tag_der (der + counter, der_len - counter, &class, &len2,
			      &tag);
      if (err != ASN1_SUCCESS)
	goto error;

      t = ((unsigned int)class) << 24;
      p_vet->value = t | tag;
      counter += len2;

      /* extraction and length */
      len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
      if (len2 < 0)
	{
	  err = ASN1_DER_ERROR;
	  goto error;
	}
      counter += len + len2;

      p_vet->end = counter;
      p = p->right;
    }

  p_vet = first;

  while (p_vet)
    {
      p2_vet = p_vet->next;
      counter = 0;
      while (p2_vet)
	{
	  if (p_vet->value > p2_vet->value)
	    {
	      /* change position */
	      temp = malloc (p_vet->end - counter);
	      if (temp == NULL)
		{
		  err = ASN1_MEM_ALLOC_ERROR;
		  goto error;
		}

	      memcpy (temp, der + counter, p_vet->end - counter);
	      memcpy (der + counter, der + p_vet->end,
		      p2_vet->end - p_vet->end);
	      memcpy (der + counter + p2_vet->end - p_vet->end, temp,
		      p_vet->end - counter);
	      free (temp);

	      tag = p_vet->value;
	      p_vet->value = p2_vet->value;
	      p2_vet->value = tag;

	      p_vet->end = counter + (p2_vet->end - p_vet->end);
	    }
	  counter = p_vet->end;

	  p2_vet = p2_vet->next;
	  p_vet = p_vet->next;
	}

      if (p_vet != first)
	p_vet->prev->next = NULL;
      else
	first = NULL;
      free (p_vet);
      p_vet = first;
    }
  return ASN1_SUCCESS;

error:
  while (first != NULL)
    {
      p_vet = first;
      first = first->next;
      free(p_vet);
    }
  return err;
}

struct vet
{
  unsigned char *ptr;
  int size;
};

static int setof_compar(const void *_e1, const void *_e2)
{
  unsigned length;
  const struct vet *e1 = _e1, *e2 = _e2;
  int rval;

  /* The encodings of the component values of a set-of value shall
   * appear in ascending order, the encodings being compared
   * as octet strings with the shorter components being
   * padded at their trailing end with 0-octets.
   * The padding octets are for comparison purposes and
   * do not appear in the encodings.
   */
  length = MIN(e1->size, e2->size);

  rval = memcmp(e1->ptr, e2->ptr, length);
  if (rval == 0 && e1->size != e2->size)
    {
      if (e1->size > e2->size)
        rval = 1;
      else if (e2->size > e1->size)
        rval = -1;
    }

  return rval;
}

/******************************************************/
/* Function : _asn1_ordering_set_of                   */
/* Description: puts the elements of a SET OF type in */
/* the correct order according to DER rules.          */
/* Parameters:                                        */
/*   der: string with the DER coding.                 */
/*   node: pointer to the SET OF element.             */
/* Return:                                            */
/*    ASN1_SUCCESS if successful                      */
/*    or an error value.                              */
/******************************************************/
static int
_asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
{
  int counter, len, len2;
  struct vet *list = NULL, *tlist;
  unsigned list_size = 0;
  struct vet *p_vet;
  asn1_node p;
  unsigned char class;
  unsigned i;
  unsigned char *out = NULL;
  int err;

  if (der == NULL)
    return ASN1_VALUE_NOT_VALID;

  counter = 0;

  if (type_field (node->type) != ASN1_ETYPE_SET_OF)
    return ASN1_VALUE_NOT_VALID;

  p = node->down;
  while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) ||
	 (type_field (p->type) == ASN1_ETYPE_SIZE)))
    p = p->right;
  if (p == NULL)
    return ASN1_VALUE_NOT_VALID;
  p = p->right;

  if ((p == NULL) || (p->right == NULL))
    return ASN1_SUCCESS;

  while (p)
    {
      list_size++;
      tlist = realloc (list, list_size*sizeof(struct vet));
      if (tlist == NULL)
	{
	  err = ASN1_MEM_ALLOC_ERROR;
	  goto error;
	}
      list = tlist;
      p_vet = &list[list_size-1];

      p_vet->ptr = der+counter;
      p_vet->size = 0;

      /* extraction of tag and length */
      if (der_len - counter > 0)
	{
	  err = asn1_get_tag_der (der + counter, der_len - counter, &class,
	                          &len, NULL);
	  if (err != ASN1_SUCCESS)
	    goto error;
	  counter += len;
          p_vet->size += len;

	  len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
	  if (len2 < 0)
	    {
	      err = ASN1_DER_ERROR;
	      goto error;
	    }
	  counter += len + len2;
          p_vet->size += len + len2;

	}
      else
	{
	  err = ASN1_DER_ERROR;
	  goto error;
	}
      p = p->right;
    }

  if (counter > der_len)
    {
      err = ASN1_DER_ERROR;
      goto error;
    }

  qsort(list, list_size, sizeof(struct vet), setof_compar);

  out = malloc(der_len);
  if (out == NULL)
    {
      err = ASN1_MEM_ERROR;
      goto error;
    }

  /* the sum of p_vet->size == der_len */
  counter = 0;
  for (i = 0; i < list_size; i++)
    {
      p_vet = &list[i];
      memcpy(out+counter, p_vet->ptr, p_vet->size);
      counter += p_vet->size;
    }
  memcpy(der, out, der_len);
  free(out);

  err = ASN1_SUCCESS;

error:
  free(list);
  return err;
}

/**
 * asn1_der_coding:
 * @element: pointer to an ASN1 element
 * @name: the name of the structure you want to encode (it must be
 *   inside *POINTER).
 * @ider: vector that will contain the DER encoding. DER must be a
 *   pointer to memory cells already allocated.
 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
 *   holds the sizeof of der vector.
 * @ErrorDescription: return the error description or an empty
 *   string if success.
 *
 * Creates the DER encoding for the NAME structure (inside *POINTER
 * structure).
 *
 * Returns: %ASN1_SUCCESS if DER encoding OK, %ASN1_ELEMENT_NOT_FOUND
 *   if @name is not a valid element, %ASN1_VALUE_NOT_FOUND if there
 *   is an element without a value, %ASN1_MEM_ERROR if the @ider
 *   vector isn't big enough and in this case @len will contain the
 *   length needed.
 **/
int
asn1_der_coding (asn1_node_const element, const char *name, void *ider, int *len,
		 char *ErrorDescription)
{
  asn1_node node, p, p2;
  unsigned char temp[MAX(LTOSTR_MAX_SIZE, SIZEOF_UNSIGNED_LONG_INT * 3 + 1)];
  int counter, counter_old, len2, len3, move, max_len, max_len_old;
  int err;
  unsigned char *der = ider;

  if (ErrorDescription)
    ErrorDescription[0] = 0;

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

  /* Node is now a locally allocated variable.
   * That is because in some point we modify the
   * structure, and I don't know why! --nmav
   */
  node = _asn1_copy_structure3 (node);
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  max_len = *len;

  if (der == NULL && max_len > 0)
    return ASN1_VALUE_NOT_VALID;

  counter = 0;
  move = DOWN;
  p = node;

  while (1)
    {

      counter_old = counter;
      max_len_old = max_len;
      if (move != UP)
	{
          p->start = counter;
	  err = _asn1_insert_tag_der (p, der, &counter, &max_len);
	  if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
	    goto error;
	}
      switch (type_field (p->type))
	{
	case ASN1_ETYPE_NULL:
	  max_len--;
	  if (der != NULL && max_len >= 0)
	    der[counter] = 0;
	  counter++;
	  move = RIGHT;
	  break;
	case ASN1_ETYPE_BOOLEAN:
	  if ((p->type & CONST_DEFAULT) && (p->value == NULL))
	    {
	      counter = counter_old;
	      max_len = max_len_old;
	    }
	  else
	    {
	      if (p->value == NULL)
		{
		  _asn1_error_description_value_not_found (p,
							   ErrorDescription);
		  err = ASN1_VALUE_NOT_FOUND;
		  goto error;
		}
	      max_len -= 2;
	      if (der != NULL && max_len >= 0)
		{
		  der[counter++] = 1;
		  if (p->value[0] == 'F')
		    der[counter++] = 0;
		  else
		    der[counter++] = 0xFF;
		}
	      else
		counter += 2;
	    }
	  move = RIGHT;
	  break;
	case ASN1_ETYPE_INTEGER:
	case ASN1_ETYPE_ENUMERATED:
	  if ((p->type & CONST_DEFAULT) && (p->value == NULL))
	    {
	      counter = counter_old;
	      max_len = max_len_old;
	    }
	  else
	    {
	      if (p->value == NULL)
		{
		  _asn1_error_description_value_not_found (p,
							   ErrorDescription);
		  err = ASN1_VALUE_NOT_FOUND;
		  goto error;
		}
	      len2 = asn1_get_length_der (p->value, p->value_len, &len3);
	      if (len2 < 0)
		{
		  err = ASN1_DER_ERROR;
		  goto error;
		}
	      max_len -= len2 + len3;
	      if (der != NULL && max_len >= 0)
		memcpy (der + counter, p->value, len3 + len2);
	      counter += len3 + len2;
	    }
	  move = RIGHT;
	  break;
	case ASN1_ETYPE_OBJECT_ID:
	  if ((p->type & CONST_DEFAULT) && (p->value == NULL))
	    {
	      counter = counter_old;
	      max_len = max_len_old;
	    }
	  else
	    {
	      if (p->value == NULL)
		{
		  _asn1_error_description_value_not_found (p,
							   ErrorDescription);
		  err = ASN1_VALUE_NOT_FOUND;
		  goto error;
		}
	      len2 = max_len;
	      err = _asn1_object_id_der ((char*)p->value, der + counter, &len2);
	      if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
		goto error;

	      max_len -= len2;
	      counter += len2;
	    }
	  move = RIGHT;
	  break;
	case ASN1_ETYPE_GENERALIZED_TIME:
	case ASN1_ETYPE_UTC_TIME:
	  if (p->value == NULL)
	    {
	      _asn1_error_description_value_not_found (p, ErrorDescription);
	      err = ASN1_VALUE_NOT_FOUND;
	      goto error;
	    }
	  len2 = max_len;
	  err = _asn1_time_der (p->value, p->value_len, der + counter, &len2);
	  if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
	    goto error;

	  max_len -= len2;
	  counter += len2;
	  move = RIGHT;
	  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:
	case ASN1_ETYPE_BIT_STRING:
	  if (p->value == NULL)
	    {
	      _asn1_error_description_value_not_found (p, ErrorDescription);
	      err = ASN1_VALUE_NOT_FOUND;
	      goto error;
	    }
	  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
	  if (len2 < 0)
	    {
	      err = ASN1_DER_ERROR;
	      goto error;
	    }
	  max_len -= len2 + len3;
	  if (der != NULL && max_len >= 0)
	    memcpy (der + counter, p->value, len3 + len2);
	  counter += len3 + len2;
	  move = RIGHT;
	  break;
	case ASN1_ETYPE_SEQUENCE:
	case ASN1_ETYPE_SET:
	  if (move != UP)
	    {
	      p->tmp_ival = counter;
	      if (p->down == NULL)
		{
		  move = UP;
		  continue;
		}
	      else
		{
		  p2 = p->down;
		  while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG))
		    p2 = p2->right;
		  if (p2)
		    {
		      p = p2;
		      move = RIGHT;
		      continue;
		    }
		  move = UP;
		  continue;
		}
	    }
	  else
	    {			/* move==UP */
	      len2 = p->tmp_ival;
	      p->tmp_ival = 0;
	      if ((type_field (p->type) == ASN1_ETYPE_SET) && (max_len >= 0))
		{
		  err = _asn1_ordering_set (der + len2, counter - len2, p);
		  if (err != ASN1_SUCCESS)
		    goto error;
		}
	      asn1_length_der (counter - len2, temp, &len3);
	      max_len -= len3;
	      if (der != NULL && max_len >= 0)
		{
		  memmove (der + len2 + len3, der + len2, counter - len2);
		  memcpy (der + len2, temp, len3);
		}
	      counter += len3;
	      move = RIGHT;
	    }
	  break;
	case ASN1_ETYPE_SEQUENCE_OF:
	case ASN1_ETYPE_SET_OF:
	  if (move != UP)
	    {
	      p->tmp_ival = counter;
	      p = p->down;
	      while ((type_field (p->type) == ASN1_ETYPE_TAG)
		     || (type_field (p->type) == ASN1_ETYPE_SIZE))
		p = p->right;
	      if (p->right)
		{
		  p = p->right;
		  move = RIGHT;
		  continue;
		}
	      else
		p = _asn1_find_up (p);
	      move = UP;
	    }
	  if (move == UP)
	    {
	      len2 = p->tmp_ival;
	      p->tmp_ival = 0;
	      if ((type_field (p->type) == ASN1_ETYPE_SET_OF)
		  && (counter - len2 > 0) && (max_len >= 0))
		{
		  err = _asn1_ordering_set_of (der + len2, counter - len2, p);
		  if (err != ASN1_SUCCESS)
		    goto error;
		}
	      asn1_length_der (counter - len2, temp, &len3);
	      max_len -= len3;
	      if (der != NULL && max_len >= 0)
		{
		  memmove (der + len2 + len3, der + len2, counter - len2);
		  memcpy (der + len2, temp, len3);
		}
	      counter += len3;
	      move = RIGHT;
	    }
	  break;
	case ASN1_ETYPE_ANY:
	  if (p->value == NULL)
	    {
	      _asn1_error_description_value_not_found (p, ErrorDescription);
	      err = ASN1_VALUE_NOT_FOUND;
	      goto error;
	    }
	  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
	  if (len2 < 0)
	    {
	      err = ASN1_DER_ERROR;
	      goto error;
	    }
	  max_len -= len2;
	  if (der != NULL && max_len >= 0)
	    memcpy (der + counter, p->value + len3, len2);
	  counter += len2;
	  move = RIGHT;
	  break;
	default:
	  move = (move == UP) ? RIGHT : DOWN;
	  break;
	}

      if ((move != DOWN) && (counter != counter_old))
	{
          p->end = counter - 1;
	  err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
	  if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
	    goto error;
	}

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

      if (move == DOWN)
	{
	  if (p->down)
	    p = p->down;
	  else
	    move = RIGHT;
	}
      if (move == RIGHT)
	{
	  if (p->right)
	    p = p->right;
	  else
	    move = UP;
	}
      if (move == UP)
	p = _asn1_find_up (p);
    }

  *len = counter;

  if (max_len < 0)
    {
      err = ASN1_MEM_ERROR;
      goto error;
    }

  err = ASN1_SUCCESS;

error:
  asn1_delete_structure (&node);
  return err;
}
