diff options
Diffstat (limited to 'lib/minitasn1')
-rw-r--r-- | lib/minitasn1/coding.c | 1782 | ||||
-rw-r--r-- | lib/minitasn1/decoding.c | 4972 | ||||
-rw-r--r-- | lib/minitasn1/element.c | 1238 | ||||
-rw-r--r-- | lib/minitasn1/element.h | 10 | ||||
-rw-r--r-- | lib/minitasn1/errors.c | 65 | ||||
-rw-r--r-- | lib/minitasn1/gstr.c | 56 | ||||
-rw-r--r-- | lib/minitasn1/gstr.h | 5 | ||||
-rw-r--r-- | lib/minitasn1/int.h | 65 | ||||
-rw-r--r-- | lib/minitasn1/libtasn1.h | 305 | ||||
-rw-r--r-- | lib/minitasn1/parser_aux.c | 1390 | ||||
-rw-r--r-- | lib/minitasn1/parser_aux.h | 91 | ||||
-rw-r--r-- | lib/minitasn1/structure.c | 1736 | ||||
-rw-r--r-- | lib/minitasn1/structure.h | 12 | ||||
-rw-r--r-- | lib/minitasn1/version.c | 9 |
14 files changed, 5860 insertions, 5876 deletions
diff --git a/lib/minitasn1/coding.c b/lib/minitasn1/coding.c index 5361b3f068..8e71683d24 100644 --- a/lib/minitasn1/coding.c +++ b/lib/minitasn1/coding.c @@ -44,17 +44,19 @@ /* Return: */ /******************************************************/ static void -_asn1_error_description_value_not_found (asn1_node node, - char *ErrorDescription) +_asn1_error_description_value_not_found(asn1_node node, + char *ErrorDescription) { - if (ErrorDescription == NULL) - return; + if (ErrorDescription == NULL) + return; - Estrcpy (ErrorDescription, ":: value of element '"); - _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), - ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40); - Estrcat (ErrorDescription, "' not found"); + Estrcpy(ErrorDescription, ":: value of element '"); + _asn1_hierarchical_name(node, + ErrorDescription + + strlen(ErrorDescription), + ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40); + Estrcat(ErrorDescription, "' not found"); } @@ -71,38 +73,33 @@ _asn1_error_description_value_not_found (asn1_node node, * To know the size of the DER encoding use a %NULL value for @der. **/ void -asn1_length_der (unsigned long int len, unsigned char *der, int *der_len) +asn1_length_der(unsigned long int len, unsigned char *der, int *der_len) { - int k; - unsigned char temp[ASN1_MAX_LENGTH_SIZE]; + int k; + unsigned char temp[ASN1_MAX_LENGTH_SIZE]; #if SIZEOF_UNSIGNED_LONG_INT > 8 - len &= 0xFFFFFFFFFFFFFFFF; + len &= 0xFFFFFFFFFFFFFFFF; #endif - if (len < 128) - { - /* short form */ - if (der != NULL) - der[0] = (unsigned char) len; - *der_len = 1; - } - else - { - /* Long form */ - k = 0; - while (len) - { - temp[k++] = len & 0xFF; - len = len >> 8; - } - *der_len = k + 1; - if (der != NULL) - { - der[0] = ((unsigned char) k & 0x7F) + 128; - while (k--) - der[*der_len - 1 - k] = temp[k]; + if (len < 128) { + /* short form */ + if (der != NULL) + der[0] = (unsigned char) len; + *der_len = 1; + } else { + /* Long form */ + k = 0; + while (len) { + temp[k++] = len & 0xFF; + len = len >> 8; + } + *der_len = k + 1; + if (der != NULL) { + der[0] = ((unsigned char) k & 0x7F) + 128; + while (k--) + der[*der_len - 1 - k] = temp[k]; + } } - } } /******************************************************/ @@ -119,36 +116,33 @@ asn1_length_der (unsigned long int len, unsigned char *der, int *der_len) /* Return: */ /******************************************************/ static void -_asn1_tag_der (unsigned char class, unsigned int tag_value, - unsigned char *ans, int *ans_len) +_asn1_tag_der(unsigned char class, unsigned int tag_value, + unsigned char *ans, int *ans_len) { - int k; - unsigned char temp[ASN1_MAX_TAG_SIZE]; - - if (tag_value < 31) - { - /* short form */ - ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F)); - *ans_len = 1; - } - else - { - /* Long form */ - ans[0] = (class & 0xE0) + 31; - k = 0; - while (tag_value != 0) - { - temp[k++] = tag_value & 0x7F; - tag_value >>= 7; - - if (k > ASN1_MAX_TAG_SIZE-1) - break; /* will not encode larger tags */ + int k; + unsigned char temp[ASN1_MAX_TAG_SIZE]; + + if (tag_value < 31) { + /* short form */ + ans[0] = + (class & 0xE0) + ((unsigned char) (tag_value & 0x1F)); + *ans_len = 1; + } else { + /* Long form */ + ans[0] = (class & 0xE0) + 31; + k = 0; + while (tag_value != 0) { + temp[k++] = tag_value & 0x7F; + tag_value >>= 7; + + if (k > ASN1_MAX_TAG_SIZE - 1) + break; /* will not encode larger tags */ + } + *ans_len = k + 1; + while (k--) + ans[*ans_len - 1 - k] = temp[k] + 128; + ans[*ans_len - 1] -= 128; } - *ans_len = k + 1; - while (k--) - ans[*ans_len - 1 - k] = temp[k] + 128; - ans[*ans_len - 1] -= 128; - } } /** @@ -169,17 +163,17 @@ _asn1_tag_der (unsigned char class, unsigned int tag_value, * asn1_length_der(). **/ void -asn1_octet_der (const unsigned char *str, int str_len, - unsigned char *der, int *der_len) +asn1_octet_der(const unsigned char *str, int str_len, + unsigned char *der, int *der_len) { - int len_len; + int len_len; - if (der == NULL || str_len < 0) - return; + 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_length_der(str_len, der, &len_len); + memcpy(der + len_len, str, str_len); + *der_len = str_len + len_len; } @@ -201,46 +195,47 @@ asn1_octet_der (const unsigned char *str, int str_len, * 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) +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; + 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 (str == NULL) + return ASN1_VALUE_NOT_VALID; - if (ETYPE_OK(etype) == 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; + /* 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_tag_der(ETYPE_CLASS(etype), ETYPE_TAG(etype), + der_tag, &tag_len); - asn1_length_der(str_len, der_length, &len_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 (tag_len <= 0 || len_len <= 0) + return ASN1_VALUE_NOT_VALID; - if (*tl_len < tlen) - return ASN1_MEM_ERROR; + tlen = tag_len + len_len; - p = tl; - memcpy(p, der_tag, tag_len); - p+=tag_len; - memcpy(p, der_length, len_len); - - *tl_len = tlen; + if (*tl_len < tlen) + return ASN1_MEM_ERROR; - return ASN1_SUCCESS; + p = tl; + memcpy(p, der_tag, tag_len); + p += tag_len; + memcpy(p, der_length, len_len); + + *tl_len = tlen; + + return ASN1_SUCCESS; } /******************************************************/ @@ -258,23 +253,24 @@ asn1_encode_simple_der (unsigned int etype, const unsigned char *str, unsigned i /* ASN1_SUCCESS otherwise */ /******************************************************/ static int -_asn1_time_der (unsigned char *str, int str_len, 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 len_len; + int max_len; - max_len = *der_len; + max_len = *der_len; - asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len); + asn1_length_der(str_len, (max_len > 0) ? der : NULL, &len_len); - if ((len_len + str_len) <= max_len) - memcpy (der + len_len, str, str_len); - *der_len = len_len + str_len; + if ((len_len + str_len) <= max_len) + memcpy(der + len_len, str, str_len); + *der_len = len_len + str_len; - if ((*der_len) > max_len) - return ASN1_MEM_ERROR; + if ((*der_len) > max_len) + return ASN1_MEM_ERROR; - return ASN1_SUCCESS; + return ASN1_SUCCESS; } @@ -329,80 +325,73 @@ _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str) /* ASN1_SUCCESS otherwise */ /******************************************************/ static int -_asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len) +_asn1_objectid_der(unsigned char *str, unsigned char *der, int *der_len) { - int len_len, counter, k, first, max_len; - char *temp, *n_end, *n_start; - unsigned char bit7; - unsigned long val, val1 = 0; - int str_len = _asn1_strlen (str); - - max_len = *der_len; - - temp = malloc (str_len + 2); - if (temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - memcpy (temp, str, str_len); - temp[str_len] = '.'; - temp[str_len + 1] = 0; - - counter = 0; - n_start = temp; - while ((n_end = strchr (n_start, '.'))) - { - *n_end = 0; - val = strtoul (n_start, NULL, 10); - counter++; - - if (counter == 1) - val1 = val; - else if (counter == 2) - { - if (max_len > 0) - der[0] = 40 * val1 + val; - *der_len = 1; - } - else - { - first = 0; - for (k = 4; k >= 0; k--) - { - bit7 = (val >> (k * 7)) & 0x7F; - if (bit7 || first || !k) - { - if (k) - bit7 |= 0x80; - if (max_len > (*der_len)) - der[*der_len] = bit7; - (*der_len)++; - first = 1; - } - } + int len_len, counter, k, first, max_len; + char *temp, *n_end, *n_start; + unsigned char bit7; + unsigned long val, val1 = 0; + int str_len = _asn1_strlen(str); + + max_len = *der_len; + + temp = malloc(str_len + 2); + if (temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + memcpy(temp, str, str_len); + temp[str_len] = '.'; + temp[str_len + 1] = 0; + + counter = 0; + n_start = temp; + while ((n_end = strchr(n_start, '.'))) { + *n_end = 0; + val = strtoul(n_start, NULL, 10); + counter++; + + if (counter == 1) + val1 = val; + else if (counter == 2) { + if (max_len > 0) + der[0] = 40 * val1 + val; + *der_len = 1; + } else { + first = 0; + for (k = 4; k >= 0; k--) { + bit7 = (val >> (k * 7)) & 0x7F; + if (bit7 || first || !k) { + if (k) + bit7 |= 0x80; + if (max_len > (*der_len)) + der[*der_len] = bit7; + (*der_len)++; + first = 1; + } + } + } + n_start = n_end + 1; } - n_start = n_end + 1; - } - asn1_length_der (*der_len, NULL, &len_len); - if (max_len >= (*der_len + len_len)) - { - memmove (der + len_len, der, *der_len); - asn1_length_der (*der_len, der, &len_len); - } - *der_len += len_len; + asn1_length_der(*der_len, NULL, &len_len); + if (max_len >= (*der_len + len_len)) { + memmove(der + len_len, der, *der_len); + asn1_length_der(*der_len, der, &len_len); + } + *der_len += len_len; - free (temp); + free(temp); - if (max_len < (*der_len)) - return ASN1_MEM_ERROR; + if (max_len < (*der_len)) + return ASN1_MEM_ERROR; - return ASN1_SUCCESS; + return ASN1_SUCCESS; } static const unsigned char bit_mask[] = - { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 }; + { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 }; /** * asn1_bit_der: @@ -424,25 +413,25 @@ static const unsigned char bit_mask[] = * asn1_length_der(). **/ void -asn1_bit_der (const unsigned char *str, int bit_len, - unsigned char *der, int *der_len) +asn1_bit_der(const unsigned char *str, int bit_len, + unsigned char *der, int *der_len) { - int len_len, len_byte, len_pad; + int len_len, len_byte, len_pad; - if (der == NULL) - return; + if (der == NULL) + return; - len_byte = bit_len >> 3; - len_pad = 8 - (bit_len & 7); - if (len_pad == 8) - len_pad = 0; - else - len_byte++; - asn1_length_der (len_byte + 1, der, &len_len); - der[len_len] = len_pad; - memcpy (der + len_len + 1, str, len_byte); - der[len_len + len_byte] &= bit_mask[len_pad]; - *der_len = len_byte + len_len + 1; + len_byte = bit_len >> 3; + len_pad = 8 - (bit_len & 7); + if (len_pad == 8) + len_pad = 0; + else + len_byte++; + asn1_length_der(len_byte + 1, der, &len_len); + der[len_len] = len_pad; + memcpy(der + len_len + 1, str, len_byte); + der[len_len + len_byte] &= bit_mask[len_pad]; + *der_len = len_byte + len_len + 1; } @@ -461,89 +450,117 @@ asn1_bit_der (const unsigned char *str, int bit_len, /* otherwise ASN1_SUCCESS. */ /******************************************************/ static int -_asn1_complete_explicit_tag (asn1_node node, unsigned char *der, - int *counter, int *max_len) +_asn1_complete_explicit_tag(asn1_node node, unsigned char *der, + int *counter, int *max_len) { - asn1_node p; - int is_tag_implicit, len2, len3; - unsigned char temp[SIZEOF_UNSIGNED_INT]; - - is_tag_implicit = 0; - - if (node->type & CONST_TAG) - { - p = node->down; - /* When there are nested tags we must complete them reverse to - the order they were created. This is because completing a tag - modifies all data within it, including the incomplete tags - which store buffer positions -- simon@josefsson.org 2002-09-06 - */ - while (p->right) - p = p->right; - while (p && p != node->down->left) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if (p->type & CONST_EXPLICIT) - { - len2 = strtol (p->name, NULL, 10); - _asn1_set_name (p, NULL); - asn1_length_der (*counter - len2, temp, &len3); - if (len3 <= (*max_len)) - { - memmove (der + len2 + len3, der + len2, - *counter - len2); - memcpy (der + len2, temp, len3); - } - *max_len -= len3; - *counter += len3; - is_tag_implicit = 0; - } - else - { /* CONST_IMPLICIT */ - if (!is_tag_implicit) - { - is_tag_implicit = 1; - } + asn1_node p; + int is_tag_implicit, len2, len3; + unsigned char temp[SIZEOF_UNSIGNED_INT]; + + is_tag_implicit = 0; + + if (node->type & CONST_TAG) { + p = node->down; + /* When there are nested tags we must complete them reverse to + the order they were created. This is because completing a tag + modifies all data within it, including the incomplete tags + which store buffer positions -- simon@josefsson.org 2002-09-06 + */ + while (p->right) + p = p->right; + while (p && p != node->down->left) { + if (type_field(p->type) == ASN1_ETYPE_TAG) { + if (p->type & CONST_EXPLICIT) { + len2 = strtol(p->name, NULL, 10); + _asn1_set_name(p, NULL); + asn1_length_der(*counter - len2, + temp, &len3); + if (len3 <= (*max_len)) { + memmove(der + len2 + len3, + der + len2, + *counter - len2); + memcpy(der + len2, temp, + len3); + } + *max_len -= len3; + *counter += len3; + is_tag_implicit = 0; + } else { /* CONST_IMPLICIT */ + if (!is_tag_implicit) { + is_tag_implicit = 1; + } + } + } + p = p->left; } - } - p = p->left; } - } - if (*max_len < 0) - return ASN1_MEM_ERROR; + if (*max_len < 0) + return ASN1_MEM_ERROR; - return ASN1_SUCCESS; + 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"}, +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]); +unsigned int _asn1_tags_size = sizeof(_asn1_tags) / sizeof(_asn1_tags[0]); /******************************************************/ /* Function : _asn1_insert_tag_der */ @@ -561,104 +578,120 @@ unsigned int _asn1_tags_size = sizeof(_asn1_tags)/sizeof(_asn1_tags[0]); /* otherwise ASN1_SUCCESS. */ /******************************************************/ static int -_asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter, - int *max_len) +_asn1_insert_tag_der(asn1_node node, unsigned char *der, int *counter, + int *max_len) { - asn1_node p; - int tag_len, is_tag_implicit; - unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1]; - unsigned long tag_implicit = 0; - unsigned char tag_der[MAX_TAG_LEN]; - - is_tag_implicit = 0; - - if (node->type & CONST_TAG) - { - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if (p->type & CONST_APPLICATION) - class = ASN1_CLASS_APPLICATION; - else if (p->type & CONST_UNIVERSAL) - class = ASN1_CLASS_UNIVERSAL; - else if (p->type & CONST_PRIVATE) - class = ASN1_CLASS_PRIVATE; - else - class = ASN1_CLASS_CONTEXT_SPECIFIC; - - if (p->type & CONST_EXPLICIT) - { - if (is_tag_implicit) - _asn1_tag_der (class_implicit, tag_implicit, tag_der, - &tag_len); - else - _asn1_tag_der (class | ASN1_CLASS_STRUCTURED, - _asn1_strtoul (p->value, NULL, 10), - tag_der, &tag_len); - - *max_len -= tag_len; - if (*max_len >= 0) - memcpy (der + *counter, tag_der, tag_len); - *counter += tag_len; - - _asn1_ltostr (*counter, (char *) temp); - _asn1_set_name (p, (const char *) temp); - - is_tag_implicit = 0; - } - else - { /* CONST_IMPLICIT */ - if (!is_tag_implicit) - { - 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); - is_tag_implicit = 1; - } + asn1_node p; + int tag_len, is_tag_implicit; + unsigned char class, class_implicit = + 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1]; + unsigned long tag_implicit = 0; + unsigned char tag_der[MAX_TAG_LEN]; + + is_tag_implicit = 0; + + if (node->type & CONST_TAG) { + p = node->down; + while (p) { + if (type_field(p->type) == ASN1_ETYPE_TAG) { + if (p->type & CONST_APPLICATION) + class = ASN1_CLASS_APPLICATION; + else if (p->type & CONST_UNIVERSAL) + class = ASN1_CLASS_UNIVERSAL; + else if (p->type & CONST_PRIVATE) + class = ASN1_CLASS_PRIVATE; + else + class = + ASN1_CLASS_CONTEXT_SPECIFIC; + + if (p->type & CONST_EXPLICIT) { + if (is_tag_implicit) + _asn1_tag_der + (class_implicit, + tag_implicit, tag_der, + &tag_len); + else + _asn1_tag_der(class | + ASN1_CLASS_STRUCTURED, + _asn1_strtoul + (p->value, + NULL, 10), + tag_der, + &tag_len); + + *max_len -= tag_len; + if (*max_len >= 0) + memcpy(der + *counter, + tag_der, tag_len); + *counter += tag_len; + + _asn1_ltostr(*counter, + (char *) temp); + _asn1_set_name(p, + (const char *) + temp); + + is_tag_implicit = 0; + } else { /* CONST_IMPLICIT */ + if (!is_tag_implicit) { + 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); + is_tag_implicit = 1; + } + } + } + p = p->right; } - } - p = p->right; } - } - - if (is_tag_implicit) - { - _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len); - } - else - { - unsigned type = type_field (node->type); - switch (type) - { - CASE_HANDLED_ETYPES: - _asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag, - tag_der, &tag_len); - break; - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_CHOICE: - case ASN1_ETYPE_ANY: - tag_len = 0; - break; - default: - return ASN1_GENERIC_ERROR; + + if (is_tag_implicit) { + _asn1_tag_der(class_implicit, tag_implicit, tag_der, + &tag_len); + } else { + unsigned type = type_field(node->type); + switch (type) { + CASE_HANDLED_ETYPES: + _asn1_tag_der(_asn1_tags[type].class, + _asn1_tags[type].tag, tag_der, + &tag_len); + break; + case ASN1_ETYPE_TAG: + case ASN1_ETYPE_CHOICE: + case ASN1_ETYPE_ANY: + tag_len = 0; + break; + default: + return ASN1_GENERIC_ERROR; + } } - } - *max_len -= tag_len; - if (*max_len >= 0) - memcpy (der + *counter, tag_der, tag_len); - *counter += tag_len; + *max_len -= tag_len; + if (*max_len >= 0) + memcpy(der + *counter, tag_der, tag_len); + *counter += tag_len; - if (*max_len < 0) - return ASN1_MEM_ERROR; + if (*max_len < 0) + return ASN1_MEM_ERROR; - return ASN1_SUCCESS; + return ASN1_SUCCESS; } /******************************************************/ @@ -671,108 +704,108 @@ _asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter, /* Return: */ /******************************************************/ static void -_asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) +_asn1_ordering_set(unsigned char *der, int der_len, asn1_node node) { - struct vet - { - int end; - unsigned long value; - struct vet *next, *prev; - }; - - int counter, len, len2; - struct vet *first, *last, *p_vet, *p2_vet; - asn1_node p; - unsigned char class, *temp; - unsigned long tag; - - counter = 0; - - if (type_field (node->type) != ASN1_ETYPE_SET) - return; + struct vet { + int end; + unsigned long value; + struct vet *next, *prev; + }; - p = node->down; - while ((type_field (p->type) == ASN1_ETYPE_TAG) - || (type_field (p->type) == ASN1_ETYPE_SIZE)) - p = p->right; + int counter, len, len2; + struct vet *first, *last, *p_vet, *p2_vet; + asn1_node p; + unsigned char class, *temp; + unsigned long tag; - if ((p == NULL) || (p->right == NULL)) - return; + counter = 0; - first = last = NULL; - while (p) - { - p_vet = malloc (sizeof (struct vet)); - if (p_vet == NULL) - return; - - p_vet->next = NULL; - p_vet->prev = last; - if (first == NULL) - first = p_vet; - else - last->next = p_vet; - last = p_vet; - - /* tag value calculation */ - if (asn1_get_tag_der - (der + counter, der_len - counter, &class, &len2, - &tag) != ASN1_SUCCESS) - return; - p_vet->value = (class << 24) | tag; - counter += len2; - - /* extraction and length */ - len2 = asn1_get_length_der (der + counter, der_len - counter, &len); - if (len2 < 0) - return; - counter += len + len2; - - p_vet->end = counter; - p = p->right; - } - - p_vet = first; - - while (p_vet) - { - p2_vet = p_vet->next; - counter = 0; - while (p2_vet) - { - if (p_vet->value > p2_vet->value) - { - /* change position */ - temp = malloc (p_vet->end - counter); - if (temp == NULL) + if (type_field(node->type) != ASN1_ETYPE_SET) return; - memcpy (temp, der + counter, p_vet->end - counter); - memcpy (der + counter, der + p_vet->end, - p2_vet->end - p_vet->end); - memcpy (der + counter + p2_vet->end - p_vet->end, temp, - p_vet->end - counter); - free (temp); - - tag = p_vet->value; - p_vet->value = p2_vet->value; - p2_vet->value = tag; + p = node->down; + while ((type_field(p->type) == ASN1_ETYPE_TAG) + || (type_field(p->type) == ASN1_ETYPE_SIZE)) + p = p->right; - p_vet->end = counter + (p2_vet->end - p_vet->end); - } - counter = p_vet->end; + if ((p == NULL) || (p->right == NULL)) + return; - p2_vet = p2_vet->next; - p_vet = p_vet->next; + first = last = NULL; + while (p) { + p_vet = malloc(sizeof(struct vet)); + if (p_vet == NULL) + return; + + p_vet->next = NULL; + p_vet->prev = last; + if (first == NULL) + first = p_vet; + else + last->next = p_vet; + last = p_vet; + + /* tag value calculation */ + if (asn1_get_tag_der + (der + counter, der_len - counter, &class, &len2, + &tag) != ASN1_SUCCESS) + return; + p_vet->value = (class << 24) | tag; + counter += len2; + + /* extraction and length */ + len2 = + asn1_get_length_der(der + counter, der_len - counter, + &len); + if (len2 < 0) + return; + counter += len + len2; + + p_vet->end = counter; + p = p->right; } - if (p_vet != first) - p_vet->prev->next = NULL; - else - first = NULL; - free (p_vet); - p_vet = first; - } + p_vet = first; + + while (p_vet) { + p2_vet = p_vet->next; + counter = 0; + while (p2_vet) { + if (p_vet->value > p2_vet->value) { + /* change position */ + temp = malloc(p_vet->end - counter); + if (temp == NULL) + return; + + memcpy(temp, der + counter, + p_vet->end - counter); + memcpy(der + counter, der + p_vet->end, + p2_vet->end - p_vet->end); + memcpy(der + counter + p2_vet->end - + p_vet->end, temp, + p_vet->end - counter); + free(temp); + + tag = p_vet->value; + p_vet->value = p2_vet->value; + p2_vet->value = tag; + + p_vet->end = + counter + (p2_vet->end - p_vet->end); + } + counter = p_vet->end; + + p2_vet = p2_vet->next; + p_vet = p_vet->next; + } + + if (p_vet != first) + p_vet->prev->next = NULL; + else + first = NULL; + free(p_vet); + p_vet = first; + } } /******************************************************/ @@ -785,128 +818,127 @@ _asn1_ordering_set (unsigned char *der, int der_len, asn1_node node) /* Return: */ /******************************************************/ static void -_asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node) +_asn1_ordering_set_of(unsigned char *der, int der_len, asn1_node node) { - struct vet - { - int end; - struct vet *next, *prev; - }; + struct vet { + int end; + struct vet *next, *prev; + }; - int counter, len, len2, change; - struct vet *first, *last, *p_vet, *p2_vet; - asn1_node p; - unsigned char *temp, class; - unsigned long k, max; + int counter, len, len2, change; + struct vet *first, *last, *p_vet, *p2_vet; + asn1_node p; + unsigned char *temp, class; + unsigned long k, max; - counter = 0; + counter = 0; - if (type_field (node->type) != ASN1_ETYPE_SET_OF) - return; - - p = node->down; - while ((type_field (p->type) == ASN1_ETYPE_TAG) - || (type_field (p->type) == ASN1_ETYPE_SIZE)) - p = p->right; - p = p->right; - - if ((p == NULL) || (p->right == NULL)) - return; + if (type_field(node->type) != ASN1_ETYPE_SET_OF) + return; - first = last = NULL; - while (p) - { - p_vet = malloc (sizeof (struct vet)); - if (p_vet == NULL) - return; - - p_vet->next = NULL; - p_vet->prev = last; - if (first == NULL) - first = p_vet; - else - last->next = p_vet; - last = p_vet; - - /* extraction of tag and length */ - if (der_len - counter > 0) - { - - if (asn1_get_tag_der - (der + counter, der_len - counter, &class, &len, - NULL) != ASN1_SUCCESS) - return; - counter += len; - - len2 = asn1_get_length_der (der + counter, der_len - counter, &len); - if (len2 < 0) - return; - counter += len + len2; - } + p = node->down; + while ((type_field(p->type) == ASN1_ETYPE_TAG) + || (type_field(p->type) == ASN1_ETYPE_SIZE)) + p = p->right; + p = p->right; - p_vet->end = counter; - p = p->right; - } - - p_vet = first; - - while (p_vet) - { - p2_vet = p_vet->next; - counter = 0; - while (p2_vet) - { - if ((p_vet->end - counter) > (p2_vet->end - p_vet->end)) - max = p_vet->end - counter; - else - max = p2_vet->end - p_vet->end; - - change = -1; - for (k = 0; k < max; k++) - if (der[counter + k] > der[p_vet->end + k]) - { - change = 1; - break; - } - else if (der[counter + k] < der[p_vet->end + k]) - { - change = 0; - break; - } - - if ((change == -1) - && ((p_vet->end - counter) > (p2_vet->end - p_vet->end))) - change = 1; - - if (change == 1) - { - /* change position */ - temp = malloc (p_vet->end - counter); - if (temp == NULL) + if ((p == NULL) || (p->right == NULL)) return; - memcpy (temp, der + counter, (p_vet->end) - counter); - memcpy (der + counter, der + (p_vet->end), - (p2_vet->end) - (p_vet->end)); - memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp, - (p_vet->end) - counter); - free (temp); - - p_vet->end = counter + (p2_vet->end - p_vet->end); - } - counter = p_vet->end; + first = last = NULL; + while (p) { + p_vet = malloc(sizeof(struct vet)); + if (p_vet == NULL) + return; + + p_vet->next = NULL; + p_vet->prev = last; + if (first == NULL) + first = p_vet; + else + last->next = p_vet; + last = p_vet; + + /* extraction of tag and length */ + if (der_len - counter > 0) { + + if (asn1_get_tag_der + (der + counter, der_len - counter, &class, + &len, NULL) != ASN1_SUCCESS) + return; + counter += len; + + len2 = + asn1_get_length_der(der + counter, + der_len - counter, &len); + if (len2 < 0) + return; + counter += len + len2; + } - p2_vet = p2_vet->next; - p_vet = p_vet->next; + p_vet->end = counter; + p = p->right; } - if (p_vet != first) - p_vet->prev->next = NULL; - else - first = NULL; - free (p_vet); - p_vet = first; - } + p_vet = first; + + while (p_vet) { + p2_vet = p_vet->next; + counter = 0; + while (p2_vet) { + if ((p_vet->end - counter) > + (p2_vet->end - p_vet->end)) + max = p_vet->end - counter; + else + max = p2_vet->end - p_vet->end; + + change = -1; + for (k = 0; k < max; k++) + if (der[counter + k] > der[p_vet->end + k]) { + change = 1; + break; + } else if (der[counter + k] < + der[p_vet->end + k]) { + change = 0; + break; + } + + if ((change == -1) + && ((p_vet->end - counter) > + (p2_vet->end - p_vet->end))) + change = 1; + + if (change == 1) { + /* change position */ + temp = malloc(p_vet->end - counter); + if (temp == NULL) + return; + + memcpy(temp, der + counter, + (p_vet->end) - counter); + memcpy(der + counter, der + (p_vet->end), + (p2_vet->end) - (p_vet->end)); + memcpy(der + counter + (p2_vet->end) - + (p_vet->end), temp, + (p_vet->end) - counter); + free(temp); + + p_vet->end = + counter + (p2_vet->end - p_vet->end); + } + counter = p_vet->end; + + p2_vet = p2_vet->next; + p_vet = p_vet->next; + } + + if (p_vet != first) + p_vet->prev->next = NULL; + else + first = NULL; + free(p_vet); + p_vet = first; + } } /** @@ -931,332 +963,334 @@ _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node) * length needed. **/ int -asn1_der_coding (asn1_node element, const char *name, void *ider, int *len, - char *ErrorDescription) +asn1_der_coding(asn1_node element, const char *name, void *ider, int *len, + char *ErrorDescription) { - asn1_node node, p, p2; - unsigned char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1]; - int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old; - int err; - unsigned char *der = ider; - - node = asn1_find_node (element, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - /* Node is now a locally allocated variable. - * That is because in some point we modify the - * structure, and I don't know why! --nmav - */ - node = _asn1_copy_structure3 (node); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - max_len = *len; - - counter = 0; - move = DOWN; - p = node; - while (1) - { - - counter_old = counter; - max_len_old = max_len; - if (move != UP) - { - err = _asn1_insert_tag_der (p, der, &counter, &max_len); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - } - switch (type_field (p->type)) - { - case ASN1_ETYPE_NULL: - max_len--; - if (max_len >= 0) - der[counter] = 0; - counter++; - move = RIGHT; - break; - case ASN1_ETYPE_BOOLEAN: - if ((p->type & CONST_DEFAULT) && (p->value == NULL)) - { - counter = counter_old; - max_len = max_len_old; - } - else - { - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, - ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - max_len -= 2; - if (max_len >= 0) - { - der[counter++] = 1; - if (p->value[0] == 'F') - der[counter++] = 0; - else - der[counter++] = 0xFF; + asn1_node node, p, p2; + unsigned char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1]; + int counter, counter_old, len2, len3, tlen, move, max_len, + max_len_old; + int err; + unsigned char *der = ider; + + node = asn1_find_node(element, name); + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + /* Node is now a locally allocated variable. + * That is because in some point we modify the + * structure, and I don't know why! --nmav + */ + node = _asn1_copy_structure3(node); + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + max_len = *len; + + counter = 0; + move = DOWN; + p = node; + while (1) { + + counter_old = counter; + max_len_old = max_len; + if (move != UP) { + err = + _asn1_insert_tag_der(p, der, &counter, + &max_len); + if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) + goto error; } - else - counter += 2; - } - move = RIGHT; - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - if ((p->type & CONST_DEFAULT) && (p->value == NULL)) - { - counter = counter_old; - max_len = max_len_old; - } - else - { - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, - ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; + switch (type_field(p->type)) { + case ASN1_ETYPE_NULL: + max_len--; + if (max_len >= 0) + der[counter] = 0; + counter++; + move = RIGHT; + break; + case ASN1_ETYPE_BOOLEAN: + if ((p->type & CONST_DEFAULT) + && (p->value == NULL)) { + counter = counter_old; + max_len = max_len_old; + } else { + if (p->value == NULL) { + _asn1_error_description_value_not_found + (p, ErrorDescription); + err = ASN1_VALUE_NOT_FOUND; + goto error; + } + max_len -= 2; + if (max_len >= 0) { + der[counter++] = 1; + if (p->value[0] == 'F') + der[counter++] = 0; + else + der[counter++] = 0xFF; + } else + counter += 2; + } + move = RIGHT; + break; + case ASN1_ETYPE_INTEGER: + case ASN1_ETYPE_ENUMERATED: + if ((p->type & CONST_DEFAULT) + && (p->value == NULL)) { + counter = counter_old; + max_len = max_len_old; + } else { + 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 ASN1_ETYPE_OBJECT_ID: + if ((p->type & CONST_DEFAULT) + && (p->value == NULL)) { + counter = counter_old; + max_len = max_len_old; + } else { + if (p->value == NULL) { + _asn1_error_description_value_not_found + (p, ErrorDescription); + err = ASN1_VALUE_NOT_FOUND; + goto error; + } + len2 = max_len; + err = + _asn1_objectid_der(p->value, + der + counter, + &len2); + if (err != ASN1_SUCCESS + && err != ASN1_MEM_ERROR) + goto error; + + max_len -= len2; + counter += len2; + } + move = RIGHT; + break; + case ASN1_ETYPE_GENERALIZED_TIME: + case ASN1_ETYPE_UTC_TIME: + if (p->value == NULL) { + _asn1_error_description_value_not_found(p, + ErrorDescription); + err = ASN1_VALUE_NOT_FOUND; + goto error; + } + len2 = max_len; + err = + _asn1_time_der(p->value, p->value_len, + der + counter, &len2); + if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) + goto error; + + max_len -= len2; + counter += len2; + move = RIGHT; + break; + 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); + 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 ASN1_ETYPE_SEQUENCE: + case ASN1_ETYPE_SET: + if (move != UP) { + _asn1_ltostr(counter, (char *) temp); + tlen = _asn1_strlen(temp); + if (tlen > 0) + _asn1_set_value(p, temp, tlen + 1); + if (p->down == NULL) { + move = UP; + continue; + } else { + p2 = p->down; + while (p2 + && (type_field(p2->type) == + ASN1_ETYPE_TAG)) + p2 = p2->right; + if (p2) { + p = p2; + move = RIGHT; + continue; + } + move = UP; + continue; + } + } else { /* move==UP */ + len2 = _asn1_strtol(p->value, NULL, 10); + _asn1_set_value(p, NULL, 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; + if (max_len >= 0) { + memmove(der + len2 + len3, + der + len2, + counter - len2); + memcpy(der + len2, temp, len3); + } + counter += len3; + move = RIGHT; + } + break; + case ASN1_ETYPE_SEQUENCE_OF: + case ASN1_ETYPE_SET_OF: + if (move != UP) { + _asn1_ltostr(counter, (char *) temp); + tlen = _asn1_strlen(temp); + + if (tlen > 0) + _asn1_set_value(p, temp, tlen + 1); + p = p->down; + while ((type_field(p->type) == + ASN1_ETYPE_TAG) + || (type_field(p->type) == + ASN1_ETYPE_SIZE)) + p = p->right; + if (p->right) { + p = p->right; + move = RIGHT; + continue; + } else + p = _asn1_find_up(p); + move = UP; + } + if (move == UP) { + len2 = _asn1_strtol(p->value, NULL, 10); + _asn1_set_value(p, NULL, 0); + if ((type_field(p->type) == + ASN1_ETYPE_SET_OF) + && (max_len - len2 > 0)) { + _asn1_ordering_set_of(der + len2, + max_len - + len2, p); + } + asn1_length_der(counter - len2, temp, + &len3); + max_len -= len3; + if (max_len >= 0) { + memmove(der + len2 + len3, + der + len2, + counter - len2); + memcpy(der + len2, temp, len3); + } + counter += len3; + move = RIGHT; + } + break; + case ASN1_ETYPE_ANY: + 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; + if (max_len >= 0) + memcpy(der + counter, p->value + len3, + len2); + counter += len2; + move = RIGHT; + break; + default: + move = (move == UP) ? RIGHT : DOWN; + break; } - 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 ASN1_ETYPE_OBJECT_ID: - if ((p->type & CONST_DEFAULT) && (p->value == NULL)) - { - counter = counter_old; - max_len = max_len_old; - } - else - { - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, - ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = max_len; - err = _asn1_objectid_der (p->value, der + counter, &len2); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - max_len -= len2; - counter += len2; - } - move = RIGHT; - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - if (p->value == NULL) - { - _asn1_error_description_value_not_found (p, ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2 = max_len; - err = _asn1_time_der (p->value, p->value_len, der + counter, &len2); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - - max_len -= len2; - counter += len2; - move = RIGHT; - break; - 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); - 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 ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_SET: - if (move != UP) - { - _asn1_ltostr (counter, (char *) temp); - tlen = _asn1_strlen (temp); - if (tlen > 0) - _asn1_set_value (p, temp, tlen + 1); - if (p->down == NULL) - { - move = UP; - continue; - } - else - { - p2 = p->down; - while (p2 && (type_field (p2->type) == ASN1_ETYPE_TAG)) - p2 = p2->right; - if (p2) - { - p = p2; - move = RIGHT; - continue; - } - move = UP; - continue; + if ((move != DOWN) && (counter != counter_old)) { + err = + _asn1_complete_explicit_tag(p, der, &counter, + &max_len); + if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) + goto error; } - } - else - { /* move==UP */ - len2 = _asn1_strtol (p->value, NULL, 10); - _asn1_set_value (p, NULL, 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; - if (max_len >= 0) - { - memmove (der + len2 + len3, der + len2, counter - len2); - memcpy (der + len2, temp, len3); - } - counter += len3; - move = RIGHT; - } - break; - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET_OF: - if (move != UP) - { - _asn1_ltostr (counter, (char *) temp); - tlen = _asn1_strlen (temp); - - if (tlen > 0) - _asn1_set_value (p, temp, tlen + 1); - p = p->down; - while ((type_field (p->type) == ASN1_ETYPE_TAG) - || (type_field (p->type) == ASN1_ETYPE_SIZE)) - p = p->right; - if (p->right) - { - p = p->right; - move = RIGHT; - continue; - } - else - p = _asn1_find_up (p); - move = UP; - } - if (move == UP) - { - len2 = _asn1_strtol (p->value, NULL, 10); - _asn1_set_value (p, NULL, 0); - if ((type_field (p->type) == ASN1_ETYPE_SET_OF) - && (max_len - len2 > 0)) - { - _asn1_ordering_set_of (der + len2, max_len - len2, p); + + if (p == node && move != DOWN) + break; + + if (move == DOWN) { + if (p->down) + p = p->down; + else + move = RIGHT; } - asn1_length_der (counter - len2, temp, &len3); - max_len -= len3; - if (max_len >= 0) - { - memmove (der + len2 + len3, der + len2, counter - len2); - memcpy (der + len2, temp, len3); + if (move == RIGHT) { + if (p->right) + p = p->right; + else + move = UP; } - counter += len3; - move = RIGHT; - } - break; - case ASN1_ETYPE_ANY: - 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; - if (max_len >= 0) - memcpy (der + counter, p->value + len3, len2); - counter += len2; - move = RIGHT; - break; - default: - move = (move == UP) ? RIGHT : DOWN; - break; - } - - if ((move != DOWN) && (counter != counter_old)) - { - err = _asn1_complete_explicit_tag (p, der, &counter, &max_len); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; + if (move == UP) + p = _asn1_find_up(p); } - if (p == node && move != DOWN) - break; + *len = counter; - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; + if (max_len < 0) { + err = ASN1_MEM_ERROR; + goto error; } - if (move == UP) - p = _asn1_find_up (p); - } - - *len = counter; - - if (max_len < 0) - { - err = ASN1_MEM_ERROR; - goto error; - } - err = ASN1_SUCCESS; + err = ASN1_SUCCESS; -error: - asn1_delete_structure (&node); - return err; + error: + asn1_delete_structure(&node); + return err; } diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c index f02fe10686..40084d43b7 100644 --- a/lib/minitasn1/decoding.c +++ b/lib/minitasn1/decoding.c @@ -33,16 +33,18 @@ #include <limits.h> static int -_asn1_get_indefinite_length_string (const unsigned char *der, int *len); +_asn1_get_indefinite_length_string(const unsigned char *der, int *len); static void -_asn1_error_description_tag_error (asn1_node node, char *ErrorDescription) +_asn1_error_description_tag_error(asn1_node node, char *ErrorDescription) { - Estrcpy (ErrorDescription, ":: tag error near element '"); - _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), - ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40); - Estrcat (ErrorDescription, "'"); + Estrcpy(ErrorDescription, ":: tag error near element '"); + _asn1_hierarchical_name(node, + ErrorDescription + + strlen(ErrorDescription), + ASN1_MAX_ERROR_DESCRIPTION_SIZE - 40); + Estrcat(ErrorDescription, "'"); } @@ -58,60 +60,52 @@ _asn1_error_description_tag_error (asn1_node node, char *ErrorDescription) * length, or -2 when the value was too big to fit in a int, or -4 * when the decoded length value plus @len would exceed @der_len. **/ -long -asn1_get_length_der (const unsigned char *der, int der_len, int *len) +long asn1_get_length_der(const unsigned char *der, int der_len, int *len) { - unsigned int ans, sum, last; - int k, punt; - - *len = 0; - if (der_len <= 0) - return 0; - - if (!(der[0] & 128)) - { - /* short form */ - *len = 1; - ans = der[0]; - } - else - { - /* Long form */ - k = der[0] & 0x7F; - punt = 1; - if (k) - { /* definite length method */ - ans = 0; - while (punt <= k && punt < der_len) - { - last = ans; - - ans = (ans*256) + der[punt++]; - if (ans < last) - /* we wrapped around, no bignum support... */ - return -2; - } - } - else - { /* indefinite length method */ - *len = punt; - return -1; - } + unsigned int ans, sum, last; + int k, punt; + + *len = 0; + if (der_len <= 0) + return 0; + + if (!(der[0] & 128)) { + /* short form */ + *len = 1; + ans = der[0]; + } else { + /* Long form */ + k = der[0] & 0x7F; + punt = 1; + if (k) { /* definite length method */ + ans = 0; + while (punt <= k && punt < der_len) { + last = ans; + + ans = (ans * 256) + der[punt++]; + if (ans < last) + /* we wrapped around, no bignum support... */ + return -2; + } + } else { /* indefinite length method */ + *len = punt; + return -1; + } - *len = punt; - } + *len = punt; + } - sum = ans + *len; + sum = ans + *len; - /* check for overflow as well INT_MAX as a maximum upper - * limit for length */ - if (sum >= INT_MAX || sum < ans) - return -2; + /* check for overflow as well INT_MAX as a maximum upper + * limit for length */ + if (sum >= INT_MAX || sum < ans) + return -2; - if (((int) sum) > der_len) - return -4; + if (((int) sum) > der_len) + return -4; - return ans; + return ans; } /** @@ -127,52 +121,48 @@ asn1_get_length_der (const unsigned char *der, int der_len, int *len) * Returns: Returns %ASN1_SUCCESS on success, or an error. **/ int -asn1_get_tag_der (const unsigned char *der, int der_len, - unsigned char *cls, int *len, unsigned long *tag) +asn1_get_tag_der(const unsigned char *der, int der_len, + unsigned char *cls, int *len, unsigned long *tag) { - unsigned int ris; - int punt; - unsigned int last; - - if (der == NULL || der_len < 2 || len == NULL) - return ASN1_DER_ERROR; - - *cls = der[0] & 0xE0; - if ((der[0] & 0x1F) != 0x1F) - { - /* short form */ - *len = 1; - ris = der[0] & 0x1F; - } - else - { - /* Long form */ - punt = 1; - ris = 0; - while (punt <= der_len && der[punt] & 128) - { - last = ris; - - ris = (ris * 128) + (der[punt++] & 0x7F); - if (ris < last) - /* wrapped around, and no bignums... */ - return ASN1_DER_ERROR; - } + unsigned int ris; + int punt; + unsigned int last; - if (punt >= der_len) - return ASN1_DER_ERROR; + if (der == NULL || der_len < 2 || len == NULL) + return ASN1_DER_ERROR; - last = ris; + *cls = der[0] & 0xE0; + if ((der[0] & 0x1F) != 0x1F) { + /* short form */ + *len = 1; + ris = der[0] & 0x1F; + } else { + /* Long form */ + punt = 1; + ris = 0; + while (punt <= der_len && der[punt] & 128) { + last = ris; + + ris = (ris * 128) + (der[punt++] & 0x7F); + if (ris < last) + /* wrapped around, and no bignums... */ + return ASN1_DER_ERROR; + } + + if (punt >= der_len) + return ASN1_DER_ERROR; - ris = (ris * 128) + (der[punt++] & 0x7F); - if (ris < last) - return ASN1_DER_ERROR; + last = ris; - *len = punt; - } - if (tag) - *tag = ris; - return ASN1_SUCCESS; + ris = (ris * 128) + (der[punt++] & 0x7F); + if (ris < last) + return ASN1_DER_ERROR; + + *len = punt; + } + if (tag) + *tag = ris; + return ASN1_SUCCESS; } /** @@ -190,22 +180,20 @@ asn1_get_tag_der (const unsigned char *der, int der_len, * * Since: 2.0 **/ -long -asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len) +long asn1_get_length_ber(const unsigned char *ber, int ber_len, int *len) { - int ret; - long err; - - ret = asn1_get_length_der (ber, ber_len, len); - if (ret == -1) - { /* indefinite length method */ - ret = ber_len; - err = _asn1_get_indefinite_length_string (ber + 1, &ret); - if (err != ASN1_SUCCESS) - return -3; - } - - return ret; + int ret; + long err; + + ret = asn1_get_length_der(ber, ber_len, len); + if (ret == -1) { /* indefinite length method */ + ret = ber_len; + err = _asn1_get_indefinite_length_string(ber + 1, &ret); + if (err != ASN1_SUCCESS) + return -3; + } + + return ret; } /** @@ -222,111 +210,109 @@ asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len) * Returns: Returns %ASN1_SUCCESS on success, or an error. **/ int -asn1_get_octet_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, int str_size, - int *str_len) +asn1_get_octet_der(const unsigned char *der, int der_len, + int *ret_len, unsigned char *str, int str_size, + int *str_len) { - int len_len; + int len_len; - if (der_len <= 0) - return ASN1_GENERIC_ERROR; + if (der_len <= 0) + return ASN1_GENERIC_ERROR; - /* if(str==NULL) return ASN1_SUCCESS; */ - *str_len = asn1_get_length_der (der, der_len, &len_len); + /* if(str==NULL) return ASN1_SUCCESS; */ + *str_len = asn1_get_length_der(der, der_len, &len_len); - if (*str_len < 0) - return ASN1_DER_ERROR; + if (*str_len < 0) + return ASN1_DER_ERROR; - *ret_len = *str_len + len_len; - if (str_size >= *str_len) - memcpy (str, der + len_len, *str_len); - else - { - return ASN1_MEM_ERROR; - } + *ret_len = *str_len + len_len; + if (str_size >= *str_len) + memcpy(str, der + len_len, *str_len); + else { + return ASN1_MEM_ERROR; + } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } /* Returns ASN1_SUCCESS on success or an error code on error. */ static int -_asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len, - char *str, int str_size) +_asn1_get_time_der(const unsigned char *der, int der_len, int *ret_len, + char *str, int str_size) { - int len_len, str_len; - - if (der_len <= 0 || str == NULL) - return ASN1_DER_ERROR; - str_len = asn1_get_length_der (der, der_len, &len_len); - if (str_len < 0 || str_size < str_len) - return ASN1_DER_ERROR; - memcpy (str, der + len_len, str_len); - str[str_len] = 0; - *ret_len = str_len + len_len; - - return ASN1_SUCCESS; + int len_len, str_len; + + if (der_len <= 0 || str == NULL) + return ASN1_DER_ERROR; + str_len = asn1_get_length_der(der, der_len, &len_len); + if (str_len < 0 || str_size < str_len) + return ASN1_DER_ERROR; + memcpy(str, der + len_len, str_len); + str[str_len] = 0; + *ret_len = str_len + len_len; + + return ASN1_SUCCESS; } static int -_asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len, - char *str, int str_size) +_asn1_get_objectid_der(const unsigned char *der, int der_len, int *ret_len, + char *str, int str_size) { - int len_len, len, k; - int leading; - char temp[20]; - unsigned long val, val1, prev_val; - - *ret_len = 0; - if (str && str_size > 0) - str[0] = 0; /* no oid */ - - if (str == NULL || der_len <= 0) - return ASN1_GENERIC_ERROR; - len = asn1_get_length_der (der, der_len, &len_len); - - if (len < 0 || len > der_len || len_len > der_len) - return ASN1_DER_ERROR; - - val1 = der[len_len] / 40; - val = der[len_len] - val1 * 40; - - _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp)); - _asn1_str_cat (str, str_size, "."); - _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp)); - - prev_val = 0; - val = 0; - leading = 1; - for (k = 1; k < len; k++) - { - /* X.690 mandates that the leading byte must never be 0x80 - */ - if (leading != 0 && der[len_len + k] == 0x80) - return ASN1_DER_ERROR; - leading = 0; - - /* check for wrap around */ - val = val << 7; - val |= der[len_len + k] & 0x7F; - - if (val < prev_val) - return ASN1_DER_ERROR; - - prev_val = val; - - if (!(der[len_len + k] & 0x80)) - { - _asn1_str_cat (str, str_size, "."); - _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp)); - val = 0; - prev_val = 0; - leading = 1; + int len_len, len, k; + int leading; + char temp[20]; + unsigned long val, val1, prev_val; + + *ret_len = 0; + if (str && str_size > 0) + str[0] = 0; /* no oid */ + + if (str == NULL || der_len <= 0) + return ASN1_GENERIC_ERROR; + len = asn1_get_length_der(der, der_len, &len_len); + + if (len < 0 || len > der_len || len_len > der_len) + return ASN1_DER_ERROR; + + val1 = der[len_len] / 40; + val = der[len_len] - val1 * 40; + + _asn1_str_cpy(str, str_size, _asn1_ltostr(val1, temp)); + _asn1_str_cat(str, str_size, "."); + _asn1_str_cat(str, str_size, _asn1_ltostr(val, temp)); + + prev_val = 0; + val = 0; + leading = 1; + for (k = 1; k < len; k++) { + /* X.690 mandates that the leading byte must never be 0x80 + */ + if (leading != 0 && der[len_len + k] == 0x80) + return ASN1_DER_ERROR; + leading = 0; + + /* check for wrap around */ + val = val << 7; + val |= der[len_len + k] & 0x7F; + + if (val < prev_val) + return ASN1_DER_ERROR; + + prev_val = val; + + if (!(der[len_len + k] & 0x80)) { + _asn1_str_cat(str, str_size, "."); + _asn1_str_cat(str, str_size, + _asn1_ltostr(val, temp)); + val = 0; + prev_val = 0; + leading = 1; + } } - } - *ret_len = len + len_len; + *ret_len = len + len_len; - return ASN1_SUCCESS; + return ASN1_SUCCESS; } /** @@ -343,433 +329,429 @@ _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len, * Returns: Return %ASN1_SUCCESS on success, or an error. **/ int -asn1_get_bit_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, int str_size, - int *bit_len) +asn1_get_bit_der(const unsigned char *der, int der_len, + int *ret_len, unsigned char *str, int str_size, + int *bit_len) { - int len_len, len_byte; + int len_len, len_byte; - if (der_len <= 0) - return ASN1_GENERIC_ERROR; - len_byte = asn1_get_length_der (der, der_len, &len_len) - 1; - if (len_byte < 0) - return ASN1_DER_ERROR; + if (der_len <= 0) + return ASN1_GENERIC_ERROR; + len_byte = asn1_get_length_der(der, der_len, &len_len) - 1; + if (len_byte < 0) + return ASN1_DER_ERROR; - *ret_len = len_byte + len_len + 1; - *bit_len = len_byte * 8 - der[len_len]; + *ret_len = len_byte + len_len + 1; + *bit_len = len_byte * 8 - der[len_len]; - if (str_size >= len_byte) - memcpy (str, der + len_len + 1, len_byte); - else - { - return ASN1_MEM_ERROR; - } + if (str_size >= len_byte) + memcpy(str, der + len_len + 1, len_byte); + else { + return ASN1_MEM_ERROR; + } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } static int -_asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len, - int *ret_len) +_asn1_extract_tag_der(asn1_node node, const unsigned char *der, + int der_len, int *ret_len) { - asn1_node p; - int counter, len2, len3, is_tag_implicit; - unsigned long tag, tag_implicit = 0; - unsigned char class, class2, class_implicit = 0; - - if (der_len <= 0) - return ASN1_GENERIC_ERROR; - - counter = is_tag_implicit = 0; - - if (node->type & CONST_TAG) - { - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if (p->type & CONST_APPLICATION) - class2 = ASN1_CLASS_APPLICATION; - else if (p->type & CONST_UNIVERSAL) - class2 = ASN1_CLASS_UNIVERSAL; - else if (p->type & CONST_PRIVATE) - class2 = ASN1_CLASS_PRIVATE; - else - class2 = ASN1_CLASS_CONTEXT_SPECIFIC; - - if (p->type & CONST_EXPLICIT) - { - if (asn1_get_tag_der - (der + counter, der_len - counter, &class, &len2, - &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - - if (counter + len2 > der_len) - return ASN1_DER_ERROR; - counter += len2; - - len3 = - asn1_get_length_ber (der + counter, der_len - counter, - &len2); - if (len3 < 0) - return ASN1_DER_ERROR; - - counter += len2; - if (counter > der_len) - return ASN1_DER_ERROR; - - if (!is_tag_implicit) - { - if ((class != (class2 | ASN1_CLASS_STRUCTURED)) || - (tag != strtoul ((char *) p->value, NULL, 10))) - return ASN1_TAG_ERROR; - } - else - { /* ASN1_TAG_IMPLICIT */ - if ((class != class_implicit) || (tag != tag_implicit)) - return ASN1_TAG_ERROR; - } - is_tag_implicit = 0; - } - else - { /* ASN1_TAG_IMPLICIT */ - if (!is_tag_implicit) - { - 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); - is_tag_implicit = 1; - } + asn1_node p; + int counter, len2, len3, is_tag_implicit; + unsigned long tag, tag_implicit = 0; + unsigned char class, class2, class_implicit = 0; + + if (der_len <= 0) + return ASN1_GENERIC_ERROR; + + counter = is_tag_implicit = 0; + + if (node->type & CONST_TAG) { + p = node->down; + while (p) { + if (type_field(p->type) == ASN1_ETYPE_TAG) { + if (p->type & CONST_APPLICATION) + class2 = ASN1_CLASS_APPLICATION; + else if (p->type & CONST_UNIVERSAL) + class2 = ASN1_CLASS_UNIVERSAL; + else if (p->type & CONST_PRIVATE) + class2 = ASN1_CLASS_PRIVATE; + else + class2 = + ASN1_CLASS_CONTEXT_SPECIFIC; + + if (p->type & CONST_EXPLICIT) { + if (asn1_get_tag_der + (der + counter, + der_len - counter, &class, + &len2, &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + + if (counter + len2 > der_len) + return ASN1_DER_ERROR; + counter += len2; + + len3 = + asn1_get_length_ber(der + + counter, + der_len - + counter, + &len2); + if (len3 < 0) + return ASN1_DER_ERROR; + + counter += len2; + if (counter > der_len) + return ASN1_DER_ERROR; + + if (!is_tag_implicit) { + if ((class != + (class2 | + ASN1_CLASS_STRUCTURED)) + || (tag != + strtoul((char *) + p->value, + NULL, 10))) + return + ASN1_TAG_ERROR; + } else { /* ASN1_TAG_IMPLICIT */ + if ((class != + class_implicit) + || (tag != + tag_implicit)) + return + ASN1_TAG_ERROR; + } + is_tag_implicit = 0; + } else { /* ASN1_TAG_IMPLICIT */ + if (!is_tag_implicit) { + 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); + is_tag_implicit = 1; + } + } + } + p = p->right; } - } - p = p->right; - } - } - - if (is_tag_implicit) - { - if (asn1_get_tag_der - (der + counter, der_len - counter, &class, &len2, - &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - if (counter + len2 > der_len) - return ASN1_DER_ERROR; - - if ((class != class_implicit) || (tag != tag_implicit)) - { - if (type_field (node->type) == ASN1_ETYPE_OCTET_STRING) - { - class_implicit |= ASN1_CLASS_STRUCTURED; - if ((class != class_implicit) || (tag != tag_implicit)) - return ASN1_TAG_ERROR; - } - else - return ASN1_TAG_ERROR; - } - } - else - { - unsigned type = type_field (node->type); - if (type == ASN1_ETYPE_TAG) - { - counter = 0; - *ret_len = counter; - return ASN1_SUCCESS; } - if (asn1_get_tag_der - (der + counter, der_len - counter, &class, &len2, - &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - - if (counter + len2 > der_len) - return ASN1_DER_ERROR; - - switch (type) - { - 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 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 ASN1_ETYPE_ANY: - counter -= len2; - break; - default: - return ASN1_DER_ERROR; - break; - } - } + if (is_tag_implicit) { + if (asn1_get_tag_der + (der + counter, der_len - counter, &class, &len2, + &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter + len2 > der_len) + return ASN1_DER_ERROR; - counter += len2; - *ret_len = counter; - return ASN1_SUCCESS; -} + if ((class != class_implicit) || (tag != tag_implicit)) { + if (type_field(node->type) == + ASN1_ETYPE_OCTET_STRING) { + class_implicit |= ASN1_CLASS_STRUCTURED; + if ((class != class_implicit) + || (tag != tag_implicit)) + return ASN1_TAG_ERROR; + } else + return ASN1_TAG_ERROR; + } + } else { + unsigned type = type_field(node->type); + if (type == ASN1_ETYPE_TAG) { + counter = 0; + *ret_len = counter; + return ASN1_SUCCESS; + } + + if (asn1_get_tag_der + (der + counter, der_len - counter, &class, &len2, + &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; -static int -_asn1_delete_not_used (asn1_node node) -{ - asn1_node p, p2; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if (p->type & CONST_NOT_USED) - { - p2 = NULL; - if (p != node) - { - p2 = _asn1_find_left (p); - if (!p2) - p2 = _asn1_find_up (p); - } - asn1_delete_structure (&p); - p = p2; - } + if (counter + len2 > der_len) + return ASN1_DER_ERROR; - if (!p) - break; /* reach node */ + switch (type) { + 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; - if (p->down) - { - p = p->down; + 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 ASN1_ETYPE_ANY: + counter -= len2; + break; + default: + return ASN1_DER_ERROR; + break; + } } - else - { - if (p == node) - p = NULL; - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; - } - if (p->right) - { - p = p->right; - break; - } + + counter += len2; + *ret_len = counter; + return ASN1_SUCCESS; +} + +static int _asn1_delete_not_used(asn1_node node) +{ + asn1_node p, p2; + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + p = node; + while (p) { + if (p->type & CONST_NOT_USED) { + p2 = NULL; + if (p != node) { + p2 = _asn1_find_left(p); + if (!p2) + p2 = _asn1_find_up(p); + } + asn1_delete_structure(&p); + p = p2; + } + + if (!p) + break; /* reach node */ + + if (p->down) { + p = p->down; + } else { + if (p == node) + p = NULL; + else if (p->right) + p = p->right; + else { + while (1) { + p = _asn1_find_up(p); + if (p == node) { + p = NULL; + break; + } + if (p->right) { + p = p->right; + break; + } + } + } } - } } - } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } static int -_asn1_extract_der_octet (asn1_node node, const unsigned char *der, - int der_len) +_asn1_extract_der_octet(asn1_node node, const unsigned char *der, + int der_len) { - int len2, len3; - int counter2, counter_end; + int len2, len3; + int counter2, counter_end; - len2 = asn1_get_length_der (der, der_len, &len3); - if (len2 < -1) - return ASN1_DER_ERROR; + len2 = asn1_get_length_der(der, der_len, &len3); + if (len2 < -1) + return ASN1_DER_ERROR; - counter2 = len3 + 1; + counter2 = len3 + 1; - if (len2 == -1) - counter_end = der_len - 2; - else - counter_end = der_len; + if (len2 == -1) + counter_end = der_len - 2; + else + counter_end = der_len; - while (counter2 < counter_end) - { - len2 = asn1_get_length_der (der + counter2, der_len - counter2, &len3); + while (counter2 < counter_end) { + len2 = + asn1_get_length_der(der + counter2, der_len - counter2, + &len3); - if (len2 < -1) - return ASN1_DER_ERROR; + if (len2 < -1) + return ASN1_DER_ERROR; - if (len2 > 0) - { - _asn1_append_value (node, der + counter2 + len3, len2); - } - else - { /* indefinite */ - - len2 = - _asn1_extract_der_octet (node, der + counter2 + len3, - der_len - counter2 - len3); - if (len2 < 0) - return len2; - } + if (len2 > 0) { + _asn1_append_value(node, der + counter2 + len3, + len2); + } else { /* indefinite */ - counter2 += len2 + len3 + 1; - } + len2 = + _asn1_extract_der_octet(node, + der + counter2 + len3, + der_len - counter2 - + len3); + if (len2 < 0) + return len2; + } - return ASN1_SUCCESS; + counter2 += len2 + len3 + 1; + } + + return ASN1_SUCCESS; } static int -_asn1_get_octet_string (const unsigned char *der, asn1_node node, int *len) +_asn1_get_octet_string(const unsigned char *der, asn1_node node, int *len) { - int len2, len3, counter, tot_len, indefinite; - - counter = 0; - - if (*(der - 1) & ASN1_CLASS_STRUCTURED) - { - tot_len = 0; - indefinite = asn1_get_length_der (der, *len, &len3); - if (indefinite < -1) - return ASN1_DER_ERROR; - - counter += len3; - if (indefinite >= 0) - indefinite += len3; - - while (1) - { - if (counter > (*len)) - return ASN1_DER_ERROR; - - if (indefinite == -1) - { - if ((der[counter] == 0) && (der[counter + 1] == 0)) - { - counter += 2; - break; - } - } - else if (counter >= indefinite) - break; + int len2, len3, counter, tot_len, indefinite; + + counter = 0; - if (der[counter] != ASN1_TAG_OCTET_STRING) - return ASN1_DER_ERROR; + if (*(der - 1) & ASN1_CLASS_STRUCTURED) { + tot_len = 0; + indefinite = asn1_get_length_der(der, *len, &len3); + if (indefinite < -1) + return ASN1_DER_ERROR; - counter++; + counter += len3; + if (indefinite >= 0) + indefinite += len3; - len2 = asn1_get_length_der (der + counter, *len - counter, &len3); - if (len2 <= 0) - return ASN1_DER_ERROR; + while (1) { + if (counter > (*len)) + return ASN1_DER_ERROR; - counter += len3 + len2; - tot_len += len2; - } + if (indefinite == -1) { + if ((der[counter] == 0) + && (der[counter + 1] == 0)) { + counter += 2; + break; + } + } else if (counter >= indefinite) + break; + + if (der[counter] != ASN1_TAG_OCTET_STRING) + return ASN1_DER_ERROR; - /* copy */ - if (node) - { - unsigned char temp[DER_LEN]; - int ret; + counter++; - len2 = sizeof (temp); + len2 = + asn1_get_length_der(der + counter, + *len - counter, &len3); + if (len2 <= 0) + return ASN1_DER_ERROR; - asn1_length_der (tot_len, temp, &len2); - _asn1_set_value (node, temp, len2); + counter += len3 + len2; + tot_len += len2; + } - ret = _asn1_extract_der_octet (node, der, *len); - if (ret != ASN1_SUCCESS) - return ret; + /* copy */ + if (node) { + unsigned char temp[DER_LEN]; + int ret; - } - } - else - { /* NOT STRUCTURED */ - len2 = asn1_get_length_der (der, *len, &len3); - if (len2 < 0) - return ASN1_DER_ERROR; + len2 = sizeof(temp); + + asn1_length_der(tot_len, temp, &len2); + _asn1_set_value(node, temp, len2); + + ret = _asn1_extract_der_octet(node, der, *len); + if (ret != ASN1_SUCCESS) + return ret; + + } + } else { /* NOT STRUCTURED */ + len2 = asn1_get_length_der(der, *len, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; - counter = len3 + len2; - if (node) - _asn1_set_value (node, der, counter); - } + counter = len3 + len2; + if (node) + _asn1_set_value(node, der, counter); + } - *len = counter; - return ASN1_SUCCESS; + *len = counter; + return ASN1_SUCCESS; } static int -_asn1_get_indefinite_length_string (const unsigned char *der, int *len) +_asn1_get_indefinite_length_string(const unsigned char *der, int *len) { - int len2, len3, counter, indefinite; - unsigned long tag; - unsigned char class; - - counter = indefinite = 0; - - while (1) - { - if ((*len) < counter) - return ASN1_DER_ERROR; - - if ((der[counter] == 0) && (der[counter + 1] == 0)) - { - counter += 2; - indefinite--; - if (indefinite <= 0) - break; - else - continue; - } + int len2, len3, counter, indefinite; + unsigned long tag; + unsigned char class; - if (asn1_get_tag_der - (der + counter, *len - counter, &class, &len2, - &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - if (counter + len2 > *len) - return ASN1_DER_ERROR; - counter += len2; - len2 = asn1_get_length_der (der + counter, *len - counter, &len3); - if (len2 < -1) - return ASN1_DER_ERROR; - if (len2 == -1) - { - indefinite++; - counter += 1; - } - else - { - counter += len2 + len3; + counter = indefinite = 0; + + while (1) { + if ((*len) < counter) + return ASN1_DER_ERROR; + + if ((der[counter] == 0) && (der[counter + 1] == 0)) { + counter += 2; + indefinite--; + if (indefinite <= 0) + break; + else + continue; + } + + if (asn1_get_tag_der + (der + counter, *len - counter, &class, &len2, + &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter + len2 > *len) + return ASN1_DER_ERROR; + counter += len2; + len2 = + asn1_get_length_der(der + counter, *len - counter, + &len3); + if (len2 < -1) + return ASN1_DER_ERROR; + if (len2 == -1) { + indefinite++; + counter += 1; + } else { + counter += len2 + len3; + } } - } - *len = counter; - return ASN1_SUCCESS; + *len = counter; + return ASN1_SUCCESS; } @@ -793,555 +775,563 @@ _asn1_get_indefinite_length_string (const unsigned char *der, int *len) * name (*@ELEMENT deleted). **/ int -asn1_der_decoding (asn1_node * element, const void *ider, int len, - char *errorDescription) +asn1_der_decoding(asn1_node * element, const void *ider, int len, + char *errorDescription) { - asn1_node node, p, p2, p3; - char temp[128]; - int counter, len2, len3, len4, move, ris, tlen; - unsigned char class; - unsigned long tag; - int indefinite, result; - const unsigned char *der = ider; - - node = *element; - - if (errorDescription != NULL) - errorDescription[0] = 0; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - if (node->type & CONST_OPTION) - { - result = ASN1_GENERIC_ERROR; - goto cleanup; - } - - counter = 0; - move = DOWN; - p = node; - while (1) - { - ris = ASN1_SUCCESS; - if (move != UP) - { - if (p->type & CONST_SET) - { - p2 = _asn1_find_up (p); - len2 = _asn1_strtol (p2->value, NULL, 10); - if (len2 == -1) - { - if (!der[counter] && !der[counter + 1]) - { - p = p2; - move = UP; - counter += 2; - continue; - } - } - else if (counter == len2) - { - p = p2; - move = UP; - continue; - } - else if (counter > len2) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - p2 = p2->down; - while (p2) - { - if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) - { - if (type_field (p2->type) != ASN1_ETYPE_CHOICE) - ris = - _asn1_extract_tag_der (p2, der + counter, - len - counter, &len2); - else - { - p3 = p2->down; - while (p3) - { - ris = - _asn1_extract_tag_der (p3, der + counter, - len - counter, &len2); - if (ris == ASN1_SUCCESS) - break; - p3 = p3->right; - } - } - if (ris == ASN1_SUCCESS) - { - p2->type &= ~CONST_NOT_USED; - p = p2; - break; - } - } - p2 = p2->right; - } - if (p2 == NULL) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - } - - if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) - { - p2 = _asn1_find_up (p); - len2 = _asn1_strtol (p2->value, NULL, 10); - if (counter == len2) - { - if (p->right) - { - p2 = p->right; - move = RIGHT; - } - else - move = UP; - - if (p->type & CONST_OPTION) - asn1_delete_structure (&p); - - p = p2; - continue; - } - } - - if (type_field (p->type) == ASN1_ETYPE_CHOICE) - { - while (p->down) - { - if (counter < len) - ris = - _asn1_extract_tag_der (p->down, der + counter, - len - counter, &len2); - else - ris = ASN1_DER_ERROR; - if (ris == ASN1_SUCCESS) - { - while (p->down->right) - { - p2 = p->down->right; - asn1_delete_structure (&p2); - } - break; - } - else if (ris == ASN1_ERROR_TYPE_ANY) - { - result = ASN1_ERROR_TYPE_ANY; - goto cleanup; - } - else - { - p2 = p->down; - asn1_delete_structure (&p2); - } - } + asn1_node node, p, p2, p3; + char temp[128]; + int counter, len2, len3, len4, move, ris, tlen; + unsigned char class; + unsigned long tag; + int indefinite, result; + const unsigned char *der = ider; - if (p->down == NULL) - { - if (!(p->type & CONST_OPTION)) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - } - else - p = p->down; - } - - if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) - { - p2 = _asn1_find_up (p); - len2 = _asn1_strtol (p2->value, NULL, 10); - if ((len2 != -1) && (counter > len2)) - ris = ASN1_TAG_ERROR; - } - - if (ris == ASN1_SUCCESS) - ris = - _asn1_extract_tag_der (p, der + counter, len - counter, &len2); - if (ris != ASN1_SUCCESS) - { - if (p->type & CONST_OPTION) - { - p->type |= CONST_NOT_USED; - move = RIGHT; - } - else if (p->type & CONST_DEFAULT) - { - _asn1_set_value (p, NULL, 0); - move = RIGHT; - } - else - { - if (errorDescription != NULL) - _asn1_error_description_tag_error (p, errorDescription); + node = *element; - result = ASN1_TAG_ERROR; - goto cleanup; - } - } - else - counter += len2; - } + if (errorDescription != NULL) + errorDescription[0] = 0; - if (ris == ASN1_SUCCESS) - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_NULL: - if (der[counter]) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - counter++; - move = RIGHT; - break; - case ASN1_ETYPE_BOOLEAN: - if (der[counter++] != 1) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - if (der[counter++] == 0) - _asn1_set_value (p, "F", 1); - else - _asn1_set_value (p, "T", 1); - move = RIGHT; - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - len2 = - asn1_get_length_der (der + counter, len - counter, &len3); - if (len2 < 0) - { - result = ASN1_DER_ERROR; - goto cleanup; - } + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; - _asn1_set_value (p, der + counter, len3 + len2); - counter += len3 + len2; - move = RIGHT; - break; - case ASN1_ETYPE_OBJECT_ID: - result = - _asn1_get_objectid_der (der + counter, len - counter, &len2, - temp, sizeof (temp)); - if (result != ASN1_SUCCESS) + if (node->type & CONST_OPTION) { + result = ASN1_GENERIC_ERROR; goto cleanup; + } - tlen = strlen (temp); - if (tlen > 0) - _asn1_set_value (p, temp, tlen + 1); - counter += len2; - move = RIGHT; - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - result = - _asn1_get_time_der (der + counter, len - counter, &len2, temp, - sizeof (temp) - 1); - if (result != ASN1_SUCCESS) - goto cleanup; + counter = 0; + move = DOWN; + p = node; + while (1) { + ris = ASN1_SUCCESS; + if (move != UP) { + if (p->type & CONST_SET) { + p2 = _asn1_find_up(p); + len2 = _asn1_strtol(p2->value, NULL, 10); + if (len2 == -1) { + if (!der[counter] + && !der[counter + 1]) { + p = p2; + move = UP; + counter += 2; + continue; + } + } else if (counter == len2) { + p = p2; + move = UP; + continue; + } else if (counter > len2) { + result = ASN1_DER_ERROR; + goto cleanup; + } + p2 = p2->down; + while (p2) { + if ((p2->type & CONST_SET) + && (p2-> + type & CONST_NOT_USED)) { + if (type_field(p2->type) != + ASN1_ETYPE_CHOICE) + ris = + _asn1_extract_tag_der + (p2, + der + counter, + len - counter, + &len2); + else { + p3 = p2->down; + while (p3) { + ris = + _asn1_extract_tag_der + (p3, + der + + counter, + len - + counter, + &len2); + if (ris == + ASN1_SUCCESS) + break; + p3 = p3-> + right; + } + } + if (ris == ASN1_SUCCESS) { + p2->type &= + ~CONST_NOT_USED; + p = p2; + break; + } + } + p2 = p2->right; + } + if (p2 == NULL) { + result = ASN1_DER_ERROR; + goto cleanup; + } + } - tlen = strlen (temp); - if (tlen > 0) - _asn1_set_value (p, temp, tlen); - counter += len2; - move = RIGHT; - break; - case ASN1_ETYPE_OCTET_STRING: - len3 = len - counter; - result = _asn1_get_octet_string (der + counter, p, &len3); - if (result != ASN1_SUCCESS) - goto cleanup; + if ((p->type & CONST_OPTION) + || (p->type & CONST_DEFAULT)) { + p2 = _asn1_find_up(p); + len2 = _asn1_strtol(p2->value, NULL, 10); + if (counter == len2) { + if (p->right) { + p2 = p->right; + move = RIGHT; + } else + move = UP; + + if (p->type & CONST_OPTION) + asn1_delete_structure(&p); + + p = p2; + continue; + } + } - counter += len3; - move = RIGHT; - 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_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) - { - result = ASN1_DER_ERROR; - goto cleanup; - } + if (type_field(p->type) == ASN1_ETYPE_CHOICE) { + while (p->down) { + if (counter < len) + ris = + _asn1_extract_tag_der + (p->down, + der + counter, + len - counter, &len2); + else + ris = ASN1_DER_ERROR; + if (ris == ASN1_SUCCESS) { + while (p->down->right) { + p2 = p->down-> + right; + asn1_delete_structure + (&p2); + } + break; + } else if (ris == + ASN1_ERROR_TYPE_ANY) { + result = + ASN1_ERROR_TYPE_ANY; + goto cleanup; + } else { + p2 = p->down; + asn1_delete_structure(&p2); + } + } - _asn1_set_value (p, der + counter, len3 + len2); - counter += len3 + len2; - move = RIGHT; - break; - case ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_SET: - if (move == UP) - { - len2 = _asn1_strtol (p->value, NULL, 10); - _asn1_set_value (p, NULL, 0); - if (len2 == -1) - { /* indefinite length method */ - if (len - counter + 1 > 0) - { - if ((der[counter]) || der[counter + 1]) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - } - else - { - result = ASN1_DER_ERROR; - goto cleanup; - } - counter += 2; - } - else - { /* definite length method */ - if (len2 != counter) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - } - move = RIGHT; - } - else - { /* move==DOWN || move==RIGHT */ - len3 = - asn1_get_length_der (der + counter, len - counter, &len2); - if (len3 < -1) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - counter += len2; - if (len3 > 0) - { - _asn1_ltostr (counter + len3, temp); - tlen = strlen (temp); - if (tlen > 0) - _asn1_set_value (p, temp, tlen + 1); - move = DOWN; - } - else if (len3 == 0) - { - p2 = p->down; - while (p2) - { - if (type_field (p2->type) != ASN1_ETYPE_TAG) - { - p3 = p2->right; - asn1_delete_structure (&p2); - p2 = p3; - } - else - p2 = p2->right; - } - move = RIGHT; - } - else - { /* indefinite length method */ - _asn1_set_value (p, "-1", 3); - move = DOWN; - } - } - break; - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET_OF: - if (move == UP) - { - len2 = _asn1_strtol (p->value, NULL, 10); - if (len2 == -1) - { /* indefinite length method */ - if ((counter + 2) > len) - { - result = ASN1_DER_ERROR; - goto cleanup; + if (p->down == NULL) { + if (!(p->type & CONST_OPTION)) { + result = ASN1_DER_ERROR; + goto cleanup; + } + } else + p = p->down; } - if ((der[counter]) || der[counter + 1]) - { - _asn1_append_sequence_set (p); - p = p->down; - while (p->right) - p = p->right; - move = RIGHT; - continue; - } - _asn1_set_value (p, NULL, 0); - counter += 2; - } - else - { /* definite length method */ - if (len2 > counter) - { - _asn1_append_sequence_set (p); - p = p->down; - while (p->right) - p = p->right; - move = RIGHT; - continue; - } - _asn1_set_value (p, NULL, 0); - if (len2 != counter) - { - result = ASN1_DER_ERROR; - goto cleanup; + if ((p->type & CONST_OPTION) + || (p->type & CONST_DEFAULT)) { + p2 = _asn1_find_up(p); + len2 = _asn1_strtol(p2->value, NULL, 10); + if ((len2 != -1) && (counter > len2)) + ris = ASN1_TAG_ERROR; } - } + + if (ris == ASN1_SUCCESS) + ris = + _asn1_extract_tag_der(p, der + counter, + len - counter, + &len2); + if (ris != ASN1_SUCCESS) { + if (p->type & CONST_OPTION) { + p->type |= CONST_NOT_USED; + move = RIGHT; + } else if (p->type & CONST_DEFAULT) { + _asn1_set_value(p, NULL, 0); + move = RIGHT; + } else { + if (errorDescription != NULL) + _asn1_error_description_tag_error + (p, errorDescription); + + result = ASN1_TAG_ERROR; + goto cleanup; + } + } else + counter += len2; } - else - { /* move==DOWN || move==RIGHT */ - len3 = - asn1_get_length_der (der + counter, len - counter, &len2); - if (len3 < -1) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - counter += len2; - if (len3) - { - if (len3 > 0) - { /* definite length method */ - _asn1_ltostr (counter + len3, temp); - tlen = strlen (temp); - - if (tlen > 0) - _asn1_set_value (p, temp, tlen + 1); - } - else - { /* indefinite length method */ - _asn1_set_value (p, "-1", 3); + + if (ris == ASN1_SUCCESS) { + switch (type_field(p->type)) { + case ASN1_ETYPE_NULL: + if (der[counter]) { + result = ASN1_DER_ERROR; + goto cleanup; + } + counter++; + move = RIGHT; + break; + case ASN1_ETYPE_BOOLEAN: + if (der[counter++] != 1) { + result = ASN1_DER_ERROR; + goto cleanup; + } + if (der[counter++] == 0) + _asn1_set_value(p, "F", 1); + else + _asn1_set_value(p, "T", 1); + move = RIGHT; + break; + case ASN1_ETYPE_INTEGER: + case ASN1_ETYPE_ENUMERATED: + 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 ASN1_ETYPE_OBJECT_ID: + result = + _asn1_get_objectid_der(der + counter, + len - counter, + &len2, temp, + sizeof(temp)); + if (result != ASN1_SUCCESS) + goto cleanup; + + tlen = strlen(temp); + if (tlen > 0) + _asn1_set_value(p, temp, tlen + 1); + counter += len2; + move = RIGHT; + break; + case ASN1_ETYPE_GENERALIZED_TIME: + case ASN1_ETYPE_UTC_TIME: + result = + _asn1_get_time_der(der + counter, + len - counter, + &len2, temp, + sizeof(temp) - 1); + if (result != ASN1_SUCCESS) + goto cleanup; + + tlen = strlen(temp); + if (tlen > 0) + _asn1_set_value(p, temp, tlen); + counter += len2; + move = RIGHT; + break; + case ASN1_ETYPE_OCTET_STRING: + len3 = len - counter; + result = + _asn1_get_octet_string(der + counter, + p, &len3); + if (result != ASN1_SUCCESS) + goto cleanup; + + counter += len3; + move = RIGHT; + 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_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) { + result = ASN1_DER_ERROR; + goto cleanup; + } + + _asn1_set_value(p, der + counter, + len3 + len2); + counter += len3 + len2; + move = RIGHT; + break; + case ASN1_ETYPE_SEQUENCE: + case ASN1_ETYPE_SET: + if (move == UP) { + len2 = + _asn1_strtol(p->value, NULL, + 10); + _asn1_set_value(p, NULL, 0); + if (len2 == -1) { /* indefinite length method */ + if (len - counter + 1 > 0) { + if ((der[counter]) + || der[counter + + 1]) { + result = + ASN1_DER_ERROR; + goto cleanup; + } + } else { + result = + ASN1_DER_ERROR; + goto cleanup; + } + counter += 2; + } else { /* definite length method */ + if (len2 != counter) { + result = + ASN1_DER_ERROR; + goto cleanup; + } + } + move = RIGHT; + } else { /* move==DOWN || move==RIGHT */ + len3 = + asn1_get_length_der(der + + counter, + len - + counter, + &len2); + if (len3 < -1) { + result = ASN1_DER_ERROR; + goto cleanup; + } + counter += len2; + if (len3 > 0) { + _asn1_ltostr(counter + + len3, temp); + tlen = strlen(temp); + if (tlen > 0) + _asn1_set_value(p, + temp, + tlen + + + 1); + move = DOWN; + } else if (len3 == 0) { + p2 = p->down; + while (p2) { + if (type_field + (p2->type) != + ASN1_ETYPE_TAG) + { + p3 = p2-> + right; + asn1_delete_structure + (&p2); + p2 = p3; + } else + p2 = p2-> + right; + } + move = RIGHT; + } else { /* indefinite length method */ + _asn1_set_value(p, "-1", + 3); + move = DOWN; + } + } + break; + case ASN1_ETYPE_SEQUENCE_OF: + case ASN1_ETYPE_SET_OF: + if (move == UP) { + len2 = + _asn1_strtol(p->value, NULL, + 10); + if (len2 == -1) { /* indefinite length method */ + if ((counter + 2) > len) { + result = + ASN1_DER_ERROR; + goto cleanup; + } + + if ((der[counter]) + || der[counter + 1]) { + _asn1_append_sequence_set + (p); + p = p->down; + while (p->right) + p = p-> + right; + move = RIGHT; + continue; + } + _asn1_set_value(p, NULL, + 0); + counter += 2; + } else { /* definite length method */ + if (len2 > counter) { + _asn1_append_sequence_set + (p); + p = p->down; + while (p->right) + p = p-> + right; + move = RIGHT; + continue; + } + _asn1_set_value(p, NULL, + 0); + if (len2 != counter) { + result = + ASN1_DER_ERROR; + goto cleanup; + } + } + } else { /* move==DOWN || move==RIGHT */ + len3 = + asn1_get_length_der(der + + counter, + len - + counter, + &len2); + if (len3 < -1) { + result = ASN1_DER_ERROR; + goto cleanup; + } + counter += len2; + if (len3) { + if (len3 > 0) { /* definite length method */ + _asn1_ltostr + (counter + + len3, temp); + tlen = + strlen(temp); + + if (tlen > 0) + _asn1_set_value + (p, + temp, + tlen + + 1); + } else { /* indefinite length method */ + _asn1_set_value(p, + "-1", + 3); + } + p2 = p->down; + 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); + p = p2; + } + } + move = RIGHT; + break; + case ASN1_ETYPE_ANY: + if (asn1_get_tag_der + (der + counter, len - counter, &class, + &len2, &tag) != ASN1_SUCCESS) { + result = ASN1_DER_ERROR; + goto cleanup; + } + + if (counter + len2 > len) { + result = ASN1_DER_ERROR; + goto cleanup; + } + len4 = + asn1_get_length_der(der + counter + + len2, + len - counter - + len2, &len3); + if (len4 < -1) { + result = ASN1_DER_ERROR; + goto cleanup; + } + if (len4 != -1) { + len2 += len4; + _asn1_set_value_lv(p, + der + counter, + len2 + len3); + counter += len2 + len3; + } else { /* indefinite length */ + /* Check indefinite lenth method in an EXPLICIT TAG */ + if ((p->type & CONST_TAG) + && (der[counter - 1] == 0x80)) + indefinite = 1; + else + indefinite = 0; + + len2 = len - counter; + result = + _asn1_get_indefinite_length_string + (der + counter, &len2); + if (result != ASN1_SUCCESS) + goto cleanup; + + _asn1_set_value_lv(p, + der + counter, + len2); + counter += len2; + + /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with + an indefinite length method. */ + if (indefinite) { + if (!der[counter] + && !der[counter + 1]) { + counter += 2; + } else { + result = + ASN1_DER_ERROR; + goto cleanup; + } + } + } + move = RIGHT; + break; + default: + move = (move == UP) ? RIGHT : DOWN; + break; } - p2 = p->down; - 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); - p = p2; - } - } - move = RIGHT; - break; - case ASN1_ETYPE_ANY: - if (asn1_get_tag_der - (der + counter, len - counter, &class, &len2, - &tag) != ASN1_SUCCESS) - { - result = ASN1_DER_ERROR; - goto cleanup; } - if (counter + len2 > len) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - len4 = - asn1_get_length_der (der + counter + len2, - len - counter - len2, &len3); - if (len4 < -1) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - if (len4 != -1) - { - len2 += len4; - _asn1_set_value_lv (p, der + counter, len2 + len3); - counter += len2 + len3; + if (p == node && move != DOWN) + break; + + if (move == DOWN) { + if (p->down) + p = p->down; + else + move = RIGHT; } - else - { /* indefinite length */ - /* Check indefinite lenth method in an EXPLICIT TAG */ - if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80)) - indefinite = 1; - else - indefinite = 0; - - len2 = len - counter; - result = - _asn1_get_indefinite_length_string (der + counter, &len2); - if (result != ASN1_SUCCESS) - goto cleanup; - - _asn1_set_value_lv (p, der + counter, len2); - counter += len2; - - /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with - an indefinite length method. */ - if (indefinite) - { - if (!der[counter] && !der[counter + 1]) - { - counter += 2; - } - else - { - result = ASN1_DER_ERROR; - goto cleanup; - } - } + if ((move == RIGHT) && !(p->type & CONST_SET)) { + if (p->right) + p = p->right; + else + move = UP; } - move = RIGHT; - break; - default: - move = (move == UP) ? RIGHT : DOWN; - break; - } + if (move == UP) + p = _asn1_find_up(p); } - if (p == node && move != DOWN) - break; + _asn1_delete_not_used(*element); - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - if ((move == RIGHT) && !(p->type & CONST_SET)) - { - if (p->right) - p = p->right; - else - move = UP; + if (counter != len) { + result = ASN1_DER_ERROR; + goto cleanup; } - if (move == UP) - p = _asn1_find_up (p); - } - - _asn1_delete_not_used (*element); - if (counter != len) - { - result = ASN1_DER_ERROR; - goto cleanup; - } + return ASN1_SUCCESS; - return ASN1_SUCCESS; - -cleanup: - asn1_delete_structure (element); - return result; + cleanup: + asn1_delete_structure(element); + return result; } #define FOUND 1 @@ -1371,779 +1361,796 @@ cleanup: * match the structure @structure (*ELEMENT deleted). **/ int -asn1_der_decoding_element (asn1_node * structure, const char *elementName, - const void *ider, int len, char *errorDescription) +asn1_der_decoding_element(asn1_node * structure, const char *elementName, + const void *ider, int len, + char *errorDescription) { - asn1_node node, p, p2, p3, nodeFound = NULL; - char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p; - int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state; - int counter, len2, len3, len4, move, ris, tlen; - unsigned char class; - unsigned long tag; - int indefinite, result; - const unsigned char *der = ider; - - node = *structure; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - if (elementName == NULL) - { - result = ASN1_ELEMENT_NOT_FOUND; - goto cleanup; - } - - if (node->type & CONST_OPTION) - { - result = ASN1_GENERIC_ERROR; - goto cleanup; - } - - if ((*structure)->name[0] != 0) - { /* Has *structure got a name? */ - nameLen -= strlen ((*structure)->name); - if (nameLen > 0) - strcpy (currentName, (*structure)->name); - else - { - result = ASN1_MEM_ERROR; - goto cleanup; - } - if (!(strcmp (currentName, elementName))) - { - state = FOUND; - nodeFound = *structure; - } - else if (!memcmp (currentName, elementName, strlen (currentName))) - state = SAME_BRANCH; - else - state = OTHER_BRANCH; - } - else - { /* *structure doesn't have a name? */ - currentName[0] = 0; - if (elementName[0] == 0) - { - state = FOUND; - nodeFound = *structure; + asn1_node node, p, p2, p3, nodeFound = NULL; + char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, + *char_p; + int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state; + int counter, len2, len3, len4, move, ris, tlen; + unsigned char class; + unsigned long tag; + int indefinite, result; + const unsigned char *der = ider; + + node = *structure; + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + if (elementName == NULL) { + result = ASN1_ELEMENT_NOT_FOUND; + goto cleanup; } - else - { - state = SAME_BRANCH; + + if (node->type & CONST_OPTION) { + result = ASN1_GENERIC_ERROR; + goto cleanup; } - } - - counter = 0; - move = DOWN; - p = node; - while (1) - { - - ris = ASN1_SUCCESS; - - if (move != UP) - { - if (p->type & CONST_SET) - { - p2 = _asn1_find_up (p); - len2 = _asn1_strtol (p2->value, NULL, 10); - if (counter == len2) - { - p = p2; - move = UP; - continue; - } - else if (counter > len2) - { - result = ASN1_DER_ERROR; - goto cleanup; + + if ((*structure)->name[0] != 0) { /* Has *structure got a name? */ + nameLen -= strlen((*structure)->name); + if (nameLen > 0) + strcpy(currentName, (*structure)->name); + else { + result = ASN1_MEM_ERROR; + goto cleanup; + } + if (!(strcmp(currentName, elementName))) { + state = FOUND; + nodeFound = *structure; + } else + if (!memcmp + (currentName, elementName, strlen(currentName))) + state = SAME_BRANCH; + else + state = OTHER_BRANCH; + } else { /* *structure doesn't have a name? */ + currentName[0] = 0; + if (elementName[0] == 0) { + state = FOUND; + nodeFound = *structure; + } else { + state = SAME_BRANCH; } - p2 = p2->down; - while (p2) - { - if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) - { - if (type_field (p2->type) != ASN1_ETYPE_CHOICE) - ris = - _asn1_extract_tag_der (p2, der + counter, - len - counter, &len2); - else - { - p3 = p2->down; - while (p3) - { - ris = - _asn1_extract_tag_der (p3, der + counter, - len - counter, &len2); - if (ris == ASN1_SUCCESS) - break; - p3 = p3->right; - } + } + + counter = 0; + move = DOWN; + p = node; + while (1) { + + ris = ASN1_SUCCESS; + + if (move != UP) { + if (p->type & CONST_SET) { + p2 = _asn1_find_up(p); + len2 = _asn1_strtol(p2->value, NULL, 10); + if (counter == len2) { + p = p2; + move = UP; + continue; + } else if (counter > len2) { + result = ASN1_DER_ERROR; + goto cleanup; + } + p2 = p2->down; + while (p2) { + if ((p2->type & CONST_SET) + && (p2-> + type & CONST_NOT_USED)) { + if (type_field(p2->type) != + ASN1_ETYPE_CHOICE) + ris = + _asn1_extract_tag_der + (p2, + der + counter, + len - counter, + &len2); + else { + p3 = p2->down; + while (p3) { + ris = + _asn1_extract_tag_der + (p3, + der + + counter, + len - + counter, + &len2); + if (ris == + ASN1_SUCCESS) + break; + p3 = p3-> + right; + } + } + if (ris == ASN1_SUCCESS) { + p2->type &= + ~CONST_NOT_USED; + p = p2; + break; + } + } + p2 = p2->right; + } + if (p2 == NULL) { + result = ASN1_DER_ERROR; + goto cleanup; + } } - if (ris == ASN1_SUCCESS) - { - p2->type &= ~CONST_NOT_USED; - p = p2; - break; + + if ((p->type & CONST_OPTION) + || (p->type & CONST_DEFAULT)) { + p2 = _asn1_find_up(p); + len2 = _asn1_strtol(p2->value, NULL, 10); + if (counter == len2) { + if (p->right) { + p2 = p->right; + move = RIGHT; + } else + move = UP; + + if (p->type & CONST_OPTION) + asn1_delete_structure(&p); + + p = p2; + continue; + } } - } - p2 = p2->right; - } - if (p2 == NULL) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - } - - if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) - { - p2 = _asn1_find_up (p); - len2 = _asn1_strtol (p2->value, NULL, 10); - if (counter == len2) - { - if (p->right) - { - p2 = p->right; - move = RIGHT; - } - else - move = UP; - - if (p->type & CONST_OPTION) - asn1_delete_structure (&p); - - p = p2; - continue; - } - } - - if (type_field (p->type) == ASN1_ETYPE_CHOICE) - { - while (p->down) - { - if (counter < len) - ris = - _asn1_extract_tag_der (p->down, der + counter, - len - counter, &len2); - else - ris = ASN1_DER_ERROR; - if (ris == ASN1_SUCCESS) - { - while (p->down->right) - { - p2 = p->down->right; - asn1_delete_structure (&p2); + + if (type_field(p->type) == ASN1_ETYPE_CHOICE) { + while (p->down) { + if (counter < len) + ris = + _asn1_extract_tag_der + (p->down, + der + counter, + len - counter, &len2); + else + ris = ASN1_DER_ERROR; + if (ris == ASN1_SUCCESS) { + while (p->down->right) { + p2 = p->down-> + right; + asn1_delete_structure + (&p2); + } + break; + } else if (ris == + ASN1_ERROR_TYPE_ANY) { + result = + ASN1_ERROR_TYPE_ANY; + goto cleanup; + } else { + p2 = p->down; + asn1_delete_structure(&p2); + } + } + + if (p->down == NULL) { + if (!(p->type & CONST_OPTION)) { + result = ASN1_DER_ERROR; + goto cleanup; + } + } else + p = p->down; } - break; - } - else if (ris == ASN1_ERROR_TYPE_ANY) - { - result = ASN1_ERROR_TYPE_ANY; - goto cleanup; - } - else - { - p2 = p->down; - asn1_delete_structure (&p2); - } - } - if (p->down == NULL) - { - if (!(p->type & CONST_OPTION)) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - } - else - p = p->down; - } - - if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) - { - p2 = _asn1_find_up (p); - len2 = _asn1_strtol (p2->value, NULL, 10); - if (counter > len2) - ris = ASN1_TAG_ERROR; - } - - if (ris == ASN1_SUCCESS) - ris = - _asn1_extract_tag_der (p, der + counter, len - counter, &len2); - if (ris != ASN1_SUCCESS) - { - if (p->type & CONST_OPTION) - { - p->type |= CONST_NOT_USED; - move = RIGHT; - } - else if (p->type & CONST_DEFAULT) - { - _asn1_set_value (p, NULL, 0); - move = RIGHT; - } - else - { - if (errorDescription != NULL) - _asn1_error_description_tag_error (p, errorDescription); + if ((p->type & CONST_OPTION) + || (p->type & CONST_DEFAULT)) { + p2 = _asn1_find_up(p); + len2 = _asn1_strtol(p2->value, NULL, 10); + if (counter > len2) + ris = ASN1_TAG_ERROR; + } - result = ASN1_TAG_ERROR; - goto cleanup; + if (ris == ASN1_SUCCESS) + ris = + _asn1_extract_tag_der(p, der + counter, + len - counter, + &len2); + if (ris != ASN1_SUCCESS) { + if (p->type & CONST_OPTION) { + p->type |= CONST_NOT_USED; + move = RIGHT; + } else if (p->type & CONST_DEFAULT) { + _asn1_set_value(p, NULL, 0); + move = RIGHT; + } else { + if (errorDescription != NULL) + _asn1_error_description_tag_error + (p, errorDescription); + + result = ASN1_TAG_ERROR; + goto cleanup; + } + } else + counter += len2; } - } - else - counter += len2; - } - if (ris == ASN1_SUCCESS) - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_NULL: - if (der[counter]) - { - result = ASN1_DER_ERROR; - goto cleanup; - } + if (ris == ASN1_SUCCESS) { + switch (type_field(p->type)) { + case ASN1_ETYPE_NULL: + if (der[counter]) { + result = ASN1_DER_ERROR; + goto cleanup; + } - if (p == nodeFound) - state = EXIT; - - counter++; - move = RIGHT; - break; - case ASN1_ETYPE_BOOLEAN: - if (der[counter++] != 1) - { - result = ASN1_DER_ERROR; - goto cleanup; - } + if (p == nodeFound) + state = EXIT; - if (state == FOUND) - { - if (der[counter++] == 0) - _asn1_set_value (p, "F", 1); - else - _asn1_set_value (p, "T", 1); + counter++; + move = RIGHT; + break; + case ASN1_ETYPE_BOOLEAN: + if (der[counter++] != 1) { + result = ASN1_DER_ERROR; + goto cleanup; + } - if (p == nodeFound) - state = EXIT; + if (state == FOUND) { + if (der[counter++] == 0) + _asn1_set_value(p, "F", 1); + else + _asn1_set_value(p, "T", 1); - } - else - counter++; - - move = RIGHT; - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - len2 = - asn1_get_length_der (der + counter, len - counter, &len3); - if (len2 < 0) - { - result = ASN1_DER_ERROR; - goto cleanup; - } + if (p == nodeFound) + state = EXIT; - 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 ASN1_ETYPE_OBJECT_ID: - if (state == FOUND) - { - result = - _asn1_get_objectid_der (der + counter, len - counter, - &len2, temp, sizeof (temp)); - if (result != ASN1_SUCCESS) - goto cleanup; - - tlen = strlen (temp); - - if (tlen > 0) - _asn1_set_value (p, temp, tlen + 1); - - if (p == nodeFound) - state = EXIT; - } - else - { - len2 = - asn1_get_length_der (der + counter, len - counter, &len3); - if (len2 < 0) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - len2 += len3; - } + } else + counter++; - counter += len2; - move = RIGHT; - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - if (state == FOUND) - { - result = - _asn1_get_time_der (der + counter, len - counter, &len2, - temp, sizeof (temp) - 1); - if (result != ASN1_SUCCESS) - goto cleanup; - - tlen = strlen (temp); - if (tlen > 0) - _asn1_set_value (p, temp, tlen + 1); - - if (p == nodeFound) - state = EXIT; - } - else - { - len2 = - asn1_get_length_der (der + counter, len - counter, &len3); - if (len2 < 0) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - len2 += len3; - } + move = RIGHT; + break; + case ASN1_ETYPE_INTEGER: + case ASN1_ETYPE_ENUMERATED: + len2 = + asn1_get_length_der(der + counter, + len - counter, + &len3); + if (len2 < 0) { + result = ASN1_DER_ERROR; + goto cleanup; + } - counter += len2; - move = RIGHT; - break; - case ASN1_ETYPE_OCTET_STRING: - len3 = len - counter; - if (state == FOUND) - { - result = _asn1_get_octet_string (der + counter, p, &len3); - if (p == nodeFound) - state = EXIT; - } - else - result = _asn1_get_octet_string (der + counter, NULL, &len3); + if (state == FOUND) { + if (len3 + len2 > len - counter) { + result = ASN1_DER_ERROR; + goto cleanup; + } + _asn1_set_value(p, der + counter, + len3 + len2); - if (result != ASN1_SUCCESS) - goto cleanup; + if (p == nodeFound) + state = EXIT; + } + counter += len3 + len2; + move = RIGHT; + break; + case ASN1_ETYPE_OBJECT_ID: + if (state == FOUND) { + result = + _asn1_get_objectid_der(der + + counter, + len - + counter, + &len2, + temp, + sizeof + (temp)); + if (result != ASN1_SUCCESS) + goto cleanup; + + tlen = strlen(temp); + + if (tlen > 0) + _asn1_set_value(p, temp, + tlen + 1); + + if (p == nodeFound) + state = EXIT; + } else { + len2 = + asn1_get_length_der(der + + counter, + len - + counter, + &len3); + if (len2 < 0) { + result = ASN1_DER_ERROR; + goto cleanup; + } + len2 += len3; + } - counter += len3; - move = RIGHT; - 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_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) - { - result = ASN1_DER_ERROR; - goto cleanup; - } + counter += len2; + move = RIGHT; + break; + case ASN1_ETYPE_GENERALIZED_TIME: + case ASN1_ETYPE_UTC_TIME: + if (state == FOUND) { + result = + _asn1_get_time_der(der + + counter, + len - + counter, + &len2, temp, + sizeof(temp) + - 1); + if (result != ASN1_SUCCESS) + goto cleanup; + + tlen = strlen(temp); + if (tlen > 0) + _asn1_set_value(p, temp, + tlen + 1); + + if (p == nodeFound) + state = EXIT; + } else { + len2 = + asn1_get_length_der(der + + counter, + len - + counter, + &len3); + if (len2 < 0) { + result = ASN1_DER_ERROR; + goto cleanup; + } + len2 += len3; + } - 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 ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_SET: - if (move == UP) - { - len2 = _asn1_strtol (p->value, NULL, 10); - _asn1_set_value (p, NULL, 0); - if (len2 == -1) - { /* indefinite length method */ - if ((der[counter]) || der[counter + 1]) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - counter += 2; - } - else - { /* definite length method */ - if (len2 != counter) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - } - if (p == nodeFound) - state = EXIT; - move = RIGHT; - } - else - { /* move==DOWN || move==RIGHT */ - if (state == OTHER_BRANCH) - { - len3 = - asn1_get_length_der (der + counter, len - counter, - &len2); - if (len3 < 0) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - counter += len2 + len3; - move = RIGHT; - } - else - { /* state==SAME_BRANCH or state==FOUND */ - len3 = - asn1_get_length_der (der + counter, len - counter, - &len2); - if (len3 < 0) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - counter += len2; - if (len3 > 0) - { - _asn1_ltostr (counter + len3, temp); - tlen = strlen (temp); - - if (tlen > 0) - _asn1_set_value (p, temp, tlen + 1); - move = DOWN; - } - else if (len3 == 0) - { - p2 = p->down; - while (p2) - { - if (type_field (p2->type) != ASN1_ETYPE_TAG) - { - p3 = p2->right; - asn1_delete_structure (&p2); - p2 = p3; + counter += len2; + move = RIGHT; + break; + case ASN1_ETYPE_OCTET_STRING: + len3 = len - counter; + if (state == FOUND) { + result = + _asn1_get_octet_string(der + + counter, + p, + &len3); + if (p == nodeFound) + state = EXIT; + } else + result = + _asn1_get_octet_string(der + + counter, + NULL, + &len3); + + if (result != ASN1_SUCCESS) + goto cleanup; + + counter += len3; + move = RIGHT; + 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_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) { + result = ASN1_DER_ERROR; + goto cleanup; } - else - p2 = p2->right; - } - move = RIGHT; - } - else - { /* indefinite length method */ - _asn1_set_value (p, "-1", 3); - move = DOWN; - } - } - } - break; - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET_OF: - if (move == UP) - { - len2 = _asn1_strtol (p->value, NULL, 10); - if (len2 > counter) - { - _asn1_append_sequence_set (p); - p = p->down; - while (p->right) - p = p->right; - move = RIGHT; - continue; - } - _asn1_set_value (p, NULL, 0); - if (len2 != counter) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - - if (p == nodeFound) - state = EXIT; - } - else - { /* move==DOWN || move==RIGHT */ - if (state == OTHER_BRANCH) - { - len3 = - asn1_get_length_der (der + counter, len - counter, - &len2); - if (len3 < 0) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - counter += len2 + len3; - move = RIGHT; - } - else - { /* state==FOUND or state==SAME_BRANCH */ - len3 = - asn1_get_length_der (der + counter, len - counter, - &len2); - if (len3 < 0) - { - result = ASN1_DER_ERROR; - goto cleanup; - } - counter += len2; - if (len3) - { - _asn1_ltostr (counter + len3, temp); - tlen = strlen (temp); - - if (tlen > 0) - _asn1_set_value (p, temp, tlen + 1); - p2 = p->down; - 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); - p = p2; - state = FOUND; - } - } - } - break; - case ASN1_ETYPE_ANY: - if (asn1_get_tag_der - (der + counter, len - counter, &class, &len2, - &tag) != ASN1_SUCCESS) - { - 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 (counter + len2 > len) - { - result = ASN1_DER_ERROR; - goto cleanup; - } + if (p == nodeFound) + state = EXIT; + } + counter += len3 + len2; + move = RIGHT; + break; + case ASN1_ETYPE_SEQUENCE: + case ASN1_ETYPE_SET: + if (move == UP) { + len2 = + _asn1_strtol(p->value, NULL, + 10); + _asn1_set_value(p, NULL, 0); + if (len2 == -1) { /* indefinite length method */ + if ((der[counter]) + || der[counter + 1]) { + result = + ASN1_DER_ERROR; + goto cleanup; + } + counter += 2; + } else { /* definite length method */ + if (len2 != counter) { + result = + ASN1_DER_ERROR; + goto cleanup; + } + } + if (p == nodeFound) + state = EXIT; + move = RIGHT; + } else { /* move==DOWN || move==RIGHT */ + if (state == OTHER_BRANCH) { + len3 = + asn1_get_length_der(der + + + counter, + len + - + counter, + &len2); + if (len3 < 0) { + result = + ASN1_DER_ERROR; + goto cleanup; + } + counter += len2 + len3; + move = RIGHT; + } else { /* state==SAME_BRANCH or state==FOUND */ + len3 = + asn1_get_length_der(der + + + counter, + len + - + counter, + &len2); + if (len3 < 0) { + result = + ASN1_DER_ERROR; + goto cleanup; + } + counter += len2; + if (len3 > 0) { + _asn1_ltostr + (counter + + len3, temp); + tlen = + strlen(temp); + + if (tlen > 0) + _asn1_set_value + (p, + temp, + tlen + + 1); + move = DOWN; + } else if (len3 == 0) { + p2 = p->down; + while (p2) { + if (type_field(p2->type) != ASN1_ETYPE_TAG) { + p3 = p2->right; + asn1_delete_structure + (&p2); + p2 = p3; + } else + p2 = p2->right; + } + move = RIGHT; + } else { /* indefinite length method */ + _asn1_set_value(p, + "-1", + 3); + move = DOWN; + } + } + } + break; + case ASN1_ETYPE_SEQUENCE_OF: + case ASN1_ETYPE_SET_OF: + if (move == UP) { + len2 = + _asn1_strtol(p->value, NULL, + 10); + if (len2 > counter) { + _asn1_append_sequence_set + (p); + p = p->down; + while (p->right) + p = p->right; + move = RIGHT; + continue; + } + _asn1_set_value(p, NULL, 0); + if (len2 != counter) { + result = ASN1_DER_ERROR; + goto cleanup; + } - len4 = - asn1_get_length_der (der + counter + len2, - len - counter - len2, &len3); - if (len4 < -1) - { - result = ASN1_DER_ERROR; - goto cleanup; - } + if (p == nodeFound) + state = EXIT; + } else { /* move==DOWN || move==RIGHT */ + if (state == OTHER_BRANCH) { + len3 = + asn1_get_length_der(der + + + counter, + len + - + counter, + &len2); + if (len3 < 0) { + result = + ASN1_DER_ERROR; + goto cleanup; + } + counter += len2 + len3; + move = RIGHT; + } else { /* state==FOUND or state==SAME_BRANCH */ + len3 = + asn1_get_length_der(der + + + counter, + len + - + counter, + &len2); + if (len3 < 0) { + result = + ASN1_DER_ERROR; + goto cleanup; + } + counter += len2; + if (len3) { + _asn1_ltostr + (counter + + len3, temp); + tlen = + strlen(temp); + + if (tlen > 0) + _asn1_set_value + (p, + temp, + tlen + + 1); + p2 = p->down; + 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); + p = p2; + state = FOUND; + } + } + } - if (len4 != -1) - { - len2 += len4; - if (state == FOUND) - { - _asn1_set_value_lv (p, der + counter, len2 + len3); - - if (p == nodeFound) - state = EXIT; - } - counter += len2 + len3; - } - else - { /* indefinite length */ - /* Check indefinite lenth method in an EXPLICIT TAG */ - if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80)) - indefinite = 1; - else - indefinite = 0; - - len2 = len - counter; - result = - _asn1_get_indefinite_length_string (der + counter, &len2); - if (result != ASN1_SUCCESS) - goto cleanup; - - if (state == FOUND) - { - _asn1_set_value_lv (p, der + counter, len2); - - if (p == nodeFound) - state = EXIT; - } - - counter += len2; - - /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with - an indefinite length method. */ - if (indefinite) - { - if (!der[counter] && !der[counter + 1]) - { - counter += 2; - } - else - { - result = ASN1_DER_ERROR; - goto cleanup; + break; + case ASN1_ETYPE_ANY: + if (asn1_get_tag_der + (der + counter, len - counter, &class, + &len2, &tag) != ASN1_SUCCESS) { + result = ASN1_DER_ERROR; + goto cleanup; + } + + if (counter + len2 > len) { + result = ASN1_DER_ERROR; + goto cleanup; + } + + len4 = + asn1_get_length_der(der + counter + + len2, + len - counter - + len2, &len3); + if (len4 < -1) { + result = ASN1_DER_ERROR; + goto cleanup; + } + + if (len4 != -1) { + len2 += len4; + if (state == FOUND) { + _asn1_set_value_lv(p, + der + + counter, + len2 + + len3); + + if (p == nodeFound) + state = EXIT; + } + counter += len2 + len3; + } else { /* indefinite length */ + /* Check indefinite lenth method in an EXPLICIT TAG */ + if ((p->type & CONST_TAG) + && (der[counter - 1] == 0x80)) + indefinite = 1; + else + indefinite = 0; + + len2 = len - counter; + result = + _asn1_get_indefinite_length_string + (der + counter, &len2); + if (result != ASN1_SUCCESS) + goto cleanup; + + if (state == FOUND) { + _asn1_set_value_lv(p, + der + + counter, + len2); + + if (p == nodeFound) + state = EXIT; + } + + counter += len2; + + /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with + an indefinite length method. */ + if (indefinite) { + if (!der[counter] + && !der[counter + 1]) { + counter += 2; + } else { + result = + ASN1_DER_ERROR; + goto cleanup; + } + } + } + move = RIGHT; + break; + + default: + move = (move == UP) ? RIGHT : DOWN; + break; } - } } - move = RIGHT; - break; - default: - move = (move == UP) ? RIGHT : DOWN; - break; - } - } + if ((p == node && move != DOWN) || (state == EXIT)) + break; - if ((p == node && move != DOWN) || (state == EXIT)) - break; - - if (move == DOWN) - { - if (p->down) - { - p = p->down; - - if (state != FOUND) - { - nameLen -= strlen (p->name) + 1; - if (nameLen > 0) - { - if (currentName[0]) - strcat (currentName, "."); - strcat (currentName, p->name); - } - else - { - result = ASN1_MEM_ERROR; - goto cleanup; - } - if (!(strcmp (currentName, elementName))) - { - state = FOUND; - nodeFound = p; - } - else - if (!memcmp - (currentName, elementName, strlen (currentName))) - state = SAME_BRANCH; - else - state = OTHER_BRANCH; + if (move == DOWN) { + if (p->down) { + p = p->down; + + if (state != FOUND) { + nameLen -= strlen(p->name) + 1; + if (nameLen > 0) { + if (currentName[0]) + strcat(currentName, + "."); + strcat(currentName, + p->name); + } else { + result = ASN1_MEM_ERROR; + goto cleanup; + } + if (! + (strcmp + (currentName, elementName))) { + state = FOUND; + nodeFound = p; + } else + if (!memcmp + (currentName, elementName, + strlen(currentName))) + state = SAME_BRANCH; + else + state = OTHER_BRANCH; + } + } else + move = RIGHT; } - } - else - move = RIGHT; - } - if ((move == RIGHT) && !(p->type & CONST_SET)) - { - if (p->right) - { - p = p->right; - - if (state != FOUND) - { - dot_p = char_p = currentName; - while ((char_p = strchr (char_p, '.'))) - { - dot_p = char_p++; - dot_p++; - } - - nameLen += strlen (currentName) - (dot_p - currentName); - *dot_p = 0; - - nameLen -= strlen (p->name); - if (nameLen > 0) - strcat (currentName, p->name); - else - { - result = ASN1_MEM_ERROR; - goto cleanup; - } - - if (!(strcmp (currentName, elementName))) - { - state = FOUND; - nodeFound = p; - } - else - if (!memcmp - (currentName, elementName, strlen (currentName))) - state = SAME_BRANCH; - else - state = OTHER_BRANCH; - } - } - else - move = UP; - } + if ((move == RIGHT) && !(p->type & CONST_SET)) { + if (p->right) { + p = p->right; + + if (state != FOUND) { + dot_p = char_p = currentName; + while ((char_p = + strchr(char_p, '.'))) { + dot_p = char_p++; + dot_p++; + } - if (move == UP) - { - p = _asn1_find_up (p); - - if (state != FOUND) - { - dot_p = char_p = currentName; - while ((char_p = strchr (char_p, '.'))) - { - dot_p = char_p++; - dot_p++; + nameLen += + strlen(currentName) - (dot_p - + currentName); + *dot_p = 0; + + nameLen -= strlen(p->name); + if (nameLen > 0) + strcat(currentName, + p->name); + else { + result = ASN1_MEM_ERROR; + goto cleanup; + } + + if (! + (strcmp + (currentName, elementName))) { + state = FOUND; + nodeFound = p; + } else + if (!memcmp + (currentName, elementName, + strlen(currentName))) + state = SAME_BRANCH; + else + state = OTHER_BRANCH; + } + } else + move = UP; } - nameLen += strlen (currentName) - (dot_p - currentName); - *dot_p = 0; + if (move == UP) { + p = _asn1_find_up(p); - if (!(strcmp (currentName, elementName))) - { - state = FOUND; - nodeFound = p; + if (state != FOUND) { + dot_p = char_p = currentName; + while ((char_p = strchr(char_p, '.'))) { + dot_p = char_p++; + dot_p++; + } + + nameLen += + strlen(currentName) - (dot_p - + currentName); + *dot_p = 0; + + if (!(strcmp(currentName, elementName))) { + state = FOUND; + nodeFound = p; + } else + if (!memcmp + (currentName, elementName, + strlen(currentName))) + state = SAME_BRANCH; + else + state = OTHER_BRANCH; + } } - else - if (!memcmp (currentName, elementName, strlen (currentName))) - state = SAME_BRANCH; - else - state = OTHER_BRANCH; - } } - } - _asn1_delete_not_used (*structure); + _asn1_delete_not_used(*structure); - if (counter > len) - { - result = ASN1_DER_ERROR; - goto cleanup; - } + if (counter > len) { + result = ASN1_DER_ERROR; + goto cleanup; + } - return ASN1_SUCCESS; + return ASN1_SUCCESS; -cleanup: - asn1_delete_structure (structure); - return result; + cleanup: + asn1_delete_structure(structure); + return result; } /** @@ -2172,319 +2179,319 @@ cleanup: * doesn't match the structure ELEMENT. **/ int -asn1_der_decoding_startEnd (asn1_node element, const void *ider, int len, - const char *name_element, int *start, int *end) +asn1_der_decoding_startEnd(asn1_node element, const void *ider, int len, + const char *name_element, int *start, int *end) { - asn1_node node, node_to_find, p, p2, p3; - int counter, len2, len3, len4, move, ris; - unsigned char class; - unsigned long tag; - int indefinite; - const unsigned char *der = ider; - - node = element; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - node_to_find = asn1_find_node (node, name_element); - - if (node_to_find == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - if (node_to_find == node) - { - *start = 0; - *end = len - 1; - return ASN1_SUCCESS; - } - - if (node->type & CONST_OPTION) - return ASN1_GENERIC_ERROR; - - counter = 0; - move = DOWN; - p = node; - while (1) - { - if (p == NULL) - return ASN1_DER_ERROR; - - ris = ASN1_SUCCESS; - - if (move != UP) - { - if (p->type & CONST_SET) - { - p2 = _asn1_find_up (p); - if (p2 == NULL) - return ASN1_DER_ERROR; - - len2 = _asn1_strtol (p2->value, NULL, 10); - if (len2 == -1) - { - if (!der[counter] && !der[counter + 1]) - { - p = p2; - move = UP; - counter += 2; - continue; - } - } - else if (counter == len2) - { - p = p2; - move = UP; - continue; - } - else if (counter > len2) - return ASN1_DER_ERROR; + asn1_node node, node_to_find, p, p2, p3; + int counter, len2, len3, len4, move, ris; + unsigned char class; + unsigned long tag; + int indefinite; + const unsigned char *der = ider; + + node = element; + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; - p2 = p2->down; - - while (p2) - { - if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) - { /* CONTROLLARE */ - if (type_field (p2->type) != ASN1_ETYPE_CHOICE) - ris = - _asn1_extract_tag_der (p2, der + counter, - len - counter, &len2); - else - { - p3 = p2->down; - if (p3 == NULL) - return ASN1_DER_ERROR; - - ris = - _asn1_extract_tag_der (p3, der + counter, - len - counter, &len2); + node_to_find = asn1_find_node(node, name_element); + + if (node_to_find == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + if (node_to_find == node) { + *start = 0; + *end = len - 1; + return ASN1_SUCCESS; + } + + if (node->type & CONST_OPTION) + return ASN1_GENERIC_ERROR; + + counter = 0; + move = DOWN; + p = node; + while (1) { + if (p == NULL) + return ASN1_DER_ERROR; + + ris = ASN1_SUCCESS; + + if (move != UP) { + if (p->type & CONST_SET) { + p2 = _asn1_find_up(p); + if (p2 == NULL) + return ASN1_DER_ERROR; + + len2 = _asn1_strtol(p2->value, NULL, 10); + if (len2 == -1) { + if (!der[counter] + && !der[counter + 1]) { + p = p2; + move = UP; + counter += 2; + continue; + } + } else if (counter == len2) { + p = p2; + move = UP; + continue; + } else if (counter > len2) + return ASN1_DER_ERROR; + + p2 = p2->down; + + while (p2) { + if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) { /* CONTROLLARE */ + if (type_field(p2->type) != + ASN1_ETYPE_CHOICE) + ris = + _asn1_extract_tag_der + (p2, + der + counter, + len - counter, + &len2); + else { + p3 = p2->down; + if (p3 == NULL) + return + ASN1_DER_ERROR; + + ris = + _asn1_extract_tag_der + (p3, + der + counter, + len - counter, + &len2); + } + if (ris == ASN1_SUCCESS) { + p2->type &= + ~CONST_NOT_USED; + p = p2; + break; + } + } + p2 = p2->right; + } + if (p2 == NULL) + return ASN1_DER_ERROR; } - if (ris == ASN1_SUCCESS) - { - p2->type &= ~CONST_NOT_USED; - p = p2; - break; + + if (p == node_to_find) + *start = counter; + + if (type_field(p->type) == ASN1_ETYPE_CHOICE) { + p = p->down; + if (p == NULL) + return ASN1_DER_ERROR; + + ris = + _asn1_extract_tag_der(p, der + counter, + len - counter, + &len2); + if (p == node_to_find) + *start = counter; } - } - p2 = p2->right; - } - if (p2 == NULL) - return ASN1_DER_ERROR; - } - - if (p == node_to_find) - *start = counter; - - if (type_field (p->type) == ASN1_ETYPE_CHOICE) - { - p = p->down; - if (p == NULL) - return ASN1_DER_ERROR; - - ris = - _asn1_extract_tag_der (p, der + counter, len - counter, - &len2); - if (p == node_to_find) - *start = counter; - } - - if (ris == ASN1_SUCCESS) - ris = - _asn1_extract_tag_der (p, der + counter, len - counter, &len2); - if (ris != ASN1_SUCCESS) - { - if (p->type & CONST_OPTION) - { - p->type |= CONST_NOT_USED; - move = RIGHT; - } - else if (p->type & CONST_DEFAULT) - { - move = RIGHT; - } - else - { - return ASN1_TAG_ERROR; - } - } - else - counter += len2; - } - if (ris == ASN1_SUCCESS) - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_NULL: - if (der[counter]) - return ASN1_DER_ERROR; - counter++; - move = RIGHT; - break; - case ASN1_ETYPE_BOOLEAN: - if (der[counter++] != 1) - return ASN1_DER_ERROR; - counter++; - move = RIGHT; - break; - case ASN1_ETYPE_OCTET_STRING: - len3 = len - counter; - ris = _asn1_get_octet_string (der + counter, NULL, &len3); - if (ris != ASN1_SUCCESS) - return ris; - counter += len3; - move = RIGHT; - break; - 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) - return ASN1_DER_ERROR; - counter += len3 + len2; - move = RIGHT; - break; - case ASN1_ETYPE_SEQUENCE: - case ASN1_ETYPE_SET: - if (move != UP) - { - len3 = - asn1_get_length_der (der + counter, len - counter, &len2); - if (len3 < -1) - return ASN1_DER_ERROR; - counter += len2; - if (len3 == 0) - move = RIGHT; - else - move = DOWN; - } - else - { - if (!der[counter] && !der[counter + 1]) /* indefinite length method */ - counter += 2; - move = RIGHT; + if (ris == ASN1_SUCCESS) + ris = + _asn1_extract_tag_der(p, der + counter, + len - counter, + &len2); + if (ris != ASN1_SUCCESS) { + if (p->type & CONST_OPTION) { + p->type |= CONST_NOT_USED; + move = RIGHT; + } else if (p->type & CONST_DEFAULT) { + move = RIGHT; + } else { + return ASN1_TAG_ERROR; + } + } else + counter += len2; } - break; - case ASN1_ETYPE_SEQUENCE_OF: - case ASN1_ETYPE_SET_OF: - if (move != UP) - { - len3 = - asn1_get_length_der (der + counter, len - counter, &len2); - if (len3 < -1) - return ASN1_DER_ERROR; - counter += len2; - if ((len3 == -1) && !der[counter] && !der[counter + 1]) - counter += 2; - else if (len3) - { - p2 = p->down; - while ((type_field (p2->type) == ASN1_ETYPE_TAG) || - (type_field (p2->type) == ASN1_ETYPE_SIZE)) - p2 = p2->right; - p = p2; - } + + if (ris == ASN1_SUCCESS) { + switch (type_field(p->type)) { + case ASN1_ETYPE_NULL: + if (der[counter]) + return ASN1_DER_ERROR; + counter++; + move = RIGHT; + break; + case ASN1_ETYPE_BOOLEAN: + if (der[counter++] != 1) + return ASN1_DER_ERROR; + counter++; + move = RIGHT; + break; + case ASN1_ETYPE_OCTET_STRING: + len3 = len - counter; + ris = + _asn1_get_octet_string(der + counter, + NULL, &len3); + if (ris != ASN1_SUCCESS) + return ris; + counter += len3; + move = RIGHT; + break; + 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) + return ASN1_DER_ERROR; + counter += len3 + len2; + move = RIGHT; + break; + case ASN1_ETYPE_SEQUENCE: + case ASN1_ETYPE_SET: + if (move != UP) { + len3 = + asn1_get_length_der(der + + counter, + len - + counter, + &len2); + if (len3 < -1) + return ASN1_DER_ERROR; + counter += len2; + if (len3 == 0) + move = RIGHT; + else + move = DOWN; + } else { + if (!der[counter] && !der[counter + 1]) /* indefinite length method */ + counter += 2; + move = RIGHT; + } + break; + case ASN1_ETYPE_SEQUENCE_OF: + case ASN1_ETYPE_SET_OF: + if (move != UP) { + len3 = + asn1_get_length_der(der + + counter, + len - + counter, + &len2); + if (len3 < -1) + return ASN1_DER_ERROR; + counter += len2; + if ((len3 == -1) && !der[counter] + && !der[counter + 1]) + counter += 2; + else if (len3) { + p2 = p->down; + while ((type_field + (p2->type) == + ASN1_ETYPE_TAG) + || + (type_field + (p2->type) == + ASN1_ETYPE_SIZE)) + p2 = p2->right; + p = p2; + } + } else { + if (!der[counter] && !der[counter + 1]) /* indefinite length method */ + counter += 2; + } + move = RIGHT; + break; + case ASN1_ETYPE_ANY: + if (asn1_get_tag_der + (der + counter, len - counter, &class, + &len2, &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter + len2 > len) + return ASN1_DER_ERROR; + + len4 = + asn1_get_length_der(der + counter + + len2, + len - counter - + len2, &len3); + if (len4 < -1) + return ASN1_DER_ERROR; + + if (len4 != -1) { + counter += len2 + len4 + len3; + } else { /* indefinite length */ + /* Check indefinite lenth method in an EXPLICIT TAG */ + if ((p->type & CONST_TAG) + && (der[counter - 1] == 0x80)) + indefinite = 1; + else + indefinite = 0; + + len2 = len - counter; + ris = + _asn1_get_indefinite_length_string + (der + counter, &len2); + if (ris != ASN1_SUCCESS) + return ris; + counter += len2; + + /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with + an indefinite length method. */ + if (indefinite) { + if (!der[counter] + && !der[counter + 1]) + counter += 2; + else + return + ASN1_DER_ERROR; + } + } + move = RIGHT; + break; + default: + move = (move == UP) ? RIGHT : DOWN; + break; + } } - else - { - if (!der[counter] && !der[counter + 1]) /* indefinite length method */ - counter += 2; + + if ((p == node_to_find) && (move == RIGHT)) { + *end = counter - 1; + return ASN1_SUCCESS; } - move = RIGHT; - break; - case ASN1_ETYPE_ANY: - if (asn1_get_tag_der - (der + counter, len - counter, &class, &len2, - &tag) != ASN1_SUCCESS) - return ASN1_DER_ERROR; - if (counter + len2 > len) - return ASN1_DER_ERROR; - len4 = - asn1_get_length_der (der + counter + len2, - len - counter - len2, &len3); - if (len4 < -1) - return ASN1_DER_ERROR; + if (p == node && move != DOWN) + break; - if (len4 != -1) - { - counter += len2 + len4 + len3; + if (move == DOWN) { + if (p->down) + p = p->down; + else + move = RIGHT; } - else - { /* indefinite length */ - /* Check indefinite lenth method in an EXPLICIT TAG */ - if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80)) - indefinite = 1; - else - indefinite = 0; - - len2 = len - counter; - ris = - _asn1_get_indefinite_length_string (der + counter, &len2); - if (ris != ASN1_SUCCESS) - return ris; - counter += len2; - - /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with - an indefinite length method. */ - if (indefinite) - { - if (!der[counter] && !der[counter + 1]) - counter += 2; - else - return ASN1_DER_ERROR; - } + if ((move == RIGHT) && !(p->type & CONST_SET)) { + if (p->right) + p = p->right; + else + move = UP; } - move = RIGHT; - break; - default: - move = (move == UP) ? RIGHT : DOWN; - break; - } - } - - if ((p == node_to_find) && (move == RIGHT)) - { - *end = counter - 1; - return ASN1_SUCCESS; + if (move == UP) + p = _asn1_find_up(p); } - if (p == node && move != DOWN) - break; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - if ((move == RIGHT) && !(p->type & CONST_SET)) - { - if (p->right) - p = p->right; - else - move = UP; - } - if (move == UP) - p = _asn1_find_up (p); - } - - return ASN1_ELEMENT_NOT_FOUND; + return ASN1_ELEMENT_NOT_FOUND; } /** @@ -2503,216 +2510,236 @@ asn1_der_decoding_startEnd (asn1_node element, const void *ider, int len, * problem in OBJECT_ID -> TYPE association, or other error codes * depending on DER decoding. **/ -int -asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element) +int asn1_expand_any_defined_by(asn1_node definitions, asn1_node * element) { - char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1], - value[ASN1_MAX_NAME_SIZE]; - int retCode = ASN1_SUCCESS, result; - int len, len2, len3; - asn1_node p, p2, p3, aux = NULL; - char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - - if ((definitions == NULL) || (*element == NULL)) - return ASN1_ELEMENT_NOT_FOUND; - - strcpy (definitionsName, definitions->name); - strcat (definitionsName, "."); - - p = *element; - while (p) - { - - switch (type_field (p->type)) - { - 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) != ASN1_ETYPE_CONSTANT)) - p2 = p2->right; - - if (!p2) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } + char definitionsName[ASN1_MAX_NAME_SIZE], + name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE]; + int retCode = ASN1_SUCCESS, result; + int len, len2, len3; + asn1_node p, p2, p3, aux = NULL; + char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; + + if ((definitions == NULL) || (*element == NULL)) + return ASN1_ELEMENT_NOT_FOUND; + + strcpy(definitionsName, definitions->name); + strcat(definitionsName, "."); + + p = *element; + while (p) { + + switch (type_field(p->type)) { + 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) != + ASN1_ETYPE_CONSTANT)) + p2 = p2->right; + + if (!p2) { + retCode = ASN1_ERROR_TYPE_ANY; + break; + } - p3 = _asn1_find_up (p); + p3 = _asn1_find_up(p); - if (!p3) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - - p3 = p3->down; - while (p3) - { - if (!(strcmp (p3->name, p2->name))) - break; - p3 = p3->right; - } + if (!p3) { + retCode = ASN1_ERROR_TYPE_ANY; + break; + } - if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) || - (p3->value == NULL)) - { + p3 = p3->down; + while (p3) { + if (!(strcmp(p3->name, p2->name))) + break; + p3 = p3->right; + } - p3 = _asn1_find_up (p); - p3 = _asn1_find_up (p3); + if ((!p3) + || (type_field(p3->type) != + ASN1_ETYPE_OBJECT_ID) + || (p3->value == NULL)) { - if (!p3) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } + p3 = _asn1_find_up(p); + p3 = _asn1_find_up(p3); - p3 = p3->down; + if (!p3) { + retCode = + ASN1_ERROR_TYPE_ANY; + break; + } - while (p3) - { - if (!(strcmp (p3->name, p2->name))) - break; - p3 = p3->right; - } - - if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) || - (p3->value == NULL)) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; - } - } + p3 = p3->down; - /* search the OBJECT_ID into definitions */ - p2 = definitions->down; - while (p2) - { - if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) && - (p2->type & CONST_ASSIGN)) - { - strcpy (name, definitionsName); - strcat (name, p2->name); - - len = ASN1_MAX_NAME_SIZE; - result = - asn1_read_value (definitions, name, value, &len); - - if ((result == ASN1_SUCCESS) - && (!_asn1_strcmp (p3->value, value))) - { - p2 = p2->right; /* pointer to the structure to - use for expansion */ - while ((p2) && (p2->type & CONST_ASSIGN)) - p2 = p2->right; - - if (p2) - { - strcpy (name, definitionsName); - strcat (name, p2->name); - - result = - asn1_create_element (definitions, name, &aux); - if (result == ASN1_SUCCESS) - { - _asn1_cpy_name (aux, p); - len2 = - asn1_get_length_der (p->value, - p->value_len, &len3); - if (len2 < 0) - return ASN1_DER_ERROR; - - result = - asn1_der_decoding (&aux, p->value + len3, - len2, - errorDescription); - if (result == ASN1_SUCCESS) - { - - _asn1_set_right (aux, p->right); - _asn1_set_right (p, aux); - - result = asn1_delete_structure (&p); - if (result == ASN1_SUCCESS) - { - p = aux; - aux = NULL; - break; + while (p3) { + if (! + (strcmp + (p3->name, p2->name))) + break; + p3 = p3->right; } - else - { /* error with asn1_delete_structure */ - asn1_delete_structure (&aux); - retCode = result; - break; + + if ((!p3) + || (type_field(p3->type) != + ASN1_ETYPE_OBJECT_ID) + || (p3->value == NULL)) { + retCode = + ASN1_ERROR_TYPE_ANY; + break; } - } - else - { /* error with asn1_der_decoding */ - retCode = result; - break; - } } - else - { /* error with asn1_create_element */ - retCode = result; - break; + + /* search the OBJECT_ID into definitions */ + p2 = definitions->down; + while (p2) { + if ((type_field(p2->type) == + ASN1_ETYPE_OBJECT_ID) + && (p2->type & CONST_ASSIGN)) { + strcpy(name, + definitionsName); + strcat(name, p2->name); + + len = ASN1_MAX_NAME_SIZE; + result = + asn1_read_value + (definitions, name, + value, &len); + + if ((result == + ASN1_SUCCESS) + && + (!_asn1_strcmp + (p3->value, value))) { + p2 = p2->right; /* pointer to the structure to + use for expansion */ + while ((p2) + && (p2-> + type & + CONST_ASSIGN)) + p2 = p2-> + right; + + if (p2) { + strcpy + (name, + definitionsName); + strcat + (name, + p2-> + name); + + result = + asn1_create_element + (definitions, + name, + &aux); + if (result + == + ASN1_SUCCESS) + { + _asn1_cpy_name + (aux, + p); + len2 = asn1_get_length_der(p->value, p->value_len, &len3); + if (len2 < 0) + return + ASN1_DER_ERROR; + + result + = + asn1_der_decoding + (&aux, + p-> + value + + + len3, + len2, + errorDescription); + if (result == ASN1_SUCCESS) { + + _asn1_set_right + (aux, + p-> + right); + _asn1_set_right + (p, + aux); + + result + = + asn1_delete_structure + (&p); + if (result == ASN1_SUCCESS) { + p = aux; + aux = NULL; + break; + } else { /* error with asn1_delete_structure */ + asn1_delete_structure + (&aux); + retCode + = + result; + break; + } + } else { /* error with asn1_der_decoding */ + retCode + = + result; + break; + } + } else { /* error with asn1_create_element */ + retCode + = + result; + break; + } + } else { /* error with the pointer to the structure to exapand */ + retCode = + ASN1_ERROR_TYPE_ANY; + break; + } + } + } + p2 = p2->right; + } /* end while */ + + if (!p2) { + retCode = ASN1_ERROR_TYPE_ANY; + break; } - } - else - { /* error with the pointer to the structure to exapand */ - retCode = ASN1_ERROR_TYPE_ANY; - break; - } + } - } - p2 = p2->right; - } /* end while */ - - if (!p2) - { - retCode = ASN1_ERROR_TYPE_ANY; - break; + break; + default: + break; } - } - break; - default: - break; - } - - if (p->down) - { - p = p->down; - } - else if (p == *element) - { - p = NULL; - break; - } - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == *element) - { - p = NULL; - break; - } - if (p->right) - { - p = p->right; - break; + if (p->down) { + p = p->down; + } else if (p == *element) { + p = NULL; + break; + } else if (p->right) + p = p->right; + else { + while (1) { + p = _asn1_find_up(p); + if (p == *element) { + p = NULL; + break; + } + if (p->right) { + p = p->right; + break; + } + } } - } } - } - return retCode; + return retCode; } /** @@ -2734,127 +2761,135 @@ asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element) * use for expansion, or other errors depending on DER decoding. **/ int -asn1_expand_octet_string (asn1_node definitions, asn1_node * element, - const char *octetName, const char *objectName) +asn1_expand_octet_string(asn1_node definitions, asn1_node * element, + const char *octetName, const char *objectName) { - char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE]; - int retCode = ASN1_SUCCESS, result; - int len, len2, len3; - asn1_node p2, aux = NULL; - asn1_node octetNode = NULL, objectNode = NULL; - char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; - - if ((definitions == NULL) || (*element == NULL)) - return ASN1_ELEMENT_NOT_FOUND; - - octetNode = asn1_find_node (*element, octetName); - if (octetNode == NULL) - return ASN1_ELEMENT_NOT_FOUND; - if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING) - return ASN1_ELEMENT_NOT_FOUND; - if (octetNode->value == NULL) - return ASN1_VALUE_NOT_FOUND; - - objectNode = asn1_find_node (*element, objectName); - if (objectNode == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - if (type_field (objectNode->type) != ASN1_ETYPE_OBJECT_ID) - return ASN1_ELEMENT_NOT_FOUND; - - if (objectNode->value == NULL) - return ASN1_VALUE_NOT_FOUND; - - - /* search the OBJECT_ID into definitions */ - p2 = definitions->down; - while (p2) - { - if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) && - (p2->type & CONST_ASSIGN)) - { - strcpy (name, definitions->name); - strcat (name, "."); - strcat (name, p2->name); - - len = sizeof (value); - result = asn1_read_value (definitions, name, value, &len); - - if ((result == ASN1_SUCCESS) - && (!_asn1_strcmp (objectNode->value, value))) - { - - p2 = p2->right; /* pointer to the structure to - use for expansion */ - while ((p2) && (p2->type & CONST_ASSIGN)) - p2 = p2->right; - - if (p2) - { - strcpy (name, definitions->name); - strcat (name, "."); - strcat (name, p2->name); - - result = asn1_create_element (definitions, name, &aux); - if (result == ASN1_SUCCESS) - { - _asn1_cpy_name (aux, octetNode); - len2 = - asn1_get_length_der (octetNode->value, - octetNode->value_len, &len3); - if (len2 < 0) - return ASN1_DER_ERROR; - - result = - asn1_der_decoding (&aux, octetNode->value + len3, - len2, errorDescription); - if (result == ASN1_SUCCESS) - { - - _asn1_set_right (aux, octetNode->right); - _asn1_set_right (octetNode, aux); - - result = asn1_delete_structure (&octetNode); - if (result == ASN1_SUCCESS) - { - aux = NULL; - break; - } - else - { /* error with asn1_delete_structure */ - asn1_delete_structure (&aux); - retCode = result; - break; - } - } - else - { /* error with asn1_der_decoding */ - retCode = result; - break; + char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE]; + int retCode = ASN1_SUCCESS, result; + int len, len2, len3; + asn1_node p2, aux = NULL; + asn1_node octetNode = NULL, objectNode = NULL; + char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; + + if ((definitions == NULL) || (*element == NULL)) + return ASN1_ELEMENT_NOT_FOUND; + + octetNode = asn1_find_node(*element, octetName); + if (octetNode == NULL) + return ASN1_ELEMENT_NOT_FOUND; + if (type_field(octetNode->type) != ASN1_ETYPE_OCTET_STRING) + return ASN1_ELEMENT_NOT_FOUND; + if (octetNode->value == NULL) + return ASN1_VALUE_NOT_FOUND; + + objectNode = asn1_find_node(*element, objectName); + if (objectNode == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + if (type_field(objectNode->type) != ASN1_ETYPE_OBJECT_ID) + return ASN1_ELEMENT_NOT_FOUND; + + if (objectNode->value == NULL) + return ASN1_VALUE_NOT_FOUND; + + + /* search the OBJECT_ID into definitions */ + p2 = definitions->down; + while (p2) { + if ((type_field(p2->type) == ASN1_ETYPE_OBJECT_ID) && + (p2->type & CONST_ASSIGN)) { + strcpy(name, definitions->name); + strcat(name, "."); + strcat(name, p2->name); + + len = sizeof(value); + result = + asn1_read_value(definitions, name, value, + &len); + + if ((result == ASN1_SUCCESS) + && (!_asn1_strcmp(objectNode->value, value))) { + + p2 = p2->right; /* pointer to the structure to + use for expansion */ + while ((p2) && (p2->type & CONST_ASSIGN)) + p2 = p2->right; + + if (p2) { + strcpy(name, definitions->name); + strcat(name, "."); + strcat(name, p2->name); + + result = + asn1_create_element + (definitions, name, &aux); + if (result == ASN1_SUCCESS) { + _asn1_cpy_name(aux, + octetNode); + len2 = + asn1_get_length_der + (octetNode->value, + octetNode->value_len, + &len3); + if (len2 < 0) + return + ASN1_DER_ERROR; + + result = + asn1_der_decoding(&aux, + octetNode-> + value + + + len3, + len2, + errorDescription); + if (result == ASN1_SUCCESS) { + + _asn1_set_right + (aux, + octetNode-> + right); + _asn1_set_right + (octetNode, + aux); + + result = + asn1_delete_structure + (&octetNode); + if (result == + ASN1_SUCCESS) { + aux = NULL; + break; + } else { /* error with asn1_delete_structure */ + asn1_delete_structure + (&aux); + retCode = + result; + break; + } + } else { /* error with asn1_der_decoding */ + retCode = result; + break; + } + } else { /* error with asn1_create_element */ + retCode = result; + break; + } + } else { /* error with the pointer to the structure to exapand */ + retCode = ASN1_VALUE_NOT_VALID; + break; + } } - } - else - { /* error with asn1_create_element */ - retCode = result; - break; - } } - else - { /* error with the pointer to the structure to exapand */ - retCode = ASN1_VALUE_NOT_VALID; - break; - } - } - } - p2 = p2->right; + p2 = p2->right; - } + } - if (!p2) - retCode = ASN1_VALUE_NOT_VALID; + if (!p2) + retCode = ASN1_VALUE_NOT_VALID; - return retCode; + return retCode; } /** @@ -2871,45 +2906,46 @@ asn1_expand_octet_string (asn1_node definitions, asn1_node * element, * 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) +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; + 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 763ac586b7..dd561802ad 100644 --- a/lib/minitasn1/element.c +++ b/lib/minitasn1/element.c @@ -33,30 +33,27 @@ #include "element.h" -void -_asn1_hierarchical_name (asn1_node node, char *name, int name_size) +void _asn1_hierarchical_name(asn1_node node, char *name, int name_size) { - asn1_node p; - char tmp_name[64]; + asn1_node p; + char tmp_name[64]; - p = node; + p = node; - name[0] = 0; + name[0] = 0; - while (p != NULL) - { - if (p->name[0] != 0) - { - _asn1_str_cpy (tmp_name, sizeof (tmp_name), name), - _asn1_str_cpy (name, name_size, p->name); - _asn1_str_cat (name, name_size, "."); - _asn1_str_cat (name, name_size, tmp_name); + while (p != NULL) { + if (p->name[0] != 0) { + _asn1_str_cpy(tmp_name, sizeof(tmp_name), name), + _asn1_str_cpy(name, name_size, p->name); + _asn1_str_cat(name, name_size, "."); + _asn1_str_cat(name, name_size, tmp_name); + } + p = _asn1_find_up(p); } - p = _asn1_find_up (p); - } - if (name[0] == 0) - _asn1_str_cpy (name, name_size, "ROOT"); + if (name[0] == 0) + _asn1_str_cpy(name, name_size, "ROOT"); } @@ -75,89 +72,88 @@ _asn1_hierarchical_name (asn1_node node, char *name, int name_size) /* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */ /******************************************************************/ int -_asn1_convert_integer (const unsigned char *value, unsigned char *value_out, - int value_out_size, int *len) +_asn1_convert_integer(const unsigned char *value, unsigned char *value_out, + int value_out_size, int *len) { - char negative; - unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; - long valtmp; - int k, k2; + char negative; + unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; + long valtmp; + int k, k2; - valtmp = _asn1_strtol (value, NULL, 10); + valtmp = _asn1_strtol(value, NULL, 10); - for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) - { - val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF; - } + for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) { + val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = + (valtmp >> (8 * k)) & 0xFF; + } - if (val[0] & 0x80) - negative = 1; - else - negative = 0; + if (val[0] & 0x80) + negative = 1; + else + negative = 0; - for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++) - { - if (negative && (val[k] != 0xFF)) - break; - else if (!negative && val[k]) - break; - } + for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++) { + if (negative && (val[k] != 0xFF)) + break; + else if (!negative && val[k]) + break; + } - if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80))) - k--; + if ((negative && !(val[k] & 0x80)) + || (!negative && (val[k] & 0x80))) + k--; - *len = SIZEOF_UNSIGNED_LONG_INT - k; + *len = SIZEOF_UNSIGNED_LONG_INT - k; - if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size) - /* VALUE_OUT is too short to contain the value conversion */ - return ASN1_MEM_ERROR; + if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size) + /* VALUE_OUT is too short to contain the value conversion */ + return ASN1_MEM_ERROR; - for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++) - value_out[k2 - k] = val[k2]; + for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++) + value_out[k2 - k] = val[k2]; #if 0 - printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len); - for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) - printf (", vOut[%d]=%d", k, value_out[k]); - printf ("\n"); + printf("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, + *len); + for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) + printf(", vOut[%d]=%d", k, value_out[k]); + printf("\n"); #endif - return ASN1_SUCCESS; + return ASN1_SUCCESS; } -int -_asn1_append_sequence_set (asn1_node node) +int _asn1_append_sequence_set(asn1_node node) { - asn1_node p, p2; - char temp[10]; - long n; - - if (!node || !(node->down)) - return ASN1_GENERIC_ERROR; - - p = node->down; - 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) - p = p->right; - _asn1_set_right (p, p2); - - if (p->name[0] == 0) - _asn1_str_cpy (temp, sizeof (temp), "?1"); - else - { - n = strtol (p->name + 1, NULL, 0); - n++; - temp[0] = '?'; - _asn1_ltostr (n, temp + 1); - } - _asn1_set_name (p2, temp); - /* p2->type |= CONST_OPTION; */ - - return ASN1_SUCCESS; + asn1_node p, p2; + char temp[10]; + long n; + + if (!node || !(node->down)) + return ASN1_GENERIC_ERROR; + + p = node->down; + 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) + p = p->right; + _asn1_set_right(p, p2); + + if (p->name[0] == 0) + _asn1_str_cpy(temp, sizeof(temp), "?1"); + else { + n = strtol(p->name + 1, NULL, 0); + n++; + temp[0] = '?'; + _asn1_ltostr(n, temp + 1); + } + _asn1_set_name(p2, temp); + /* p2->type |= CONST_OPTION; */ + + return ASN1_SUCCESS; } @@ -268,346 +264,334 @@ _asn1_append_sequence_set (asn1_node node) * %ASN1_VALUE_NOT_VALID if @ivalue has a wrong format. **/ int -asn1_write_value (asn1_node node_root, const char *name, - const void *ivalue, int len) +asn1_write_value(asn1_node node_root, const char *name, + const void *ivalue, int len) { - asn1_node node, p, p2; - unsigned char *temp, *value_temp = NULL, *default_temp = NULL; - 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) - return ASN1_ELEMENT_NOT_FOUND; - - if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0)) - { - asn1_delete_structure (&node); - return ASN1_SUCCESS; - } - - type = type_field(node->type); - - if ((type == ASN1_ETYPE_SEQUENCE_OF) && (value == NULL) - && (len == 0)) - { - p = node->down; - while ((type_field (p->type) == ASN1_ETYPE_TAG) - || (type_field (p->type) == ASN1_ETYPE_SIZE)) - p = p->right; - - while (p->right) - asn1_delete_structure (&p->right); - - return ASN1_SUCCESS; - } - - switch (type) - { - case ASN1_ETYPE_BOOLEAN: - if (!_asn1_strcmp (value, "TRUE")) - { - if (node->type & CONST_DEFAULT) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (p->type & CONST_TRUE) - _asn1_set_value (node, NULL, 0); - else - _asn1_set_value (node, "T", 1); - } - else - _asn1_set_value (node, "T", 1); + asn1_node node, p, p2; + unsigned char *temp, *value_temp = NULL, *default_temp = NULL; + 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) + return ASN1_ELEMENT_NOT_FOUND; + + if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0)) { + asn1_delete_structure(&node); + return ASN1_SUCCESS; } - else if (!_asn1_strcmp (value, "FALSE")) - { - if (node->type & CONST_DEFAULT) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (p->type & CONST_FALSE) - _asn1_set_value (node, NULL, 0); - else - _asn1_set_value (node, "F", 1); - } - else - _asn1_set_value (node, "F", 1); + + type = type_field(node->type); + + if ((type == ASN1_ETYPE_SEQUENCE_OF) && (value == NULL) + && (len == 0)) { + p = node->down; + while ((type_field(p->type) == ASN1_ETYPE_TAG) + || (type_field(p->type) == ASN1_ETYPE_SIZE)) + p = p->right; + + while (p->right) + asn1_delete_structure(&p->right); + + return ASN1_SUCCESS; } - else - return ASN1_VALUE_NOT_VALID; - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - if (len == 0) - { - if ((isdigit (value[0])) || (value[0] == '-')) - { - value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (value_temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - _asn1_convert_integer (value, value_temp, - SIZEOF_UNSIGNED_LONG_INT, &len); - } - else - { /* is an identifier like v1 */ - if (!(node->type & CONST_LIST)) - return ASN1_VALUE_NOT_VALID; - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_CONSTANT) - { - if (!_asn1_strcmp (p->name, value)) - { - value_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (value_temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - _asn1_convert_integer (p->value, - value_temp, - SIZEOF_UNSIGNED_LONG_INT, - &len); - break; + + switch (type) { + case ASN1_ETYPE_BOOLEAN: + if (!_asn1_strcmp(value, "TRUE")) { + if (node->type & CONST_DEFAULT) { + p = node->down; + while (type_field(p->type) != + ASN1_ETYPE_DEFAULT) + p = p->right; + if (p->type & CONST_TRUE) + _asn1_set_value(node, NULL, 0); + else + _asn1_set_value(node, "T", 1); + } else + _asn1_set_value(node, "T", 1); + } else if (!_asn1_strcmp(value, "FALSE")) { + if (node->type & CONST_DEFAULT) { + p = node->down; + while (type_field(p->type) != + ASN1_ETYPE_DEFAULT) + p = p->right; + if (p->type & CONST_FALSE) + _asn1_set_value(node, NULL, 0); + else + _asn1_set_value(node, "F", 1); + } else + _asn1_set_value(node, "F", 1); + } else + return ASN1_VALUE_NOT_VALID; + break; + case ASN1_ETYPE_INTEGER: + case ASN1_ETYPE_ENUMERATED: + if (len == 0) { + if ((isdigit(value[0])) || (value[0] == '-')) { + value_temp = + malloc(SIZEOF_UNSIGNED_LONG_INT); + if (value_temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + _asn1_convert_integer(value, value_temp, + SIZEOF_UNSIGNED_LONG_INT, + &len); + } else { /* is an identifier like v1 */ + if (!(node->type & CONST_LIST)) + return ASN1_VALUE_NOT_VALID; + p = node->down; + while (p) { + if (type_field(p->type) == + ASN1_ETYPE_CONSTANT) { + if (!_asn1_strcmp + (p->name, value)) { + value_temp = + malloc + (SIZEOF_UNSIGNED_LONG_INT); + if (value_temp == + NULL) + return + ASN1_MEM_ALLOC_ERROR; + + _asn1_convert_integer + (p->value, + value_temp, + SIZEOF_UNSIGNED_LONG_INT, + &len); + break; + } + } + p = p->right; + } + if (p == NULL) + return ASN1_VALUE_NOT_VALID; } - } - p = p->right; + } else { /* len != 0 */ + value_temp = malloc(len); + if (value_temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + memcpy(value_temp, value, len); } - if (p == NULL) - return ASN1_VALUE_NOT_VALID; - } - } - else - { /* len != 0 */ - value_temp = malloc (len); - if (value_temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - memcpy (value_temp, value, len); - } - - if (value_temp[0] & 0x80) - negative = 1; - else - negative = 0; - if (negative && (type_field (node->type) == ASN1_ETYPE_ENUMERATED)) - { - free (value_temp); - return ASN1_VALUE_NOT_VALID; - } + if (value_temp[0] & 0x80) + negative = 1; + else + negative = 0; - for (k = 0; k < len - 1; k++) - if (negative && (value_temp[k] != 0xFF)) - break; - else if (!negative && value_temp[k]) - break; - - if ((negative && !(value_temp[k] & 0x80)) || - (!negative && (value_temp[k] & 0x80))) - k--; - - _asn1_set_value_lv (node, value_temp + k, len - k); - - if (node->type & CONST_DEFAULT) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if ((isdigit (p->value[0])) || (p->value[0] == '-')) - { - default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (default_temp == NULL) - { - free (value_temp); - return ASN1_MEM_ALLOC_ERROR; + if (negative + && (type_field(node->type) == ASN1_ETYPE_ENUMERATED)) { + free(value_temp); + return ASN1_VALUE_NOT_VALID; } - _asn1_convert_integer (p->value, default_temp, - SIZEOF_UNSIGNED_LONG_INT, &len2); - } - else - { /* is an identifier like v1 */ - if (!(node->type & CONST_LIST)) - { - free (value_temp); - return ASN1_VALUE_NOT_VALID; + for (k = 0; k < len - 1; k++) + if (negative && (value_temp[k] != 0xFF)) + break; + else if (!negative && value_temp[k]) + break; + + if ((negative && !(value_temp[k] & 0x80)) || + (!negative && (value_temp[k] & 0x80))) + k--; + + _asn1_set_value_lv(node, value_temp + k, len - k); + + if (node->type & CONST_DEFAULT) { + p = node->down; + while (type_field(p->type) != ASN1_ETYPE_DEFAULT) + p = p->right; + if ((isdigit(p->value[0])) || (p->value[0] == '-')) { + default_temp = + malloc(SIZEOF_UNSIGNED_LONG_INT); + if (default_temp == NULL) { + free(value_temp); + return ASN1_MEM_ALLOC_ERROR; + } + + _asn1_convert_integer(p->value, + default_temp, + SIZEOF_UNSIGNED_LONG_INT, + &len2); + } else { /* is an identifier like v1 */ + if (!(node->type & CONST_LIST)) { + free(value_temp); + return ASN1_VALUE_NOT_VALID; + } + p2 = node->down; + while (p2) { + if (type_field(p2->type) == + ASN1_ETYPE_CONSTANT) { + if (!_asn1_strcmp + (p2->name, p->value)) { + default_temp = + malloc + (SIZEOF_UNSIGNED_LONG_INT); + if (default_temp == + NULL) { + free(value_temp); + return + ASN1_MEM_ALLOC_ERROR; + } + + _asn1_convert_integer + (p2->value, + default_temp, + SIZEOF_UNSIGNED_LONG_INT, + &len2); + break; + } + } + p2 = p2->right; + } + if (p2 == NULL) { + free(value_temp); + return ASN1_VALUE_NOT_VALID; + } + } + + + if ((len - k) == len2) { + for (k2 = 0; k2 < len2; k2++) + if (value_temp[k + k2] != + default_temp[k2]) { + break; + } + if (k2 == len2) + _asn1_set_value(node, NULL, 0); + } + free(default_temp); } - p2 = node->down; - while (p2) - { - if (type_field (p2->type) == ASN1_ETYPE_CONSTANT) - { - if (!_asn1_strcmp (p2->name, p->value)) - { - default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT); - if (default_temp == NULL) - { - free (value_temp); - return ASN1_MEM_ALLOC_ERROR; - } - - _asn1_convert_integer (p2->value, - default_temp, - SIZEOF_UNSIGNED_LONG_INT, - &len2); - break; + free(value_temp); + break; + 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) != ASN1_ETYPE_DEFAULT) + p = p->right; + if (!_asn1_strcmp(value, p->value)) { + _asn1_set_value(node, NULL, 0); + break; } - } - p2 = p2->right; } - if (p2 == NULL) + _asn1_set_value(node, value, _asn1_strlen(value) + 1); + break; + case ASN1_ETYPE_UTC_TIME: { - free (value_temp); - return ASN1_VALUE_NOT_VALID; + 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 (len) { + case 11: + if (value[10] != 'Z') + return ASN1_VALUE_NOT_VALID; + break; + case 13: + if ((!isdigit(value[10])) + || (!isdigit(value[11])) + || (value[12] != 'Z')) + return ASN1_VALUE_NOT_VALID; + break; + case 15: + if ((value[10] != '+') + && (value[10] != '-')) + return ASN1_VALUE_NOT_VALID; + for (k = 11; k < 15; k++) + if (!isdigit(value[k])) + return + ASN1_VALUE_NOT_VALID; + break; + case 17: + if ((!isdigit(value[10])) + || (!isdigit(value[11]))) + return ASN1_VALUE_NOT_VALID; + if ((value[12] != '+') + && (value[12] != '-')) + return ASN1_VALUE_NOT_VALID; + for (k = 13; k < 17; k++) + if (!isdigit(value[k])) + return + ASN1_VALUE_NOT_VALID; + break; + default: + return ASN1_VALUE_NOT_FOUND; + } + _asn1_set_value(node, value, len); } - } - - - if ((len - k) == len2) - { - for (k2 = 0; k2 < len2; k2++) - if (value_temp[k + k2] != default_temp[k2]) - { - break; - } - if (k2 == len2) - _asn1_set_value (node, NULL, 0); - } - free (default_temp); - } - free (value_temp); - break; - 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) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (!_asn1_strcmp (value, p->value)) - { - _asn1_set_value (node, NULL, 0); - break; - } - } - _asn1_set_value (node, value, _asn1_strlen (value) + 1); - break; - case ASN1_ETYPE_UTC_TIME: - { - 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 (len) - { - case 11: - if (value[10] != 'Z') - return ASN1_VALUE_NOT_VALID; - break; - case 13: - if ((!isdigit (value[10])) || (!isdigit (value[11])) || - (value[12] != 'Z')) - return ASN1_VALUE_NOT_VALID; - break; - case 15: - if ((value[10] != '+') && (value[10] != '-')) - return ASN1_VALUE_NOT_VALID; - for (k = 11; k < 15; k++) - if (!isdigit (value[k])) - return ASN1_VALUE_NOT_VALID; - break; - case 17: - if ((!isdigit (value[10])) || (!isdigit (value[11]))) - return ASN1_VALUE_NOT_VALID; - if ((value[12] != '+') && (value[12] != '-')) - return ASN1_VALUE_NOT_VALID; - for (k = 13; k < 17; k++) - if (!isdigit (value[k])) - return ASN1_VALUE_NOT_VALID; - break; - default: - return ASN1_VALUE_NOT_FOUND; - } - _asn1_set_value (node, value, len); - } - break; - case ASN1_ETYPE_GENERALIZED_TIME: - len = _asn1_strlen(value); - _asn1_set_value (node, value, len); - break; - 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_lv (node, value, len); - break; - case ASN1_ETYPE_BIT_STRING: - if (len == 0) - len = _asn1_strlen (value); - asn1_length_der ((len >> 3) + 2, NULL, &len2); - temp = malloc ((len >> 3) + 2 + len2); - if (temp == NULL) - return ASN1_MEM_ALLOC_ERROR; - - asn1_bit_der (value, len, temp, &len2); - _asn1_set_value_m (node, temp, len2); - temp = NULL; - break; - case ASN1_ETYPE_CHOICE: - p = node->down; - while (p) - { - if (!_asn1_strcmp (p->name, value)) - { - p2 = node->down; - while (p2) - { - if (p2 != p) - { - asn1_delete_structure (&p2); - p2 = node->down; - } - else - p2 = p2->right; + break; + case ASN1_ETYPE_GENERALIZED_TIME: + len = _asn1_strlen(value); + _asn1_set_value(node, value, len); + break; + 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_lv(node, value, len); + break; + case ASN1_ETYPE_BIT_STRING: + if (len == 0) + len = _asn1_strlen(value); + asn1_length_der((len >> 3) + 2, NULL, &len2); + temp = malloc((len >> 3) + 2 + len2); + if (temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + asn1_bit_der(value, len, temp, &len2); + _asn1_set_value_m(node, temp, len2); + temp = NULL; + break; + case ASN1_ETYPE_CHOICE: + p = node->down; + while (p) { + if (!_asn1_strcmp(p->name, value)) { + p2 = node->down; + while (p2) { + if (p2 != p) { + asn1_delete_structure(&p2); + p2 = node->down; + } else + p2 = p2->right; + } + break; + } + p = p->right; } - break; - } - p = p->right; + if (!p) + return ASN1_ELEMENT_NOT_FOUND; + break; + case ASN1_ETYPE_ANY: + _asn1_set_value_lv(node, value, len); + break; + 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); + break; + default: + return ASN1_ELEMENT_NOT_FOUND; + break; } - if (!p) - return ASN1_ELEMENT_NOT_FOUND; - break; - case ASN1_ETYPE_ANY: - _asn1_set_value_lv (node, value, len); - break; - 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); - break; - default: - return ASN1_ELEMENT_NOT_FOUND; - break; - } - - return ASN1_SUCCESS; + + return ASN1_SUCCESS; } @@ -709,9 +693,9 @@ asn1_write_value (asn1_node node_root, const char *name, * bytes needed. **/ int -asn1_read_value (asn1_node root, const char *name, void *ivalue, int *len) +asn1_read_value(asn1_node root, const char *name, void *ivalue, int *len) { - return asn1_read_value_type( root, name, ivalue, len, NULL); + return asn1_read_value_type(root, name, ivalue, len, NULL); } /** @@ -777,174 +761,158 @@ asn1_read_value (asn1_node root, const char *name, void *ivalue, int *len) * bytes needed. **/ int -asn1_read_value_type (asn1_node root, const char *name, void *ivalue, int *len, - unsigned int *etype) +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; - - 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; - - if (etype) - *etype = type; - switch (type) - { - case ASN1_ETYPE_NULL: - PUT_STR_VALUE (value, value_size, "NULL"); - break; - case ASN1_ETYPE_BOOLEAN: - if ((node->type & CONST_DEFAULT) && (node->value == NULL)) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if (p->type & CONST_TRUE) - { - PUT_STR_VALUE (value, value_size, "TRUE"); - } - else - { - PUT_STR_VALUE (value, value_size, "FALSE"); - } - } - else if (node->value[0] == 'T') - { - PUT_STR_VALUE (value, value_size, "TRUE"); - } - else - { - PUT_STR_VALUE (value, value_size, "FALSE"); - } - break; - case ASN1_ETYPE_INTEGER: - case ASN1_ETYPE_ENUMERATED: - if ((node->type & CONST_DEFAULT) && (node->value == NULL)) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - if ((isdigit (p->value[0])) || (p->value[0] == '-') - || (p->value[0] == '+')) - { - if (_asn1_convert_integer - (p->value, value, value_size, len) != ASN1_SUCCESS) - return ASN1_MEM_ERROR; - } - else - { /* is an identifier like v1 */ - p2 = node->down; - while (p2) - { - if (type_field (p2->type) == ASN1_ETYPE_CONSTANT) - { - if (!_asn1_strcmp (p2->name, p->value)) - { - if (_asn1_convert_integer - (p2->value, value, value_size, - len) != ASN1_SUCCESS) - return ASN1_MEM_ERROR; - break; + 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; + + 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; + + if (etype) + *etype = type; + switch (type) { + case ASN1_ETYPE_NULL: + PUT_STR_VALUE(value, value_size, "NULL"); + break; + case ASN1_ETYPE_BOOLEAN: + if ((node->type & CONST_DEFAULT) && (node->value == NULL)) { + p = node->down; + while (type_field(p->type) != ASN1_ETYPE_DEFAULT) + p = p->right; + if (p->type & CONST_TRUE) { + PUT_STR_VALUE(value, value_size, "TRUE"); + } else { + PUT_STR_VALUE(value, value_size, "FALSE"); } - } - p2 = p2->right; + } else if (node->value[0] == 'T') { + PUT_STR_VALUE(value, value_size, "TRUE"); + } else { + PUT_STR_VALUE(value, value_size, "FALSE"); } - } - } - else - { - 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 ASN1_ETYPE_OBJECT_ID: - if (node->type & CONST_ASSIGN) - { - value[0] = 0; - p = node->down; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_CONSTANT) - { - ADD_STR_VALUE (value, value_size, p->value); - if (p->right) - { - ADD_STR_VALUE (value, value_size, "."); - } + break; + case ASN1_ETYPE_INTEGER: + case ASN1_ETYPE_ENUMERATED: + if ((node->type & CONST_DEFAULT) && (node->value == NULL)) { + p = node->down; + while (type_field(p->type) != ASN1_ETYPE_DEFAULT) + p = p->right; + if ((isdigit(p->value[0])) || (p->value[0] == '-') + || (p->value[0] == '+')) { + if (_asn1_convert_integer + (p->value, value, value_size, + len) != ASN1_SUCCESS) + return ASN1_MEM_ERROR; + } else { /* is an identifier like v1 */ + p2 = node->down; + while (p2) { + if (type_field(p2->type) == + ASN1_ETYPE_CONSTANT) { + if (!_asn1_strcmp + (p2->name, p->value)) { + if (_asn1_convert_integer(p2->value, value, value_size, len) != ASN1_SUCCESS) + return + ASN1_MEM_ERROR; + break; + } + } + p2 = p2->right; + } + } + } else { + len2 = -1; + if (asn1_get_octet_der + (node->value, node->value_len, &len2, value, + value_size, len) != ASN1_SUCCESS) + return ASN1_MEM_ERROR; } - p = p->right; - } - *len = _asn1_strlen (value) + 1; - } - else if ((node->type & CONST_DEFAULT) && (node->value == NULL)) - { - p = node->down; - while (type_field (p->type) != ASN1_ETYPE_DEFAULT) - p = p->right; - PUT_STR_VALUE (value, value_size, p->value); - } - else - { - PUT_STR_VALUE (value, value_size, node->value); + break; + case ASN1_ETYPE_OBJECT_ID: + if (node->type & CONST_ASSIGN) { + value[0] = 0; + p = node->down; + while (p) { + if (type_field(p->type) == + ASN1_ETYPE_CONSTANT) { + ADD_STR_VALUE(value, value_size, + p->value); + if (p->right) { + ADD_STR_VALUE(value, + value_size, + "."); + } + } + p = p->right; + } + *len = _asn1_strlen(value) + 1; + } else if ((node->type & CONST_DEFAULT) + && (node->value == NULL)) { + p = node->down; + while (type_field(p->type) != ASN1_ETYPE_DEFAULT) + p = p->right; + PUT_STR_VALUE(value, value_size, p->value); + } else { + PUT_STR_VALUE(value, value_size, node->value); + } + break; + case ASN1_ETYPE_GENERALIZED_TIME: + case ASN1_ETYPE_UTC_TIME: + PUT_AS_STR_VALUE(value, value_size, node->value, + node->value_len); + break; + 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 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 ASN1_ETYPE_CHOICE: + PUT_STR_VALUE(value, value_size, node->down->name); + break; + case ASN1_ETYPE_ANY: + len3 = -1; + len2 = + asn1_get_length_der(node->value, node->value_len, + &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + PUT_VALUE(value, value_size, node->value + len3, len2); + break; + default: + return ASN1_ELEMENT_NOT_FOUND; + break; } - break; - case ASN1_ETYPE_GENERALIZED_TIME: - case ASN1_ETYPE_UTC_TIME: - PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len); - break; - 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 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 ASN1_ETYPE_CHOICE: - PUT_STR_VALUE (value, value_size, node->down->name); - break; - case ASN1_ETYPE_ANY: - len3 = -1; - len2 = asn1_get_length_der (node->value, node->value_len, &len3); - if (len2 < 0) - return ASN1_DER_ERROR; - PUT_VALUE (value, value_size, node->value + len3, len2); - break; - default: - return ASN1_ELEMENT_NOT_FOUND; - break; - } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } @@ -964,68 +932,62 @@ asn1_read_value_type (asn1_node root, const char *name, void *ivalue, int *len, * @name is not a valid element. **/ int -asn1_read_tag (asn1_node root, const char *name, int *tagValue, - int *classValue) +asn1_read_tag(asn1_node root, const char *name, int *tagValue, + int *classValue) { - asn1_node node, p, pTag; - - node = asn1_find_node (root, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node->down; - - /* pTag will points to the IMPLICIT TAG */ - pTag = NULL; - if (node->type & CONST_TAG) - { - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_TAG) - { - if ((p->type & CONST_IMPLICIT) && (pTag == NULL)) - pTag = p; - else if (p->type & CONST_EXPLICIT) - pTag = NULL; - } - p = p->right; + asn1_node node, p, pTag; + + node = asn1_find_node(root, name); + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + p = node->down; + + /* pTag will points to the IMPLICIT TAG */ + pTag = NULL; + if (node->type & CONST_TAG) { + while (p) { + if (type_field(p->type) == ASN1_ETYPE_TAG) { + if ((p->type & CONST_IMPLICIT) + && (pTag == NULL)) + pTag = p; + else if (p->type & CONST_EXPLICIT) + pTag = NULL; + } + p = p->right; + } } - } - - if (pTag) - { - *tagValue = _asn1_strtoul (pTag->value, NULL, 10); - - if (pTag->type & CONST_APPLICATION) - *classValue = ASN1_CLASS_APPLICATION; - else if (pTag->type & CONST_UNIVERSAL) - *classValue = ASN1_CLASS_UNIVERSAL; - else if (pTag->type & CONST_PRIVATE) - *classValue = ASN1_CLASS_PRIVATE; - else - *classValue = ASN1_CLASS_CONTEXT_SPECIFIC; - } - else - { - unsigned type = type_field (node->type); - *classValue = ASN1_CLASS_UNIVERSAL; - - switch (type) - { - CASE_HANDLED_ETYPES: - *tagValue = _asn1_tags[type].tag; - break; - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_CHOICE: - case ASN1_ETYPE_ANY: - *tagValue = -1; - break; - default: - break; + + if (pTag) { + *tagValue = _asn1_strtoul(pTag->value, NULL, 10); + + if (pTag->type & CONST_APPLICATION) + *classValue = ASN1_CLASS_APPLICATION; + else if (pTag->type & CONST_UNIVERSAL) + *classValue = ASN1_CLASS_UNIVERSAL; + else if (pTag->type & CONST_PRIVATE) + *classValue = ASN1_CLASS_PRIVATE; + else + *classValue = ASN1_CLASS_CONTEXT_SPECIFIC; + } else { + unsigned type = type_field(node->type); + *classValue = ASN1_CLASS_UNIVERSAL; + + switch (type) { + CASE_HANDLED_ETYPES: + *tagValue = _asn1_tags[type].tag; + break; + case ASN1_ETYPE_TAG: + case ASN1_ETYPE_CHOICE: + case ASN1_ETYPE_ANY: + *tagValue = -1; + break; + default: + break; + } } - } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } /** @@ -1038,12 +1000,12 @@ asn1_read_tag (asn1_node root, const char *name, int *tagValue, * * Returns: %ASN1_SUCCESS if the node exists. **/ -int asn1_read_node_value (asn1_node node, asn1_data_node_st* data) +int asn1_read_node_value(asn1_node node, asn1_data_node_st * data) { - data->name = node->name; - data->value = node->value; - data->value_len = node->value_len; - data->type = type_field(node->type); - - return ASN1_SUCCESS; + data->name = node->name; + data->value = node->value; + data->value_len = node->value_len; + data->type = type_field(node->type); + + return ASN1_SUCCESS; } diff --git a/lib/minitasn1/element.h b/lib/minitasn1/element.h index 3bd38bb923..aca0238b42 100644 --- a/lib/minitasn1/element.h +++ b/lib/minitasn1/element.h @@ -23,12 +23,12 @@ #define _ELEMENT_H -int _asn1_append_sequence_set (asn1_node node); +int _asn1_append_sequence_set(asn1_node node); -int _asn1_convert_integer (const unsigned char *value, - unsigned char *value_out, - int value_out_size, int *len); +int _asn1_convert_integer(const unsigned char *value, + unsigned char *value_out, + int value_out_size, int *len); -void _asn1_hierarchical_name (asn1_node node, char *name, int name_size); +void _asn1_hierarchical_name(asn1_node node, char *name, int name_size); #endif diff --git a/lib/minitasn1/errors.c b/lib/minitasn1/errors.c index e01c3ee9ea..db9f1fa051 100644 --- a/lib/minitasn1/errors.c +++ b/lib/minitasn1/errors.c @@ -26,33 +26,32 @@ #define LIBTASN1_ERROR_ENTRY(name) { #name, name } -struct libtasn1_error_entry -{ - const char *name; - int number; +struct libtasn1_error_entry { + const char *name; + int number; }; typedef struct libtasn1_error_entry libtasn1_error_entry; static const libtasn1_error_entry error_algorithms[] = { - LIBTASN1_ERROR_ENTRY (ASN1_SUCCESS), - LIBTASN1_ERROR_ENTRY (ASN1_FILE_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_IDENTIFIER_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_DER_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_FOUND), - LIBTASN1_ERROR_ENTRY (ASN1_GENERIC_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_VALID), - LIBTASN1_ERROR_ENTRY (ASN1_TAG_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_TAG_IMPLICIT), - LIBTASN1_ERROR_ENTRY (ASN1_ERROR_TYPE_ANY), - LIBTASN1_ERROR_ENTRY (ASN1_SYNTAX_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_MEM_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_MEM_ALLOC_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_DER_OVERFLOW), - LIBTASN1_ERROR_ENTRY (ASN1_NAME_TOO_LONG), - LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR), - LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY), - {0, 0} + LIBTASN1_ERROR_ENTRY(ASN1_SUCCESS), + LIBTASN1_ERROR_ENTRY(ASN1_FILE_NOT_FOUND), + LIBTASN1_ERROR_ENTRY(ASN1_ELEMENT_NOT_FOUND), + LIBTASN1_ERROR_ENTRY(ASN1_IDENTIFIER_NOT_FOUND), + LIBTASN1_ERROR_ENTRY(ASN1_DER_ERROR), + LIBTASN1_ERROR_ENTRY(ASN1_VALUE_NOT_FOUND), + LIBTASN1_ERROR_ENTRY(ASN1_GENERIC_ERROR), + LIBTASN1_ERROR_ENTRY(ASN1_VALUE_NOT_VALID), + LIBTASN1_ERROR_ENTRY(ASN1_TAG_ERROR), + LIBTASN1_ERROR_ENTRY(ASN1_TAG_IMPLICIT), + LIBTASN1_ERROR_ENTRY(ASN1_ERROR_TYPE_ANY), + LIBTASN1_ERROR_ENTRY(ASN1_SYNTAX_ERROR), + LIBTASN1_ERROR_ENTRY(ASN1_MEM_ERROR), + LIBTASN1_ERROR_ENTRY(ASN1_MEM_ALLOC_ERROR), + LIBTASN1_ERROR_ENTRY(ASN1_DER_OVERFLOW), + LIBTASN1_ERROR_ENTRY(ASN1_NAME_TOO_LONG), + LIBTASN1_ERROR_ENTRY(ASN1_ARRAY_ERROR), + LIBTASN1_ERROR_ENTRY(ASN1_ELEMENT_NOT_EMPTY), + {0, 0} }; /** @@ -67,11 +66,10 @@ static const libtasn1_error_entry error_algorithms[] = { * * Since: 1.6 **/ -void -asn1_perror (int error) +void asn1_perror(int error) { - const char *str = asn1_strerror (error); - fprintf (stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)"); + const char *str = asn1_strerror(error); + fprintf(stderr, "LIBTASN1 ERROR: %s\n", str ? str : "(null)"); } /** @@ -89,14 +87,13 @@ asn1_perror (int error) * * Since: 1.6 **/ -const char * -asn1_strerror (int error) +const char *asn1_strerror(int error) { - const libtasn1_error_entry *p; + const libtasn1_error_entry *p; - for (p = error_algorithms; p->name != NULL; p++) - if (p->number == error) - return p->name + sizeof ("ASN1_") - 1; + for (p = error_algorithms; p->name != NULL; p++) + if (p->number == error) + return p->name + sizeof("ASN1_") - 1; - return NULL; + return NULL; } diff --git a/lib/minitasn1/gstr.c b/lib/minitasn1/gstr.c index 0558c77771..f10dd2ac3d 100644 --- a/lib/minitasn1/gstr.c +++ b/lib/minitasn1/gstr.c @@ -28,46 +28,38 @@ * * They should be used only with null terminated strings. */ -void -_asn1_str_cat (char *dest, size_t dest_tot_size, const char *src) +void _asn1_str_cat(char *dest, size_t dest_tot_size, const char *src) { - size_t str_size = strlen (src); - size_t dest_size = strlen (dest); + size_t str_size = strlen(src); + size_t dest_size = strlen(dest); - if (dest_tot_size - dest_size > str_size) - { - strcat (dest, src); - } - else - { - if (dest_tot_size - dest_size > 0) - { - strncat (dest, src, (dest_tot_size - dest_size) - 1); - dest[dest_tot_size - 1] = 0; + if (dest_tot_size - dest_size > str_size) { + strcat(dest, src); + } else { + if (dest_tot_size - dest_size > 0) { + strncat(dest, src, + (dest_tot_size - dest_size) - 1); + dest[dest_tot_size - 1] = 0; + } } - } } /* Returns the bytes copied (not including the null terminator) */ unsigned int -_asn1_str_cpy (char *dest, size_t dest_tot_size, const char *src) +_asn1_str_cpy(char *dest, size_t dest_tot_size, const char *src) { - size_t str_size = strlen (src); + size_t str_size = strlen(src); - if (dest_tot_size > str_size) - { - strcpy (dest, src); - return str_size; - } - else - { - if (dest_tot_size > 0) - { - str_size = dest_tot_size - 1; - memcpy (dest, src, str_size); - dest[str_size] = 0; - return str_size; + if (dest_tot_size > str_size) { + strcpy(dest, src); + return str_size; + } else { + if (dest_tot_size > 0) { + str_size = dest_tot_size - 1; + memcpy(dest, src, str_size); + dest[str_size] = 0; + return str_size; + } else + return 0; } - else return 0; - } } diff --git a/lib/minitasn1/gstr.h b/lib/minitasn1/gstr.h index 672d59eb59..9b7176a4a1 100644 --- a/lib/minitasn1/gstr.h +++ b/lib/minitasn1/gstr.h @@ -19,8 +19,9 @@ * 02110-1301, USA */ -unsigned int _asn1_str_cpy (char *dest, size_t dest_tot_size, const char *src); -void _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src); +unsigned int _asn1_str_cpy(char *dest, size_t dest_tot_size, + const char *src); +void _asn1_str_cat(char *dest, size_t dest_tot_size, const char *src); #define Estrcpy(x,y) _asn1_str_cpy(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) #define Estrcat(x,y) _asn1_str_cat(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) diff --git a/lib/minitasn1/int.h b/lib/minitasn1/int.h index 3163d50d14..d422a79c6b 100644 --- a/lib/minitasn1/int.h +++ b/lib/minitasn1/int.h @@ -43,25 +43,24 @@ /* This structure is also in libtasn1.h, but then contains less fields. You cannot make any modifications to these first fields without breaking ABI. */ -struct asn1_node_st -{ - /* public fields: */ - char name[ASN1_MAX_NAME_SIZE+1]; /* Node name */ - unsigned int name_hash; - unsigned int type; /* Node type */ - unsigned char *value; /* Node value */ - int value_len; - asn1_node down; /* Pointer to the son node */ - asn1_node right; /* Pointer to the brother node */ - asn1_node left; /* Pointer to the next list element */ - /* private fields: */ - unsigned char small_value[ASN1_SMALL_VALUE_SIZE]; /* For small values */ +struct asn1_node_st { + /* public fields: */ + char name[ASN1_MAX_NAME_SIZE + 1]; /* Node name */ + unsigned int name_hash; + unsigned int type; /* Node type */ + unsigned char *value; /* Node value */ + int value_len; + asn1_node down; /* Pointer to the son node */ + asn1_node right; /* Pointer to the brother node */ + asn1_node left; /* Pointer to the next list element */ + /* private fields: */ + unsigned char small_value[ASN1_SMALL_VALUE_SIZE]; /* For small values */ }; typedef struct tag_and_class_st { - unsigned tag; - unsigned class; - const char* desc; + unsigned tag; + unsigned class; + const char *desc; } tag_and_class_st; /* the types that are handled in _asn1_tags */ @@ -158,28 +157,26 @@ extern const tag_and_class_st _asn1_tags[]; /****************************************/ inline static unsigned int type_field(unsigned int ntype) { - return (ntype & 0xff); + 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; + 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 */ +#endif /* INT_H */ diff --git a/lib/minitasn1/libtasn1.h b/lib/minitasn1/libtasn1.h index 06474f3f33..37fd376c68 100644 --- a/lib/minitasn1/libtasn1.h +++ b/lib/minitasn1/libtasn1.h @@ -21,33 +21,32 @@ */ #ifndef LIBTASN1_H -# define LIBTASN1_H - -# ifndef ASN1_API -# if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY -# define ASN1_API __attribute__((__visibility__("default"))) -# elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC -# define ASN1_API __declspec(dllexport) -# elif defined _MSC_VER && ! defined ASN1_STATIC -# define ASN1_API __declspec(dllimport) -# else -# define ASN1_API -# endif -# endif +#define LIBTASN1_H + +#ifndef ASN1_API +#if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY +#define ASN1_API __attribute__((__visibility__("default"))) +#elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC +#define ASN1_API __declspec(dllexport) +#elif defined _MSC_VER && ! defined ASN1_STATIC +#define ASN1_API __declspec(dllimport) +#else +#define ASN1_API +#endif +#endif #include <stdio.h> /* for FILE* */ #include <sys/types.h> #include <time.h> #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif #define ASN1_VERSION "3.1" /*****************************************/ - /* Errors returned by libtasn1 functions */ + /* Errors returned by libtasn1 functions */ /*****************************************/ #define ASN1_SUCCESS 0 #define ASN1_FILE_NOT_FOUND 1 @@ -69,7 +68,7 @@ extern "C" #define ASN1_ELEMENT_NOT_EMPTY 17 /*************************************/ - /* Constants used in asn1_visit_tree */ + /* Constants used in asn1_visit_tree */ /*************************************/ #define ASN1_PRINT_NAME 1 #define ASN1_PRINT_NAME_TYPE 2 @@ -77,7 +76,7 @@ extern "C" #define ASN1_PRINT_ALL 4 /*****************************************/ - /* Constants returned by asn1_read_tag */ + /* Constants returned by asn1_read_tag */ /*****************************************/ #define ASN1_CLASS_UNIVERSAL 0x00 /* old: 1 */ #define ASN1_CLASS_APPLICATION 0x40 /* old: 2 */ @@ -86,7 +85,7 @@ extern "C" #define ASN1_CLASS_STRUCTURED 0x20 /*****************************************/ - /* Constants returned by asn1_read_tag */ + /* Constants returned by asn1_read_tag */ /*****************************************/ #define ASN1_TAG_BOOLEAN 0x01 #define ASN1_TAG_INTEGER 0x02 @@ -110,29 +109,28 @@ extern "C" #define ASN1_TAG_VISIBLE_STRING 0x1A /******************************************************/ - /* Structure definition used for the node of the tree */ - /* that represent an ASN.1 DEFINITION. */ + /* Structure definition used for the node of the tree */ + /* that represent an ASN.1 DEFINITION. */ /******************************************************/ - typedef struct asn1_node_st asn1_node_st; + typedef struct asn1_node_st asn1_node_st; - typedef asn1_node_st *asn1_node; + typedef asn1_node_st *asn1_node; - /* maximum number of characters of a name */ - /* inside a file with ASN1 definitons */ + /* maximum number of characters of a name */ + /* inside a file with ASN1 definitons */ #define ASN1_MAX_NAME_SIZE 64 /*****************************************/ - /* For the on-disk format of ASN.1 trees */ + /* For the on-disk format of ASN.1 trees */ /*****************************************/ - struct asn1_static_node_st - { - const char *name; /* Node name */ - unsigned int type; /* Node type */ - const void *value; /* Node value */ - }; - typedef struct asn1_static_node_st asn1_static_node; + struct asn1_static_node_st { + const char *name; /* Node name */ + unsigned int type; /* Node type */ + const void *value; /* Node value */ + }; + typedef struct asn1_static_node_st asn1_static_node; /* List of constants for field type of node_asn */ #define ASN1_ETYPE_INVALID 0 @@ -168,171 +166,185 @@ extern "C" #define ASN1_ETYPE_UTC_TIME 36 #define ASN1_ETYPE_GENERALIZED_TIME 37 - struct asn1_data_node_st - { - const char *name; /* Node name */ - const void *value; /* Node value */ - unsigned int value_len; /* Node value size */ - unsigned int type; /* Node value type (ASN1_ETYPE_*) */ - }; - typedef struct asn1_data_node_st asn1_data_node_st; + struct asn1_data_node_st { + const char *name; /* Node name */ + const void *value; /* Node value */ + unsigned int value_len; /* Node value size */ + unsigned int type; /* Node value type (ASN1_ETYPE_*) */ + }; + typedef struct asn1_data_node_st asn1_data_node_st; /***********************************/ - /* Fixed constants */ + /* Fixed constants */ /***********************************/ - /* maximum number of characters */ - /* of a description message */ - /* (null character included) */ + /* maximum number of characters */ + /* of a description message */ + /* (null character included) */ #define ASN1_MAX_ERROR_DESCRIPTION_SIZE 128 /***********************************/ - /* Functions definitions */ + /* Functions definitions */ /***********************************/ - extern ASN1_API int - asn1_parser2tree (const char *file_name, - asn1_node * definitions, char *errorDescription); + extern ASN1_API int + asn1_parser2tree(const char *file_name, + asn1_node * definitions, char *errorDescription); - extern ASN1_API int - asn1_parser2array (const char *inputFileName, - const char *outputFileName, - const char *vectorName, char *errorDescription); + extern ASN1_API int + asn1_parser2array(const char *inputFileName, + const char *outputFileName, + const char *vectorName, char *errorDescription); - extern ASN1_API int - asn1_array2tree (const asn1_static_node * array, - asn1_node * definitions, char *errorDescription); + extern ASN1_API int + asn1_array2tree(const asn1_static_node * array, + asn1_node * definitions, char *errorDescription); - extern ASN1_API void - asn1_print_structure (FILE * out, asn1_node structure, - const char *name, int mode); + extern ASN1_API void + asn1_print_structure(FILE * out, asn1_node structure, + const char *name, int mode); - extern ASN1_API int - asn1_create_element (asn1_node definitions, - const char *source_name, asn1_node * element); + extern ASN1_API int + asn1_create_element(asn1_node definitions, + const char *source_name, asn1_node * element); - extern ASN1_API int asn1_delete_structure (asn1_node * structure); + extern ASN1_API int asn1_delete_structure(asn1_node * structure); - extern ASN1_API int - asn1_delete_element (asn1_node structure, const char *element_name); + extern ASN1_API int + asn1_delete_element(asn1_node structure, + const char *element_name); - extern ASN1_API int - asn1_write_value (asn1_node node_root, const char *name, - const void *ivalue, int len); + extern ASN1_API int + asn1_write_value(asn1_node node_root, const char *name, + const void *ivalue, int len); - extern ASN1_API int - asn1_read_value (asn1_node root, const char *name, - void *ivalue, int *len); + extern ASN1_API int + asn1_read_value(asn1_node root, const char *name, + void *ivalue, int *len); - extern ASN1_API int - asn1_read_value_type (asn1_node root, const char *name, - void *ivalue, int *len, unsigned int* etype); + extern ASN1_API int + asn1_read_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 + asn1_read_node_value(asn1_node node, asn1_data_node_st * data); - extern ASN1_API int - asn1_number_of_elements (asn1_node element, const char *name, int *num); + extern ASN1_API int + asn1_number_of_elements(asn1_node element, const char *name, + int *num); - extern ASN1_API int - asn1_der_coding (asn1_node element, const char *name, - void *ider, int *len, char *ErrorDescription); + extern ASN1_API int + asn1_der_coding(asn1_node element, const char *name, + void *ider, int *len, char *ErrorDescription); - extern ASN1_API int - asn1_der_decoding (asn1_node * element, const void *ider, - int len, char *errorDescription); + extern ASN1_API int + asn1_der_decoding(asn1_node * element, const void *ider, + int len, char *errorDescription); - extern ASN1_API int - asn1_der_decoding_element (asn1_node * structure, - const char *elementName, - const void *ider, int len, - char *errorDescription); + extern ASN1_API int + asn1_der_decoding_element(asn1_node * structure, + const char *elementName, + const void *ider, int len, + char *errorDescription); - extern ASN1_API int - asn1_der_decoding_startEnd (asn1_node element, - const void *ider, int len, - const char *name_element, - int *start, int *end); + extern ASN1_API int + asn1_der_decoding_startEnd(asn1_node element, + const void *ider, int len, + const char *name_element, + int *start, int *end); - extern ASN1_API int - asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element); + extern ASN1_API int + asn1_expand_any_defined_by(asn1_node definitions, + asn1_node * element); - extern ASN1_API int - asn1_expand_octet_string (asn1_node definitions, - asn1_node * element, - const char *octetName, const char *objectName); + extern ASN1_API int + asn1_expand_octet_string(asn1_node definitions, + asn1_node * element, + const char *octetName, + const char *objectName); - extern ASN1_API int - asn1_read_tag (asn1_node root, const char *name, - int *tagValue, int *classValue); + extern ASN1_API int + asn1_read_tag(asn1_node root, const char *name, + int *tagValue, int *classValue); - extern ASN1_API const char *asn1_find_structure_from_oid (asn1_node - definitions, - const char - *oidValue); + extern ASN1_API const char *asn1_find_structure_from_oid(asn1_node + definitions, + const char + *oidValue); - extern ASN1_API const char *asn1_check_version (const char *req_version); + extern ASN1_API const char *asn1_check_version(const char + *req_version); - extern ASN1_API const char *asn1_strerror (int error); + extern ASN1_API const char *asn1_strerror(int error); - extern ASN1_API void asn1_perror (int error); + extern ASN1_API void asn1_perror(int error); #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_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 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); + extern ASN1_API void + asn1_length_der(unsigned long int len, unsigned char *ans, + int *ans_len); - /* Other utility functions. */ + /* 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_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 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 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); + 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. */ + /* Internal and low-level DER utility functions. */ - extern ASN1_API int - asn1_get_tag_der (const unsigned char *der, int der_len, - unsigned char *cls, int *len, unsigned long *tag); + extern ASN1_API int + asn1_get_tag_der(const unsigned char *der, int der_len, + unsigned char *cls, int *len, + unsigned long *tag); - extern ASN1_API void - asn1_octet_der (const unsigned char *str, int str_len, - unsigned char *der, int *der_len); + extern ASN1_API void + asn1_octet_der(const unsigned char *str, int str_len, + unsigned char *der, int *der_len); - extern ASN1_API int - asn1_get_octet_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, - int str_size, int *str_len); + extern ASN1_API int + asn1_get_octet_der(const unsigned char *der, int der_len, + int *ret_len, unsigned char *str, + int str_size, int *str_len); - extern ASN1_API void asn1_bit_der (const unsigned char *str, int bit_len, - unsigned char *der, int *der_len); + extern ASN1_API void asn1_bit_der(const unsigned char *str, + int bit_len, unsigned char *der, + int *der_len); - extern ASN1_API int - asn1_get_bit_der (const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, - int str_size, int *bit_len); + extern ASN1_API int + asn1_get_bit_der(const unsigned char *der, int der_len, + int *ret_len, unsigned char *str, + int str_size, int *bit_len); /* Compatibility types */ -typedef int asn1_retCode; /* type returned by libtasn1 functions */ + typedef int asn1_retCode; /* type returned by libtasn1 functions */ #define node_asn_struct asn1_node_st #define node_asn asn1_node_st @@ -349,5 +361,4 @@ typedef int asn1_retCode; /* type returned by libtasn1 functions */ #ifdef __cplusplus } #endif - #endif /* LIBTASN1_H */ diff --git a/lib/minitasn1/parser_aux.c b/lib/minitasn1/parser_aux.c index 50238d2c92..3413dab6f7 100644 --- a/lib/minitasn1/parser_aux.c +++ b/lib/minitasn1/parser_aux.c @@ -33,10 +33,9 @@ char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not fou /* Description: type used in the list during */ /* the structure creation. */ /***********************************************/ -typedef struct list_struct -{ - asn1_node node; - struct list_struct *next; +typedef struct list_struct { + asn1_node node; + struct list_struct *next; } list_type; @@ -52,30 +51,28 @@ list_type *firstElement = NULL; /* and CONST_ constants). */ /* Return: pointer to the new element. */ /******************************************************/ -asn1_node -_asn1_add_static_node (unsigned int type) +asn1_node _asn1_add_static_node(unsigned int type) { - list_type *listElement; - asn1_node punt; + list_type *listElement; + asn1_node punt; - punt = calloc (1, sizeof (struct asn1_node_st)); - if (punt == NULL) - return NULL; + punt = calloc(1, sizeof(struct asn1_node_st)); + if (punt == NULL) + return NULL; - listElement = malloc (sizeof (list_type)); - if (listElement == NULL) - { - free (punt); - return NULL; - } + listElement = malloc(sizeof(list_type)); + if (listElement == NULL) { + free(punt); + return NULL; + } - listElement->node = punt; - listElement->next = firstElement; - firstElement = listElement; + listElement->node = punt; + listElement->next = firstElement; + firstElement = listElement; - punt->type = type; + punt->type = type; - return punt; + return punt; } /** @@ -90,111 +87,97 @@ _asn1_add_static_node (unsigned int type) * * Returns: the search result, or %NULL if not found. **/ -asn1_node -asn1_find_node (asn1_node pointer, const char *name) +asn1_node asn1_find_node(asn1_node pointer, const char *name) { - asn1_node p; - char *n_end, n[ASN1_MAX_NAME_SIZE + 1]; - const char *n_start; - unsigned int nsize; - unsigned int nhash; - - if (pointer == NULL) - return NULL; - - if (name == NULL) - return NULL; - - p = pointer; - n_start = name; - - if (p->name[0] != 0) - { /* has *pointer got a name ? */ - n_end = strchr (n_start, '.'); /* search the first dot */ - if (n_end) - { - nsize = n_end - n_start; - memcpy (n, n_start, nsize); - n[nsize] = 0; - n_start = n_end; - n_start++; - - nhash = hash_pjw_bare(n, nsize); - } - else - { - nsize = _asn1_str_cpy (n, sizeof (n), n_start); - nhash = hash_pjw_bare(n, nsize); + asn1_node p; + char *n_end, n[ASN1_MAX_NAME_SIZE + 1]; + const char *n_start; + unsigned int nsize; + unsigned int nhash; + + if (pointer == NULL) + return NULL; + + if (name == NULL) + return NULL; + + p = pointer; + n_start = name; + + if (p->name[0] != 0) { /* has *pointer got a name ? */ + n_end = strchr(n_start, '.'); /* search the first dot */ + if (n_end) { + nsize = n_end - n_start; + memcpy(n, n_start, nsize); + n[nsize] = 0; + n_start = n_end; + n_start++; + + nhash = hash_pjw_bare(n, nsize); + } else { + nsize = _asn1_str_cpy(n, sizeof(n), n_start); + nhash = hash_pjw_bare(n, nsize); + + n_start = NULL; + } - n_start = NULL; + while (p) { + if ((p->name) && nhash == p->name_hash + && (!strcmp(p->name, n))) + break; + else + p = p->right; + } /* while */ + + if (p == NULL) + return NULL; + } else { /* *pointer doesn't have a name */ + if (n_start[0] == 0) + return p; } - while (p) - { - if ((p->name) && nhash == p->name_hash && (!strcmp (p->name, n))) - break; - else - p = p->right; + while (n_start) { /* Has the end of NAME been reached? */ + n_end = strchr(n_start, '.'); /* search the next dot */ + if (n_end) { + nsize = n_end - n_start; + memcpy(n, n_start, nsize); + n[nsize] = 0; + n_start = n_end; + n_start++; + + nhash = hash_pjw_bare(n, nsize); + } else { + nsize = _asn1_str_cpy(n, sizeof(n), n_start); + nhash = hash_pjw_bare(n, nsize); + n_start = NULL; + } + + if (p->down == NULL) + return NULL; + + p = p->down; + + /* The identifier "?LAST" indicates the last element + in the right chain. */ + if (!strcmp(n, "?LAST")) { + if (p == NULL) + return NULL; + while (p->right) + p = p->right; + } else { /* no "?LAST" */ + while (p) { + if (p->name_hash == nhash + && !strcmp(p->name, n)) + break; + else + p = p->right; + } + if (p == NULL) + return NULL; + } } /* while */ - if (p == NULL) - return NULL; - } - else - { /* *pointer doesn't have a name */ - if (n_start[0] == 0) return p; - } - - while (n_start) - { /* Has the end of NAME been reached? */ - n_end = strchr (n_start, '.'); /* search the next dot */ - if (n_end) - { - nsize = n_end - n_start; - memcpy (n, n_start, nsize); - n[nsize] = 0; - n_start = n_end; - n_start++; - - nhash = hash_pjw_bare(n, nsize); - } - else - { - nsize = _asn1_str_cpy (n, sizeof (n), n_start); - nhash = hash_pjw_bare(n, nsize); - n_start = NULL; - } - - if (p->down == NULL) - return NULL; - - p = p->down; - - /* The identifier "?LAST" indicates the last element - in the right chain. */ - if (!strcmp (n, "?LAST")) - { - if (p == NULL) - return NULL; - while (p->right) - p = p->right; - } - else - { /* no "?LAST" */ - while (p) - { - if (p->name_hash == nhash && !strcmp (p->name, n)) - break; - else - p = p->right; - } - if (p == NULL) - return NULL; - } - } /* while */ - - return p; } @@ -209,35 +192,31 @@ asn1_find_node (asn1_node pointer, const char *name) /* Return: pointer to the NODE_ASN element. */ /******************************************************************/ asn1_node -_asn1_set_value (asn1_node node, const void *value, unsigned int len) +_asn1_set_value(asn1_node node, const void *value, unsigned int len) { - if (node == NULL) - return node; - if (node->value) - { - if (node->value != node->small_value) - free (node->value); - node->value = NULL; - node->value_len = 0; - } - - if (!len) - return node; - - if (len < sizeof (node->small_value)) - { - node->value = node->small_value; - } - else - { - node->value = malloc (len); - if (node->value == NULL) - return NULL; - } - node->value_len = len; - - memcpy (node->value, value, len); - return node; + if (node == NULL) + return node; + if (node->value) { + if (node->value != node->small_value) + free(node->value); + node->value = NULL; + node->value_len = 0; + } + + if (!len) + return node; + + if (len < sizeof(node->small_value)) { + node->value = node->small_value; + } else { + node->value = malloc(len); + if (node->value == NULL) + return NULL; + } + node->value_len = len; + + memcpy(node->value, value, len); + return node; } /******************************************************************/ @@ -252,47 +231,45 @@ _asn1_set_value (asn1_node node, const void *value, unsigned int len) /* Return: pointer to the NODE_ASN element. */ /******************************************************************/ asn1_node -_asn1_set_value_lv (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; + int len2; + void *temp; - if (node == NULL) - return node; + if (node == NULL) + return node; - asn1_length_der (len, NULL, &len2); - temp = malloc (len + len2); - if (temp == NULL) - return NULL; + asn1_length_der(len, NULL, &len2); + temp = malloc(len + len2); + if (temp == NULL) + return NULL; - asn1_octet_der (value, len, temp, &len2); - return _asn1_set_value_m (node, temp, len2); + asn1_octet_der(value, len, temp, &len2); + return _asn1_set_value_m(node, temp, len2); } /* the same as _asn1_set_value except that it sets an already malloc'ed * value. */ -asn1_node -_asn1_set_value_m (asn1_node node, void *value, unsigned int len) +asn1_node _asn1_set_value_m(asn1_node node, void *value, unsigned int len) { - if (node == NULL) - return node; - - if (node->value) - { - if (node->value != node->small_value) - free (node->value); - node->value = NULL; - node->value_len = 0; - } + if (node == NULL) + return node; + + if (node->value) { + if (node->value != node->small_value) + free(node->value); + node->value = NULL; + node->value_len = 0; + } - if (!len) - return node; + if (!len) + return node; - node->value = value; - node->value_len = len; + node->value = value; + node->value_len = len; - return node; + return node; } /******************************************************************/ @@ -306,43 +283,37 @@ _asn1_set_value_m (asn1_node node, void *value, unsigned int len) /* Return: pointer to the NODE_ASN element. */ /******************************************************************/ asn1_node -_asn1_append_value (asn1_node node, const void *value, unsigned int len) +_asn1_append_value(asn1_node node, const void *value, unsigned int len) { - if (node == NULL) - return node; - if (node->value != NULL && node->value != node->small_value) - { - /* value is allocated */ - int prev_len = node->value_len; - node->value_len += len; - node->value = realloc (node->value, node->value_len); - if (node->value == NULL) - { - node->value_len = 0; - return NULL; - } - memcpy (&node->value[prev_len], value, len); - - return node; - } - else if (node->value == node->small_value) - { - /* value is in node */ - int prev_len = node->value_len; - node->value_len += len; - node->value = malloc (node->value_len); - if (node->value == NULL) - { - node->value_len = 0; - return NULL; - } - memcpy (node->value, node->small_value, prev_len); - memcpy (&node->value[prev_len], value, len); + if (node == NULL) + return node; + if (node->value != NULL && node->value != node->small_value) { + /* value is allocated */ + int prev_len = node->value_len; + node->value_len += len; + node->value = realloc(node->value, node->value_len); + if (node->value == NULL) { + node->value_len = 0; + return NULL; + } + memcpy(&node->value[prev_len], value, len); + + return node; + } else if (node->value == node->small_value) { + /* value is in node */ + int prev_len = node->value_len; + node->value_len += len; + node->value = malloc(node->value_len); + if (node->value == NULL) { + node->value_len = 0; + return NULL; + } + memcpy(node->value, node->small_value, prev_len); + memcpy(&node->value[prev_len], value, len); - return node; - } - else /* node->value == NULL */ - return _asn1_set_value (node, value, len); + return node; + } else /* node->value == NULL */ + return _asn1_set_value(node, value, len); } /******************************************************************/ @@ -355,25 +326,23 @@ _asn1_append_value (asn1_node node, const void *value, unsigned int len) /* to set. */ /* Return: pointer to the NODE_ASN element. */ /******************************************************************/ -asn1_node -_asn1_set_name (asn1_node node, const char *name) +asn1_node _asn1_set_name(asn1_node node, const char *name) { -unsigned int nsize; + unsigned int nsize; - if (node == NULL) - return node; + if (node == NULL) + return node; - if (name == NULL) - { - node->name[0] = 0; - node->name_hash = hash_pjw_bare(node->name, 0); - return node; - } + if (name == NULL) { + node->name[0] = 0; + node->name_hash = hash_pjw_bare(node->name, 0); + return node; + } - nsize = _asn1_str_cpy (node->name, sizeof (node->name), name); - node->name_hash = hash_pjw_bare(node->name, nsize); + nsize = _asn1_str_cpy(node->name, sizeof(node->name), name); + node->name_hash = hash_pjw_bare(node->name, nsize); - return node; + return node; } /******************************************************************/ @@ -384,23 +353,21 @@ unsigned int nsize; /* src: a source element pointer. */ /* Return: pointer to the NODE_ASN element. */ /******************************************************************/ -asn1_node -_asn1_cpy_name (asn1_node dst, asn1_node src) +asn1_node _asn1_cpy_name(asn1_node dst, asn1_node src) { - if (dst == NULL) - return dst; + if (dst == NULL) + return dst; - if (src == NULL) - { - dst->name[0] = 0; - dst->name_hash = hash_pjw_bare(dst->name, 0); - return dst; - } + if (src == NULL) { + dst->name[0] = 0; + dst->name_hash = hash_pjw_bare(dst->name, 0); + return dst; + } - _asn1_str_cpy (dst->name, sizeof (dst->name), src->name); - dst->name_hash = src->name_hash; + _asn1_str_cpy(dst->name, sizeof(dst->name), src->name); + dst->name_hash = src->name_hash; - return dst; + return dst; } /******************************************************************/ @@ -412,15 +379,14 @@ _asn1_cpy_name (asn1_node dst, asn1_node src) /* by NODE. */ /* Return: pointer to *NODE. */ /******************************************************************/ -asn1_node -_asn1_set_right (asn1_node node, asn1_node right) +asn1_node _asn1_set_right(asn1_node node, asn1_node right) { - if (node == NULL) - return node; - node->right = right; - if (right) - right->left = node; - return node; + if (node == NULL) + return node; + node->right = right; + if (right) + right->left = node; + return node; } @@ -431,17 +397,16 @@ _asn1_set_right (asn1_node node, asn1_node right) /* node: starting element pointer. */ /* Return: pointer to the last element along the right chain. */ /******************************************************************/ -asn1_node -_asn1_get_last_right (asn1_node node) +asn1_node _asn1_get_last_right(asn1_node node) { - asn1_node p; - - if (node == NULL) - return NULL; - p = node; - while (p->right) - p = p->right; - return p; + asn1_node p; + + if (node == NULL) + return NULL; + p = node; + while (p->right) + p = p->right; + return p; } /******************************************************************/ @@ -451,15 +416,14 @@ _asn1_get_last_right (asn1_node node) /* Parameters: */ /* node: NODE_ASN element pointer. */ /******************************************************************/ -void -_asn1_remove_node (asn1_node node) +void _asn1_remove_node(asn1_node node) { - if (node == NULL) - return; + if (node == NULL) + return; - if (node->value != NULL && node->value != node->small_value) - free (node->value); - free (node); + if (node->value != NULL && node->value != node->small_value) + free(node->value); + free(node); } /******************************************************************/ @@ -469,20 +433,19 @@ _asn1_remove_node (asn1_node node) /* node: NODE_ASN element pointer. */ /* Return: Null if not found. */ /******************************************************************/ -asn1_node -_asn1_find_up (asn1_node node) +asn1_node _asn1_find_up(asn1_node node) { - asn1_node p; + asn1_node p; - if (node == NULL) - return NULL; + if (node == NULL) + return NULL; - p = node; + p = node; - while ((p->left != NULL) && (p->left->right == p)) - p = p->left; + while ((p->left != NULL) && (p->left->right == p)) + p = p->left; - return p->left; + return p->left; } /******************************************************************/ @@ -490,17 +453,15 @@ _asn1_find_up (asn1_node node) /* Description: deletes the list elements (not the elements */ /* pointed by them). */ /******************************************************************/ -void -_asn1_delete_list (void) +void _asn1_delete_list(void) { - list_type *listElement; - - while (firstElement) - { - listElement = firstElement; - firstElement = firstElement->next; - free (listElement); - } + list_type *listElement; + + while (firstElement) { + listElement = firstElement; + firstElement = firstElement->next; + free(listElement); + } } /******************************************************************/ @@ -508,52 +469,46 @@ _asn1_delete_list (void) /* Description: deletes the list elements and the elements */ /* pointed by them. */ /******************************************************************/ -void -_asn1_delete_list_and_nodes (void) +void _asn1_delete_list_and_nodes(void) { - list_type *listElement; - - while (firstElement) - { - listElement = firstElement; - firstElement = firstElement->next; - _asn1_remove_node (listElement->node); - free (listElement); - } + list_type *listElement; + + while (firstElement) { + listElement = firstElement; + firstElement = firstElement->next; + _asn1_remove_node(listElement->node); + free(listElement); + } } -char * -_asn1_ltostr (long v, char *str) +char *_asn1_ltostr(long v, char *str) { - long d, r; - char temp[20]; - int count, k, start; - - if (v < 0) - { - str[0] = '-'; - start = 1; - v = -v; - } - else - start = 0; - - count = 0; - do - { - d = v / 10; - r = v - d * 10; - temp[start + count] = '0' + (char) r; - count++; - v = d; - } - while (v); - - for (k = 0; k < count; k++) - str[k + start] = temp[start + count - k - 1]; - str[count + start] = 0; - return str; + long d, r; + char temp[20]; + int count, k, start; + + if (v < 0) { + str[0] = '-'; + start = 1; + v = -v; + } else + start = 0; + + count = 0; + do { + d = v / 10; + r = v - d * 10; + temp[start + count] = '0' + (char) r; + count++; + v = d; + } + while (v); + + for (k = 0; k < count; k++) + str[k + start] = temp[start + count - k - 1]; + str[count + start] = 0; + return str; } @@ -567,61 +522,52 @@ _asn1_ltostr (long v, char *str) /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ /* otherwise ASN1_SUCCESS */ /******************************************************************/ -int -_asn1_change_integer_value (asn1_node node) +int _asn1_change_integer_value(asn1_node node) { - asn1_node p; - unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; - unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1]; - int len; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if ((type_field (p->type) == ASN1_ETYPE_INTEGER) && (p->type & CONST_ASSIGN)) - { - if (p->value) - { - _asn1_convert_integer (p->value, val, sizeof (val), &len); - asn1_octet_der (val, len, val2, &len); - _asn1_set_value (p, val2, len); - } - } + asn1_node p; + unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; + unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1]; + int len; + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + p = node; + while (p) { + if ((type_field(p->type) == ASN1_ETYPE_INTEGER) + && (p->type & CONST_ASSIGN)) { + if (p->value) { + _asn1_convert_integer(p->value, val, + sizeof(val), &len); + asn1_octet_der(val, len, val2, &len); + _asn1_set_value(p, val2, len); + } + } - if (p->down) - { - p = p->down; - } - else - { - if (p == node) - p = NULL; - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; - } - if (p->right) - { - p = p->right; - break; - } + if (p->down) { + p = p->down; + } else { + if (p == node) + p = NULL; + else if (p->right) + p = p->right; + else { + while (1) { + p = _asn1_find_up(p); + if (p == node) { + p = NULL; + break; + } + if (p->right) { + p = p->right; + break; + } + } + } } - } } - } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } @@ -634,176 +580,217 @@ _asn1_change_integer_value (asn1_node node) /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ /* otherwise ASN1_SUCCESS */ /******************************************************************/ -int -_asn1_expand_object_id (asn1_node node) +int _asn1_expand_object_id(asn1_node node) { - asn1_node p, p2, p3, p4, p5; - char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; - int move, tlen; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - _asn1_str_cpy (name_root, sizeof (name_root), node->name); - - p = node; - move = DOWN; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) - && (p->type & CONST_ASSIGN)) - { - p2 = p->down; - if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT)) - { - if (p2->value && !isdigit (p2->value[0])) - { - _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) != ASN1_ETYPE_OBJECT_ID) || - !(p3->type & CONST_ASSIGN)) - return ASN1_ELEMENT_NOT_FOUND; - _asn1_set_down (p, p2->right); - _asn1_remove_node (p2); - p2 = p; - p4 = p3->down; - while (p4) - { - if (type_field (p4->type) == ASN1_ETYPE_CONSTANT) - { - p5 = _asn1_add_single_node (ASN1_ETYPE_CONSTANT); - _asn1_set_name (p5, p4->name); - tlen = _asn1_strlen (p4->value); - if (tlen > 0) - _asn1_set_value (p5, p4->value, tlen + 1); - if (p2 == p) - { - _asn1_set_right (p5, p->down); - _asn1_set_down (p, p5); - } - else - { - _asn1_set_right (p5, p2->right); - _asn1_set_right (p2, p5); + asn1_node p, p2, p3, p4, p5; + char name_root[ASN1_MAX_NAME_SIZE], + name2[2 * ASN1_MAX_NAME_SIZE + 1]; + int move, tlen; + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + _asn1_str_cpy(name_root, sizeof(name_root), node->name); + + p = node; + move = DOWN; + + while (!((p == node) && (move == UP))) { + if (move != UP) { + if ((type_field(p->type) == ASN1_ETYPE_OBJECT_ID) + && (p->type & CONST_ASSIGN)) { + p2 = p->down; + if (p2 + && (type_field(p2->type) == + ASN1_ETYPE_CONSTANT)) { + if (p2->value + && !isdigit(p2->value[0])) { + _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) + != + ASN1_ETYPE_OBJECT_ID) + || !(p3-> + type & + CONST_ASSIGN)) + return + ASN1_ELEMENT_NOT_FOUND; + _asn1_set_down(p, + p2->right); + _asn1_remove_node(p2); + p2 = p; + p4 = p3->down; + while (p4) { + if (type_field + (p4->type) == + ASN1_ETYPE_CONSTANT) + { + p5 = _asn1_add_single_node(ASN1_ETYPE_CONSTANT); + _asn1_set_name + (p5, + p4-> + name); + tlen = + _asn1_strlen + (p4-> + value); + if (tlen > + 0) + _asn1_set_value + (p5, + p4-> + value, + tlen + + + 1); + if (p2 == + p) { + _asn1_set_right + (p5, + p-> + down); + _asn1_set_down + (p, + p5); + } else { + _asn1_set_right + (p5, + p2-> + right); + _asn1_set_right + (p2, + p5); + } + p2 = p5; + } + p4 = p4->right; + } + move = DOWN; + continue; + } } - p2 = p5; - } - p4 = p4->right; } - move = DOWN; - continue; - } + move = DOWN; + } else + move = RIGHT; + + if (move == DOWN) { + if (p->down) + p = p->down; + else + move = RIGHT; } - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - if (p == node) - { - move = UP; - continue; - } + if (p == node) { + move = UP; + continue; + } - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; + if (move == RIGHT) { + if (p->right) + p = p->right; + else + move = UP; + } + if (move == UP) + p = _asn1_find_up(p); } - if (move == UP) - p = _asn1_find_up (p); - } /*******************************/ - /* expand DEFAULT */ + /* expand DEFAULT */ /*******************************/ - p = node; - move = DOWN; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_DEFAULT)) - { - p2 = p->down; - 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) != 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) == ASN1_ETYPE_CONSTANT) - { - if (name2[0]) - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), - (char *) p4->value); + p = node; + move = DOWN; + + while (!((p == node) && (move == UP))) { + if (move != UP) { + if ((type_field(p->type) == ASN1_ETYPE_OBJECT_ID) + && (p->type & CONST_DEFAULT)) { + p2 = p->down; + 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) != + 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) == + ASN1_ETYPE_CONSTANT) { + if (name2[0]) + _asn1_str_cat + (name2, + sizeof + (name2), + "."); + _asn1_str_cat + (name2, + sizeof(name2), + (char *) p4-> + value); + } + p4 = p4->right; + } + tlen = strlen(name2); + if (tlen > 0) + _asn1_set_value(p2, name2, + tlen + 1); + } } - p4 = p4->right; - } - tlen = strlen (name2); - if (tlen > 0) - _asn1_set_value (p2, name2, tlen + 1); + move = DOWN; + } else + move = RIGHT; + + if (move == DOWN) { + if (p->down) + p = p->down; + else + move = RIGHT; } - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - if (p == node) - { - move = UP; - continue; - } + if (p == node) { + move = UP; + continue; + } - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; + if (move == RIGHT) { + if (p->right) + p = p->right; + else + move = UP; + } + if (move == UP) + p = _asn1_find_up(p); } - if (move == UP) - p = _asn1_find_up (p); - } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } @@ -817,63 +804,57 @@ _asn1_expand_object_id (asn1_node node) /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ /* otherwise ASN1_SUCCESS */ /******************************************************************/ -int -_asn1_type_set_config (asn1_node node) +int _asn1_type_set_config(asn1_node node) { - asn1_node p, p2; - int move; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - move = DOWN; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if (type_field (p->type) == ASN1_ETYPE_SET) - { - p2 = p->down; - while (p2) - { - if (type_field (p2->type) != ASN1_ETYPE_TAG) - p2->type |= CONST_SET | CONST_NOT_USED; - p2 = p2->right; + asn1_node p, p2; + int move; + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + p = node; + move = DOWN; + + while (!((p == node) && (move == UP))) { + if (move != UP) { + if (type_field(p->type) == ASN1_ETYPE_SET) { + p2 = p->down; + while (p2) { + if (type_field(p2->type) != + ASN1_ETYPE_TAG) + p2->type |= + CONST_SET | + CONST_NOT_USED; + p2 = p2->right; + } + } + move = DOWN; + } else + move = RIGHT; + + if (move == DOWN) { + if (p->down) + p = p->down; + else + move = RIGHT; } - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - if (p == node) - { - move = UP; - continue; - } + if (p == node) { + move = UP; + continue; + } - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; + if (move == RIGHT) { + if (p->right) + p = p->right; + else + move = UP; + } + if (move == UP) + p = _asn1_find_up(p); } - if (move == UP) - p = _asn1_find_up (p); - } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } @@ -890,99 +871,105 @@ _asn1_type_set_config (asn1_node node) /* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */ /* otherwise ASN1_SUCCESS */ /******************************************************************/ -int -_asn1_check_identifier (asn1_node node) +int _asn1_check_identifier(asn1_node node) { - asn1_node p, p2; - char name2[ASN1_MAX_NAME_SIZE * 2 + 2]; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER) - { - _asn1_str_cpy (name2, sizeof (name2), node->name); - _asn1_str_cat (name2, sizeof (name2), "."); - _asn1_str_cat (name2, sizeof (name2), (char *) p->value); - p2 = asn1_find_node (node, name2); - if (p2 == NULL) - { - if (p->value) - _asn1_strcpy (_asn1_identifierMissing, p->value); - else - _asn1_strcpy (_asn1_identifierMissing, "(null)"); - return ASN1_IDENTIFIER_NOT_FOUND; - } - } - else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_DEFAULT)) - { - p2 = p->down; - 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) != ASN1_ETYPE_OBJECT_ID) || - !(p2->type & CONST_ASSIGN)) - return ASN1_IDENTIFIER_NOT_FOUND; - else - _asn1_identifierMissing[0] = 0; - } - } - else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_ASSIGN)) - { - p2 = p->down; - if (p2 && (type_field (p2->type) == ASN1_ETYPE_CONSTANT)) - { - if (p2->value && !isdigit (p2->value[0])) - { - _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) != ASN1_ETYPE_OBJECT_ID) || - !(p2->type & CONST_ASSIGN)) - return ASN1_IDENTIFIER_NOT_FOUND; - else - _asn1_identifierMissing[0] = 0; + asn1_node p, p2; + char name2[ASN1_MAX_NAME_SIZE * 2 + 2]; + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + p = node; + while (p) { + if (type_field(p->type) == ASN1_ETYPE_IDENTIFIER) { + _asn1_str_cpy(name2, sizeof(name2), node->name); + _asn1_str_cat(name2, sizeof(name2), "."); + _asn1_str_cat(name2, sizeof(name2), + (char *) p->value); + p2 = asn1_find_node(node, name2); + if (p2 == NULL) { + if (p->value) + _asn1_strcpy + (_asn1_identifierMissing, + p->value); + else + _asn1_strcpy + (_asn1_identifierMissing, + "(null)"); + return ASN1_IDENTIFIER_NOT_FOUND; + } + } else if ((type_field(p->type) == ASN1_ETYPE_OBJECT_ID) && + (p->type & CONST_DEFAULT)) { + p2 = p->down; + 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) != + ASN1_ETYPE_OBJECT_ID) + || !(p2->type & CONST_ASSIGN)) + return ASN1_IDENTIFIER_NOT_FOUND; + else + _asn1_identifierMissing[0] = 0; + } + } else if ((type_field(p->type) == ASN1_ETYPE_OBJECT_ID) && + (p->type & CONST_ASSIGN)) { + p2 = p->down; + if (p2 + && (type_field(p2->type) == + ASN1_ETYPE_CONSTANT)) { + if (p2->value && !isdigit(p2->value[0])) { + _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) != + ASN1_ETYPE_OBJECT_ID) + || !(p2->type & CONST_ASSIGN)) + return + ASN1_IDENTIFIER_NOT_FOUND; + else + _asn1_identifierMissing[0] + = 0; + } + } } - } - } - if (p->down) - { - p = p->down; - } - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; - } - if (p->right) - { - p = p->right; - break; + if (p->down) { + p = p->down; + } else if (p->right) + p = p->right; + else { + while (1) { + p = _asn1_find_up(p); + if (p == node) { + p = NULL; + break; + } + if (p->right) { + p = p->right; + break; + } + } } - } } - } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } @@ -997,50 +984,43 @@ _asn1_check_identifier (asn1_node node) /* a DEFINITIONS element, */ /* otherwise ASN1_SUCCESS */ /******************************************************************/ -int -_asn1_set_default_tag (asn1_node node) +int _asn1_set_default_tag(asn1_node node) { - asn1_node p; - - if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS)) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - while (p) - { - if ((type_field (p->type) == ASN1_ETYPE_TAG) && - !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT)) - { - if (node->type & CONST_EXPLICIT) - p->type |= CONST_EXPLICIT; - else - p->type |= CONST_IMPLICIT; - } - - if (p->down) - { - p = p->down; - } - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == node) - { - p = NULL; - break; + asn1_node p; + + if ((node == NULL) + || (type_field(node->type) != ASN1_ETYPE_DEFINITIONS)) + return ASN1_ELEMENT_NOT_FOUND; + + p = node; + while (p) { + if ((type_field(p->type) == ASN1_ETYPE_TAG) && + !(p->type & CONST_EXPLICIT) + && !(p->type & CONST_IMPLICIT)) { + if (node->type & CONST_EXPLICIT) + p->type |= CONST_EXPLICIT; + else + p->type |= CONST_IMPLICIT; } - if (p->right) - { - p = p->right; - break; + + if (p->down) { + p = p->down; + } else if (p->right) + p = p->right; + else { + while (1) { + p = _asn1_find_up(p); + if (p == node) { + p = NULL; + break; + } + if (p->right) { + p = p->right; + break; + } + } } - } } - } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } diff --git a/lib/minitasn1/parser_aux.h b/lib/minitasn1/parser_aux.h index f270b73595..8b5e6c79bc 100644 --- a/lib/minitasn1/parser_aux.h +++ b/lib/minitasn1/parser_aux.h @@ -27,46 +27,46 @@ /***************************************/ /* Functions used by ASN.1 parser */ /***************************************/ -asn1_node _asn1_add_static_node (unsigned int type); +asn1_node _asn1_add_static_node(unsigned int type); asn1_node -_asn1_set_value (asn1_node node, const void *value, unsigned int len); +_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_m(asn1_node node, void *value, unsigned int len); asn1_node -_asn1_set_value_lv (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); +_asn1_append_value(asn1_node node, const void *value, unsigned int len); -asn1_node _asn1_set_name (asn1_node node, const char *name); +asn1_node _asn1_set_name(asn1_node node, const char *name); -asn1_node _asn1_cpy_name (asn1_node dst, asn1_node src); +asn1_node _asn1_cpy_name(asn1_node dst, asn1_node src); -asn1_node _asn1_set_right (asn1_node node, asn1_node right); +asn1_node _asn1_set_right(asn1_node node, asn1_node right); -asn1_node _asn1_get_last_right (asn1_node node); +asn1_node _asn1_get_last_right(asn1_node node); -void _asn1_remove_node (asn1_node node); +void _asn1_remove_node(asn1_node node); -void _asn1_delete_list (void); +void _asn1_delete_list(void); -void _asn1_delete_list_and_nodes (void); +void _asn1_delete_list_and_nodes(void); -char *_asn1_ltostr (long v, char *str); +char *_asn1_ltostr(long v, char *str); -asn1_node _asn1_find_up (asn1_node node); +asn1_node _asn1_find_up(asn1_node node); -int _asn1_change_integer_value (asn1_node node); +int _asn1_change_integer_value(asn1_node node); -int _asn1_expand_object_id (asn1_node node); +int _asn1_expand_object_id(asn1_node node); -int _asn1_type_set_config (asn1_node node); +int _asn1_type_set_config(asn1_node node); -int _asn1_check_identifier (asn1_node node); +int _asn1_check_identifier(asn1_node node); -int _asn1_set_default_tag (asn1_node node); +int _asn1_set_default_tag(asn1_node node); /******************************************************************/ /* Function : _asn1_get_right */ @@ -76,12 +76,11 @@ int _asn1_set_default_tag (asn1_node node); /* node: NODE_ASN element pointer. */ /* Return: field RIGHT of NODE. */ /******************************************************************/ -inline static asn1_node -_asn1_get_right (asn1_node node) +inline static asn1_node _asn1_get_right(asn1_node node) { - if (node == NULL) - return NULL; - return node->right; + if (node == NULL) + return NULL; + return node->right; } /******************************************************************/ @@ -93,15 +92,14 @@ _asn1_get_right (asn1_node node) /* by NODE. */ /* Return: pointer to *NODE. */ /******************************************************************/ -inline static asn1_node -_asn1_set_down (asn1_node node, asn1_node down) +inline static asn1_node _asn1_set_down(asn1_node node, asn1_node down) { - if (node == NULL) - return node; - node->down = down; - if (down) - down->left = node; - return node; + if (node == NULL) + return node; + node->down = down; + if (down) + down->left = node; + return node; } /******************************************************************/ @@ -112,12 +110,11 @@ _asn1_set_down (asn1_node node, asn1_node down) /* node: NODE_ASN element pointer. */ /* Return: field DOWN of NODE. */ /******************************************************************/ -inline static asn1_node -_asn1_get_down (asn1_node node) +inline static asn1_node _asn1_get_down(asn1_node node) { - if (node == NULL) - return NULL; - return node->down; + if (node == NULL) + return NULL; + return node->down; } /******************************************************************/ @@ -127,12 +124,11 @@ _asn1_get_down (asn1_node node) /* node: NODE_ASN element pointer. */ /* Return: a null terminated string. */ /******************************************************************/ -inline static char * -_asn1_get_name (asn1_node node) +inline static char *_asn1_get_name(asn1_node node) { - if (node == NULL) - return NULL; - return node->name; + if (node == NULL) + return NULL; + return node->name; } /******************************************************************/ @@ -146,13 +142,12 @@ _asn1_get_name (asn1_node node) /* value of field TYPE. */ /* Return: NODE pointer. */ /******************************************************************/ -inline static asn1_node -_asn1_mod_type (asn1_node node, unsigned int value) +inline static asn1_node _asn1_mod_type(asn1_node node, unsigned int value) { - if (node == NULL) - return node; - node->type |= value; - return node; + if (node == NULL) + return node; + node->type |= value; + return node; } #endif diff --git a/lib/minitasn1/structure.c b/lib/minitasn1/structure.c index 31a5f654bb..567c5cec67 100644 --- a/lib/minitasn1/structure.c +++ b/lib/minitasn1/structure.c @@ -44,18 +44,17 @@ extern char _asn1_identifierMissing[]; /* and CONST_ constants). */ /* Return: pointer to the new element. */ /******************************************************/ -asn1_node -_asn1_add_single_node (unsigned int type) +asn1_node _asn1_add_single_node(unsigned int type) { - asn1_node punt; + asn1_node punt; - punt = calloc (1, sizeof (struct asn1_node_st)); - if (punt == NULL) - return NULL; + punt = calloc(1, sizeof(struct asn1_node_st)); + if (punt == NULL) + return NULL; - punt->type = type; + punt->type = type; - return punt; + return punt; } @@ -67,93 +66,84 @@ _asn1_add_single_node (unsigned int type) /* node: NODE_ASN element pointer. */ /* Return: NULL if not found. */ /******************************************************************/ -asn1_node -_asn1_find_left (asn1_node node) +asn1_node _asn1_find_left(asn1_node node) { - if ((node == NULL) || (node->left == NULL) || (node->left->down == node)) - return NULL; + if ((node == NULL) || (node->left == NULL) + || (node->left->down == node)) + return NULL; - return node->left; + return node->left; } int -_asn1_create_static_structure (asn1_node pointer, char *output_file_name, - char *vector_name) +_asn1_create_static_structure(asn1_node pointer, char *output_file_name, + char *vector_name) { - FILE *file; - asn1_node p; - unsigned long t; + FILE *file; + asn1_node p; + unsigned long t; - file = fopen (output_file_name, "w"); + file = fopen(output_file_name, "w"); - if (file == NULL) - return ASN1_FILE_NOT_FOUND; + if (file == NULL) + return ASN1_FILE_NOT_FOUND; - fprintf (file, "#if HAVE_CONFIG_H\n"); - fprintf (file, "# include \"config.h\"\n"); - fprintf (file, "#endif\n\n"); + fprintf(file, "#if HAVE_CONFIG_H\n"); + fprintf(file, "# include \"config.h\"\n"); + fprintf(file, "#endif\n\n"); - fprintf (file, "#include <libtasn1.h>\n\n"); + fprintf(file, "#include <libtasn1.h>\n\n"); - fprintf (file, "const asn1_static_node %s[] = {\n", vector_name); + fprintf(file, "const asn1_static_node %s[] = {\n", vector_name); - p = pointer; + p = pointer; - while (p) - { - fprintf (file, " { "); + while (p) { + fprintf(file, " { "); - if (p->name[0] != 0) - fprintf (file, "\"%s\", ", p->name); - else - fprintf (file, "NULL, "); + if (p->name[0] != 0) + fprintf(file, "\"%s\", ", p->name); + else + fprintf(file, "NULL, "); - t = p->type; - if (p->down) - t |= CONST_DOWN; - if (p->right) - t |= CONST_RIGHT; + t = p->type; + if (p->down) + t |= CONST_DOWN; + if (p->right) + t |= CONST_RIGHT; - fprintf (file, "%lu, ", t); + fprintf(file, "%lu, ", t); - if (p->value) - fprintf (file, "\"%s\"},\n", p->value); - else - fprintf (file, "NULL },\n"); - - if (p->down) - { - p = p->down; - } - else if (p->right) - { - p = p->right; - } - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == pointer) - { - p = NULL; - break; - } - if (p->right) - { - p = p->right; - break; + if (p->value) + fprintf(file, "\"%s\"},\n", p->value); + else + fprintf(file, "NULL },\n"); + + if (p->down) { + p = p->down; + } else if (p->right) { + p = p->right; + } else { + while (1) { + p = _asn1_find_up(p); + if (p == pointer) { + p = NULL; + break; + } + if (p->right) { + p = p->right; + break; + } + } } - } } - } - fprintf (file, " { NULL, 0, NULL }\n};\n"); + fprintf(file, " { NULL, 0, NULL }\n};\n"); - fclose (file); + fclose(file); - return ASN1_SUCCESS; + return ASN1_SUCCESS; } @@ -174,104 +164,92 @@ _asn1_create_static_structure (asn1_node pointer, char *output_file_name, * %ASN1_ARRAY_ERROR if the array pointed by @array is wrong. **/ int -asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, - char *errorDescription) +asn1_array2tree(const asn1_static_node * array, asn1_node * definitions, + char *errorDescription) { - asn1_node p, p_last = NULL; - unsigned long k; - int move; - int result; - unsigned int type; - - - if (*definitions != NULL) - return ASN1_ELEMENT_NOT_EMPTY; - - move = UP; - - k = 0; - while (array[k].value || array[k].type || array[k].name) - { - 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) - _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1); - - if (*definitions == NULL) - *definitions = p; - - if (move == DOWN) - _asn1_set_down (p_last, p); - else if (move == RIGHT) - _asn1_set_right (p_last, p); - - p_last = p; - - if (type & CONST_DOWN) - move = DOWN; - else if (type & CONST_RIGHT) - move = RIGHT; - else - { - while (1) - { - if (p_last == *definitions) - break; - - p_last = _asn1_find_up (p_last); - - if (p_last == NULL) - break; - - if (p_last->type & CONST_RIGHT) - { - p_last->type &= ~CONST_RIGHT; - move = RIGHT; - break; + asn1_node p, p_last = NULL; + unsigned long k; + int move; + int result; + unsigned int type; + + + if (*definitions != NULL) + return ASN1_ELEMENT_NOT_EMPTY; + + move = UP; + + k = 0; + while (array[k].value || array[k].type || array[k].name) { + 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) + _asn1_set_value(p, array[k].value, + strlen(array[k].value) + 1); + + if (*definitions == NULL) + *definitions = p; + + if (move == DOWN) + _asn1_set_down(p_last, p); + else if (move == RIGHT) + _asn1_set_right(p_last, p); + + p_last = p; + + if (type & CONST_DOWN) + move = DOWN; + else if (type & CONST_RIGHT) + move = RIGHT; + else { + while (1) { + if (p_last == *definitions) + break; + + p_last = _asn1_find_up(p_last); + + if (p_last == NULL) + break; + + if (p_last->type & CONST_RIGHT) { + p_last->type &= ~CONST_RIGHT; + move = RIGHT; + break; + } + } /* while */ } - } /* while */ - } - k++; - } /* while */ - - if (p_last == *definitions) - { - result = _asn1_check_identifier (*definitions); - if (result == ASN1_SUCCESS) - { - _asn1_change_integer_value (*definitions); - _asn1_expand_object_id (*definitions); + k++; + } /* while */ + + if (p_last == *definitions) { + result = _asn1_check_identifier(*definitions); + if (result == ASN1_SUCCESS) { + _asn1_change_integer_value(*definitions); + _asn1_expand_object_id(*definitions); + } + } else { + result = ASN1_ARRAY_ERROR; } - } - else - { - result = ASN1_ARRAY_ERROR; - } - - if (errorDescription != NULL) - { - if (result == ASN1_IDENTIFIER_NOT_FOUND) - { - Estrcpy (errorDescription, ":: identifier '"); - Estrcat (errorDescription, _asn1_identifierMissing); - Estrcat (errorDescription, "' not found"); + + if (errorDescription != NULL) { + if (result == ASN1_IDENTIFIER_NOT_FOUND) { + Estrcpy(errorDescription, ":: identifier '"); + Estrcat(errorDescription, _asn1_identifierMissing); + Estrcat(errorDescription, "' not found"); + } else + errorDescription[0] = 0; } - else - errorDescription[0] = 0; - } - - if (result != ASN1_SUCCESS) - { - _asn1_delete_list_and_nodes (); - *definitions = NULL; - } - else - _asn1_delete_list (); - - return result; + + if (result != ASN1_SUCCESS) { + _asn1_delete_list_and_nodes(); + *definitions = NULL; + } else + _asn1_delete_list(); + + return result; } /** @@ -284,55 +262,45 @@ asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if * *@structure was NULL. **/ -int -asn1_delete_structure (asn1_node * structure) +int asn1_delete_structure(asn1_node * structure) { - asn1_node p, p2, p3; - - if (*structure == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = *structure; - while (p) - { - if (p->down) - { - p = p->down; - } - else - { /* no down */ - p2 = p->right; - if (p != *structure) - { - p3 = _asn1_find_up (p); - _asn1_set_down (p3, p2); - _asn1_remove_node (p); - p = p3; - } - else - { /* p==root */ - p3 = _asn1_find_left (p); - if (!p3) - { - p3 = _asn1_find_up (p); - if (p3) - _asn1_set_down (p3, p2); - else - { - if (p->right) - p->right->left = NULL; - } + asn1_node p, p2, p3; + + if (*structure == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + p = *structure; + while (p) { + if (p->down) { + p = p->down; + } else { /* no down */ + p2 = p->right; + if (p != *structure) { + p3 = _asn1_find_up(p); + _asn1_set_down(p3, p2); + _asn1_remove_node(p); + p = p3; + } else { /* p==root */ + p3 = _asn1_find_left(p); + if (!p3) { + p3 = _asn1_find_up(p); + if (p3) + _asn1_set_down(p3, p2); + else { + if (p->right) + p->right->left = + NULL; + } + } else + _asn1_set_right(p3, p2); + _asn1_remove_node(p); + p = NULL; + } } - else - _asn1_set_right (p3, p2); - _asn1_remove_node (p); - p = NULL; - } } - } - *structure = NULL; - return ASN1_SUCCESS; + *structure = NULL; + return ASN1_SUCCESS; } @@ -348,291 +316,279 @@ asn1_delete_structure (asn1_node * structure) * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if * the @element_name was not found. **/ -int -asn1_delete_element (asn1_node structure, const char *element_name) +int asn1_delete_element(asn1_node structure, const char *element_name) { - asn1_node p2, p3, source_node; - - source_node = asn1_find_node (structure, element_name); - - if (source_node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p2 = source_node->right; - p3 = _asn1_find_left (source_node); - if (!p3) - { - p3 = _asn1_find_up (source_node); - if (p3) - _asn1_set_down (p3, p2); - else if (source_node->right) - source_node->right->left = NULL; - } - else - _asn1_set_right (p3, p2); - - return asn1_delete_structure (&source_node); + asn1_node p2, p3, source_node; + + source_node = asn1_find_node(structure, element_name); + + if (source_node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + p2 = source_node->right; + p3 = _asn1_find_left(source_node); + if (!p3) { + p3 = _asn1_find_up(source_node); + if (p3) + _asn1_set_down(p3, p2); + else if (source_node->right) + source_node->right->left = NULL; + } else + _asn1_set_right(p3, p2); + + return asn1_delete_structure(&source_node); } -asn1_node -_asn1_copy_structure3 (asn1_node source_node) +asn1_node _asn1_copy_structure3(asn1_node source_node) { - asn1_node dest_node, p_s, p_d, p_d_prev; - int move; - - if (source_node == NULL) - return NULL; - - dest_node = _asn1_add_single_node (source_node->type); - - p_s = source_node; - p_d = dest_node; - - move = DOWN; - - do - { - if (move != UP) - { - if (p_s->name[0] != 0) - _asn1_cpy_name (p_d, p_s); - if (p_s->value) - _asn1_set_value (p_d, p_s->value, p_s->value_len); - if (p_s->down) - { - p_s = p_s->down; - p_d_prev = p_d; - p_d = _asn1_add_single_node (p_s->type); - _asn1_set_down (p_d_prev, p_d); - continue; - } + asn1_node dest_node, p_s, p_d, p_d_prev; + int move; + + if (source_node == NULL) + return NULL; + + dest_node = _asn1_add_single_node(source_node->type); + + p_s = source_node; + p_d = dest_node; + + move = DOWN; + + do { + if (move != UP) { + if (p_s->name[0] != 0) + _asn1_cpy_name(p_d, p_s); + if (p_s->value) + _asn1_set_value(p_d, p_s->value, + p_s->value_len); + if (p_s->down) { + p_s = p_s->down; + p_d_prev = p_d; + p_d = _asn1_add_single_node(p_s->type); + _asn1_set_down(p_d_prev, p_d); + continue; + } + } + + if (p_s == source_node) + break; + + if (p_s->right) { + move = RIGHT; + p_s = p_s->right; + p_d_prev = p_d; + p_d = _asn1_add_single_node(p_s->type); + _asn1_set_right(p_d_prev, p_d); + } else { + move = UP; + p_s = _asn1_find_up(p_s); + p_d = _asn1_find_up(p_d); + } } + while (p_s != source_node); - if (p_s == source_node) - break; - - if (p_s->right) - { - move = RIGHT; - p_s = p_s->right; - p_d_prev = p_d; - p_d = _asn1_add_single_node (p_s->type); - _asn1_set_right (p_d_prev, p_d); - } - else - { - move = UP; - p_s = _asn1_find_up (p_s); - p_d = _asn1_find_up (p_d); - } - } - while (p_s != source_node); - - return dest_node; + return dest_node; } static asn1_node -_asn1_copy_structure2 (asn1_node root, const char *source_name) +_asn1_copy_structure2(asn1_node root, const char *source_name) { - asn1_node source_node; + asn1_node source_node; - source_node = asn1_find_node (root, source_name); + source_node = asn1_find_node(root, source_name); - return _asn1_copy_structure3 (source_node); + return _asn1_copy_structure3(source_node); } -static int -_asn1_type_choice_config (asn1_node node) +static int _asn1_type_choice_config(asn1_node node) { - asn1_node p, p2, p3, p4; - int move, tlen; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = node; - move = DOWN; - - while (!((p == node) && (move == UP))) - { - if (move != UP) - { - if ((type_field (p->type) == ASN1_ETYPE_CHOICE) && (p->type & CONST_TAG)) - { - p2 = p->down; - while (p2) - { - if (type_field (p2->type) != ASN1_ETYPE_TAG) - { - p2->type |= CONST_TAG; - p3 = _asn1_find_left (p2); - while (p3) - { - if (type_field (p3->type) == ASN1_ETYPE_TAG) - { - p4 = _asn1_add_single_node (p3->type); - tlen = _asn1_strlen (p3->value); - if (tlen > 0) - _asn1_set_value (p4, p3->value, tlen + 1); - _asn1_set_right (p4, p2->down); - _asn1_set_down (p2, p4); - } - p3 = _asn1_find_left (p3); + asn1_node p, p2, p3, p4; + int move, tlen; + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + p = node; + move = DOWN; + + while (!((p == node) && (move == UP))) { + if (move != UP) { + if ((type_field(p->type) == ASN1_ETYPE_CHOICE) + && (p->type & CONST_TAG)) { + p2 = p->down; + while (p2) { + if (type_field(p2->type) != + ASN1_ETYPE_TAG) { + p2->type |= CONST_TAG; + p3 = _asn1_find_left(p2); + while (p3) { + if (type_field + (p3->type) == + ASN1_ETYPE_TAG) + { + p4 = _asn1_add_single_node(p3->type); + tlen = + _asn1_strlen + (p3-> + value); + if (tlen > + 0) + _asn1_set_value + (p4, + p3-> + value, + tlen + + + 1); + _asn1_set_right + (p4, + p2-> + down); + _asn1_set_down + (p2, + p4); + } + p3 = _asn1_find_left(p3); + } + } + p2 = p2->right; + } + p->type &= ~(CONST_TAG); + p2 = p->down; + while (p2) { + p3 = p2->right; + if (type_field(p2->type) == + ASN1_ETYPE_TAG) + asn1_delete_structure(&p2); + p2 = p3; + } } - } - p2 = p2->right; + move = DOWN; + } else + move = RIGHT; + + if (move == DOWN) { + if (p->down) + p = p->down; + else + move = RIGHT; } - p->type &= ~(CONST_TAG); - p2 = p->down; - while (p2) - { - p3 = p2->right; - if (type_field (p2->type) == ASN1_ETYPE_TAG) - asn1_delete_structure (&p2); - p2 = p3; - } - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } - if (p == node) - { - move = UP; - continue; - } + if (p == node) { + move = UP; + continue; + } - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; + if (move == RIGHT) { + if (p->right) + p = p->right; + else + move = UP; + } + if (move == UP) + p = _asn1_find_up(p); } - if (move == UP) - p = _asn1_find_up (p); - } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } -static int -_asn1_expand_identifier (asn1_node * node, asn1_node root) +static int _asn1_expand_identifier(asn1_node * node, asn1_node root) { - asn1_node p, p2, p3; - char name2[ASN1_MAX_NAME_SIZE + 2]; - int move; - - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; - - p = *node; - move = DOWN; - - while (!((p == *node) && (move == UP))) - { - if (move != UP) - { - if (type_field (p->type) == ASN1_ETYPE_IDENTIFIER) - { - snprintf(name2, sizeof (name2), "%s.%s", root->name, p->value); - p2 = _asn1_copy_structure2 (root, name2); - if (p2 == NULL) - { - return ASN1_IDENTIFIER_NOT_FOUND; - } - _asn1_cpy_name (p2, p); - p2->right = p->right; - p2->left = p->left; - if (p->right) - p->right->left = p2; - p3 = p->down; - if (p3) - { - while (p3->right) - p3 = p3->right; - _asn1_set_right (p3, p2->down); - _asn1_set_down (p2, p->down); - } + asn1_node p, p2, p3; + char name2[ASN1_MAX_NAME_SIZE + 2]; + int move; - p3 = _asn1_find_left (p); - if (p3) - _asn1_set_right (p3, p2); - else - { - p3 = _asn1_find_up (p); - if (p3) - _asn1_set_down (p3, p2); - else - { - p2->left = NULL; - } - } + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; - if (p->type & CONST_SIZE) - p2->type |= CONST_SIZE; - if (p->type & CONST_TAG) - p2->type |= CONST_TAG; - if (p->type & CONST_OPTION) - p2->type |= CONST_OPTION; - if (p->type & CONST_DEFAULT) - p2->type |= CONST_DEFAULT; - if (p->type & CONST_SET) - p2->type |= CONST_SET; - if (p->type & CONST_NOT_USED) - p2->type |= CONST_NOT_USED; - - if (p == *node) - *node = p2; - _asn1_remove_node (p); - p = p2; - move = DOWN; - continue; - } - move = DOWN; - } - else - move = RIGHT; - - if (move == DOWN) - { - if (p->down) - p = p->down; - else - move = RIGHT; - } + p = *node; + move = DOWN; - if (p == *node) - { - move = UP; - continue; - } + while (!((p == *node) && (move == UP))) { + if (move != UP) { + if (type_field(p->type) == ASN1_ETYPE_IDENTIFIER) { + snprintf(name2, sizeof(name2), "%s.%s", + root->name, p->value); + p2 = _asn1_copy_structure2(root, name2); + if (p2 == NULL) { + return ASN1_IDENTIFIER_NOT_FOUND; + } + _asn1_cpy_name(p2, p); + p2->right = p->right; + p2->left = p->left; + if (p->right) + p->right->left = p2; + p3 = p->down; + if (p3) { + while (p3->right) + p3 = p3->right; + _asn1_set_right(p3, p2->down); + _asn1_set_down(p2, p->down); + } + + p3 = _asn1_find_left(p); + if (p3) + _asn1_set_right(p3, p2); + else { + p3 = _asn1_find_up(p); + if (p3) + _asn1_set_down(p3, p2); + else { + p2->left = NULL; + } + } + + if (p->type & CONST_SIZE) + p2->type |= CONST_SIZE; + if (p->type & CONST_TAG) + p2->type |= CONST_TAG; + if (p->type & CONST_OPTION) + p2->type |= CONST_OPTION; + if (p->type & CONST_DEFAULT) + p2->type |= CONST_DEFAULT; + if (p->type & CONST_SET) + p2->type |= CONST_SET; + if (p->type & CONST_NOT_USED) + p2->type |= CONST_NOT_USED; + + if (p == *node) + *node = p2; + _asn1_remove_node(p); + p = p2; + move = DOWN; + continue; + } + move = DOWN; + } else + move = RIGHT; + + if (move == DOWN) { + if (p->down) + p = p->down; + else + move = RIGHT; + } + + if (p == *node) { + move = UP; + continue; + } - if (move == RIGHT) - { - if (p->right) - p = p->right; - else - move = UP; + if (move == RIGHT) { + if (p->right) + p = p->right; + else + move = UP; + } + if (move == UP) + p = _asn1_find_up(p); } - if (move == UP) - p = _asn1_find_up (p); - } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } @@ -652,25 +608,25 @@ _asn1_expand_identifier (asn1_node * node, asn1_node root) * @source_name is not known. **/ int -asn1_create_element (asn1_node definitions, const char *source_name, - asn1_node * element) +asn1_create_element(asn1_node definitions, const char *source_name, + asn1_node * element) { - asn1_node dest_node; - int res; + asn1_node dest_node; + int res; - dest_node = _asn1_copy_structure2 (definitions, source_name); + dest_node = _asn1_copy_structure2(definitions, source_name); - if (dest_node == NULL) - return ASN1_ELEMENT_NOT_FOUND; + if (dest_node == NULL) + return ASN1_ELEMENT_NOT_FOUND; - _asn1_set_name (dest_node, ""); + _asn1_set_name(dest_node, ""); - res = _asn1_expand_identifier (&dest_node, definitions); - _asn1_type_choice_config (dest_node); + res = _asn1_expand_identifier(&dest_node, definitions); + _asn1_type_choice_config(dest_node); - *element = dest_node; + *element = dest_node; - return res; + return res; } @@ -687,331 +643,358 @@ asn1_create_element (asn1_node definitions, const char *source_name, * from the @name element inside the structure @structure. **/ void -asn1_print_structure (FILE * out, asn1_node structure, const char *name, - int mode) +asn1_print_structure(FILE * out, asn1_node structure, const char *name, + int mode) { - asn1_node p, root; - int k, indent = 0, len, len2, len3; - - if (out == NULL) - return; - - root = asn1_find_node (structure, name); - - if (root == NULL) - return; - - p = root; - while (p) - { - if (mode == ASN1_PRINT_ALL) - { - for (k = 0; k < indent; k++) - fprintf (out, " "); - fprintf (out, "name:"); - if (p->name[0] != 0) - fprintf (out, "%s ", p->name); - else - fprintf (out, "NULL "); - } - else - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_CONSTANT: - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_SIZE: - break; - default: - for (k = 0; k < indent; k++) - fprintf (out, " "); - fprintf (out, "name:"); - if (p->name[0] != 0) - fprintf (out, "%s ", p->name); - else - fprintf (out, "NULL "); - } - } - - if (mode != ASN1_PRINT_NAME) - { - unsigned type = type_field (p->type); - switch (type) - { - case ASN1_ETYPE_CONSTANT: - if (mode == ASN1_PRINT_ALL) - fprintf (out, "type:CONST"); - break; - case ASN1_ETYPE_TAG: - if (mode == ASN1_PRINT_ALL) - fprintf (out, "type:TAG"); - break; - case ASN1_ETYPE_SIZE: - if (mode == ASN1_PRINT_ALL) - fprintf (out, "type:SIZE"); - break; - case ASN1_ETYPE_DEFAULT: - fprintf (out, "type:DEFAULT"); - break; - case ASN1_ETYPE_IDENTIFIER: - fprintf (out, "type:IDENTIFIER"); - break; - case ASN1_ETYPE_ANY: - fprintf (out, "type:ANY"); - break; - case ASN1_ETYPE_CHOICE: - fprintf (out, "type:CHOICE"); - break; - case ASN1_ETYPE_DEFINITIONS: - fprintf (out, "type:DEFINITIONS"); - break; - CASE_HANDLED_ETYPES: - fprintf (out, "%s", _asn1_tags[type].desc); - break; - default: - break; - } - } - - if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL)) - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_CONSTANT: - if (mode == ASN1_PRINT_ALL) - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_TAG: - if (mode == ASN1_PRINT_ALL) - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_SIZE: - if (mode == ASN1_PRINT_ALL) - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_DEFAULT: - if (p->value) - fprintf (out, " value:%s", p->value); - else if (p->type & CONST_TRUE) - fprintf (out, " value:TRUE"); - else if (p->type & CONST_FALSE) - fprintf (out, " value:FALSE"); - break; - case ASN1_ETYPE_IDENTIFIER: - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_INTEGER: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:0x"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%02x", (p->value)[k + len2]); - } - break; - case ASN1_ETYPE_ENUMERATED: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:0x"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%02x", (p->value)[k + len2]); - } - break; - case ASN1_ETYPE_BOOLEAN: - if (p->value) - { - if (p->value[0] == 'T') - fprintf (out, " value:TRUE"); - else if (p->value[0] == 'F') - fprintf (out, " value:FALSE"); - } - break; - case ASN1_ETYPE_BIT_STRING: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - if (len > 0) - { - fprintf (out, " value(%i):", - (len - 1) * 8 - (p->value[len2])); - for (k = 1; k < len; k++) - fprintf (out, "%02x", (p->value)[k + len2]); - } - } - break; - 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; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%c", (p->value)[k + len2]); - } - break; - case ASN1_ETYPE_BMP_STRING: - case ASN1_ETYPE_OCTET_STRING: - if (p->value) - { - len2 = -1; - len = asn1_get_length_der (p->value, p->value_len, &len2); - fprintf (out, " value:"); - if (len > 0) - for (k = 0; k < len; k++) - fprintf (out, "%02x", (p->value)[k + len2]); + asn1_node p, root; + int k, indent = 0, len, len2, len3; + + if (out == NULL) + return; + + root = asn1_find_node(structure, name); + + if (root == NULL) + return; + + p = root; + while (p) { + if (mode == ASN1_PRINT_ALL) { + for (k = 0; k < indent; k++) + fprintf(out, " "); + fprintf(out, "name:"); + if (p->name[0] != 0) + fprintf(out, "%s ", p->name); + else + fprintf(out, "NULL "); + } else { + switch (type_field(p->type)) { + case ASN1_ETYPE_CONSTANT: + case ASN1_ETYPE_TAG: + case ASN1_ETYPE_SIZE: + break; + default: + for (k = 0; k < indent; k++) + fprintf(out, " "); + fprintf(out, "name:"); + if (p->name[0] != 0) + fprintf(out, "%s ", p->name); + else + fprintf(out, "NULL "); + } } - break; - case ASN1_ETYPE_OBJECT_ID: - if (p->value) - fprintf (out, " value:%s", p->value); - break; - case ASN1_ETYPE_ANY: - if (p->value) - { - len3 = -1; - len2 = asn1_get_length_der (p->value, p->value_len, &len3); - fprintf (out, " value:"); - if (len2 > 0) - for (k = 0; k < len2; k++) - fprintf (out, "%02x", (p->value)[k + len3]); + + if (mode != ASN1_PRINT_NAME) { + unsigned type = type_field(p->type); + switch (type) { + case ASN1_ETYPE_CONSTANT: + if (mode == ASN1_PRINT_ALL) + fprintf(out, "type:CONST"); + break; + case ASN1_ETYPE_TAG: + if (mode == ASN1_PRINT_ALL) + fprintf(out, "type:TAG"); + break; + case ASN1_ETYPE_SIZE: + if (mode == ASN1_PRINT_ALL) + fprintf(out, "type:SIZE"); + break; + case ASN1_ETYPE_DEFAULT: + fprintf(out, "type:DEFAULT"); + break; + case ASN1_ETYPE_IDENTIFIER: + fprintf(out, "type:IDENTIFIER"); + break; + case ASN1_ETYPE_ANY: + fprintf(out, "type:ANY"); + break; + case ASN1_ETYPE_CHOICE: + fprintf(out, "type:CHOICE"); + break; + case ASN1_ETYPE_DEFINITIONS: + fprintf(out, "type:DEFINITIONS"); + break; + CASE_HANDLED_ETYPES: + fprintf(out, "%s", _asn1_tags[type].desc); + break; + default: + break; + } } - break; - 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; - } - } - if (mode == ASN1_PRINT_ALL) - { - if (p->type & 0x1FFFFF00) - { - fprintf (out, " attr:"); - if (p->type & CONST_UNIVERSAL) - fprintf (out, "UNIVERSAL,"); - if (p->type & CONST_PRIVATE) - fprintf (out, "PRIVATE,"); - if (p->type & CONST_APPLICATION) - fprintf (out, "APPLICATION,"); - if (p->type & CONST_EXPLICIT) - fprintf (out, "EXPLICIT,"); - if (p->type & CONST_IMPLICIT) - fprintf (out, "IMPLICIT,"); - if (p->type & CONST_TAG) - fprintf (out, "TAG,"); - if (p->type & CONST_DEFAULT) - fprintf (out, "DEFAULT,"); - if (p->type & CONST_TRUE) - fprintf (out, "TRUE,"); - if (p->type & CONST_FALSE) - fprintf (out, "FALSE,"); - if (p->type & CONST_LIST) - fprintf (out, "LIST,"); - if (p->type & CONST_MIN_MAX) - fprintf (out, "MIN_MAX,"); - if (p->type & CONST_OPTION) - fprintf (out, "OPTION,"); - if (p->type & CONST_1_PARAM) - fprintf (out, "1_PARAM,"); - if (p->type & CONST_SIZE) - fprintf (out, "SIZE,"); - if (p->type & CONST_DEFINED_BY) - fprintf (out, "DEF_BY,"); - if (p->type & CONST_GENERALIZED) - fprintf (out, "GENERALIZED,"); - if (p->type & CONST_UTC) - fprintf (out, "UTC,"); - if (p->type & CONST_SET) - fprintf (out, "SET,"); - if (p->type & CONST_NOT_USED) - fprintf (out, "NOT_USED,"); - if (p->type & CONST_ASSIGN) - fprintf (out, "ASSIGNMENT,"); - } - } + if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) + || (mode == ASN1_PRINT_ALL)) { + switch (type_field(p->type)) { + case ASN1_ETYPE_CONSTANT: + if (mode == ASN1_PRINT_ALL) + if (p->value) + fprintf(out, " value:%s", + p->value); + break; + case ASN1_ETYPE_TAG: + if (mode == ASN1_PRINT_ALL) + if (p->value) + fprintf(out, " value:%s", + p->value); + break; + case ASN1_ETYPE_SIZE: + if (mode == ASN1_PRINT_ALL) + if (p->value) + fprintf(out, " value:%s", + p->value); + break; + case ASN1_ETYPE_DEFAULT: + if (p->value) + fprintf(out, " value:%s", + p->value); + else if (p->type & CONST_TRUE) + fprintf(out, " value:TRUE"); + else if (p->type & CONST_FALSE) + fprintf(out, " value:FALSE"); + break; + case ASN1_ETYPE_IDENTIFIER: + if (p->value) + fprintf(out, " value:%s", + p->value); + break; + case ASN1_ETYPE_INTEGER: + if (p->value) { + len2 = -1; + len = + asn1_get_length_der(p->value, + p-> + value_len, + &len2); + fprintf(out, " value:0x"); + if (len > 0) + for (k = 0; k < len; k++) + fprintf(out, + "%02x", + (p-> + value)[k + + len2]); + } + break; + case ASN1_ETYPE_ENUMERATED: + if (p->value) { + len2 = -1; + len = + asn1_get_length_der(p->value, + p-> + value_len, + &len2); + fprintf(out, " value:0x"); + if (len > 0) + for (k = 0; k < len; k++) + fprintf(out, + "%02x", + (p-> + value)[k + + len2]); + } + break; + case ASN1_ETYPE_BOOLEAN: + if (p->value) { + if (p->value[0] == 'T') + fprintf(out, + " value:TRUE"); + else if (p->value[0] == 'F') + fprintf(out, + " value:FALSE"); + } + break; + case ASN1_ETYPE_BIT_STRING: + if (p->value) { + len2 = -1; + len = + asn1_get_length_der(p->value, + p-> + value_len, + &len2); + if (len > 0) { + fprintf(out, + " value(%i):", + (len - 1) * 8 - + (p->value[len2])); + for (k = 1; k < len; k++) + fprintf(out, + "%02x", + (p-> + value)[k + + len2]); + } + } + break; + 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; + len = + asn1_get_length_der(p->value, + p-> + value_len, + &len2); + fprintf(out, " value:"); + if (len > 0) + for (k = 0; k < len; k++) + fprintf(out, "%c", + (p-> + value)[k + + len2]); + } + break; + case ASN1_ETYPE_BMP_STRING: + case ASN1_ETYPE_OCTET_STRING: + if (p->value) { + len2 = -1; + len = + asn1_get_length_der(p->value, + p-> + value_len, + &len2); + fprintf(out, " value:"); + if (len > 0) + for (k = 0; k < len; k++) + fprintf(out, + "%02x", + (p-> + value)[k + + len2]); + } + break; + case ASN1_ETYPE_OBJECT_ID: + if (p->value) + fprintf(out, " value:%s", + p->value); + break; + case ASN1_ETYPE_ANY: + if (p->value) { + len3 = -1; + len2 = + asn1_get_length_der(p->value, + p-> + value_len, + &len3); + fprintf(out, " value:"); + if (len2 > 0) + for (k = 0; k < len2; k++) + fprintf(out, + "%02x", + (p-> + value)[k + + len3]); + } + break; + 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; + } + } - if (mode == ASN1_PRINT_ALL) - { - fprintf (out, "\n"); - } - else - { - switch (type_field (p->type)) - { - case ASN1_ETYPE_CONSTANT: - case ASN1_ETYPE_TAG: - case ASN1_ETYPE_SIZE: - break; - default: - fprintf (out, "\n"); - } - } + if (mode == ASN1_PRINT_ALL) { + if (p->type & 0x1FFFFF00) { + fprintf(out, " attr:"); + if (p->type & CONST_UNIVERSAL) + fprintf(out, "UNIVERSAL,"); + if (p->type & CONST_PRIVATE) + fprintf(out, "PRIVATE,"); + if (p->type & CONST_APPLICATION) + fprintf(out, "APPLICATION,"); + if (p->type & CONST_EXPLICIT) + fprintf(out, "EXPLICIT,"); + if (p->type & CONST_IMPLICIT) + fprintf(out, "IMPLICIT,"); + if (p->type & CONST_TAG) + fprintf(out, "TAG,"); + if (p->type & CONST_DEFAULT) + fprintf(out, "DEFAULT,"); + if (p->type & CONST_TRUE) + fprintf(out, "TRUE,"); + if (p->type & CONST_FALSE) + fprintf(out, "FALSE,"); + if (p->type & CONST_LIST) + fprintf(out, "LIST,"); + if (p->type & CONST_MIN_MAX) + fprintf(out, "MIN_MAX,"); + if (p->type & CONST_OPTION) + fprintf(out, "OPTION,"); + if (p->type & CONST_1_PARAM) + fprintf(out, "1_PARAM,"); + if (p->type & CONST_SIZE) + fprintf(out, "SIZE,"); + if (p->type & CONST_DEFINED_BY) + fprintf(out, "DEF_BY,"); + if (p->type & CONST_GENERALIZED) + fprintf(out, "GENERALIZED,"); + if (p->type & CONST_UTC) + fprintf(out, "UTC,"); + if (p->type & CONST_SET) + fprintf(out, "SET,"); + if (p->type & CONST_NOT_USED) + fprintf(out, "NOT_USED,"); + if (p->type & CONST_ASSIGN) + fprintf(out, "ASSIGNMENT,"); + } + } - if (p->down) - { - p = p->down; - indent += 2; - } - else if (p == root) - { - p = NULL; - break; - } - else if (p->right) - p = p->right; - else - { - while (1) - { - p = _asn1_find_up (p); - if (p == root) - { - p = NULL; - break; + if (mode == ASN1_PRINT_ALL) { + fprintf(out, "\n"); + } else { + switch (type_field(p->type)) { + case ASN1_ETYPE_CONSTANT: + case ASN1_ETYPE_TAG: + case ASN1_ETYPE_SIZE: + break; + default: + fprintf(out, "\n"); + } } - indent -= 2; - if (p->right) - { - p = p->right; - break; + + if (p->down) { + p = p->down; + indent += 2; + } else if (p == root) { + p = NULL; + break; + } else if (p->right) + p = p->right; + else { + while (1) { + p = _asn1_find_up(p); + if (p == root) { + p = NULL; + break; + } + indent -= 2; + if (p->right) { + p = p->right; + break; + } + } } - } } - } } @@ -1028,30 +1011,28 @@ asn1_print_structure (FILE * out, asn1_node structure, const char *name, * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if * @name is not known, %ASN1_GENERIC_ERROR if pointer @num is %NULL. **/ -int -asn1_number_of_elements (asn1_node element, const char *name, int *num) +int asn1_number_of_elements(asn1_node element, const char *name, int *num) { - asn1_node node, p; + asn1_node node, p; - if (num == NULL) - return ASN1_GENERIC_ERROR; + if (num == NULL) + return ASN1_GENERIC_ERROR; - *num = 0; + *num = 0; - node = asn1_find_node (element, name); - if (node == NULL) - return ASN1_ELEMENT_NOT_FOUND; + node = asn1_find_node(element, name); + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; - p = node->down; + p = node->down; - while (p) - { - if (p->name[0] == '?') - (*num)++; - p = p->right; - } + while (p) { + if (p->name[0] == '?') + (*num)++; + p = p->right; + } - return ASN1_SUCCESS; + return ASN1_SUCCESS; } @@ -1066,48 +1047,49 @@ asn1_number_of_elements (asn1_node element, const char *name, int *num) * constant string that contains the element name defined just after * the OID. **/ -const char * -asn1_find_structure_from_oid (asn1_node definitions, const char *oidValue) +const char *asn1_find_structure_from_oid(asn1_node definitions, + const char *oidValue) { - char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1]; - char value[ASN1_MAX_NAME_SIZE]; - asn1_node p; - int len; - int result; - - if ((definitions == NULL) || (oidValue == NULL)) - return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ - - - strcpy (definitionsName, definitions->name); - strcat (definitionsName, "."); - - /* search the OBJECT_ID into definitions */ - p = definitions->down; - while (p) - { - if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && - (p->type & CONST_ASSIGN)) - { - strcpy (name, definitionsName); - strcat (name, p->name); - - len = ASN1_MAX_NAME_SIZE; - result = asn1_read_value (definitions, name, value, &len); - - if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value))) - { - p = p->right; - if (p == NULL) /* reach the end of ASN1 definitions */ + char definitionsName[ASN1_MAX_NAME_SIZE], + name[2 * ASN1_MAX_NAME_SIZE + 1]; + char value[ASN1_MAX_NAME_SIZE]; + asn1_node p; + int len; + int result; + + if ((definitions == NULL) || (oidValue == NULL)) return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ - return p->name; - } + + strcpy(definitionsName, definitions->name); + strcat(definitionsName, "."); + + /* search the OBJECT_ID into definitions */ + p = definitions->down; + while (p) { + if ((type_field(p->type) == ASN1_ETYPE_OBJECT_ID) && + (p->type & CONST_ASSIGN)) { + strcpy(name, definitionsName); + strcat(name, p->name); + + len = ASN1_MAX_NAME_SIZE; + result = + asn1_read_value(definitions, name, value, + &len); + + if ((result == ASN1_SUCCESS) + && (!strcmp(oidValue, value))) { + p = p->right; + if (p == NULL) /* reach the end of ASN1 definitions */ + return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ + + return p->name; + } + } + p = p->right; } - p = p->right; - } - return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ + return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ } /** @@ -1122,42 +1104,40 @@ asn1_find_structure_from_oid (asn1_node definitions, const char *oidValue) * Returns: Return %ASN1_SUCCESS on success. **/ int -asn1_copy_node (asn1_node dst, const char *dst_name, - asn1_node src, const char *src_name) +asn1_copy_node(asn1_node dst, const char *dst_name, + asn1_node src, const char *src_name) { /* FIXME: rewrite using copy_structure(). * It seems quite hard to do. */ - int result; - asn1_node dst_node; - void *data = NULL; - int size = 0; - - result = asn1_der_coding (src, src_name, NULL, &size, NULL); - if (result != ASN1_MEM_ERROR) - return result; - - data = malloc (size); - if (data == NULL) - return ASN1_MEM_ERROR; - - result = asn1_der_coding (src, src_name, data, &size, NULL); - if (result != ASN1_SUCCESS) - { - free (data); - return result; - } - - dst_node = asn1_find_node (dst, dst_name); - if (dst_node == NULL) - { - free (data); - return ASN1_ELEMENT_NOT_FOUND; - } - - result = asn1_der_decoding (&dst_node, data, size, NULL); - - free (data); - - return result; + int result; + asn1_node dst_node; + void *data = NULL; + int size = 0; + + result = asn1_der_coding(src, src_name, NULL, &size, NULL); + if (result != ASN1_MEM_ERROR) + return result; + + data = malloc(size); + if (data == NULL) + return ASN1_MEM_ERROR; + + result = asn1_der_coding(src, src_name, data, &size, NULL); + if (result != ASN1_SUCCESS) { + free(data); + return result; + } + + dst_node = asn1_find_node(dst, dst_name); + if (dst_node == NULL) { + free(data); + return ASN1_ELEMENT_NOT_FOUND; + } + + result = asn1_der_decoding(&dst_node, data, size, NULL); + + free(data); + + return result; } diff --git a/lib/minitasn1/structure.h b/lib/minitasn1/structure.h index 986e13a309..c56beb6413 100644 --- a/lib/minitasn1/structure.h +++ b/lib/minitasn1/structure.h @@ -28,14 +28,14 @@ #ifndef _STRUCTURE_H #define _STRUCTURE_H -int _asn1_create_static_structure (asn1_node pointer, - char *output_file_name, - char *vector_name); +int _asn1_create_static_structure(asn1_node pointer, + char *output_file_name, + char *vector_name); -asn1_node _asn1_copy_structure3 (asn1_node source_node); +asn1_node _asn1_copy_structure3(asn1_node source_node); -asn1_node _asn1_add_single_node (unsigned int type); +asn1_node _asn1_add_single_node(unsigned int type); -asn1_node _asn1_find_left (asn1_node node); +asn1_node _asn1_find_left(asn1_node node); #endif diff --git a/lib/minitasn1/version.c b/lib/minitasn1/version.c index 83d70c9623..2941af916a 100644 --- a/lib/minitasn1/version.c +++ b/lib/minitasn1/version.c @@ -41,11 +41,10 @@ * Returns: Version string of run-time library, or %NULL if the * run-time library does not meet the required version number. */ -const char * -asn1_check_version (const char *req_version) +const char *asn1_check_version(const char *req_version) { - if (!req_version || strverscmp (req_version, ASN1_VERSION) <= 0) - return ASN1_VERSION; + if (!req_version || strverscmp(req_version, ASN1_VERSION) <= 0) + return ASN1_VERSION; - return NULL; + return NULL; } |