summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--lib/ASN1.c4
-rw-r--r--lib/ASN1.y4
-rw-r--r--lib/coding.c20
-rw-r--r--lib/decoding.c30
-rw-r--r--lib/element.c30
-rw-r--r--lib/int.h30
-rw-r--r--lib/libtasn1.h3
-rw-r--r--lib/structure.c6
9 files changed, 66 insertions, 62 deletions
diff --git a/NEWS b/NEWS
index 371e804..b2dddec 100644
--- 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.
diff --git a/lib/ASN1.c b/lib/ASN1.c
index 928d28d..2a60527 100644
--- a/lib/ASN1.c
+++ b/lib/ASN1.c
@@ -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:
diff --git a/lib/ASN1.y b/lib/ASN1.y
index dafe15a..874eb13 100644
--- a/lib/ASN1.y
+++ b/lib/ASN1.y
@@ -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);
diff --git a/lib/coding.c b/lib/coding.c
index 5c1a58b..c39c595 100644
--- a/lib/coding.c
+++ b/lib/coding.c
@@ -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);
diff --git a/lib/decoding.c b/lib/decoding.c
index 5df1f36..68f0634 100644
--- a/lib/decoding.c
+++ b/lib/decoding.c
@@ -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)
diff --git a/lib/element.c b/lib/element.c
index 2e3d48e..c1718e2 100644
--- a/lib/element.c
+++ b/lib/element.c
@@ -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:
diff --git a/lib/int.h b/lib/int.h
index 072e0c6..1cd3e66 100644
--- 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 */
diff --git a/lib/libtasn1.h b/lib/libtasn1.h
index 403ee80..5b50c47 100644
--- a/lib/libtasn1.h
+++ b/lib/libtasn1.h
@@ -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
{
diff --git a/lib/structure.c b/lib/structure.c
index a508030..4d69765 100644
--- a/lib/structure.c
+++ b/lib/structure.c
@@ -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;