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

#include <config.h>

/*****************************************************/
/* File: 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"

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

  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 successful                       */
/*   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[ASN1_MAX_TAG_SIZE];
  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[ASN1_MAX_TAG_SIZE];

  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;

  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], Initially
 *   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;
  unsigned char dummy;

  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)
    {
      err = ASN1_VALUE_NOT_VALID;
      goto error;
    }

  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 ? der + counter : &dummy, &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 ? der + counter : &dummy, &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 ? der + len2 : &dummy,
					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 ? der + len2 : &dummy,
					   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;
}
