diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-11-08 22:14:07 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-11-08 22:17:10 +0100 |
commit | 76c93d23c073ef8b885503b7d28a31ffe2add6d8 (patch) | |
tree | 1dd2d22a197bc40c5330e516969a7cb1ae9bc96f /lib/minitasn1/coding.c | |
parent | 559a144f6bbcbb611453f82e655dd7438c14d1a7 (diff) | |
download | gnutls-76c93d23c073ef8b885503b7d28a31ffe2add6d8.tar.gz |
reindented code
Diffstat (limited to 'lib/minitasn1/coding.c')
-rw-r--r-- | lib/minitasn1/coding.c | 1782 |
1 files changed, 908 insertions, 874 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; } |