]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Update minitasn1 to version 3.1.
authorSimon Josefsson <simon@josefsson.org>
Mon, 26 Nov 2012 20:34:25 +0000 (21:34 +0100)
committerSimon Josefsson <simon@josefsson.org>
Mon, 26 Nov 2012 20:34:25 +0000 (21:34 +0100)
lib/minitasn1/coding.c
lib/minitasn1/decoding.c
lib/minitasn1/element.c
lib/minitasn1/int.h
lib/minitasn1/libtasn1.h
lib/minitasn1/parser_aux.c
lib/minitasn1/parser_aux.h
lib/minitasn1/structure.c

index 581ef9675f2d9cf8b8bf39229f5878353a585c45..5361b3f068423dedddc8094643fbfe71dbcb3b55 100644 (file)
@@ -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);
index 79766a1802ceb64ec08bd6099b4def5da827414c..f02fe10686be996a71996324e933d0f2cd3d1024 100644 (file)
@@ -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;
+}
index 4c871a1b3117805e1f5f6deb624c0f3c07e62ff0..763ac586b799724c4c0a08ed9946c65821b725d7 100644 (file)
@@ -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)) { \
@@ -695,32 +710,106 @@ 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;
index 09082845ac606157dd887987a40529ced753f912..3163d50d14f7eed816f74cc85418234d65872981 100644 (file)
@@ -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 */
index c80a5ca457ff31f79bd35260f6cfb4f714c43854..06474f3f33ad2d8bc5e54b57a3aba54f8eb313c2 100644 (file)
@@ -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
   {
@@ -207,6 +225,10 @@ extern "C"
     asn1_read_value (asn1_node root, const char *name,
                     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);
 
@@ -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 */
index 96ecac6bb2d982dc3de026fc290466dc25adb3e7..50238d2c92f3b7b47cfa29088d2d061628287300 100644 (file)
@@ -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)
index df369c79c6114297e39a3cb69e64cc0c7a8b047b..f270b73595850104fbf0660024eeccf0700c7951 100644 (file)
@@ -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);
index 32be50b7c3625907c5825c0b14ddc664a64d1318..31a5f654bbd7817649e1d8998d3f1ab0c29623bf 100644 (file)
@@ -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);