diff options
author | Simon Josefsson <simon@josefsson.org> | 2008-11-06 09:18:32 +0100 |
---|---|---|
committer | Simon Josefsson <simon@josefsson.org> | 2008-11-06 09:18:32 +0100 |
commit | d416af22ab948ab774f0978be74c520af6a85a07 (patch) | |
tree | cd40eb01c792fdba32a1d3478309d4ce7ca7e179 | |
parent | d1f8decbeedf10f04c488db45c9fbe60e9ae9a9b (diff) | |
download | gnutls-d416af22ab948ab774f0978be74c520af6a85a07.tar.gz |
Revert "* added BER octet string decoder from libtasn1."
This reverts commit 47a0c91a38c458653be1645ff162c53253cbeadd.
-rw-r--r-- | lib/minitasn1/decoding.c | 193 | ||||
-rw-r--r-- | lib/minitasn1/element.c | 45 | ||||
-rw-r--r-- | lib/minitasn1/libtasn1.h | 5 | ||||
-rw-r--r-- | lib/minitasn1/parser_aux.c | 120 | ||||
-rw-r--r-- | lib/minitasn1/parser_aux.h | 10 |
5 files changed, 140 insertions, 233 deletions
diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c index 51ecc01cea..c1de9e6773 100644 --- a/lib/minitasn1/decoding.c +++ b/lib/minitasn1/decoding.c @@ -33,10 +33,8 @@ #include "structure.h" #include "element.h" -static asn1_retCode -_asn1_get_indefinite_length_string (const unsigned char *der, int *len); -static void +void _asn1_error_description_tag_error (node_asn * node, char *ErrorDescription) { @@ -103,6 +101,8 @@ asn1_get_length_der (const unsigned char *der, int der_len, int *len) } + + /** * asn1_get_tag_der: * @der: DER data to decode. @@ -121,7 +121,7 @@ asn1_get_tag_der (const unsigned char *der, int der_len, { int punt, ris; - if (der == NULL || der_len < 2 || len == NULL) + if (der == NULL || der_len <= 0 || len == NULL) return ASN1_DER_ERROR; *cls = der[0] & 0xE0; @@ -160,36 +160,8 @@ asn1_get_tag_der (const unsigned char *der, int der_len, return ASN1_SUCCESS; } -/** - * asn1_get_length_ber: - * @ber: BER data to decode. - * @ber_len: Length of BER data to decode. - * @len: Output variable containing the length of the BER length field. - * - * Extract a length field from BER data. - * - * Return value: Return the decoded length value, or negative value - * when the value was too big. The difference with asn1_get_length_der() - * is that it will return length even if the value has indefinite encoding. - * - **/ -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; -} + + /** * asn1_get_octet_der: @@ -296,6 +268,9 @@ _asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len, *ret_len = len + len_len; } + + + /** * asn1_get_bit_der: * @der: DER data to decode containing the BIT SEQUENCE. @@ -374,21 +349,15 @@ _asn1_extract_tag_der (node_asn * node, const unsigned char *der, int der_len, (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, + asn1_get_length_der (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)) || @@ -400,6 +369,7 @@ _asn1_extract_tag_der (node_asn * node, const unsigned char *der, int der_len, if ((class != class_implicit) || (tag != tag_implicit)) return ASN1_TAG_ERROR; } + is_tag_implicit = 0; } else @@ -455,7 +425,6 @@ _asn1_extract_tag_der (node_asn * node, const unsigned char *der, int der_len, (der + counter, der_len - counter, &class, &len2, &tag) != ASN1_SUCCESS) return ASN1_DER_ERROR; - if (counter + len2 > der_len) return ASN1_DER_ERROR; @@ -596,52 +565,12 @@ _asn1_delete_not_used (node_asn * node) return ASN1_SUCCESS; } -asn1_retCode _asn1_extract_der_octet(node_asn * node, const unsigned char *der, int der_len) -{ -int len2, len3; -int counter2, counter_end; - - len2 = asn1_get_length_der (der, der_len, &len3); - if (len2 < -1) - return ASN1_DER_ERROR; - - counter2 = len3 + 1; - - 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); - - 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; - } - - counter2 += len2 + len3 + 1; - } - - return ASN1_SUCCESS; -} - asn1_retCode _asn1_get_octet_string (const unsigned char *der, node_asn * node, int *len) { - int len2, len3, counter, tot_len, indefinite; + int len2, len3, counter, counter2, counter_end, tot_len, indefinite; + unsigned char *temp, *temp2; counter = 0; @@ -688,20 +617,43 @@ _asn1_get_octet_string (const unsigned char *der, node_asn * node, int *len) /* copy */ if (node) { - unsigned char temp[DER_LEN]; - int ret; - - len2 = sizeof(temp); + asn1_length_der (tot_len, NULL, &len2); + temp = _asn1_malloc (len2 + tot_len); + if (temp == NULL) + { + return ASN1_MEM_ALLOC_ERROR; + } asn1_length_der (tot_len, temp, &len2); - _asn1_set_value (node, temp, len2); - tot_len += len2; + temp2 = temp + len2; + len2 = asn1_get_length_der (der, *len, &len3); + if (len2 < -1) + return ASN1_DER_ERROR; + counter2 = len3 + 1; - ret = _asn1_extract_der_octet(node, der, *len); - if (ret!=ASN1_SUCCESS) - return ret; + if (indefinite == -1) + counter_end = counter - 2; + else + counter_end = counter; + while (counter2 < counter_end) + { + len2 = + asn1_get_length_der (der + counter2, *len - counter, &len3); + if (len2 < -1) + return ASN1_DER_ERROR; + + /* FIXME: to be checked. Is this ok? Has the + * size been checked before? + */ + memcpy (temp2, der + counter2 + len3, len2); + temp2 += len2; + counter2 += len2 + len3 + 1; + } + + _asn1_set_value (node, temp, tot_len); + _asn1_free (temp); } } else @@ -721,7 +673,8 @@ _asn1_get_octet_string (const unsigned char *der, node_asn * node, int *len) } -static asn1_retCode + +asn1_retCode _asn1_get_indefinite_length_string (const unsigned char *der, int *len) { int len2, len3, counter, indefinite; @@ -803,7 +756,7 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len, node_asn *node, *p, *p2, *p3; char temp[128]; int counter, len2, len3, len4, move, ris, tlen; - unsigned char class; + unsigned char class, *temp2; unsigned long tag; int indefinite, result; const unsigned char *der = ider; @@ -1239,7 +1192,17 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len, if (len4 != -1) { len2 += len4; - _asn1_set_value_octet (p, der+counter, len2+len3); + asn1_length_der (len2 + len3, NULL, &len4); + temp2 = (unsigned char *) _asn1_malloc (len2 + len3 + len4); + if (temp2 == NULL) + { + asn1_delete_structure (element); + return ASN1_MEM_ALLOC_ERROR; + } + + asn1_octet_der (der + counter, len2 + len3, temp2, &len4); + _asn1_set_value (p, temp2, len4); + _asn1_free (temp2); counter += len2 + len3; } else @@ -1258,8 +1221,17 @@ asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len, asn1_delete_structure (element); return ris; } + asn1_length_der (len2, NULL, &len4); + temp2 = (unsigned char *) _asn1_malloc (len2 + len4); + if (temp2 == NULL) + { + asn1_delete_structure (element); + return ASN1_MEM_ALLOC_ERROR; + } - _asn1_set_value_octet (p, der+counter, len2); + asn1_octet_der (der + counter, len2, temp2, &len4); + _asn1_set_value (p, temp2, len4); + _asn1_free (temp2); counter += len2; /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with @@ -1905,8 +1877,19 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName, len2 += len4; if (state == FOUND) { - _asn1_set_value_octet (p, der+counter, len2+len3); - temp2 = NULL; + asn1_length_der (len2 + len3, NULL, &len4); + temp2 = + (unsigned char *) _asn1_malloc (len2 + len3 + len4); + if (temp2 == NULL) + { + asn1_delete_structure (structure); + return ASN1_MEM_ALLOC_ERROR; + } + + asn1_octet_der (der + counter, len2 + len3, temp2, + &len4); + _asn1_set_value (p, temp2, len4); + _asn1_free (temp2); if (p == nodeFound) state = EXIT; @@ -1932,7 +1915,17 @@ asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName, if (state == FOUND) { - _asn1_set_value_octet (p, der+counter, len2); + asn1_length_der (len2, NULL, &len4); + temp2 = (unsigned char *) _asn1_malloc (len2 + len4); + if (temp2 == NULL) + { + asn1_delete_structure (structure); + return ASN1_MEM_ALLOC_ERROR; + } + + asn1_octet_der (der + counter, len2, temp2, &len4); + _asn1_set_value (p, temp2, len4); + _asn1_free (temp2); if (p == nodeFound) state = EXIT; diff --git a/lib/minitasn1/element.c b/lib/minitasn1/element.c index 25ecd5af3f..703276c809 100644 --- a/lib/minitasn1/element.c +++ b/lib/minitasn1/element.c @@ -417,7 +417,19 @@ asn1_write_value (ASN1_TYPE node_root, const char *name, (!negative && (value_temp[k] & 0x80))) k--; - _asn1_set_value_octet (node, value_temp+k, len-k); + asn1_length_der (len - k, NULL, &len2); + temp = (unsigned char *) _asn1_malloc (len - k + len2); + if (temp == NULL) + { + _asn1_free (value_temp); + return ASN1_MEM_ALLOC_ERROR; + } + + asn1_octet_der (value_temp + k, len - k, temp, &len2); + _asn1_set_value (node, temp, len2); + + _asn1_free (temp); + if (node->type & CONST_DEFAULT) { @@ -557,12 +569,26 @@ asn1_write_value (ASN1_TYPE node_root, const char *name, case TYPE_OCTET_STRING: if (len == 0) len = strlen (value); - _asn1_set_value_octet (node, value, len); + asn1_length_der (len, NULL, &len2); + temp = (unsigned char *) _asn1_malloc (len + len2); + if (temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + asn1_octet_der (value, len, temp, &len2); + _asn1_set_value (node, temp, len2); + _asn1_free (temp); break; case TYPE_GENERALSTRING: if (len == 0) len = strlen (value); - _asn1_set_value_octet (node, value, len); + asn1_length_der (len, NULL, &len2); + temp = (unsigned char *) _asn1_malloc (len + len2); + if (temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + asn1_octet_der (value, len, temp, &len2); + _asn1_set_value (node, temp, len2); + _asn1_free (temp); break; case TYPE_BIT_STRING: if (len == 0) @@ -573,8 +599,8 @@ asn1_write_value (ASN1_TYPE node_root, const char *name, return ASN1_MEM_ALLOC_ERROR; asn1_bit_der (value, len, temp, &len2); - _asn1_set_value_m (node, temp, len2); - temp = NULL; + _asn1_set_value (node, temp, len2); + _asn1_free (temp); break; case TYPE_CHOICE: p = node->down; @@ -601,7 +627,14 @@ asn1_write_value (ASN1_TYPE node_root, const char *name, return ASN1_ELEMENT_NOT_FOUND; break; case TYPE_ANY: - _asn1_set_value_octet (node, value, len); + asn1_length_der (len, NULL, &len2); + temp = (unsigned char *) _asn1_malloc (len + len2); + if (temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + asn1_octet_der (value, len, temp, &len2); + _asn1_set_value (node, temp, len2); + _asn1_free (temp); break; case TYPE_SEQUENCE_OF: case TYPE_SET_OF: diff --git a/lib/minitasn1/libtasn1.h b/lib/minitasn1/libtasn1.h index efcee0e1bc..d7d4f70a7c 100644 --- a/lib/minitasn1/libtasn1.h +++ b/lib/minitasn1/libtasn1.h @@ -105,14 +105,11 @@ extern "C" /* that represent an ASN.1 DEFINITION. */ /******************************************************/ -#define SMALL_VALUE_SIZE 16 - struct node_asn_struct { char *name; /* Node name */ unsigned int type; /* Node type */ unsigned char *value; /* Node value */ - unsigned char small_value[SMALL_VALUE_SIZE]; /* if value is less than that store it here */ int value_len; struct node_asn_struct *down; /* Pointer to the son node */ struct node_asn_struct *right; /* Pointer to the brother node */ @@ -231,8 +228,6 @@ extern "C" signed long asn1_get_length_der (const unsigned char *der, int der_len, int *len); - long asn1_get_length_ber (const unsigned char *ber, int ber_len, - int *len); void asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len); diff --git a/lib/minitasn1/parser_aux.c b/lib/minitasn1/parser_aux.c index 43522dace6..51169b14b4 100644 --- a/lib/minitasn1/parser_aux.c +++ b/lib/minitasn1/parser_aux.c @@ -199,134 +199,30 @@ asn1_find_node (ASN1_TYPE pointer, const char *name) /* Return: pointer to the NODE_ASN element. */ /******************************************************************/ node_asn * -_asn1_set_value (node_asn * node, const void *value, unsigned int len) +_asn1_set_value (node_asn * node, const void *_value, unsigned int len) { - if (node == NULL) - return node; - if (node->value) - { - if (node->value != node->small_value) _asn1_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 = _asn1_malloc (len); - if (node->value == NULL) - return NULL; - } - node->value_len = len; - - memcpy (node->value, value, len); - return node; -} - -/******************************************************************/ -/* Function : _asn1_set_value_octet */ -/* Description: sets the field VALUE in a NODE_ASN element. The */ -/* previous value (if exist) will be lost. The value */ -/* given is stored as an octet string. */ -/* Parameters: */ -/* node: element pointer. */ -/* value: pointer to the value that you want to set. */ -/* len: character number of value. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -node_asn * -_asn1_set_value_octet (node_asn * node, const void *value, unsigned int len) -{ -int len2; -void* temp; + const unsigned char *value = _value; if (node == NULL) return node; - - asn1_length_der (len, NULL, &len2); - temp = (unsigned char *) _asn1_malloc (len + len2); - if (temp == NULL) - return NULL; - - 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. - */ -node_asn * -_asn1_set_value_m (node_asn * node, void *value, unsigned int len) -{ - if (node == NULL) - return node; - if (node->value) { - if (node->value != node->small_value) _asn1_free (node->value); + _asn1_free (node->value); node->value = NULL; node->value_len = 0; } - if (!len) return node; - - node->value = value; + node->value = (unsigned char *) _asn1_malloc (len); + if (node->value == NULL) + return NULL; node->value_len = len; + memcpy (node->value, value, len); return node; } /******************************************************************/ -/* Function : _asn1_append_value */ -/* Description: appends to the field VALUE in a NODE_ASN element. */ -/* */ -/* Parameters: */ -/* node: element pointer. */ -/* value: pointer to the value that you want to be appended. */ -/* len: character number of value. */ -/* Return: pointer to the NODE_ASN element. */ -/******************************************************************/ -node_asn * -_asn1_append_value (node_asn * 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 = _asn1_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 = _asn1_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); -} - -/******************************************************************/ /* Function : _asn1_set_name */ /* Description: sets the field NAME in a NODE_ASN element. The */ /* previous value (if exist) will be lost */ @@ -505,7 +401,7 @@ _asn1_remove_node (node_asn * node) if (node->name != NULL) _asn1_free (node->name); - if (node->value != NULL && node->value != node->small_value) + if (node->value != NULL) _asn1_free (node->value); _asn1_free (node); } diff --git a/lib/minitasn1/parser_aux.h b/lib/minitasn1/parser_aux.h index 6e18bb69c2..3055510cbe 100644 --- a/lib/minitasn1/parser_aux.h +++ b/lib/minitasn1/parser_aux.h @@ -2,7 +2,6 @@ #ifndef _PARSER_AUX_H #define _PARSER_AUX_H -#define DER_LEN 16 /***************************************/ /* Functions used by ASN.1 parser */ @@ -14,15 +13,6 @@ node_asn * _asn1_set_value(node_asn *node,const void *value,unsigned int len); node_asn * -_asn1_set_value_m(node_asn *node,void *value,unsigned int len); - -node_asn * -_asn1_set_value_octet(node_asn *node,const void *value,unsigned int len); - -node_asn * -_asn1_append_value(node_asn *node,const void *value,unsigned int len); - -node_asn * _asn1_set_name(node_asn *node,const char *name); node_asn * |