Introduced ASN1_ETYPE_UTC_TIME and ASN1_ETYPE_GENERALIZED_TIME
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 24 Nov 2012 08:41:50 +0000 (09:41 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sat, 24 Nov 2012 08:41:50 +0000 (09:41 +0100)
NEWS
lib/ASN1.c
lib/ASN1.y
lib/coding.c
lib/decoding.c
lib/element.c
lib/int.h
lib/libtasn1.h
lib/structure.c

diff --git a/NEWS b/NEWS
index 371e804..b2dddec 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,7 @@ GNU Libtasn1 NEWS                                     -*- outline -*-
 - Parser outputs more detailed syntax error message.
 - Added asn1_decode_simple_der() and asn1_encode_simple_der().
 - Added asn1_read_value_type() to return value and type.
+- Introduced ASN1_ETYPE_UTC_TIME and ASN1_ETYPE_GENERALIZED_TIME
 
 * Noteworthy changes in release 3.0 (2012-10-28) [stable]
 - Added tool in tests/ to benchmark X.509 structure decoding.
index 928d28d..2a60527 100644 (file)
@@ -1987,14 +1987,14 @@ yyreduce:
 
 /* Line 1806 of yacc.c  */
 #line 233 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TIME|CONST_UTC);}
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UTC_TIME);}
     break;
 
   case 39:
 
 /* Line 1806 of yacc.c  */
 #line 234 "ASN1.y"
-    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TIME|CONST_GENERALIZED);}
+    {(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_GENERALIZED_TIME);}
     break;
 
   case 40:
index dafe15a..874eb13 100644 (file)
@@ -230,8 +230,8 @@ integer_def: INTEGER                    {$$=_asn1_add_static_node(ASN1_ETYPE_INT
 boolean_def: BOOLEAN   {$$=_asn1_add_static_node(ASN1_ETYPE_BOOLEAN);}
 ;
 
-Time:   UTCTime          {$$=_asn1_add_static_node(ASN1_ETYPE_TIME|CONST_UTC);}
-      | GeneralizedTime  {$$=_asn1_add_static_node(ASN1_ETYPE_TIME|CONST_GENERALIZED);}
+Time:   UTCTime          {$$=_asn1_add_static_node(ASN1_ETYPE_UTC_TIME);}
+      | GeneralizedTime  {$$=_asn1_add_static_node(ASN1_ETYPE_GENERALIZED_TIME);}
 ;
 
 size_def2: SIZE'('num_identifier')'  {$$=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_1_PARAM);
index 5c1a58b..c39c595 100644 (file)
@@ -216,6 +216,10 @@ asn1_encode_simple_der (unsigned int etype, const unsigned char *str, unsigned i
   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);
 
@@ -536,7 +540,10 @@ const tag_and_class_st _asn1_tags[] =
   [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]);
 
 /******************************************************/
@@ -630,16 +637,6 @@ _asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
       unsigned type = type_field (node->type);
       switch (type)
        {
-       case ASN1_ETYPE_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_HANDLED_ETYPES:
          _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag,
                         tag_der, &tag_len);
@@ -1064,7 +1061,8 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
            }
          move = RIGHT;
          break;
-       case ASN1_ETYPE_TIME:
+       case ASN1_ETYPE_GENERALIZED_TIME:
+       case ASN1_ETYPE_UTC_TIME:
          if (p->value == NULL)
            {
              _asn1_error_description_value_not_found (p, ErrorDescription);
index 5df1f36..68f0634 100644 (file)
@@ -511,25 +511,12 @@ _asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
        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 ASN1_ETYPE_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 ASN1_ETYPE_OCTET_STRING:
          /* OCTET STRING is handled differently to allow
           * BER encodings (structured class). */
@@ -1055,7 +1042,8 @@ asn1_der_decoding (asn1_node * element, const void *ider, int len,
              counter += len2;
              move = RIGHT;
              break;
-           case ASN1_ETYPE_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);
@@ -1707,7 +1695,8 @@ asn1_der_decoding_element (asn1_node * structure, const char *elementName,
              counter += len2;
              move = RIGHT;
              break;
-           case ASN1_ETYPE_TIME:
+           case ASN1_ETYPE_GENERALIZED_TIME:
+           case ASN1_ETYPE_UTC_TIME:
              if (state == FOUND)
                {
                  result =
@@ -2347,7 +2336,8 @@ asn1_der_decoding_startEnd (asn1_node element, const void *ider, int len,
              counter += len3;
              move = RIGHT;
              break;
-           case ASN1_ETYPE_TIME:
+           case ASN1_ETYPE_UTC_TIME:
+           case ASN1_ETYPE_GENERALIZED_TIME:
            case ASN1_ETYPE_OBJECT_ID:
            case ASN1_ETYPE_INTEGER:
            case ASN1_ETYPE_ENUMERATED:
@@ -2896,6 +2886,10 @@ asn1_decode_simple_der (unsigned int etype, const unsigned char *der, unsigned i
   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)
index 2e3d48e..c1718e2 100644 (file)
@@ -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,8 +287,10 @@ 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) == ASN1_ETYPE_SEQUENCE_OF) && (value == NULL)
+  if ((type == ASN1_ETYPE_SEQUENCE_OF) && (value == NULL)
       && (len == 0))
     {
       p = node->down;
@@ -301,7 +304,7 @@ asn1_write_value (asn1_node node_root, const char *name,
       return ASN1_SUCCESS;
     }
 
-  switch (type_field (node->type))
+  switch (type)
     {
     case ASN1_ETYPE_BOOLEAN:
       if (!_asn1_strcmp (value, "TRUE"))
@@ -496,8 +499,7 @@ asn1_write_value (asn1_node node_root, const char *name,
        }
       _asn1_set_value (node, value, _asn1_strlen (value) + 1);
       break;
-    case ASN1_ETYPE_TIME:
-      if (node->type & CONST_UTC)
+    case ASN1_ETYPE_UTC_TIME:
        {
          if (_asn1_strlen (value) < 11)
            return ASN1_VALUE_NOT_VALID;
@@ -536,11 +538,10 @@ asn1_write_value (asn1_node node_root, const char *name,
            }
          _asn1_set_value (node, value, _asn1_strlen (value) + 1);
        }
-      else
-       {                       /* GENERALIZED TIME */
-         if (value)
-           _asn1_set_value (node, value, _asn1_strlen (value) + 1);
-       }
+      break;
+    case ASN1_ETYPE_GENERALIZED_TIME:
+      if (value)
+        _asn1_set_value (node, value, _asn1_strlen (value) + 1);
       break;
     case ASN1_ETYPE_OCTET_STRING:
     case ASN1_ETYPE_GENERALSTRING:
@@ -892,7 +893,8 @@ asn1_read_value_type (asn1_node root, const char *name, void *ivalue, int *len,
          PUT_STR_VALUE (value, value_size, node->value);
        }
       break;
-    case ASN1_ETYPE_TIME:
+    case ASN1_ETYPE_GENERALIZED_TIME:
+    case ASN1_ETYPE_UTC_TIME:
       PUT_STR_VALUE (value, value_size, node->value);
       break;
     case ASN1_ETYPE_OCTET_STRING:
@@ -1003,14 +1005,6 @@ asn1_read_tag (asn1_node root, const char *name, int *tagValue,
        CASE_HANDLED_ETYPES:
          *tagValue = _asn1_tags[type].tag;
          break;
-       case ASN1_ETYPE_TIME:
-         if (node->type & CONST_UTC)
-           {
-             *tagValue = ASN1_TAG_UTCTime;
-           }
-         else
-           *tagValue = ASN1_TAG_GENERALIZEDTime;
-         break;
        case ASN1_ETYPE_TAG:
        case ASN1_ETYPE_CHOICE:
        case ASN1_ETYPE_ANY:
index 072e0c6..1cd3e66 100644 (file)
--- a/lib/int.h
+++ b/lib/int.h
@@ -85,6 +85,8 @@ typedef struct tag_and_class_st {
        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)
@@ -110,12 +112,6 @@ extern const tag_and_class_st _asn1_tags[];
 #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 to better specify the type of typedef asn1_node_st.   */
 /***********************************************************************/
@@ -141,6 +137,7 @@ extern const tag_and_class_st _asn1_tags[];
 
 #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)
 
@@ -153,4 +150,25 @@ extern const tag_and_class_st _asn1_tags[];
 #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)
+{
+unsigned int type = ntype & 0xff;
+  if (type == ASN1_ETYPE_TIME)
+    {
+      if (type & CONST_UTC)
+        type = ASN1_ETYPE_UTC_TIME;
+      else
+        type = ASN1_ETYPE_GENERALIZED_TIME;
+    }
+  
+  return type;
+}
+
+
 #endif /* INT_H */
index 403ee80..5b50c47 100644 (file)
@@ -152,7 +152,6 @@ 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
@@ -166,6 +165,8 @@ extern "C"
 #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
   {
index a508030..4d69765 100644 (file)
@@ -753,9 +753,6 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
            case ASN1_ETYPE_IDENTIFIER:
              fprintf (out, "type:IDENTIFIER");
              break;
-           case ASN1_ETYPE_TIME:
-             fprintf (out, "type:TIME");
-             break;
            case ASN1_ETYPE_ANY:
              fprintf (out, "type:ANY");
              break;
@@ -826,7 +823,8 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name,
                      fprintf (out, "%02x", (p->value)[k + len2]);
                }
              break;
-           case ASN1_ETYPE_TIME:
+           case ASN1_ETYPE_GENERALIZED_TIME:
+           case ASN1_ETYPE_UTC_TIME:
              if (p->value)
                fprintf (out, "  value:%s", p->value);
              break;