diff options
Diffstat (limited to 'lib/minitasn1/coding.c')
-rw-r--r-- | lib/minitasn1/coding.c | 1527 |
1 files changed, 854 insertions, 673 deletions
diff --git a/lib/minitasn1/coding.c b/lib/minitasn1/coding.c index aa19d20ef2..0ca407e837 100644 --- a/lib/minitasn1/coding.c +++ b/lib/minitasn1/coding.c @@ -46,15 +46,17 @@ /* Return: */ /******************************************************/ void -_asn1_error_description_value_not_found(node_asn *node,char *ErrorDescription) +_asn1_error_description_value_not_found (node_asn * node, + char *ErrorDescription) { - if (ErrorDescription == NULL) return; + if (ErrorDescription == NULL) + return; - Estrcpy(ErrorDescription,":: value of element '"); - _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription), - MAX_ERROR_DESCRIPTION_SIZE-40); - Estrcat(ErrorDescription,"' not found"); + Estrcpy (ErrorDescription, ":: value of element '"); + _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), + MAX_ERROR_DESCRIPTION_SIZE - 40); + Estrcat (ErrorDescription, "' not found"); } @@ -68,29 +70,35 @@ _asn1_error_description_value_not_found(node_asn *node,char *ErrorDescription) * The @ans buffer is pre-allocated and must have room for the output. **/ void -asn1_length_der(unsigned long int len, unsigned char *ans, int *ans_len) +asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len) { int k; unsigned char temp[SIZEOF_UNSIGNED_LONG_INT]; - if(len<128){ - /* short form */ - if(ans!=NULL) ans[0]=(unsigned char)len; - *ans_len=1; - } - else{ - /* Long form */ - k=0; - while(len){ - temp[k++]=len&0xFF; - len=len>>8; + if (len < 128) + { + /* short form */ + if (ans != NULL) + ans[0] = (unsigned char) len; + *ans_len = 1; } - *ans_len=k+1; - if(ans!=NULL){ - ans[0]=((unsigned char)k&0x7F)+128; - while(k--) ans[*ans_len-1-k]=temp[k]; + else + { + /* Long form */ + k = 0; + while (len) + { + temp[k++] = len & 0xFF; + len = len >> 8; + } + *ans_len = k + 1; + if (ans != NULL) + { + ans[0] = ((unsigned char) k & 0x7F) + 128; + while (k--) + ans[*ans_len - 1 - k] = temp[k]; + } } - } } /******************************************************/ @@ -106,28 +114,33 @@ asn1_length_der(unsigned long int len, unsigned char *ans, int *ans_len) /* Return: */ /******************************************************/ 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[SIZEOF_UNSIGNED_INT]; - 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){ - temp[k++]=tag_value&0x7F; - tag_value=tag_value>>7; + 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) + { + temp[k++] = tag_value & 0x7F; + tag_value = tag_value >> 7; + } + *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; - } } /** @@ -140,15 +153,16 @@ _asn1_tag_der(unsigned char class,unsigned int tag_value,unsigned char *ans,int * Creates the DER coding for an OCTET type (length included). **/ 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; - 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; + 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; } /******************************************************/ @@ -166,20 +180,21 @@ asn1_octet_der(const unsigned char *str,int str_len, /* ASN1_SUCCESS otherwise */ /******************************************************/ asn1_retCode -_asn1_time_der(unsigned char *str,unsigned char *der,int *der_len) +_asn1_time_der (unsigned char *str, unsigned char *der, int *der_len) { int len_len; int max_len; - max_len=*der_len; + max_len = *der_len; - asn1_length_der(strlen(str),(max_len>0)?der:NULL,&len_len); + asn1_length_der (strlen (str), (max_len > 0) ? der : NULL, &len_len); - if((len_len+(int)strlen(str))<=max_len) - memcpy(der+len_len,str,strlen(str)); - *der_len=len_len+strlen(str); + if ((len_len + (int) strlen (str)) <= max_len) + memcpy (der + len_len, str, strlen (str)); + *der_len = len_len + strlen (str); - if((*der_len)>max_len) return ASN1_MEM_ERROR; + if ((*der_len) > max_len) + return ASN1_MEM_ERROR; return ASN1_SUCCESS; } @@ -236,67 +251,77 @@ _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str) /* ASN1_SUCCESS otherwise */ /******************************************************/ asn1_retCode -_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; + int len_len, counter, k, first, max_len; + char *temp, *n_end, *n_start; unsigned char bit7; - unsigned long val,val1=0; - - max_len=*der_len; - - temp= (char *) _asn1_alloca(strlen(str)+2); - if(temp==NULL) return ASN1_MEM_ALLOC_ERROR; - - strcpy(temp, str); - strcat(temp, "."); - - 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; + unsigned long val, val1 = 0; + + max_len = *der_len; + + temp = (char *) _asn1_alloca (strlen (str) + 2); + if (temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + strcpy (temp, str); + strcat (temp, "."); + + 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; - _asn1_afree(temp); + _asn1_afree (temp); - if(max_len<(*der_len)) return ASN1_MEM_ERROR; + if (max_len < (*der_len)) + return ASN1_MEM_ERROR; return ASN1_SUCCESS; } -const char bit_mask[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80}; +const char bit_mask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 }; /** * asn1_bit_der: @@ -310,21 +335,24 @@ const char bit_mask[]={0xFF,0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80}; * included). **/ 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; - - 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; + int len_len, len_byte, len_pad; + + 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; } @@ -343,48 +371,58 @@ asn1_bit_der(const unsigned char *str, int bit_len, /* otherwise ASN1_SUCCESS. */ /******************************************************/ asn1_retCode -_asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int *max_len) +_asn1_complete_explicit_tag (node_asn * node, unsigned char *der, + int *counter, int *max_len) { node_asn *p; - int is_tag_implicit,len2,len3; + 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)==TYPE_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; - } + + 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) == TYPE_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; } @@ -406,118 +444,153 @@ _asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int * /* otherwise ASN1_SUCCESS. */ /******************************************************/ asn1_retCode -_asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter,int *max_len) +_asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter, + int *max_len) { node_asn *p; - int tag_len,is_tag_implicit; - unsigned char class,class_implicit=0,temp[SIZEOF_UNSIGNED_INT*3+1]; - unsigned long tag_implicit=0; + int tag_len, is_tag_implicit; + unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1]; + unsigned long tag_implicit = 0; 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)==TYPE_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,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,temp); - _asn1_set_name(p,temp); - - is_tag_implicit=0; - } - else{ /* CONST_IMPLICIT */ - if(!is_tag_implicit){ - if((type_field(node->type)==TYPE_SEQUENCE) || - (type_field(node->type)==TYPE_SEQUENCE_OF) || - (type_field(node->type)==TYPE_SET) || - (type_field(node->type)==TYPE_SET_OF)) class|=ASN1_CLASS_STRUCTURED; - class_implicit=class; - tag_implicit=strtoul(p->value,NULL,10); - is_tag_implicit=1; - } + is_tag_implicit = 0; + + if (node->type & CONST_TAG) + { + p = node->down; + while (p) + { + if (type_field (p->type) == TYPE_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, + 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, temp); + _asn1_set_name (p, temp); + + is_tag_implicit = 0; + } + else + { /* CONST_IMPLICIT */ + if (!is_tag_implicit) + { + if ((type_field (node->type) == TYPE_SEQUENCE) || + (type_field (node->type) == TYPE_SEQUENCE_OF) || + (type_field (node->type) == TYPE_SET) || + (type_field (node->type) == TYPE_SET_OF)) + class |= ASN1_CLASS_STRUCTURED; + class_implicit = class; + tag_implicit = 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{ - switch(type_field(node->type)){ - case TYPE_NULL: - _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_NULL,tag_der,&tag_len); - break; - case TYPE_BOOLEAN: - _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_BOOLEAN,tag_der,&tag_len); - break; - case TYPE_INTEGER: - _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_INTEGER,tag_der,&tag_len); - break; - case TYPE_ENUMERATED: - _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_ENUMERATED,tag_der,&tag_len); - break; - case TYPE_OBJECT_ID: - _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_OBJECT_ID,tag_der,&tag_len); - break; - case TYPE_TIME: - if(node->type&CONST_UTC){ - _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_UTCTime,tag_der,&tag_len); - } - else _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_GENERALIZEDTime,tag_der,&tag_len); - break; - case TYPE_OCTET_STRING: - _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_OCTET_STRING,tag_der,&tag_len); - break; - case TYPE_GENERALSTRING: - _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_GENERALSTRING,tag_der,&tag_len); - break; - case TYPE_BIT_STRING: - _asn1_tag_der(ASN1_CLASS_UNIVERSAL,ASN1_TAG_BIT_STRING,tag_der,&tag_len); - break; - case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF: - _asn1_tag_der(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED,ASN1_TAG_SEQUENCE,tag_der,&tag_len); - break; - case TYPE_SET: case TYPE_SET_OF: - _asn1_tag_der(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED,ASN1_TAG_SET,tag_der,&tag_len); - break; - case TYPE_TAG: - tag_len=0; - break; - case TYPE_CHOICE: - tag_len=0; - break; - case TYPE_ANY: - 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 + { + switch (type_field (node->type)) + { + case TYPE_NULL: + _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der, + &tag_len); + break; + case TYPE_BOOLEAN: + _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der, + &tag_len); + break; + case TYPE_INTEGER: + _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der, + &tag_len); + break; + case TYPE_ENUMERATED: + _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der, + &tag_len); + break; + case TYPE_OBJECT_ID: + _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der, + &tag_len); + break; + case TYPE_TIME: + if (node->type & CONST_UTC) + { + _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der, + &tag_len); + } + else + _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime, + tag_der, &tag_len); + break; + case TYPE_OCTET_STRING: + _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der, + &tag_len); + break; + case TYPE_GENERALSTRING: + _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING, + tag_der, &tag_len); + break; + case TYPE_BIT_STRING: + _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der, + &tag_len); + break; + case TYPE_SEQUENCE: + case TYPE_SEQUENCE_OF: + _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, + ASN1_TAG_SEQUENCE, tag_der, &tag_len); + break; + case TYPE_SET: + case TYPE_SET_OF: + _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED, + ASN1_TAG_SET, tag_der, &tag_len); + break; + case TYPE_TAG: + tag_len = 0; + break; + case TYPE_CHOICE: + tag_len = 0; + break; + case TYPE_ANY: + 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; + 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; } @@ -532,88 +605,108 @@ _asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter,int *max_len /* Return: */ /******************************************************/ void -_asn1_ordering_set(unsigned char *der, int der_len, node_asn *node) +_asn1_ordering_set (unsigned char *der, int der_len, node_asn * node) { - struct vet{ + struct vet + { int end; unsigned long value; - struct vet *next,*prev; + struct vet *next, *prev; }; - int counter,len,len2; - struct vet *first,*last,*p_vet,*p2_vet; + int counter, len, len2; + struct vet *first, *last, *p_vet, *p2_vet; node_asn *p; - unsigned char class,*temp; + unsigned char class, *temp; unsigned long tag; - counter=0; - - if(type_field(node->type)!=TYPE_SET) return; + counter = 0; - p=node->down; - while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right; - - if((p==NULL) || (p->right==NULL)) return; + if (type_field (node->type) != TYPE_SET) + return; - first=last=NULL; - while(p){ - p_vet=(struct vet *)_asn1_alloca( 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; + p = node->down; + while ((type_field (p->type) == TYPE_TAG) + || (type_field (p->type) == TYPE_SIZE)) + p = p->right; - /* 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; + if ((p == NULL) || (p->right == NULL)) + return; - /* extraction and length */ - len2=asn1_get_length_der(der+counter,der_len-counter,&len); - if (len2<0) return; - counter+=len+len2; + first = last = NULL; + while (p) + { + p_vet = (struct vet *) _asn1_alloca (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->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 = (unsigned char *) _asn1_alloca (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); + _asn1_afree (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; + } - 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=(unsigned char *)_asn1_alloca( 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); - _asn1_afree(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; + _asn1_afree (p_vet); + p_vet = first; } - - if(p_vet!=first) p_vet->prev->next=NULL; - else first=NULL; - _asn1_afree(p_vet); - p_vet=first; - } } /******************************************************/ @@ -626,98 +719,128 @@ _asn1_ordering_set(unsigned char *der, int der_len, node_asn *node) /* Return: */ /******************************************************/ void -_asn1_ordering_set_of(unsigned char *der, int der_len, node_asn *node) +_asn1_ordering_set_of (unsigned char *der, int der_len, node_asn * node) { - struct vet{ + struct vet + { int end; - struct vet *next,*prev; + struct vet *next, *prev; }; - int counter,len,len2,change; - struct vet *first,*last,*p_vet,*p2_vet; + int counter, len, len2, change; + struct vet *first, *last, *p_vet, *p2_vet; node_asn *p; - unsigned char *temp,class; - unsigned long k,max; - - counter=0; - - if(type_field(node->type)!=TYPE_SET_OF) return; - - p=node->down; - while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right; - p=p->right; - - if((p==NULL) || (p->right==NULL)) return; - - first=last=NULL; - while(p){ - p_vet=(struct vet *)_asn1_alloca(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; - } + unsigned char *temp, class; + unsigned long k, max; - p_vet->end=counter; - p=p->right; - } + counter = 0; + + if (type_field (node->type) != TYPE_SET_OF) + return; - p_vet=first; + p = node->down; + while ((type_field (p->type) == TYPE_TAG) + || (type_field (p->type) == TYPE_SIZE)) + p = p->right; + p = p->right; + + if ((p == NULL) || (p->right == NULL)) + return; - 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; + first = last = NULL; + while (p) + { + p_vet = (struct vet *) _asn1_alloca (sizeof (struct vet)); + if (p_vet == NULL) + return; + + p_vet->next = NULL; + p_vet->prev = last; + if (first == NULL) + first = p_vet; 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=(unsigned char *)_asn1_alloca(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); - _asn1_afree(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; + 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_vet->end = counter; + p = p->right; } - if(p_vet!=first) p_vet->prev->next=NULL; - else first=NULL; - _asn1_afree(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 = (unsigned char *) _asn1_alloca (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); + _asn1_afree (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; + _asn1_afree (p_vet); + p_vet = first; + } } /** @@ -748,300 +871,358 @@ _asn1_ordering_set_of(unsigned char *der, int der_len, node_asn *node) * **/ asn1_retCode -asn1_der_coding(ASN1_TYPE element,const char *name,void *ider,int *len, - char *ErrorDescription) +asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len, + char *ErrorDescription) { - node_asn *node,*p,*p2; - char temp[SIZEOF_UNSIGNED_LONG_INT*3+1]; - int counter,counter_old,len2,len3,tlen,move,max_len,max_len_old; + node_asn *node, *p, *p2; + char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1]; + int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old; asn1_retCode err; - unsigned char* der = ider; + unsigned char *der = ider; - 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; /* 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); + */ + 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 TYPE_NULL: - max_len--; - if(max_len>=0) - der[counter++]=0; - move=RIGHT; - break; - case TYPE_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 TYPE_INTEGER: case TYPE_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; + 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; } - len2=asn1_get_length_der(p->value,p->value_len, &len3); - if (len2<0) { - err = ASN1_DER_ERROR; - goto error; - } - max_len -= len2+len3; - if(max_len>=0) - memcpy(der+counter,p->value,len3+len2); - counter+=len3+len2; - } - move=RIGHT; - break; - case TYPE_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 TYPE_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,der+counter,&len2); - if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) - goto error; - - max_len-=len2; - counter+=len2; - move=RIGHT; - break; - case TYPE_OCTET_STRING: - if(p->value==NULL){ - _asn1_error_description_value_not_found(p,ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2=asn1_get_length_der(p->value,p->value_len,&len3); - if (len2<0) { - err = ASN1_DER_ERROR; - goto error; - } - max_len-=len2+len3; - if(max_len>=0) - memcpy(der+counter,p->value,len3+len2); - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_GENERALSTRING: - if(p->value==NULL){ - _asn1_error_description_value_not_found(p,ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2=asn1_get_length_der(p->value,p->value_len,&len3); - if (len2<0) { - err = ASN1_DER_ERROR; - goto error; - } - max_len-=len2+len3; - if(max_len>=0) - memcpy(der+counter,p->value,len3+len2); - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_BIT_STRING: - if(p->value==NULL){ - _asn1_error_description_value_not_found(p,ErrorDescription); - err = ASN1_VALUE_NOT_FOUND; - goto error; - } - len2=asn1_get_length_der(p->value,p->value_len,&len3); - if (len2<0) { - err = ASN1_DER_ERROR;\ - goto error; - } - max_len-=len2+len3; - if(max_len>=0) - memcpy(der+counter,p->value,len3+len2); - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_SEQUENCE: case TYPE_SET: - if(move!=UP){ - _asn1_ltostr(counter,temp); - tlen = 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)==TYPE_TAG)) p2=p2->right; - if(p2){ - p=p2; - move=RIGHT; - continue; - } - move=UP; - continue; + switch (type_field (p->type)) + { + case TYPE_NULL: + max_len--; + if (max_len >= 0) + der[counter++] = 0; + move = RIGHT; + break; + case TYPE_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 TYPE_INTEGER: + case TYPE_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 TYPE_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 TYPE_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, der + counter, &len2); + if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) + goto error; + + max_len -= len2; + counter += len2; + move = RIGHT; + break; + case TYPE_OCTET_STRING: + if (p->value == NULL) + { + _asn1_error_description_value_not_found (p, ErrorDescription); + err = ASN1_VALUE_NOT_FOUND; + goto error; + } + len2 = asn1_get_length_der (p->value, p->value_len, &len3); + if (len2 < 0) + { + err = ASN1_DER_ERROR; + goto error; + } + max_len -= len2 + len3; + if (max_len >= 0) + memcpy (der + counter, p->value, len3 + len2); + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_GENERALSTRING: + if (p->value == NULL) + { + _asn1_error_description_value_not_found (p, ErrorDescription); + err = ASN1_VALUE_NOT_FOUND; + goto error; + } + len2 = asn1_get_length_der (p->value, p->value_len, &len3); + if (len2 < 0) + { + err = ASN1_DER_ERROR; + goto error; + } + max_len -= len2 + len3; + if (max_len >= 0) + memcpy (der + counter, p->value, len3 + len2); + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_BIT_STRING: + if (p->value == NULL) + { + _asn1_error_description_value_not_found (p, ErrorDescription); + err = ASN1_VALUE_NOT_FOUND; + goto error; + } + len2 = asn1_get_length_der (p->value, p->value_len, &len3); + if (len2 < 0) + { + err = ASN1_DER_ERROR; + goto error; + } + max_len -= len2 + len3; + if (max_len >= 0) + memcpy (der + counter, p->value, len3 + len2); + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_SEQUENCE: + case TYPE_SET: + if (move != UP) + { + _asn1_ltostr (counter, temp); + tlen = 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) == TYPE_TAG)) + p2 = p2->right; + if (p2) + { + p = p2; + move = RIGHT; + continue; + } + move = UP; + continue; + } + } + else + { /* move==UP */ + len2 = strtol (p->value, NULL, 10); + _asn1_set_value (p, NULL, 0); + if ((type_field (p->type) == TYPE_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 TYPE_SEQUENCE_OF: + case TYPE_SET_OF: + if (move != UP) + { + _asn1_ltostr (counter, temp); + tlen = strlen (temp); + + if (tlen > 0) + _asn1_set_value (p, temp, tlen + 1); + p = p->down; + while ((type_field (p->type) == TYPE_TAG) + || (type_field (p->type) == TYPE_SIZE)) + p = p->right; + if (p->right) + { + p = p->right; + move = RIGHT; + continue; + } + else + p = _asn1_find_up (p); + move = UP; + } + if (move == UP) + { + len2 = strtol (p->value, NULL, 10); + _asn1_set_value (p, NULL, 0); + if ((type_field (p->type) == TYPE_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 TYPE_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; } - } - else{ /* move==UP */ - len2=strtol(p->value,NULL,10); - _asn1_set_value(p,NULL,0); - if((type_field(p->type)==TYPE_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); + + 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; } - counter+=len3; - move=RIGHT; - } - break; - case TYPE_SEQUENCE_OF: case TYPE_SET_OF: - if(move!=UP){ - _asn1_ltostr(counter,temp); - tlen = strlen(temp); - - if (tlen > 0) - _asn1_set_value(p,temp,tlen+1); - p=p->down; - while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right; - if(p->right){ - p=p->right; - move=RIGHT; - continue; + + if (p == node && move != DOWN) + break; + + if (move == DOWN) + { + if (p->down) + p = p->down; + else + move = RIGHT; } - else p=_asn1_find_up(p); - move=UP; - } - if(move==UP){ - len2=strtol(p->value,NULL,10); - _asn1_set_value(p,NULL,0); - if((type_field(p->type)==TYPE_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); + if (move == RIGHT) + { + if (p->right) + p = p->right; + else + move = UP; } - counter+=len3; - move=RIGHT; - } - break; - case TYPE_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 (max_len < 0) + { + err = ASN1_MEM_ERROR; + goto error; } - if(move==RIGHT){ - if(p->right) p=p->right; - else move=UP; - } - if(move==UP) p=_asn1_find_up(p); - } - - *len=counter; - - if(max_len<0) { - err = ASN1_MEM_ERROR; - goto error; - } err = ASN1_SUCCESS; error: - asn1_delete_structure(&node); + asn1_delete_structure (&node); return err; } |