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