gnutls-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU gnutls branch, master, updated. gnutls_3_1_5-17-gda01538


From: Simon Josefsson
Subject: [SCM] GNU gnutls branch, master, updated. gnutls_3_1_5-17-gda01538
Date: Mon, 26 Nov 2012 20:34:32 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU gnutls".

http://git.savannah.gnu.org/cgit/gnutls.git/commit/?id=da01538e01938e1f2196c389ff1dcde7c3cfcdb9

The branch, master has been updated
       via  da01538e01938e1f2196c389ff1dcde7c3cfcdb9 (commit)
      from  ec66eec0633b01645b6c50b29ad2bbb0f6d0f4c8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit da01538e01938e1f2196c389ff1dcde7c3cfcdb9
Author: Simon Josefsson <address@hidden>
Date:   Mon Nov 26 21:34:25 2012 +0100

    Update minitasn1 to version 3.1.

-----------------------------------------------------------------------

Summary of changes:
 lib/minitasn1/coding.c     |  339 ++++++++++++++++++++++-----------------
 lib/minitasn1/decoding.c   |  383 ++++++++++++++++++++++----------------------
 lib/minitasn1/element.c    |  279 +++++++++++++++++++-------------
 lib/minitasn1/int.h        |  104 +++++++++----
 lib/minitasn1/libtasn1.h   |   77 +++++++---
 lib/minitasn1/parser_aux.c |   50 +++---
 lib/minitasn1/parser_aux.h |    2 +-
 lib/minitasn1/structure.c  |  159 ++++++++----------
 8 files changed, 769 insertions(+), 624 deletions(-)

diff --git a/lib/minitasn1/coding.c b/lib/minitasn1/coding.c
index 581ef96..5361b3f 100644
--- a/lib/minitasn1/coding.c
+++ b/lib/minitasn1/coding.c
@@ -61,24 +61,30 @@ _asn1_error_description_value_not_found (asn1_node node,
 /**
  * asn1_length_der:
  * @len: value to convert.
- * @ans: string returned.
- * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]).
+ * @der: the encoding (may be %NULL).
+ * @der_len: number of meaningful bytes of ANS (der[0]..der[der_len-1]).
  *
- * Creates the DER coding for the LEN parameter (only the length).
- * The @ans buffer is pre-allocated and must have room for the output.
+ * 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 *ans, int *ans_len)
+asn1_length_der (unsigned long int len, unsigned char *der, int *der_len)
 {
   int k;
-  unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
+  unsigned char temp[ASN1_MAX_LENGTH_SIZE];
+#if SIZEOF_UNSIGNED_LONG_INT > 8
+  len &= 0xFFFFFFFFFFFFFFFF;
+#endif
 
   if (len < 128)
     {
       /* short form */
-      if (ans != NULL)
-       ans[0] = (unsigned char) len;
-      *ans_len = 1;
+      if (der != NULL)
+       der[0] = (unsigned char) len;
+      *der_len = 1;
     }
   else
     {
@@ -89,12 +95,12 @@ asn1_length_der (unsigned long int len, unsigned char *ans, 
int *ans_len)
          temp[k++] = len & 0xFF;
          len = len >> 8;
        }
-      *ans_len = k + 1;
-      if (ans != NULL)
+      *der_len = k + 1;
+      if (der != NULL)
        {
-         ans[0] = ((unsigned char) k & 0x7F) + 128;
+         der[0] = ((unsigned char) k & 0x7F) + 128;
          while (k--)
-           ans[*ans_len - 1 - k] = temp[k];
+           der[*der_len - 1 - k] = temp[k];
        }
     }
 }
@@ -103,6 +109,7 @@ asn1_length_der (unsigned long int len, unsigned char *ans, 
int *ans_len)
 /* 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.                     */
@@ -116,7 +123,7 @@ _asn1_tag_der (unsigned char class, unsigned int tag_value,
               unsigned char *ans, int *ans_len)
 {
   int k;
-  unsigned char temp[SIZEOF_UNSIGNED_INT];
+  unsigned char temp[ASN1_MAX_TAG_SIZE];
 
   if (tag_value < 31)
     {
@@ -129,10 +136,13 @@ _asn1_tag_der (unsigned char class, unsigned int 
tag_value,
       /* Long form */
       ans[0] = (class & 0xE0) + 31;
       k = 0;
-      while (tag_value)
+      while (tag_value != 0)
        {
          temp[k++] = tag_value & 0x7F;
-         tag_value = tag_value >> 7;
+         tag_value >>= 7;
+         
+         if (k > ASN1_MAX_TAG_SIZE-1)
+           break; /* will not encode larger tags */
        }
       *ans_len = k + 1;
       while (k--)
@@ -143,12 +153,20 @@ _asn1_tag_der (unsigned char class, unsigned int 
tag_value,
 
 /**
  * asn1_octet_der:
- * @str: OCTET string.
- * @str_len: STR length (str[0]..str[str_len-1]).
- * @der: string returned.
- * @der_len: number of meaningful bytes of DER (der[0]..der[ans_len-1]).
+ * @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.
  *
- * Creates the DER coding for an OCTET type (length included).
+ * 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,
@@ -158,11 +176,73 @@ asn1_octet_der (const unsigned char *str, int str_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     */
@@ -178,11 +258,10 @@ asn1_octet_der (const unsigned char *str, int str_len,
 /*   ASN1_SUCCESS otherwise                           */
 /******************************************************/
 static int
-_asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
+_asn1_time_der (unsigned char *str, int str_len, unsigned char *der, int 
*der_len)
 {
   int len_len;
   int max_len;
-  int str_len = _asn1_strlen (str);
 
   max_len = *der_len;
 
@@ -333,8 +412,16 @@ static const unsigned char bit_mask[] =
  * @der_len: number of meaningful bytes of DER
  *   (der[0]..der[ans_len-1]).
  *
- * Creates the DER coding for a BIT STRING type (length and pad
- * included).
+ * 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,
@@ -344,6 +431,7 @@ asn1_bit_der (const unsigned char *str, int bit_len,
 
   if (der == NULL)
     return;
+
   len_byte = bit_len >> 3;
   len_pad = 8 - (bit_len & 7);
   if (len_pad == 8)
@@ -394,7 +482,7 @@ _asn1_complete_explicit_tag (asn1_node node, unsigned char 
*der,
        p = p->right;
       while (p && p != node->down->left)
        {
-         if (type_field (p->type) == TYPE_TAG)
+         if (type_field (p->type) == ASN1_ETYPE_TAG)
            {
              if (p->type & CONST_EXPLICIT)
                {
@@ -429,6 +517,33 @@ _asn1_complete_explicit_tag (asn1_node node, unsigned char 
*der,
   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                    */
@@ -462,7 +577,7 @@ _asn1_insert_tag_der (asn1_node node, unsigned char *der, 
int *counter,
       p = node->down;
       while (p)
        {
-         if (type_field (p->type) == TYPE_TAG)
+         if (type_field (p->type) == ASN1_ETYPE_TAG)
            {
              if (p->type & CONST_APPLICATION)
                class = ASN1_CLASS_APPLICATION;
@@ -497,10 +612,10 @@ _asn1_insert_tag_der (asn1_node node, unsigned char *der, 
int *counter,
                {               /* CONST_IMPLICIT */
                  if (!is_tag_implicit)
                    {
-                     if ((type_field (node->type) == TYPE_SEQUENCE) ||
-                         (type_field (node->type) == TYPE_SEQUENCE_OF) ||
-                         (type_field (node->type) == TYPE_SET) ||
-                         (type_field (node->type) == TYPE_SET_OF))
+                     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);
@@ -518,67 +633,16 @@ _asn1_insert_tag_der (asn1_node node, unsigned char *der, 
int *counter,
     }
   else
     {
-      switch (type_field (node->type))
+      unsigned type = type_field (node->type);
+      switch (type)
        {
-       case TYPE_NULL:
-         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
-                        &tag_len);
-         break;
-       case TYPE_BOOLEAN:
-         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
-                        &tag_len);
-         break;
-       case TYPE_INTEGER:
-         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
-                        &tag_len);
-         break;
-       case TYPE_ENUMERATED:
-         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
-                        &tag_len);
-         break;
-       case TYPE_OBJECT_ID:
-         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
-                        &tag_len);
-         break;
-       case TYPE_TIME:
-         if (node->type & CONST_UTC)
-           {
-             _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
-                            &tag_len);
-           }
-         else
-           _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
-                          tag_der, &tag_len);
-         break;
-       case TYPE_OCTET_STRING:
-         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
-                        &tag_len);
-         break;
-       case TYPE_GENERALSTRING:
-         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
+        CASE_HANDLED_ETYPES:
+         _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag,
                         tag_der, &tag_len);
          break;
-       case TYPE_BIT_STRING:
-         _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
-                        &tag_len);
-         break;
-       case TYPE_SEQUENCE:
-       case TYPE_SEQUENCE_OF:
-         _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
-                        ASN1_TAG_SEQUENCE, tag_der, &tag_len);
-         break;
-       case TYPE_SET:
-       case TYPE_SET_OF:
-         _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
-                        ASN1_TAG_SET, tag_der, &tag_len);
-         break;
-       case TYPE_TAG:
-         tag_len = 0;
-         break;
-       case TYPE_CHOICE:
-         tag_len = 0;
-         break;
-       case TYPE_ANY:
+       case ASN1_ETYPE_TAG:
+       case ASN1_ETYPE_CHOICE:
+       case ASN1_ETYPE_ANY:
          tag_len = 0;
          break;
        default:
@@ -624,12 +688,12 @@ _asn1_ordering_set (unsigned char *der, int der_len, 
asn1_node node)
 
   counter = 0;
 
-  if (type_field (node->type) != TYPE_SET)
+  if (type_field (node->type) != ASN1_ETYPE_SET)
     return;
 
   p = node->down;
-  while ((type_field (p->type) == TYPE_TAG)
-        || (type_field (p->type) == TYPE_SIZE))
+  while ((type_field (p->type) == ASN1_ETYPE_TAG)
+        || (type_field (p->type) == ASN1_ETYPE_SIZE))
     p = p->right;
 
   if ((p == NULL) || (p->right == NULL))
@@ -737,12 +801,12 @@ _asn1_ordering_set_of (unsigned char *der, int der_len, 
asn1_node node)
 
   counter = 0;
 
-  if (type_field (node->type) != TYPE_SET_OF)
+  if (type_field (node->type) != ASN1_ETYPE_SET_OF)
     return;
 
   p = node->down;
-  while ((type_field (p->type) == TYPE_TAG)
-        || (type_field (p->type) == TYPE_SIZE))
+  while ((type_field (p->type) == ASN1_ETYPE_TAG)
+        || (type_field (p->type) == ASN1_ETYPE_SIZE))
     p = p->right;
   p = p->right;
 
@@ -906,14 +970,14 @@ asn1_der_coding (asn1_node element, const char *name, 
void *ider, int *len,
        }
       switch (type_field (p->type))
        {
-       case TYPE_NULL:
+       case ASN1_ETYPE_NULL:
          max_len--;
          if (max_len >= 0)
            der[counter] = 0;
          counter++;
          move = RIGHT;
          break;
-       case TYPE_BOOLEAN:
+       case ASN1_ETYPE_BOOLEAN:
          if ((p->type & CONST_DEFAULT) && (p->value == NULL))
            {
              counter = counter_old;
@@ -942,8 +1006,8 @@ asn1_der_coding (asn1_node element, const char *name, void 
*ider, int *len,
            }
          move = RIGHT;
          break;
-       case TYPE_INTEGER:
-       case TYPE_ENUMERATED:
+       case ASN1_ETYPE_INTEGER:
+       case ASN1_ETYPE_ENUMERATED:
          if ((p->type & CONST_DEFAULT) && (p->value == NULL))
            {
              counter = counter_old;
@@ -971,7 +1035,7 @@ asn1_der_coding (asn1_node element, const char *name, void 
*ider, int *len,
            }
          move = RIGHT;
          break;
-       case TYPE_OBJECT_ID:
+       case ASN1_ETYPE_OBJECT_ID:
          if ((p->type & CONST_DEFAULT) && (p->value == NULL))
            {
              counter = counter_old;
@@ -996,7 +1060,8 @@ asn1_der_coding (asn1_node element, const char *name, void 
*ider, int *len,
            }
          move = RIGHT;
          break;
-       case TYPE_TIME:
+       case ASN1_ETYPE_GENERALIZED_TIME:
+       case ASN1_ETYPE_UTC_TIME:
          if (p->value == NULL)
            {
              _asn1_error_description_value_not_found (p, ErrorDescription);
@@ -1004,7 +1069,7 @@ asn1_der_coding (asn1_node element, const char *name, 
void *ider, int *len,
              goto error;
            }
          len2 = max_len;
-         err = _asn1_time_der (p->value, der + counter, &len2);
+         err = _asn1_time_der (p->value, p->value_len, der + counter, &len2);
          if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
            goto error;
 
@@ -1012,45 +1077,17 @@ asn1_der_coding (asn1_node element, const char *name, 
void *ider, int *len,
          counter += len2;
          move = RIGHT;
          break;
-       case TYPE_OCTET_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 (max_len >= 0)
-           memcpy (der + counter, p->value, len3 + len2);
-         counter += len3 + len2;
-         move = RIGHT;
-         break;
-       case TYPE_GENERALSTRING:
-         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 (max_len >= 0)
-           memcpy (der + counter, p->value, len3 + len2);
-         counter += len3 + len2;
-         move = RIGHT;
-         break;
-       case TYPE_BIT_STRING:
+       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);
@@ -1069,8 +1106,8 @@ asn1_der_coding (asn1_node element, const char *name, 
void *ider, int *len,
          counter += len3 + len2;
          move = RIGHT;
          break;
-       case TYPE_SEQUENCE:
-       case TYPE_SET:
+       case ASN1_ETYPE_SEQUENCE:
+       case ASN1_ETYPE_SET:
          if (move != UP)
            {
              _asn1_ltostr (counter, (char *) temp);
@@ -1085,7 +1122,7 @@ asn1_der_coding (asn1_node element, const char *name, 
void *ider, int *len,
              else
                {
                  p2 = p->down;
-                 while (p2 && (type_field (p2->type) == TYPE_TAG))
+                 while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG))
                    p2 = p2->right;
                  if (p2)
                    {
@@ -1101,7 +1138,7 @@ asn1_der_coding (asn1_node element, const char *name, 
void *ider, int *len,
            {                   /* move==UP */
              len2 = _asn1_strtol (p->value, NULL, 10);
              _asn1_set_value (p, NULL, 0);
-             if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
+             if ((type_field (p->type) == ASN1_ETYPE_SET) && (max_len >= 0))
                _asn1_ordering_set (der + len2, max_len - len2, p);
              asn1_length_der (counter - len2, temp, &len3);
              max_len -= len3;
@@ -1114,8 +1151,8 @@ asn1_der_coding (asn1_node element, const char *name, 
void *ider, int *len,
              move = RIGHT;
            }
          break;
-       case TYPE_SEQUENCE_OF:
-       case TYPE_SET_OF:
+       case ASN1_ETYPE_SEQUENCE_OF:
+       case ASN1_ETYPE_SET_OF:
          if (move != UP)
            {
              _asn1_ltostr (counter, (char *) temp);
@@ -1124,8 +1161,8 @@ asn1_der_coding (asn1_node element, const char *name, 
void *ider, int *len,
              if (tlen > 0)
                _asn1_set_value (p, temp, tlen + 1);
              p = p->down;
-             while ((type_field (p->type) == TYPE_TAG)
-                    || (type_field (p->type) == TYPE_SIZE))
+             while ((type_field (p->type) == ASN1_ETYPE_TAG)
+                    || (type_field (p->type) == ASN1_ETYPE_SIZE))
                p = p->right;
              if (p->right)
                {
@@ -1141,7 +1178,7 @@ asn1_der_coding (asn1_node element, const char *name, 
void *ider, int *len,
            {
              len2 = _asn1_strtol (p->value, NULL, 10);
              _asn1_set_value (p, NULL, 0);
-             if ((type_field (p->type) == TYPE_SET_OF)
+             if ((type_field (p->type) == ASN1_ETYPE_SET_OF)
                  && (max_len - len2 > 0))
                {
                  _asn1_ordering_set_of (der + len2, max_len - len2, p);
@@ -1157,7 +1194,7 @@ asn1_der_coding (asn1_node element, const char *name, 
void *ider, int *len,
              move = RIGHT;
            }
          break;
-       case TYPE_ANY:
+       case ASN1_ETYPE_ANY:
          if (p->value == NULL)
            {
              _asn1_error_description_value_not_found (p, ErrorDescription);
diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c
index 79766a1..f02fe10 100644
--- a/lib/minitasn1/decoding.c
+++ b/lib/minitasn1/decoding.c
@@ -387,7 +387,7 @@ _asn1_extract_tag_der (asn1_node node, const unsigned char 
*der, int der_len,
       p = node->down;
       while (p)
        {
-         if (type_field (p->type) == TYPE_TAG)
+         if (type_field (p->type) == ASN1_ETYPE_TAG)
            {
              if (p->type & CONST_APPLICATION)
                class2 = ASN1_CLASS_APPLICATION;
@@ -436,10 +436,10 @@ _asn1_extract_tag_der (asn1_node node, const unsigned 
char *der, int der_len,
                {               /* ASN1_TAG_IMPLICIT */
                  if (!is_tag_implicit)
                    {
-                     if ((type_field (node->type) == TYPE_SEQUENCE) ||
-                         (type_field (node->type) == TYPE_SEQUENCE_OF) ||
-                         (type_field (node->type) == TYPE_SET) ||
-                         (type_field (node->type) == TYPE_SET_OF))
+                     if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
+                         (type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF) ||
+                         (type_field (node->type) == ASN1_ETYPE_SET) ||
+                         (type_field (node->type) == ASN1_ETYPE_SET_OF))
                        class2 |= ASN1_CLASS_STRUCTURED;
                      class_implicit = class2;
                      tag_implicit = strtoul ((char *) p->value, NULL, 10);
@@ -462,7 +462,7 @@ _asn1_extract_tag_der (asn1_node node, const unsigned char 
*der, int der_len,
 
       if ((class != class_implicit) || (tag != tag_implicit))
        {
-         if (type_field (node->type) == TYPE_OCTET_STRING)
+         if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING)
            {
              class_implicit |= ASN1_CLASS_STRUCTURED;
              if ((class != class_implicit) || (tag != tag_implicit))
@@ -474,7 +474,8 @@ _asn1_extract_tag_der (asn1_node node, const unsigned char 
*der, int der_len,
     }
   else
     {
-      if (type_field (node->type) == TYPE_TAG)
+      unsigned type = type_field (node->type);
+      if (type == ASN1_ETYPE_TAG)
        {
          counter = 0;
          *ret_len = counter;
@@ -489,70 +490,42 @@ _asn1_extract_tag_der (asn1_node node, const unsigned 
char *der, int der_len,
       if (counter + len2 > der_len)
        return ASN1_DER_ERROR;
 
-      switch (type_field (node->type))
+      switch (type)
        {
-       case TYPE_NULL:
-         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
+       case ASN1_ETYPE_NULL:
+       case ASN1_ETYPE_BOOLEAN:
+       case ASN1_ETYPE_INTEGER:
+       case ASN1_ETYPE_ENUMERATED:
+       case ASN1_ETYPE_OBJECT_ID:
+       case ASN1_ETYPE_GENERALSTRING:
+       case ASN1_ETYPE_NUMERIC_STRING:
+       case ASN1_ETYPE_IA5_STRING:
+       case ASN1_ETYPE_TELETEX_STRING:
+       case ASN1_ETYPE_PRINTABLE_STRING:
+       case ASN1_ETYPE_UNIVERSAL_STRING:
+       case ASN1_ETYPE_BMP_STRING:
+       case ASN1_ETYPE_UTF8_STRING:
+       case ASN1_ETYPE_VISIBLE_STRING:
+       case ASN1_ETYPE_BIT_STRING:
+       case ASN1_ETYPE_SEQUENCE:
+       case ASN1_ETYPE_SEQUENCE_OF:
+       case ASN1_ETYPE_SET:
+       case ASN1_ETYPE_SET_OF:
+       case ASN1_ETYPE_GENERALIZED_TIME:
+       case ASN1_ETYPE_UTC_TIME:
+         if ((class != _asn1_tags[type].class) || (tag != 
_asn1_tags[type].tag))
            return ASN1_DER_ERROR;
          break;
-       case TYPE_BOOLEAN:
-         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
-           return ASN1_DER_ERROR;
-         break;
-       case TYPE_INTEGER:
-         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
-           return ASN1_DER_ERROR;
-         break;
-       case TYPE_ENUMERATED:
-         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
-           return ASN1_DER_ERROR;
-         break;
-       case TYPE_OBJECT_ID:
-         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
-           return ASN1_DER_ERROR;
-         break;
-       case TYPE_TIME:
-         if (node->type & CONST_UTC)
-           {
-             if ((class != ASN1_CLASS_UNIVERSAL)
-                 || (tag != ASN1_TAG_UTCTime))
-               return ASN1_DER_ERROR;
-           }
-         else
-           {
-             if ((class != ASN1_CLASS_UNIVERSAL)
-                 || (tag != ASN1_TAG_GENERALIZEDTime))
-               return ASN1_DER_ERROR;
-           }
-         break;
-       case TYPE_OCTET_STRING:
+
+       case ASN1_ETYPE_OCTET_STRING:
+         /* OCTET STRING is handled differently to allow
+          * BER encodings (structured class). */
          if (((class != ASN1_CLASS_UNIVERSAL)
               && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
              || (tag != ASN1_TAG_OCTET_STRING))
            return ASN1_DER_ERROR;
          break;
-       case TYPE_GENERALSTRING:
-         if ((class != ASN1_CLASS_UNIVERSAL)
-             || (tag != ASN1_TAG_GENERALSTRING))
-           return ASN1_DER_ERROR;
-         break;
-       case TYPE_BIT_STRING:
-         if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
-           return ASN1_DER_ERROR;
-         break;
-       case TYPE_SEQUENCE:
-       case TYPE_SEQUENCE_OF:
-         if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
-             || (tag != ASN1_TAG_SEQUENCE))
-           return ASN1_DER_ERROR;
-         break;
-       case TYPE_SET:
-       case TYPE_SET_OF:
-         if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
-             || (tag != ASN1_TAG_SET))
-           return ASN1_DER_ERROR;
-         break;
-       case TYPE_ANY:
+       case ASN1_ETYPE_ANY:
          counter -= len2;
          break;
        default:
@@ -883,7 +856,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                {
                  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
                    {
-                     if (type_field (p2->type) != TYPE_CHOICE)
+                     if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
                        ris =
                          _asn1_extract_tag_der (p2, der + counter,
                                                 len - counter, &len2);
@@ -938,7 +911,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                }
            }
 
-         if (type_field (p->type) == TYPE_CHOICE)
+         if (type_field (p->type) == ASN1_ETYPE_CHOICE)
            {
              while (p->down)
                {
@@ -1021,7 +994,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
        {
          switch (type_field (p->type))
            {
-           case TYPE_NULL:
+           case ASN1_ETYPE_NULL:
              if (der[counter])
                {
                  result = ASN1_DER_ERROR;
@@ -1030,7 +1003,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
              counter++;
              move = RIGHT;
              break;
-           case TYPE_BOOLEAN:
+           case ASN1_ETYPE_BOOLEAN:
              if (der[counter++] != 1)
                {
                  result = ASN1_DER_ERROR;
@@ -1042,8 +1015,8 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                _asn1_set_value (p, "T", 1);
              move = RIGHT;
              break;
-           case TYPE_INTEGER:
-           case TYPE_ENUMERATED:
+           case ASN1_ETYPE_INTEGER:
+           case ASN1_ETYPE_ENUMERATED:
              len2 =
                asn1_get_length_der (der + counter, len - counter, &len3);
              if (len2 < 0)
@@ -1056,7 +1029,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
              counter += len3 + len2;
              move = RIGHT;
              break;
-           case TYPE_OBJECT_ID:
+           case ASN1_ETYPE_OBJECT_ID:
              result =
                _asn1_get_objectid_der (der + counter, len - counter, &len2,
                                        temp, sizeof (temp));
@@ -1069,7 +1042,8 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
              counter += len2;
              move = RIGHT;
              break;
-           case TYPE_TIME:
+           case ASN1_ETYPE_GENERALIZED_TIME:
+           case ASN1_ETYPE_UTC_TIME:
              result =
                _asn1_get_time_der (der + counter, len - counter, &len2, temp,
                                    sizeof (temp) - 1);
@@ -1078,11 +1052,11 @@ asn1_der_decoding (asn1_node * element, const void 
*ider, int len,
 
              tlen = strlen (temp);
              if (tlen > 0)
-               _asn1_set_value (p, temp, tlen + 1);
+               _asn1_set_value (p, temp, tlen);
              counter += len2;
              move = RIGHT;
              break;
-           case TYPE_OCTET_STRING:
+           case ASN1_ETYPE_OCTET_STRING:
              len3 = len - counter;
              result = _asn1_get_octet_string (der + counter, p, &len3);
              if (result != ASN1_SUCCESS)
@@ -1091,7 +1065,16 @@ asn1_der_decoding (asn1_node * element, const void 
*ider, int len,
              counter += len3;
              move = RIGHT;
              break;
-           case TYPE_GENERALSTRING:
+           case ASN1_ETYPE_GENERALSTRING:
+            case ASN1_ETYPE_NUMERIC_STRING:
+            case ASN1_ETYPE_IA5_STRING:
+            case ASN1_ETYPE_TELETEX_STRING:
+            case ASN1_ETYPE_PRINTABLE_STRING:
+            case ASN1_ETYPE_UNIVERSAL_STRING:
+            case ASN1_ETYPE_BMP_STRING:
+            case ASN1_ETYPE_UTF8_STRING:
+            case ASN1_ETYPE_VISIBLE_STRING:
+           case ASN1_ETYPE_BIT_STRING:
              len2 =
                asn1_get_length_der (der + counter, len - counter, &len3);
              if (len2 < 0)
@@ -1104,21 +1087,8 @@ asn1_der_decoding (asn1_node * element, const void 
*ider, int len,
              counter += len3 + len2;
              move = RIGHT;
              break;
-           case TYPE_BIT_STRING:
-             len2 =
-               asn1_get_length_der (der + counter, len - counter, &len3);
-             if (len2 < 0)
-               {
-                 result = ASN1_DER_ERROR;
-                 goto cleanup;
-               }
-
-             _asn1_set_value (p, der + counter, len3 + len2);
-             counter += len3 + len2;
-             move = RIGHT;
-             break;
-           case TYPE_SEQUENCE:
-           case TYPE_SET:
+           case ASN1_ETYPE_SEQUENCE:
+           case ASN1_ETYPE_SET:
              if (move == UP)
                {
                  len2 = _asn1_strtol (p->value, NULL, 10);
@@ -1173,7 +1143,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                      p2 = p->down;
                      while (p2)
                        {
-                         if (type_field (p2->type) != TYPE_TAG)
+                         if (type_field (p2->type) != ASN1_ETYPE_TAG)
                            {
                              p3 = p2->right;
                              asn1_delete_structure (&p2);
@@ -1191,8 +1161,8 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                    }
                }
              break;
-           case TYPE_SEQUENCE_OF:
-           case TYPE_SET_OF:
+           case ASN1_ETYPE_SEQUENCE_OF:
+           case ASN1_ETYPE_SET_OF:
              if (move == UP)
                {
                  len2 = _asn1_strtol (p->value, NULL, 10);
@@ -1260,8 +1230,8 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                          _asn1_set_value (p, "-1", 3);
                        }
                      p2 = p->down;
-                     while ((type_field (p2->type) == TYPE_TAG)
-                            || (type_field (p2->type) == TYPE_SIZE))
+                     while ((type_field (p2->type) == ASN1_ETYPE_TAG)
+                            || (type_field (p2->type) == ASN1_ETYPE_SIZE))
                        p2 = p2->right;
                      if (p2->right == NULL)
                        _asn1_append_sequence_set (p);
@@ -1270,7 +1240,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                }
              move = RIGHT;
              break;
-           case TYPE_ANY:
+           case ASN1_ETYPE_ANY:
              if (asn1_get_tag_der
                  (der + counter, len - counter, &class, &len2,
                   &tag) != ASN1_SUCCESS)
@@ -1295,7 +1265,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
              if (len4 != -1)
                {
                  len2 += len4;
-                 _asn1_set_value_octet (p, der + counter, len2 + len3);
+                 _asn1_set_value_lv (p, der + counter, len2 + len3);
                  counter += len2 + len3;
                }
              else
@@ -1312,7 +1282,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, 
int len,
                  if (result != ASN1_SUCCESS)
                    goto cleanup;
 
-                 _asn1_set_value_octet (p, der + counter, len2);
+                 _asn1_set_value_lv (p, der + counter, len2);
                  counter += len2;
 
                  /* Check if a couple of 0x00 are present due to an EXPLICIT 
TAG with
@@ -1494,7 +1464,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
                {
                  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
                    {
-                     if (type_field (p2->type) != TYPE_CHOICE)
+                     if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
                        ris =
                          _asn1_extract_tag_der (p2, der + counter,
                                                 len - counter, &len2);
@@ -1549,7 +1519,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
                }
            }
 
-         if (type_field (p->type) == TYPE_CHOICE)
+         if (type_field (p->type) == ASN1_ETYPE_CHOICE)
            {
              while (p->down)
                {
@@ -1632,7 +1602,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
        {
          switch (type_field (p->type))
            {
-           case TYPE_NULL:
+           case ASN1_ETYPE_NULL:
              if (der[counter])
                {
                  result = ASN1_DER_ERROR;
@@ -1645,7 +1615,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
              counter++;
              move = RIGHT;
              break;
-           case TYPE_BOOLEAN:
+           case ASN1_ETYPE_BOOLEAN:
              if (der[counter++] != 1)
                {
                  result = ASN1_DER_ERROR;
@@ -1668,8 +1638,8 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
 
              move = RIGHT;
              break;
-           case TYPE_INTEGER:
-           case TYPE_ENUMERATED:
+           case ASN1_ETYPE_INTEGER:
+           case ASN1_ETYPE_ENUMERATED:
              len2 =
                asn1_get_length_der (der + counter, len - counter, &len3);
              if (len2 < 0)
@@ -1693,7 +1663,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
              counter += len3 + len2;
              move = RIGHT;
              break;
-           case TYPE_OBJECT_ID:
+           case ASN1_ETYPE_OBJECT_ID:
              if (state == FOUND)
                {
                  result =
@@ -1725,7 +1695,8 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
              counter += len2;
              move = RIGHT;
              break;
-           case TYPE_TIME:
+           case ASN1_ETYPE_GENERALIZED_TIME:
+           case ASN1_ETYPE_UTC_TIME:
              if (state == FOUND)
                {
                  result =
@@ -1756,7 +1727,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
              counter += len2;
              move = RIGHT;
              break;
-           case TYPE_OCTET_STRING:
+           case ASN1_ETYPE_OCTET_STRING:
              len3 = len - counter;
              if (state == FOUND)
                {
@@ -1773,7 +1744,16 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
              counter += len3;
              move = RIGHT;
              break;
-           case TYPE_GENERALSTRING:
+           case ASN1_ETYPE_GENERALSTRING:
+            case ASN1_ETYPE_NUMERIC_STRING:
+            case ASN1_ETYPE_IA5_STRING:
+            case ASN1_ETYPE_TELETEX_STRING:
+            case ASN1_ETYPE_PRINTABLE_STRING:
+            case ASN1_ETYPE_UNIVERSAL_STRING:
+            case ASN1_ETYPE_BMP_STRING:
+            case ASN1_ETYPE_UTF8_STRING:
+            case ASN1_ETYPE_VISIBLE_STRING:
+           case ASN1_ETYPE_BIT_STRING:
              len2 =
                asn1_get_length_der (der + counter, len - counter, &len3);
              if (len2 < 0)
@@ -1797,31 +1777,8 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
              counter += len3 + len2;
              move = RIGHT;
              break;
-           case TYPE_BIT_STRING:
-             len2 =
-               asn1_get_length_der (der + counter, len - counter, &len3);
-             if (len2 < 0)
-               {
-                 result = ASN1_DER_ERROR;
-                 goto cleanup;
-               }
-             if (state == FOUND)
-               {
-                 if (len3 + len2 > len - counter)
-                   {
-                     result = ASN1_DER_ERROR;
-                     goto cleanup;
-                   }
-                 _asn1_set_value (p, der + counter, len3 + len2);
-
-                 if (p == nodeFound)
-                   state = EXIT;
-               }
-             counter += len3 + len2;
-             move = RIGHT;
-             break;
-           case TYPE_SEQUENCE:
-           case TYPE_SET:
+           case ASN1_ETYPE_SEQUENCE:
+           case ASN1_ETYPE_SET:
              if (move == UP)
                {
                  len2 = _asn1_strtol (p->value, NULL, 10);
@@ -1887,7 +1844,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
                          p2 = p->down;
                          while (p2)
                            {
-                             if (type_field (p2->type) != TYPE_TAG)
+                             if (type_field (p2->type) != ASN1_ETYPE_TAG)
                                {
                                  p3 = p2->right;
                                  asn1_delete_structure (&p2);
@@ -1906,8 +1863,8 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
                    }
                }
              break;
-           case TYPE_SEQUENCE_OF:
-           case TYPE_SET_OF:
+           case ASN1_ETYPE_SEQUENCE_OF:
+           case ASN1_ETYPE_SET_OF:
              if (move == UP)
                {
                  len2 = _asn1_strtol (p->value, NULL, 10);
@@ -1964,8 +1921,8 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
                          if (tlen > 0)
                            _asn1_set_value (p, temp, tlen + 1);
                          p2 = p->down;
-                         while ((type_field (p2->type) == TYPE_TAG)
-                                || (type_field (p2->type) == TYPE_SIZE))
+                         while ((type_field (p2->type) == ASN1_ETYPE_TAG)
+                                || (type_field (p2->type) == ASN1_ETYPE_SIZE))
                            p2 = p2->right;
                          if (p2->right == NULL)
                            _asn1_append_sequence_set (p);
@@ -1976,7 +1933,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
                }
 
              break;
-           case TYPE_ANY:
+           case ASN1_ETYPE_ANY:
              if (asn1_get_tag_der
                  (der + counter, len - counter, &class, &len2,
                   &tag) != ASN1_SUCCESS)
@@ -2005,7 +1962,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
                  len2 += len4;
                  if (state == FOUND)
                    {
-                     _asn1_set_value_octet (p, der + counter, len2 + len3);
+                     _asn1_set_value_lv (p, der + counter, len2 + len3);
 
                      if (p == nodeFound)
                        state = EXIT;
@@ -2028,7 +1985,7 @@ asn1_der_decoding_element (asn1_node * structure, const 
char *elementName,
 
                  if (state == FOUND)
                    {
-                     _asn1_set_value_octet (p, der + counter, len2);
+                     _asn1_set_value_lv (p, der + counter, len2);
 
                      if (p == nodeFound)
                        state = EXIT;
@@ -2289,7 +2246,7 @@ asn1_der_decoding_startEnd (asn1_node element, const void 
*ider, int len,
                {
                  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
                    {           /* CONTROLLARE */
-                     if (type_field (p2->type) != TYPE_CHOICE)
+                     if (type_field (p2->type) != ASN1_ETYPE_CHOICE)
                        ris =
                          _asn1_extract_tag_der (p2, der + counter,
                                                 len - counter, &len2);
@@ -2319,7 +2276,7 @@ asn1_der_decoding_startEnd (asn1_node element, const void 
*ider, int len,
          if (p == node_to_find)
            *start = counter;
 
-         if (type_field (p->type) == TYPE_CHOICE)
+         if (type_field (p->type) == ASN1_ETYPE_CHOICE)
            {
              p = p->down;
               if (p == NULL)
@@ -2359,44 +2316,19 @@ asn1_der_decoding_startEnd (asn1_node element, const 
void *ider, int len,
        {
          switch (type_field (p->type))
            {
-           case TYPE_NULL:
+           case ASN1_ETYPE_NULL:
              if (der[counter])
                return ASN1_DER_ERROR;
              counter++;
              move = RIGHT;
              break;
-           case TYPE_BOOLEAN:
+           case ASN1_ETYPE_BOOLEAN:
              if (der[counter++] != 1)
                return ASN1_DER_ERROR;
              counter++;
              move = RIGHT;
              break;
-           case TYPE_INTEGER:
-           case TYPE_ENUMERATED:
-             len2 =
-               asn1_get_length_der (der + counter, len - counter, &len3);
-             if (len2 < 0)
-               return ASN1_DER_ERROR;
-             counter += len3 + len2;
-             move = RIGHT;
-             break;
-           case TYPE_OBJECT_ID:
-             len2 =
-               asn1_get_length_der (der + counter, len - counter, &len3);
-             if (len2 < 0)
-               return ASN1_DER_ERROR;
-             counter += len2 + len3;
-             move = RIGHT;
-             break;
-           case TYPE_TIME:
-             len2 =
-               asn1_get_length_der (der + counter, len - counter, &len3);
-             if (len2 < 0)
-               return ASN1_DER_ERROR;
-             counter += len2 + len3;
-             move = RIGHT;
-             break;
-           case TYPE_OCTET_STRING:
+           case ASN1_ETYPE_OCTET_STRING:
              len3 = len - counter;
              ris = _asn1_get_octet_string (der + counter, NULL, &len3);
              if (ris != ASN1_SUCCESS)
@@ -2404,7 +2336,21 @@ asn1_der_decoding_startEnd (asn1_node element, const 
void *ider, int len,
              counter += len3;
              move = RIGHT;
              break;
-           case TYPE_GENERALSTRING:
+           case ASN1_ETYPE_UTC_TIME:
+           case ASN1_ETYPE_GENERALIZED_TIME:
+           case ASN1_ETYPE_OBJECT_ID:
+           case ASN1_ETYPE_INTEGER:
+           case ASN1_ETYPE_ENUMERATED:
+           case ASN1_ETYPE_GENERALSTRING:
+            case ASN1_ETYPE_NUMERIC_STRING:
+            case ASN1_ETYPE_IA5_STRING:
+            case ASN1_ETYPE_TELETEX_STRING:
+            case ASN1_ETYPE_PRINTABLE_STRING:
+            case ASN1_ETYPE_UNIVERSAL_STRING:
+            case ASN1_ETYPE_BMP_STRING:
+            case ASN1_ETYPE_UTF8_STRING:
+            case ASN1_ETYPE_VISIBLE_STRING:
+           case ASN1_ETYPE_BIT_STRING:
              len2 =
                asn1_get_length_der (der + counter, len - counter, &len3);
              if (len2 < 0)
@@ -2412,16 +2358,8 @@ asn1_der_decoding_startEnd (asn1_node element, const 
void *ider, int len,
              counter += len3 + len2;
              move = RIGHT;
              break;
-           case TYPE_BIT_STRING:
-             len2 =
-               asn1_get_length_der (der + counter, len - counter, &len3);
-             if (len2 < 0)
-               return ASN1_DER_ERROR;
-             counter += len3 + len2;
-             move = RIGHT;
-             break;
-           case TYPE_SEQUENCE:
-           case TYPE_SET:
+           case ASN1_ETYPE_SEQUENCE:
+           case ASN1_ETYPE_SET:
              if (move != UP)
                {
                  len3 =
@@ -2441,8 +2379,8 @@ asn1_der_decoding_startEnd (asn1_node element, const void 
*ider, int len,
                  move = RIGHT;
                }
              break;
-           case TYPE_SEQUENCE_OF:
-           case TYPE_SET_OF:
+           case ASN1_ETYPE_SEQUENCE_OF:
+           case ASN1_ETYPE_SET_OF:
              if (move != UP)
                {
                  len3 =
@@ -2455,8 +2393,8 @@ asn1_der_decoding_startEnd (asn1_node element, const void 
*ider, int len,
                  else if (len3)
                    {
                      p2 = p->down;
-                     while ((type_field (p2->type) == TYPE_TAG) ||
-                            (type_field (p2->type) == TYPE_SIZE))
+                     while ((type_field (p2->type) == ASN1_ETYPE_TAG) ||
+                            (type_field (p2->type) == ASN1_ETYPE_SIZE))
                        p2 = p2->right;
                      p = p2;
                    }
@@ -2468,7 +2406,7 @@ asn1_der_decoding_startEnd (asn1_node element, const void 
*ider, int len,
                }
              move = RIGHT;
              break;
-           case TYPE_ANY:
+           case ASN1_ETYPE_ANY:
              if (asn1_get_tag_der
                  (der + counter, len - counter, &class, &len2,
                   &tag) != ASN1_SUCCESS)
@@ -2587,12 +2525,12 @@ asn1_expand_any_defined_by (asn1_node definitions, 
asn1_node * element)
 
       switch (type_field (p->type))
        {
-       case TYPE_ANY:
+       case ASN1_ETYPE_ANY:
          if ((p->type & CONST_DEFINED_BY) && (p->value))
            {
              /* search the "DEF_BY" element */
              p2 = p->down;
-             while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
+             while ((p2) && (type_field (p2->type) != ASN1_ETYPE_CONSTANT))
                p2 = p2->right;
 
              if (!p2)
@@ -2617,7 +2555,7 @@ asn1_expand_any_defined_by (asn1_node definitions, 
asn1_node * element)
                  p3 = p3->right;
                }
 
-             if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
+             if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
                  (p3->value == NULL))
                {
 
@@ -2639,7 +2577,7 @@ asn1_expand_any_defined_by (asn1_node definitions, 
asn1_node * element)
                      p3 = p3->right;
                    }
 
-                 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
+                 if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) 
||
                      (p3->value == NULL))
                    {
                      retCode = ASN1_ERROR_TYPE_ANY;
@@ -2651,7 +2589,7 @@ asn1_expand_any_defined_by (asn1_node definitions, 
asn1_node * element)
              p2 = definitions->down;
              while (p2)
                {
-                 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
+                 if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
                      (p2->type & CONST_ASSIGN))
                    {
                      strcpy (name, definitionsName);
@@ -2812,7 +2750,7 @@ asn1_expand_octet_string (asn1_node definitions, 
asn1_node * element,
   octetNode = asn1_find_node (*element, octetName);
   if (octetNode == NULL)
     return ASN1_ELEMENT_NOT_FOUND;
-  if (type_field (octetNode->type) != TYPE_OCTET_STRING)
+  if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING)
     return ASN1_ELEMENT_NOT_FOUND;
   if (octetNode->value == NULL)
     return ASN1_VALUE_NOT_FOUND;
@@ -2821,7 +2759,7 @@ asn1_expand_octet_string (asn1_node definitions, 
asn1_node * element,
   if (objectNode == NULL)
     return ASN1_ELEMENT_NOT_FOUND;
 
-  if (type_field (objectNode->type) != TYPE_OBJECT_ID)
+  if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID)
     return ASN1_ELEMENT_NOT_FOUND;
 
   if (objectNode->value == NULL)
@@ -2832,7 +2770,7 @@ asn1_expand_octet_string (asn1_node definitions, 
asn1_node * element,
   p2 = definitions->down;
   while (p2)
     {
-      if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
+      if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) &&
          (p2->type & CONST_ASSIGN))
        {
          strcpy (name, definitions->name);
@@ -2918,3 +2856,60 @@ asn1_expand_octet_string (asn1_node definitions, 
asn1_node * element,
 
   return retCode;
 }
+
+/**
+ * asn1_decode_simple_der:
+ * @etype: The type of the string to be encoded (ASN1_ETYPE_)
+ * @der: the encoded string
+ * @der_len: the bytes of the encoded string
+ * @str: a pointer to the data
+ * @str_len: the length of the data
+ *
+ * Decodes a simple DER encoded type (e.g. a string, which is not constructed).
+ * The output is a pointer inside the @der.
+ *
+ * Returns: %ASN1_SUCCESS if successful or an error value. 
+ **/
+int
+asn1_decode_simple_der (unsigned int etype, const unsigned char *der, unsigned 
int der_len,
+                        const unsigned char **str, unsigned int *str_len)
+{
+  int tag_len, len_len;
+  const unsigned char* p;
+  unsigned char class;
+  unsigned long tag;
+  long ret;
+
+  if (der == NULL || der_len == 0)
+    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;
+
+  p = der;
+  ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
+  if (ret != ASN1_SUCCESS)
+    return ret;
+  
+  if (class != ETYPE_CLASS(etype) || tag != ETYPE_TAG(etype))
+    return ASN1_DER_ERROR;
+
+  p += tag_len;
+  der_len -= tag_len;
+  
+  ret = asn1_get_length_der (p, der_len, &len_len);
+  if (ret < 0) 
+    return ASN1_DER_ERROR;
+
+  p += len_len;
+  der_len -= len_len;
+  
+  *str_len = ret;
+  *str = p;
+
+  return ASN1_SUCCESS;
+}
diff --git a/lib/minitasn1/element.c b/lib/minitasn1/element.c
index 4c871a1..763ac58 100644
--- a/lib/minitasn1/element.c
+++ b/lib/minitasn1/element.c
@@ -137,8 +137,8 @@ _asn1_append_sequence_set (asn1_node node)
     return ASN1_GENERIC_ERROR;
 
   p = node->down;
-  while ((type_field (p->type) == TYPE_TAG)
-        || (type_field (p->type) == TYPE_SIZE))
+  while ((type_field (p->type) == ASN1_ETYPE_TAG)
+        || (type_field (p->type) == ASN1_ETYPE_SIZE))
     p = p->right;
   p2 = _asn1_copy_structure3 (p);
   while (p->right)
@@ -276,6 +276,7 @@ asn1_write_value (asn1_node node_root, const char *name,
   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)
@@ -286,13 +287,15 @@ asn1_write_value (asn1_node node_root, const char *name,
       asn1_delete_structure (&node);
       return ASN1_SUCCESS;
     }
+  
+  type = type_field(node->type);
 
-  if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL)
+  if ((type == ASN1_ETYPE_SEQUENCE_OF) && (value == NULL)
       && (len == 0))
     {
       p = node->down;
-      while ((type_field (p->type) == TYPE_TAG)
-            || (type_field (p->type) == TYPE_SIZE))
+      while ((type_field (p->type) == ASN1_ETYPE_TAG)
+            || (type_field (p->type) == ASN1_ETYPE_SIZE))
        p = p->right;
 
       while (p->right)
@@ -301,15 +304,15 @@ asn1_write_value (asn1_node node_root, const char *name,
       return ASN1_SUCCESS;
     }
 
-  switch (type_field (node->type))
+  switch (type)
     {
-    case TYPE_BOOLEAN:
+    case ASN1_ETYPE_BOOLEAN:
       if (!_asn1_strcmp (value, "TRUE"))
        {
          if (node->type & CONST_DEFAULT)
            {
              p = node->down;
-             while (type_field (p->type) != TYPE_DEFAULT)
+             while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
                p = p->right;
              if (p->type & CONST_TRUE)
                _asn1_set_value (node, NULL, 0);
@@ -324,7 +327,7 @@ asn1_write_value (asn1_node node_root, const char *name,
          if (node->type & CONST_DEFAULT)
            {
              p = node->down;
-             while (type_field (p->type) != TYPE_DEFAULT)
+             while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
                p = p->right;
              if (p->type & CONST_FALSE)
                _asn1_set_value (node, NULL, 0);
@@ -337,8 +340,8 @@ asn1_write_value (asn1_node node_root, const char *name,
       else
        return ASN1_VALUE_NOT_VALID;
       break;
-    case TYPE_INTEGER:
-    case TYPE_ENUMERATED:
+    case ASN1_ETYPE_INTEGER:
+    case ASN1_ETYPE_ENUMERATED:
       if (len == 0)
        {
          if ((isdigit (value[0])) || (value[0] == '-'))
@@ -357,7 +360,7 @@ asn1_write_value (asn1_node node_root, const char *name,
              p = node->down;
              while (p)
                {
-                 if (type_field (p->type) == TYPE_CONSTANT)
+                 if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
                    {
                      if (!_asn1_strcmp (p->name, value))
                        {
@@ -386,13 +389,12 @@ asn1_write_value (asn1_node node_root, const char *name,
          memcpy (value_temp, value, len);
        }
 
-
       if (value_temp[0] & 0x80)
        negative = 1;
       else
        negative = 0;
 
-      if (negative && (type_field (node->type) == TYPE_ENUMERATED))
+      if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED))
        {
          free (value_temp);
          return ASN1_VALUE_NOT_VALID;
@@ -408,12 +410,12 @@ asn1_write_value (asn1_node node_root, const char *name,
          (!negative && (value_temp[k] & 0x80)))
        k--;
 
-      _asn1_set_value_octet (node, value_temp + k, len - k);
+      _asn1_set_value_lv (node, value_temp + k, len - k);
 
       if (node->type & CONST_DEFAULT)
        {
          p = node->down;
-         while (type_field (p->type) != TYPE_DEFAULT)
+         while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
            p = p->right;
          if ((isdigit (p->value[0])) || (p->value[0] == '-'))
            {
@@ -437,7 +439,7 @@ asn1_write_value (asn1_node node_root, const char *name,
              p2 = node->down;
              while (p2)
                {
-                 if (type_field (p2->type) == TYPE_CONSTANT)
+                 if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
                    {
                      if (!_asn1_strcmp (p2->name, p->value))
                        {
@@ -479,14 +481,14 @@ asn1_write_value (asn1_node node_root, const char *name,
        }
       free (value_temp);
       break;
-    case TYPE_OBJECT_ID:
+    case ASN1_ETYPE_OBJECT_ID:
       for (i = 0; i < _asn1_strlen (value); i++)
        if ((!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) != TYPE_DEFAULT)
+         while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
            p = p->right;
          if (!_asn1_strcmp (value, p->value))
            {
@@ -496,15 +498,15 @@ asn1_write_value (asn1_node node_root, const char *name,
        }
       _asn1_set_value (node, value, _asn1_strlen (value) + 1);
       break;
-    case TYPE_TIME:
-      if (node->type & CONST_UTC)
+    case ASN1_ETYPE_UTC_TIME:
        {
-         if (_asn1_strlen (value) < 11)
+         len = _asn1_strlen(value);
+         if (len < 11)
            return ASN1_VALUE_NOT_VALID;
          for (k = 0; k < 10; k++)
            if (!isdigit (value[k]))
              return ASN1_VALUE_NOT_VALID;
-         switch (_asn1_strlen (value))
+         switch (len)
            {
            case 11:
              if (value[10] != 'Z')
@@ -534,25 +536,28 @@ asn1_write_value (asn1_node node_root, const char *name,
            default:
              return ASN1_VALUE_NOT_FOUND;
            }
-         _asn1_set_value (node, value, _asn1_strlen (value) + 1);
-       }
-      else
-       {                       /* GENERALIZED TIME */
-         if (value)
-           _asn1_set_value (node, value, _asn1_strlen (value) + 1);
+         _asn1_set_value (node, value, len);
        }
       break;
-    case TYPE_OCTET_STRING:
-      if (len == 0)
-       len = _asn1_strlen (value);
-      _asn1_set_value_octet (node, value, len);
+    case ASN1_ETYPE_GENERALIZED_TIME:
+      len = _asn1_strlen(value);
+      _asn1_set_value (node, value, len);
       break;
-    case TYPE_GENERALSTRING:
+    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_octet (node, value, len);
+      _asn1_set_value_lv (node, value, len);
       break;
-    case TYPE_BIT_STRING:
+    case ASN1_ETYPE_BIT_STRING:
       if (len == 0)
        len = _asn1_strlen (value);
       asn1_length_der ((len >> 3) + 2, NULL, &len2);
@@ -564,7 +569,7 @@ asn1_write_value (asn1_node node_root, const char *name,
       _asn1_set_value_m (node, temp, len2);
       temp = NULL;
       break;
-    case TYPE_CHOICE:
+    case ASN1_ETYPE_CHOICE:
       p = node->down;
       while (p)
        {
@@ -588,11 +593,11 @@ asn1_write_value (asn1_node node_root, const char *name,
       if (!p)
        return ASN1_ELEMENT_NOT_FOUND;
       break;
-    case TYPE_ANY:
-      _asn1_set_value_octet (node, value, len);
+    case ASN1_ETYPE_ANY:
+      _asn1_set_value_lv (node, value, len);
       break;
-    case TYPE_SEQUENCE_OF:
-    case TYPE_SET_OF:
+    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);
@@ -623,6 +628,16 @@ asn1_write_value (asn1_node node_root, const char *name,
                _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 */ \
+               memcpy(ptr, data, data_size); \
+               ptr[data_size] = 0; \
+       }
+
 #define ADD_STR_VALUE( ptr, ptr_size, data) \
        *len = (int) _asn1_strlen(data) + 1; \
        if (ptr_size < (int) _asn1_strlen(ptr)+(*len)) { \
@@ -696,31 +711,105 @@ asn1_write_value (asn1_node node_root, const char *name,
 int
 asn1_read_value (asn1_node 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.
+ * @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 value of one element inside a structure.
+ *
+ * If an element is OPTIONAL and the function "read_value" 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.
+ *
+ * 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.
+ **/
+int
+asn1_read_value_type (asn1_node root, const char *name, void *ivalue, int *len,
+                      unsigned int *etype)
+{
   asn1_node node, p, p2;
   int len2, len3;
   int value_size = *len;
   unsigned char *value = ivalue;
+  unsigned type;
 
   node = asn1_find_node (root, name);
   if (node == NULL)
     return ASN1_ELEMENT_NOT_FOUND;
 
-  if ((type_field (node->type) != TYPE_NULL) &&
-      (type_field (node->type) != TYPE_CHOICE) &&
+  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;
 
-  switch (type_field (node->type))
+  if (etype)
+    *etype = type;
+  switch (type)
     {
-    case TYPE_NULL:
+    case ASN1_ETYPE_NULL:
       PUT_STR_VALUE (value, value_size, "NULL");
       break;
-    case TYPE_BOOLEAN:
+    case ASN1_ETYPE_BOOLEAN:
       if ((node->type & CONST_DEFAULT) && (node->value == NULL))
        {
          p = node->down;
-         while (type_field (p->type) != TYPE_DEFAULT)
+         while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
            p = p->right;
          if (p->type & CONST_TRUE)
            {
@@ -740,12 +829,12 @@ asn1_read_value (asn1_node root, const char *name, void 
*ivalue, int *len)
          PUT_STR_VALUE (value, value_size, "FALSE");
        }
       break;
-    case TYPE_INTEGER:
-    case TYPE_ENUMERATED:
+    case ASN1_ETYPE_INTEGER:
+    case ASN1_ETYPE_ENUMERATED:
       if ((node->type & CONST_DEFAULT) && (node->value == NULL))
        {
          p = node->down;
-         while (type_field (p->type) != TYPE_DEFAULT)
+         while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
            p = p->right;
          if ((isdigit (p->value[0])) || (p->value[0] == '-')
              || (p->value[0] == '+'))
@@ -759,7 +848,7 @@ asn1_read_value (asn1_node root, const char *name, void 
*ivalue, int *len)
              p2 = node->down;
              while (p2)
                {
-                 if (type_field (p2->type) == TYPE_CONSTANT)
+                 if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
                    {
                      if (!_asn1_strcmp (p2->name, p->value))
                        {
@@ -783,14 +872,14 @@ asn1_read_value (asn1_node root, const char *name, void 
*ivalue, int *len)
            return ASN1_MEM_ERROR;
        }
       break;
-    case TYPE_OBJECT_ID:
+    case ASN1_ETYPE_OBJECT_ID:
       if (node->type & CONST_ASSIGN)
        {
          value[0] = 0;
          p = node->down;
          while (p)
            {
-             if (type_field (p->type) == TYPE_CONSTANT)
+             if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
                {
                  ADD_STR_VALUE (value, value_size, p->value);
                  if (p->right)
@@ -805,7 +894,7 @@ asn1_read_value (asn1_node root, const char *name, void 
*ivalue, int *len)
       else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
        {
          p = node->down;
-         while (type_field (p->type) != TYPE_DEFAULT)
+         while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
            p = p->right;
          PUT_STR_VALUE (value, value_size, p->value);
        }
@@ -814,34 +903,37 @@ asn1_read_value (asn1_node root, const char *name, void 
*ivalue, int *len)
          PUT_STR_VALUE (value, value_size, node->value);
        }
       break;
-    case TYPE_TIME:
-      PUT_STR_VALUE (value, value_size, node->value);
-      break;
-    case TYPE_OCTET_STRING:
-      len2 = -1;
-      if (asn1_get_octet_der
-         (node->value, node->value_len, &len2, value, value_size,
-          len) != ASN1_SUCCESS)
-       return ASN1_MEM_ERROR;
+    case ASN1_ETYPE_GENERALIZED_TIME:
+    case ASN1_ETYPE_UTC_TIME:
+      PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len);
       break;
-    case TYPE_GENERALSTRING:
+    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;
       if (asn1_get_octet_der
          (node->value, node->value_len, &len2, value, value_size,
           len) != ASN1_SUCCESS)
        return ASN1_MEM_ERROR;
       break;
-    case TYPE_BIT_STRING:
+    case ASN1_ETYPE_BIT_STRING:
       len2 = -1;
       if (asn1_get_bit_der
          (node->value, node->value_len, &len2, value, value_size,
           len) != ASN1_SUCCESS)
        return ASN1_MEM_ERROR;
       break;
-    case TYPE_CHOICE:
+    case ASN1_ETYPE_CHOICE:
       PUT_STR_VALUE (value, value_size, node->down->name);
       break;
-    case TYPE_ANY:
+    case ASN1_ETYPE_ANY:
       len3 = -1;
       len2 = asn1_get_length_der (node->value, node->value_len, &len3);
       if (len2 < 0)
@@ -889,7 +981,7 @@ asn1_read_tag (asn1_node root, const char *name, int 
*tagValue,
     {
       while (p)
        {
-         if (type_field (p->type) == TYPE_TAG)
+         if (type_field (p->type) == ASN1_ETYPE_TAG)
            {
              if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
                pTag = p;
@@ -915,53 +1007,18 @@ asn1_read_tag (asn1_node root, const char *name, int 
*tagValue,
     }
   else
     {
+      unsigned type = type_field (node->type);
       *classValue = ASN1_CLASS_UNIVERSAL;
 
-      switch (type_field (node->type))
+      switch (type)
        {
-       case TYPE_NULL:
-         *tagValue = ASN1_TAG_NULL;
-         break;
-       case TYPE_BOOLEAN:
-         *tagValue = ASN1_TAG_BOOLEAN;
-         break;
-       case TYPE_INTEGER:
-         *tagValue = ASN1_TAG_INTEGER;
-         break;
-       case TYPE_ENUMERATED:
-         *tagValue = ASN1_TAG_ENUMERATED;
-         break;
-       case TYPE_OBJECT_ID:
-         *tagValue = ASN1_TAG_OBJECT_ID;
-         break;
-       case TYPE_TIME:
-         if (node->type & CONST_UTC)
-           {
-             *tagValue = ASN1_TAG_UTCTime;
-           }
-         else
-           *tagValue = ASN1_TAG_GENERALIZEDTime;
-         break;
-       case TYPE_OCTET_STRING:
-         *tagValue = ASN1_TAG_OCTET_STRING;
-         break;
-       case TYPE_GENERALSTRING:
-         *tagValue = ASN1_TAG_GENERALSTRING;
-         break;
-       case TYPE_BIT_STRING:
-         *tagValue = ASN1_TAG_BIT_STRING;
-         break;
-       case TYPE_SEQUENCE:
-       case TYPE_SEQUENCE_OF:
-         *tagValue = ASN1_TAG_SEQUENCE;
-         break;
-       case TYPE_SET:
-       case TYPE_SET_OF:
-         *tagValue = ASN1_TAG_SET;
+       CASE_HANDLED_ETYPES:
+         *tagValue = _asn1_tags[type].tag;
          break;
-       case TYPE_TAG:
-       case TYPE_CHOICE:
-       case TYPE_ANY:
+       case ASN1_ETYPE_TAG:
+       case ASN1_ETYPE_CHOICE:
+       case ASN1_ETYPE_ANY:
+         *tagValue = -1;
          break;
        default:
          break;
diff --git a/lib/minitasn1/int.h b/lib/minitasn1/int.h
index 0908284..3163d50 100644
--- a/lib/minitasn1/int.h
+++ b/lib/minitasn1/int.h
@@ -58,6 +58,46 @@ struct asn1_node_st
   unsigned char small_value[ASN1_SMALL_VALUE_SIZE];    /* For small values */
 };
 
+typedef struct tag_and_class_st {
+  unsigned tag;
+  unsigned class;
+  const char* desc;
+} tag_and_class_st;
+
+/* the types that are handled in _asn1_tags */
+#define CASE_HANDLED_ETYPES \
+       case ASN1_ETYPE_NULL: \
+       case ASN1_ETYPE_BOOLEAN: \
+       case ASN1_ETYPE_INTEGER: \
+       case ASN1_ETYPE_ENUMERATED: \
+       case ASN1_ETYPE_OBJECT_ID: \
+       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: \
+       case ASN1_ETYPE_SEQUENCE: \
+       case ASN1_ETYPE_SEQUENCE_OF: \
+       case ASN1_ETYPE_SET: \
+       case ASN1_ETYPE_UTC_TIME: \
+       case ASN1_ETYPE_GENERALIZED_TIME: \
+       case ASN1_ETYPE_SET_OF
+
+#define ETYPE_TAG(etype) (_asn1_tags[etype].tag)
+#define ETYPE_CLASS(etype) (_asn1_tags[etype].class)
+#define ETYPE_OK(etype) ((etype != ASN1_ETYPE_INVALID && \
+                          etype <= _asn1_tags_size && \
+                          _asn1_tags[etype].desc != NULL)?1:0)
+
+extern unsigned int _asn1_tags_size;
+extern const tag_and_class_st _asn1_tags[];
+
 #define _asn1_strlen(s) strlen((const char *) s)
 #define _asn1_strtol(n,e,b) strtol((const char *) n, e, b)
 #define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b)
@@ -72,37 +112,6 @@ struct asn1_node_st
 #define RIGHT  2
 #define DOWN   3
 
-/****************************************/
-/* Returns the first 8 bits.            */
-/* Used with the field type of asn1_node_st */
-/****************************************/
-#define type_field(x)     (x&0xFF)
-
-/* List of constants for field type of typedef asn1_node_st  */
-#define TYPE_CONSTANT      ASN1_ETYPE_CONSTANT
-#define TYPE_IDENTIFIER    ASN1_ETYPE_IDENTIFIER
-#define TYPE_INTEGER       ASN1_ETYPE_INTEGER
-#define TYPE_BOOLEAN       ASN1_ETYPE_BOOLEAN
-#define TYPE_SEQUENCE      ASN1_ETYPE_SEQUENCE
-#define TYPE_BIT_STRING    ASN1_ETYPE_BIT_STRING
-#define TYPE_OCTET_STRING  ASN1_ETYPE_OCTET_STRING
-#define TYPE_TAG           ASN1_ETYPE_TAG
-#define TYPE_DEFAULT       ASN1_ETYPE_DEFAULT
-#define TYPE_SIZE          ASN1_ETYPE_SIZE
-#define TYPE_SEQUENCE_OF   ASN1_ETYPE_SEQUENCE_OF
-#define TYPE_OBJECT_ID     ASN1_ETYPE_OBJECT_ID
-#define TYPE_ANY           ASN1_ETYPE_ANY
-#define TYPE_SET           ASN1_ETYPE_SET
-#define TYPE_SET_OF        ASN1_ETYPE_SET_OF
-#define TYPE_DEFINITIONS   ASN1_ETYPE_DEFINITIONS
-#define TYPE_TIME          ASN1_ETYPE_TIME
-#define TYPE_CHOICE        ASN1_ETYPE_CHOICE
-#define TYPE_IMPORTS       ASN1_ETYPE_IMPORTS
-#define TYPE_NULL          ASN1_ETYPE_NULL
-#define TYPE_ENUMERATED    ASN1_ETYPE_ENUMERATED
-#define TYPE_GENERALSTRING ASN1_ETYPE_GENERALSTRING
-
-
 /***********************************************************************/
 /* List of constants to better specify the type of typedef asn1_node_st.   */
 /***********************************************************************/
@@ -128,6 +137,7 @@ struct asn1_node_st
 
 #define CONST_DEFINED_BY  (1<<22)
 
+/* Those two are deprecated and used for backwards compatibility */
 #define CONST_GENERALIZED (1<<23)
 #define CONST_UTC         (1<<24)
 
@@ -140,4 +150,36 @@ struct asn1_node_st
 #define CONST_DOWN        (1<<29)
 #define CONST_RIGHT       (1<<30)
 
+
+#define ASN1_ETYPE_TIME 17
+/****************************************/
+/* Returns the first 8 bits.            */
+/* Used with the field type of asn1_node_st */
+/****************************************/
+inline static unsigned int type_field(unsigned int ntype)
+{
+  return (ntype & 0xff);
+}
+
+/* To convert old types from a static structure */
+inline static unsigned int convert_old_type(unsigned int ntype)
+{
+unsigned int type = ntype & 0xff;
+  if (type == ASN1_ETYPE_TIME)
+    {
+      if (ntype & CONST_UTC)
+        type = ASN1_ETYPE_UTC_TIME;
+      else
+        type = ASN1_ETYPE_GENERALIZED_TIME;
+
+      ntype &= ~(CONST_UTC|CONST_GENERALIZED);
+      ntype &= 0xffffff00;
+      ntype |= type;
+
+      return ntype;
+    }
+  else
+    return ntype;
+}
+
 #endif /* INT_H */
diff --git a/lib/minitasn1/libtasn1.h b/lib/minitasn1/libtasn1.h
index c80a5ca..06474f3 100644
--- a/lib/minitasn1/libtasn1.h
+++ b/lib/minitasn1/libtasn1.h
@@ -44,7 +44,7 @@ extern "C"
 {
 #endif
 
-#define ASN1_VERSION "3.0"
+#define ASN1_VERSION "3.1"
 
   /*****************************************/
   /* Errors returned by libtasn1 functions */
@@ -100,6 +100,14 @@ extern "C"
 #define ASN1_TAG_ENUMERATED            0x0A
 #define ASN1_TAG_NULL                  0x05
 #define ASN1_TAG_GENERALSTRING         0x1B
+#define ASN1_TAG_NUMERIC_STRING                0x12
+#define ASN1_TAG_IA5_STRING            0x16
+#define ASN1_TAG_TELETEX_STRING                0x14
+#define ASN1_TAG_PRINTABLE_STRING      0x13
+#define ASN1_TAG_UNIVERSAL_STRING      0x1C
+#define ASN1_TAG_BMP_STRING            0x1E
+#define ASN1_TAG_UTF8_STRING           0x0C
+#define ASN1_TAG_VISIBLE_STRING                0x1A
 
   /******************************************************/
   /* Structure definition used for the node of the tree */
@@ -126,7 +134,8 @@ extern "C"
   };
   typedef struct asn1_static_node_st asn1_static_node;
 
-/* List of constants for field type of typedef node_asn  */
+/* List of constants for field type of node_asn  */
+#define ASN1_ETYPE_INVALID        0
 #define ASN1_ETYPE_CONSTANT       1
 #define ASN1_ETYPE_IDENTIFIER     2
 #define ASN1_ETYPE_INTEGER        3
@@ -143,12 +152,21 @@ extern "C"
 #define ASN1_ETYPE_SET           14
 #define ASN1_ETYPE_SET_OF        15
 #define ASN1_ETYPE_DEFINITIONS   16
-#define ASN1_ETYPE_TIME          17
 #define ASN1_ETYPE_CHOICE        18
 #define ASN1_ETYPE_IMPORTS       19
 #define ASN1_ETYPE_NULL          20
 #define ASN1_ETYPE_ENUMERATED    21
 #define ASN1_ETYPE_GENERALSTRING 27
+#define ASN1_ETYPE_NUMERIC_STRING 28
+#define ASN1_ETYPE_IA5_STRING     29
+#define ASN1_ETYPE_TELETEX_STRING 30
+#define ASN1_ETYPE_PRINTABLE_STRING 31
+#define ASN1_ETYPE_UNIVERSAL_STRING 32
+#define ASN1_ETYPE_BMP_STRING     33
+#define ASN1_ETYPE_UTF8_STRING    34
+#define ASN1_ETYPE_VISIBLE_STRING 35
+#define ASN1_ETYPE_UTC_TIME       36
+#define ASN1_ETYPE_GENERALIZED_TIME 37
 
   struct asn1_data_node_st
   {
@@ -208,6 +226,10 @@ extern "C"
                     void *ivalue, int *len);
 
   extern ASN1_API int
+    asn1_read_value_type (asn1_node root, const char *name,
+                         void *ivalue, int *len, unsigned int* etype);
+
+  extern ASN1_API int
     asn1_read_node_value (asn1_node node, asn1_data_node_st* data);
 
   extern ASN1_API int
@@ -256,7 +278,36 @@ extern "C"
 
   extern ASN1_API void asn1_perror (int error);
 
-  /* DER utility functions. */
+#define ASN1_MAX_TAG_SIZE 4
+#define ASN1_MAX_LENGTH_SIZE 9
+#define ASN1_MAX_TL_SIZE (ASN1_MAX_TAG_SIZE+ASN1_MAX_LENGTH_SIZE)
+  extern ASN1_API long
+    asn1_get_length_der (const unsigned char *der, int der_len, int *len);
+
+  extern ASN1_API long
+    asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len);
+
+  extern ASN1_API void
+    asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len);
+
+  /* Other utility functions. */
+
+  extern ASN1_API 
+    int asn1_decode_simple_der (unsigned int etype, const unsigned char *der, 
unsigned int der_len,
+                        const unsigned char **str, unsigned int *str_len);
+
+  extern ASN1_API int
+    asn1_encode_simple_der (unsigned int etype, const unsigned char *str, 
unsigned int str_len,
+                        unsigned char *tl, unsigned int *tl_len);
+
+  extern ASN1_API asn1_node
+    asn1_find_node (asn1_node pointer, const char *name);
+
+  extern ASN1_API int
+    asn1_copy_node (asn1_node dst, const char *dst_name,
+                   asn1_node src, const char *src_name);
+
+  /* Internal and low-level DER utility functions. */
 
   extern ASN1_API int
     asn1_get_tag_der (const unsigned char *der, int der_len,
@@ -279,24 +330,6 @@ extern "C"
                      int *ret_len, unsigned char *str,
                      int str_size, int *bit_len);
 
-  extern ASN1_API long
-    asn1_get_length_der (const unsigned char *der, int der_len, int *len);
-
-  extern ASN1_API long
-    asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len);
-
-  extern ASN1_API void
-    asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len);
-
-  /* Other utility functions. */
-
-  extern ASN1_API asn1_node
-    asn1_find_node (asn1_node pointer, const char *name);
-
-  extern ASN1_API int
-    asn1_copy_node (asn1_node dst, const char *dst_name,
-                   asn1_node src, const char *src_name);
-
 /* Compatibility types */
 
 typedef int asn1_retCode;      /* type returned by libtasn1 functions */
diff --git a/lib/minitasn1/parser_aux.c b/lib/minitasn1/parser_aux.c
index 96ecac6..50238d2 100644
--- a/lib/minitasn1/parser_aux.c
+++ b/lib/minitasn1/parser_aux.c
@@ -48,7 +48,7 @@ list_type *firstElement = NULL;
 /* Description: creates a new NODE_ASN element and    */
 /* puts it in the list pointed by firstElement.       */
 /* Parameters:                                        */
-/*   type: type of the new element (see TYPE_         */
+/*   type: type of the new element (see ASN1_ETYPE_   */
 /*         and CONST_ constants).                     */
 /* Return: pointer to the new element.                */
 /******************************************************/
@@ -241,10 +241,10 @@ _asn1_set_value (asn1_node node, const void *value, 
unsigned int len)
 }
 
 /******************************************************************/
-/* Function : _asn1_set_value_octet                               */
+/* Function : _asn1_set_value_lv                                  */
 /* Description: sets the field VALUE in a NODE_ASN element. The   */
 /*              previous value (if exist) will be lost. The value */
-/*             given is stored as an octet string.               */
+/*             given is stored as an length-value format (LV     */
 /* Parameters:                                                    */
 /*   node: element pointer.                                       */
 /*   value: pointer to the value that you want to set.            */
@@ -252,7 +252,7 @@ _asn1_set_value (asn1_node node, const void *value, 
unsigned int len)
 /* Return: pointer to the NODE_ASN element.                       */
 /******************************************************************/
 asn1_node
-_asn1_set_value_octet (asn1_node node, const void *value, unsigned int len)
+_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len)
 {
   int len2;
   void *temp;
@@ -581,7 +581,7 @@ _asn1_change_integer_value (asn1_node node)
   p = node;
   while (p)
     {
-      if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN))
+      if ((type_field (p->type) == ASN1_ETYPE_INTEGER) && (p->type & 
CONST_ASSIGN))
        {
          if (p->value)
            {
@@ -653,11 +653,11 @@ _asn1_expand_object_id (asn1_node node)
     {
       if (move != UP)
        {
-         if ((type_field (p->type) == TYPE_OBJECT_ID)
+         if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID)
              && (p->type & CONST_ASSIGN))
            {
              p2 = p->down;
-             if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
+             if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
                {
                  if (p2->value && !isdigit (p2->value[0]))
                    {
@@ -666,7 +666,7 @@ _asn1_expand_object_id (asn1_node node)
                      _asn1_str_cat (name2, sizeof (name2),
                                     (char *) p2->value);
                      p3 = asn1_find_node (node, name2);
-                     if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
+                     if (!p3 || (type_field (p3->type) != 
ASN1_ETYPE_OBJECT_ID) ||
                          !(p3->type & CONST_ASSIGN))
                        return ASN1_ELEMENT_NOT_FOUND;
                      _asn1_set_down (p, p2->right);
@@ -675,9 +675,9 @@ _asn1_expand_object_id (asn1_node node)
                      p4 = p3->down;
                      while (p4)
                        {
-                         if (type_field (p4->type) == TYPE_CONSTANT)
+                         if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
                            {
-                             p5 = _asn1_add_single_node (TYPE_CONSTANT);
+                             p5 = _asn1_add_single_node (ASN1_ETYPE_CONSTANT);
                              _asn1_set_name (p5, p4->name);
                              tlen = _asn1_strlen (p4->value);
                              if (tlen > 0)
@@ -742,24 +742,24 @@ _asn1_expand_object_id (asn1_node node)
     {
       if (move != UP)
        {
-         if ((type_field (p->type) == TYPE_OBJECT_ID) &&
+         if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
              (p->type & CONST_DEFAULT))
            {
              p2 = p->down;
-             if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
+             if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
                {
                  _asn1_str_cpy (name2, sizeof (name2), name_root);
                  _asn1_str_cat (name2, sizeof (name2), ".");
                  _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
                  p3 = asn1_find_node (node, name2);
-                 if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
+                 if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) ||
                      !(p3->type & CONST_ASSIGN))
                    return ASN1_ELEMENT_NOT_FOUND;
                  p4 = p3->down;
                  name2[0] = 0;
                  while (p4)
                    {
-                     if (type_field (p4->type) == TYPE_CONSTANT)
+                     if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
                        {
                          if (name2[0])
                            _asn1_str_cat (name2, sizeof (name2), ".");
@@ -833,12 +833,12 @@ _asn1_type_set_config (asn1_node node)
     {
       if (move != UP)
        {
-         if (type_field (p->type) == TYPE_SET)
+         if (type_field (p->type) == ASN1_ETYPE_SET)
            {
              p2 = p->down;
              while (p2)
                {
-                 if (type_field (p2->type) != TYPE_TAG)
+                 if (type_field (p2->type) != ASN1_ETYPE_TAG)
                    p2->type |= CONST_SET | CONST_NOT_USED;
                  p2 = p2->right;
                }
@@ -902,7 +902,7 @@ _asn1_check_identifier (asn1_node node)
   p = node;
   while (p)
     {
-      if (type_field (p->type) == TYPE_IDENTIFIER)
+      if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
        {
          _asn1_str_cpy (name2, sizeof (name2), node->name);
          _asn1_str_cat (name2, sizeof (name2), ".");
@@ -917,29 +917,29 @@ _asn1_check_identifier (asn1_node node)
              return ASN1_IDENTIFIER_NOT_FOUND;
            }
        }
-      else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
+      else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
               (p->type & CONST_DEFAULT))
        {
          p2 = p->down;
-         if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
+         if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
            {
              _asn1_str_cpy (name2, sizeof (name2), node->name);
              _asn1_str_cat (name2, sizeof (name2), ".");
              _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
              _asn1_strcpy (_asn1_identifierMissing, p2->value);
              p2 = asn1_find_node (node, name2);
-             if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
+             if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) ||
                  !(p2->type & CONST_ASSIGN))
                return ASN1_IDENTIFIER_NOT_FOUND;
              else
                _asn1_identifierMissing[0] = 0;
            }
        }
-      else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
+      else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
               (p->type & CONST_ASSIGN))
        {
          p2 = p->down;
-         if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
+         if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT))
            {
              if (p2->value && !isdigit (p2->value[0]))
                {
@@ -948,7 +948,7 @@ _asn1_check_identifier (asn1_node node)
                  _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
                  _asn1_strcpy (_asn1_identifierMissing, p2->value);
                  p2 = asn1_find_node (node, name2);
-                 if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
+                 if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) ||
                      !(p2->type & CONST_ASSIGN))
                    return ASN1_IDENTIFIER_NOT_FOUND;
                  else
@@ -1002,13 +1002,13 @@ _asn1_set_default_tag (asn1_node node)
 {
   asn1_node p;
 
-  if ((node == NULL) || (type_field (node->type) != TYPE_DEFINITIONS))
+  if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS))
     return ASN1_ELEMENT_NOT_FOUND;
 
   p = node;
   while (p)
     {
-      if ((type_field (p->type) == TYPE_TAG) &&
+      if ((type_field (p->type) == ASN1_ETYPE_TAG) &&
          !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
        {
          if (node->type & CONST_EXPLICIT)
diff --git a/lib/minitasn1/parser_aux.h b/lib/minitasn1/parser_aux.h
index df369c7..f270b73 100644
--- a/lib/minitasn1/parser_aux.h
+++ b/lib/minitasn1/parser_aux.h
@@ -35,7 +35,7 @@ _asn1_set_value (asn1_node node, const void *value, unsigned 
int len);
 asn1_node _asn1_set_value_m (asn1_node node, void *value, unsigned int len);
 
 asn1_node
-_asn1_set_value_octet (asn1_node node, const void *value, unsigned int len);
+_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len);
 
 asn1_node
 _asn1_append_value (asn1_node node, const void *value, unsigned int len);
diff --git a/lib/minitasn1/structure.c b/lib/minitasn1/structure.c
index 32be50b..31a5f65 100644
--- a/lib/minitasn1/structure.c
+++ b/lib/minitasn1/structure.c
@@ -40,7 +40,7 @@ extern char _asn1_identifierMissing[];
 /* Function : _asn1_add_single_node                     */
 /* Description: creates a new NODE_ASN element.       */
 /* Parameters:                                        */
-/*   type: type of the new element (see TYPE_         */
+/*   type: type of the new element (see ASN1_ETYPE_         */
 /*         and CONST_ constants).                     */
 /* Return: pointer to the new element.                */
 /******************************************************/
@@ -181,6 +181,7 @@ asn1_array2tree (const asn1_static_node * array, asn1_node 
* definitions,
   unsigned long k;
   int move;
   int result;
+  unsigned int type;
 
 
   if (*definitions != NULL)
@@ -191,7 +192,9 @@ asn1_array2tree (const asn1_static_node * array, asn1_node 
* definitions,
   k = 0;
   while (array[k].value || array[k].type || array[k].name)
     {
-      p = _asn1_add_static_node (array[k].type & (~CONST_DOWN));
+      type = convert_old_type(array[k].type);
+
+      p = _asn1_add_static_node (type & (~CONST_DOWN));
       if (array[k].name)
        _asn1_set_name (p, array[k].name);
       if (array[k].value)
@@ -207,9 +210,9 @@ asn1_array2tree (const asn1_static_node * array, asn1_node 
* definitions,
 
       p_last = p;
 
-      if (array[k].type & CONST_DOWN)
+      if (type & CONST_DOWN)
        move = DOWN;
-      else if (array[k].type & CONST_RIGHT)
+      else if (type & CONST_RIGHT)
        move = RIGHT;
       else
        {
@@ -457,18 +460,18 @@ _asn1_type_choice_config (asn1_node node)
     {
       if (move != UP)
        {
-         if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
+         if ((type_field (p->type) == ASN1_ETYPE_CHOICE) && (p->type & 
CONST_TAG))
            {
              p2 = p->down;
              while (p2)
                {
-                 if (type_field (p2->type) != TYPE_TAG)
+                 if (type_field (p2->type) != ASN1_ETYPE_TAG)
                    {
                      p2->type |= CONST_TAG;
                      p3 = _asn1_find_left (p2);
                      while (p3)
                        {
-                         if (type_field (p3->type) == TYPE_TAG)
+                         if (type_field (p3->type) == ASN1_ETYPE_TAG)
                            {
                              p4 = _asn1_add_single_node (p3->type);
                              tlen = _asn1_strlen (p3->value);
@@ -487,7 +490,7 @@ _asn1_type_choice_config (asn1_node node)
              while (p2)
                {
                  p3 = p2->right;
-                 if (type_field (p2->type) == TYPE_TAG)
+                 if (type_field (p2->type) == ASN1_ETYPE_TAG)
                    asn1_delete_structure (&p2);
                  p2 = p3;
                }
@@ -543,7 +546,7 @@ _asn1_expand_identifier (asn1_node * node, asn1_node root)
     {
       if (move != UP)
        {
-         if (type_field (p->type) == TYPE_IDENTIFIER)
+         if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER)
            {
              snprintf(name2, sizeof (name2), "%s.%s", root->name, p->value);
              p2 = _asn1_copy_structure2 (root, name2);
@@ -715,9 +718,9 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
        {
          switch (type_field (p->type))
            {
-           case TYPE_CONSTANT:
-           case TYPE_TAG:
-           case TYPE_SIZE:
+           case ASN1_ETYPE_CONSTANT:
+           case ASN1_ETYPE_TAG:
+           case ASN1_ETYPE_SIZE:
              break;
            default:
              for (k = 0; k < indent; k++)
@@ -732,74 +735,39 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
 
       if (mode != ASN1_PRINT_NAME)
        {
-         switch (type_field (p->type))
+         unsigned type = type_field (p->type);
+         switch (type)
            {
-           case TYPE_CONSTANT:
+           case ASN1_ETYPE_CONSTANT:
              if (mode == ASN1_PRINT_ALL)
                fprintf (out, "type:CONST");
              break;
-           case TYPE_TAG:
+           case ASN1_ETYPE_TAG:
              if (mode == ASN1_PRINT_ALL)
                fprintf (out, "type:TAG");
              break;
-           case TYPE_SIZE:
+           case ASN1_ETYPE_SIZE:
              if (mode == ASN1_PRINT_ALL)
                fprintf (out, "type:SIZE");
              break;
-           case TYPE_DEFAULT:
+           case ASN1_ETYPE_DEFAULT:
              fprintf (out, "type:DEFAULT");
              break;
-           case TYPE_NULL:
-             fprintf (out, "type:NULL");
-             break;
-           case TYPE_IDENTIFIER:
+           case ASN1_ETYPE_IDENTIFIER:
              fprintf (out, "type:IDENTIFIER");
              break;
-           case TYPE_INTEGER:
-             fprintf (out, "type:INTEGER");
-             break;
-           case TYPE_ENUMERATED:
-             fprintf (out, "type:ENUMERATED");
-             break;
-           case TYPE_TIME:
-             fprintf (out, "type:TIME");
-             break;
-           case TYPE_BOOLEAN:
-             fprintf (out, "type:BOOLEAN");
-             break;
-           case TYPE_SEQUENCE:
-             fprintf (out, "type:SEQUENCE");
-             break;
-           case TYPE_BIT_STRING:
-             fprintf (out, "type:BIT_STR");
-             break;
-           case TYPE_OCTET_STRING:
-             fprintf (out, "type:OCT_STR");
-             break;
-           case TYPE_GENERALSTRING:
-             fprintf (out, "type:GENERALSTRING");
-             break;
-           case TYPE_SEQUENCE_OF:
-             fprintf (out, "type:SEQ_OF");
-             break;
-           case TYPE_OBJECT_ID:
-             fprintf (out, "type:OBJ_ID");
-             break;
-           case TYPE_ANY:
+           case ASN1_ETYPE_ANY:
              fprintf (out, "type:ANY");
              break;
-           case TYPE_SET:
-             fprintf (out, "type:SET");
-             break;
-           case TYPE_SET_OF:
-             fprintf (out, "type:SET_OF");
-             break;
-           case TYPE_CHOICE:
+           case ASN1_ETYPE_CHOICE:
              fprintf (out, "type:CHOICE");
              break;
-           case TYPE_DEFINITIONS:
+           case ASN1_ETYPE_DEFINITIONS:
              fprintf (out, "type:DEFINITIONS");
              break;
+            CASE_HANDLED_ETYPES:
+             fprintf (out, "%s", _asn1_tags[type].desc);
+             break;
            default:
              break;
            }
@@ -809,22 +777,22 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
        {
          switch (type_field (p->type))
            {
-           case TYPE_CONSTANT:
+           case ASN1_ETYPE_CONSTANT:
              if (mode == ASN1_PRINT_ALL)
                if (p->value)
                  fprintf (out, "  value:%s", p->value);
              break;
-           case TYPE_TAG:
+           case ASN1_ETYPE_TAG:
              if (mode == ASN1_PRINT_ALL)
                if (p->value)
                  fprintf (out, "  value:%s", p->value);
              break;
-           case TYPE_SIZE:
+           case ASN1_ETYPE_SIZE:
              if (mode == ASN1_PRINT_ALL)
                if (p->value)
                  fprintf (out, "  value:%s", p->value);
              break;
-           case TYPE_DEFAULT:
+           case ASN1_ETYPE_DEFAULT:
              if (p->value)
                fprintf (out, "  value:%s", p->value);
              else if (p->type & CONST_TRUE)
@@ -832,11 +800,11 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
              else if (p->type & CONST_FALSE)
                fprintf (out, "  value:FALSE");
              break;
-           case TYPE_IDENTIFIER:
+           case ASN1_ETYPE_IDENTIFIER:
              if (p->value)
                fprintf (out, "  value:%s", p->value);
              break;
-           case TYPE_INTEGER:
+           case ASN1_ETYPE_INTEGER:
              if (p->value)
                {
                  len2 = -1;
@@ -847,7 +815,7 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
                      fprintf (out, "%02x", (p->value)[k + len2]);
                }
              break;
-           case TYPE_ENUMERATED:
+           case ASN1_ETYPE_ENUMERATED:
              if (p->value)
                {
                  len2 = -1;
@@ -858,11 +826,7 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
                      fprintf (out, "%02x", (p->value)[k + len2]);
                }
              break;
-           case TYPE_TIME:
-             if (p->value)
-               fprintf (out, "  value:%s", p->value);
-             break;
-           case TYPE_BOOLEAN:
+           case ASN1_ETYPE_BOOLEAN:
              if (p->value)
                {
                  if (p->value[0] == 'T')
@@ -871,7 +835,7 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
                    fprintf (out, "  value:FALSE");
                }
              break;
-           case TYPE_BIT_STRING:
+           case ASN1_ETYPE_BIT_STRING:
              if (p->value)
                {
                  len2 = -1;
@@ -885,7 +849,23 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
                    }
                }
              break;
-           case TYPE_OCTET_STRING:
+           case ASN1_ETYPE_GENERALIZED_TIME:
+           case ASN1_ETYPE_UTC_TIME:
+             if (p->value)
+               {
+                 fprintf (out, "  value:");
+                  for (k = 0; k < p->value_len; k++)
+                   fprintf (out, "%c", (p->value)[k]);
+               }
+             break;
+           case ASN1_ETYPE_GENERALSTRING:
+           case ASN1_ETYPE_NUMERIC_STRING:
+           case ASN1_ETYPE_IA5_STRING:
+           case ASN1_ETYPE_TELETEX_STRING:
+           case ASN1_ETYPE_PRINTABLE_STRING:
+           case ASN1_ETYPE_UNIVERSAL_STRING:
+           case ASN1_ETYPE_UTF8_STRING:
+           case ASN1_ETYPE_VISIBLE_STRING:
              if (p->value)
                {
                  len2 = -1;
@@ -893,10 +873,11 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
                  fprintf (out, "  value:");
                  if (len > 0)
                    for (k = 0; k < len; k++)
-                     fprintf (out, "%02x", (p->value)[k + len2]);
+                     fprintf (out, "%c", (p->value)[k + len2]);
                }
              break;
-           case TYPE_GENERALSTRING:
+           case ASN1_ETYPE_BMP_STRING:
+           case ASN1_ETYPE_OCTET_STRING:
              if (p->value)
                {
                  len2 = -1;
@@ -907,11 +888,11 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
                      fprintf (out, "%02x", (p->value)[k + len2]);
                }
              break;
-           case TYPE_OBJECT_ID:
+           case ASN1_ETYPE_OBJECT_ID:
              if (p->value)
                fprintf (out, "  value:%s", p->value);
              break;
-           case TYPE_ANY:
+           case ASN1_ETYPE_ANY:
              if (p->value)
                {
                  len3 = -1;
@@ -922,13 +903,13 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
                      fprintf (out, "%02x", (p->value)[k + len3]);
                }
              break;
-           case TYPE_SET:
-           case TYPE_SET_OF:
-           case TYPE_CHOICE:
-           case TYPE_DEFINITIONS:
-           case TYPE_SEQUENCE_OF:
-           case TYPE_SEQUENCE:
-           case TYPE_NULL:
+           case ASN1_ETYPE_SET:
+           case ASN1_ETYPE_SET_OF:
+           case ASN1_ETYPE_CHOICE:
+           case ASN1_ETYPE_DEFINITIONS:
+           case ASN1_ETYPE_SEQUENCE_OF:
+           case ASN1_ETYPE_SEQUENCE:
+           case ASN1_ETYPE_NULL:
              break;
            default:
              break;
@@ -991,9 +972,9 @@ asn1_print_structure (FILE * out, asn1_node structure, 
const char *name,
        {
          switch (type_field (p->type))
            {
-           case TYPE_CONSTANT:
-           case TYPE_TAG:
-           case TYPE_SIZE:
+           case ASN1_ETYPE_CONSTANT:
+           case ASN1_ETYPE_TAG:
+           case ASN1_ETYPE_SIZE:
              break;
            default:
              fprintf (out, "\n");
@@ -1105,7 +1086,7 @@ asn1_find_structure_from_oid (asn1_node definitions, 
const char *oidValue)
   p = definitions->down;
   while (p)
     {
-      if ((type_field (p->type) == TYPE_OBJECT_ID) &&
+      if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
          (p->type & CONST_ASSIGN))
        {
          strcpy (name, definitionsName);


hooks/post-receive
-- 
GNU gnutls



reply via email to

[Prev in Thread] Current Thread [Next in Thread]