- 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.
/* 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:
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);
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_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]);
/******************************************************/
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);
}
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);
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). */
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);
counter += len2;
move = RIGHT;
break;
- case ASN1_ETYPE_TIME:
+ case ASN1_ETYPE_GENERALIZED_TIME:
+ case ASN1_ETYPE_UTC_TIME:
if (state == FOUND)
{
result =
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:
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)
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)
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;
return ASN1_SUCCESS;
}
- switch (type_field (node->type))
+ switch (type)
{
case ASN1_ETYPE_BOOLEAN:
if (!_asn1_strcmp (value, "TRUE"))
}
_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;
}
_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:
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:
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:
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 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. */
/***********************************************************************/
#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)
#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 */
#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_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
{
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;
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;