diff options
author | Simon Josefsson <simon@josefsson.org> | 2006-05-10 17:12:36 +0000 |
---|---|---|
committer | Simon Josefsson <simon@josefsson.org> | 2006-05-10 17:12:36 +0000 |
commit | e11d1682be2fc8b9f2fb70b8acc4d2ec94b7634e (patch) | |
tree | 9ece77d896282c31c0c8bfdc95f7ab34e62f4356 | |
parent | 08e9c6b30823418a16fba30c989814b5e9b25e7c (diff) | |
download | gnutls-e11d1682be2fc8b9f2fb70b8acc4d2ec94b7634e.tar.gz |
Update to 0.3.4.
-rw-r--r-- | lib/minitasn1/coding.c | 1527 | ||||
-rw-r--r-- | lib/minitasn1/decoding.c | 4034 | ||||
-rw-r--r-- | lib/minitasn1/element.c | 1113 | ||||
-rw-r--r-- | lib/minitasn1/errors.c | 93 | ||||
-rw-r--r-- | lib/minitasn1/gstr.c | 50 | ||||
-rw-r--r-- | lib/minitasn1/libtasn1.h | 8 | ||||
-rw-r--r-- | lib/minitasn1/parser_aux.c | 1118 | ||||
-rw-r--r-- | lib/minitasn1/parser_aux.h | 2 | ||||
-rw-r--r-- | lib/minitasn1/structure.c | 7 |
9 files changed, 4515 insertions, 3437 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; } diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c index 15396660cd..3df85318e6 100644 --- a/lib/minitasn1/decoding.c +++ b/lib/minitasn1/decoding.c @@ -19,13 +19,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA */ - + /*****************************************************/ /* File: decoding.c */ /* Description: Functions to manage DER decoding */ /*****************************************************/ - + #include <int.h> #include <errors.h> #include "parser_aux.h" @@ -35,13 +35,13 @@ void -_asn1_error_description_tag_error(node_asn *node,char *ErrorDescription) +_asn1_error_description_tag_error (node_asn * node, char *ErrorDescription) { - Estrcpy(ErrorDescription,":: tag error near element '"); - _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription), - MAX_ERROR_DESCRIPTION_SIZE-40); - Estrcat(ErrorDescription,"'"); + Estrcpy (ErrorDescription, ":: tag error near element '"); + _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription), + MAX_ERROR_DESCRIPTION_SIZE - 40); + Estrcat (ErrorDescription, "'"); } @@ -57,41 +57,47 @@ _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription) * length, or -2 when the value was too big. **/ signed long -asn1_get_length_der(const unsigned char *der, int der_len, int *len) +asn1_get_length_der (const unsigned char *der, int der_len, int *len) { unsigned long ans; - int k,punt; + int k, punt; *len = 0; - if (der_len <= 0) return 0; - - if(!(der[0]&128)){ - /* short form */ - *len=1; - return der[0]; - } - else{ - /* Long form */ - k=der[0]&0x7F; - punt=1; - if(k){ /* definite length method */ - ans=0; - while(punt<=k && punt < der_len) { - unsigned long last = ans; - - ans=ans*256+der[punt++]; - if (ans < last) - /* we wrapped around, no bignum support... */ - return -2; - } - } - else{ /* indefinite length method */ - ans=-1; + if (der_len <= 0) + return 0; + + if (!(der[0] & 128)) + { + /* short form */ + *len = 1; + return der[0]; } + else + { + /* Long form */ + k = der[0] & 0x7F; + punt = 1; + if (k) + { /* definite length method */ + ans = 0; + while (punt <= k && punt < der_len) + { + unsigned long last = ans; + + ans = ans * 256 + der[punt++]; + if (ans < last) + /* we wrapped around, no bignum support... */ + return -2; + } + } + else + { /* indefinite length method */ + ans = -1; + } - *len=punt; - return ans; - } + *len = punt; + return ans; + } } @@ -110,43 +116,47 @@ asn1_get_length_der(const unsigned char *der, int der_len, int *len) * Return value: Returns ASN1_SUCCESS on success, or an error. **/ int -asn1_get_tag_der(const unsigned char *der, int der_len, - unsigned char *class,int *len, unsigned long *tag) +asn1_get_tag_der (const unsigned char *der, int der_len, + unsigned char *class, int *len, unsigned long *tag) { - int punt,ris; - - if (der==NULL || der_len <= 0 || len == NULL) return ASN1_DER_ERROR; - - *class=der[0]&0xE0; - if((der[0]&0x1F)!=0x1F){ - /* short form */ - *len=1; - ris=der[0]&0x1F; - } - else{ - /* Long form */ - punt=1; - ris=0; - while(punt <= der_len && der[punt]&128) + int punt, ris; + + if (der == NULL || der_len <= 0 || len == NULL) + return ASN1_DER_ERROR; + + *class = der[0] & 0xE0; + if ((der[0] & 0x1F) != 0x1F) + { + /* short form */ + *len = 1; + ris = der[0] & 0x1F; + } + else + { + /* Long form */ + punt = 1; + ris = 0; + while (punt <= der_len && der[punt] & 128) + { + int last = ris; + ris = ris * 128 + (der[punt++] & 0x7F); + if (ris < last) + /* wrapper around, and no bignums... */ + return ASN1_DER_ERROR; + } + if (punt >= der_len) + return ASN1_DER_ERROR; { int last = ris; - ris=ris*128+(der[punt++]&0x7F); + ris = ris * 128 + (der[punt++] & 0x7F); if (ris < last) /* wrapper around, and no bignums... */ return ASN1_DER_ERROR; } - if (punt >= der_len) - return ASN1_DER_ERROR; - { - int last = ris; - ris=ris*128+(der[punt++]&0x7F); - if (ris < last) - /* wrapper around, and no bignums... */ - return ASN1_DER_ERROR; + *len = punt; } - *len=punt; - } - if (tag) *tag = ris; + if (tag) + *tag = ris; return ASN1_SUCCESS; } @@ -167,25 +177,28 @@ asn1_get_tag_der(const unsigned char *der, int der_len, * Return value: Returns ASN1_SUCCESS on success, or an error. **/ int -asn1_get_octet_der(const unsigned char *der, int der_len, - int *ret_len,unsigned char *str, int str_size, int *str_len) +asn1_get_octet_der (const unsigned char *der, int der_len, + int *ret_len, unsigned char *str, int str_size, + int *str_len) { int len_len; - if (der_len <= 0) return ASN1_GENERIC_ERROR; + if (der_len <= 0) + return ASN1_GENERIC_ERROR; /* if(str==NULL) return ASN1_SUCCESS; */ - *str_len=asn1_get_length_der(der, der_len, &len_len); + *str_len = asn1_get_length_der (der, der_len, &len_len); if (*str_len < 0) - return ASN1_DER_ERROR; + return ASN1_DER_ERROR; - *ret_len=*str_len+len_len; - if ( str_size >= *str_len) - memcpy(str,der+len_len,*str_len); - else { - return ASN1_MEM_ERROR; - } + *ret_len = *str_len + len_len; + if (str_size >= *str_len) + memcpy (str, der + len_len, *str_len); + else + { + return ASN1_MEM_ERROR; + } return ASN1_SUCCESS; } @@ -195,56 +208,64 @@ asn1_get_octet_der(const unsigned char *der, int der_len, /* Returns ASN1_SUCCESS on success or an error code on error. */ int -_asn1_get_time_der(const unsigned char *der, int der_len, int *ret_len,unsigned char *str,int str_size) +_asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len, + char *str, int str_size) { - int len_len,str_len; - - if(der_len <=0 || str==NULL) return ASN1_DER_ERROR; - str_len=asn1_get_length_der(der, der_len, &len_len); - if (str_len < 0 || str_size < str_len) - return ASN1_DER_ERROR; - memcpy(str,der+len_len,str_len); - str[str_len]=0; - *ret_len=str_len+len_len; - + int len_len, str_len; + + if (der_len <= 0 || str == NULL) + return ASN1_DER_ERROR; + str_len = asn1_get_length_der (der, der_len, &len_len); + if (str_len < 0 || str_size < str_len) + return ASN1_DER_ERROR; + memcpy (str, der + len_len, str_len); + str[str_len] = 0; + *ret_len = str_len + len_len; + return ASN1_SUCCESS; } void -_asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsigned char *str, int str_size) +_asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len, + char *str, int str_size) { - int len_len,len,k; + int len_len, len, k; char temp[20]; - unsigned long val,val1; + unsigned long val, val1; *ret_len = 0; - if (str && str_size > 0) str[0] = 0; /* no oid */ - - if(str==NULL || der_len <= 0) return; - len=asn1_get_length_der(der,der_len, &len_len); - - if (len < 0 || len > der_len || len_len > der_len) return; - - val1=der[len_len]/40; - val=der[len_len]-val1*40; - - _asn1_str_cpy(str, str_size, _asn1_ltostr(val1,temp)); - _asn1_str_cat(str, str_size, "."); - _asn1_str_cat(str, str_size, _asn1_ltostr(val,temp)); - - val=0; - for(k=1;k<len;k++){ - val=val<<7; - val|=der[len_len+k]&0x7F; - if(!(der[len_len+k]&0x80)){ - _asn1_str_cat(str, str_size,"."); - _asn1_str_cat(str, str_size,_asn1_ltostr(val,temp)); - val=0; + if (str && str_size > 0) + str[0] = 0; /* no oid */ + + if (str == NULL || der_len <= 0) + return; + len = asn1_get_length_der (der, der_len, &len_len); + + if (len < 0 || len > der_len || len_len > der_len) + return; + + val1 = der[len_len] / 40; + val = der[len_len] - val1 * 40; + + _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp)); + _asn1_str_cat (str, str_size, "."); + _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp)); + + val = 0; + for (k = 1; k < len; k++) + { + val = val << 7; + val |= der[len_len + k] & 0x7F; + if (!(der[len_len + k] & 0x80)) + { + _asn1_str_cat (str, str_size, "."); + _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp)); + val = 0; + } } - } - *ret_len=len+len_len; + *ret_len = len + len_len; } @@ -264,24 +285,27 @@ _asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsign * Return value: Return ASN1_SUCCESS on success, or an error. **/ int -asn1_get_bit_der(const unsigned char *der, int der_len, - int *ret_len, unsigned char *str, int str_size, int *bit_len) +asn1_get_bit_der (const unsigned char *der, int der_len, + int *ret_len, unsigned char *str, int str_size, + int *bit_len) { - int len_len,len_byte; + int len_len, len_byte; - if (der_len <=0) return ASN1_GENERIC_ERROR; - len_byte=asn1_get_length_der(der,der_len,&len_len)-1; + if (der_len <= 0) + return ASN1_GENERIC_ERROR; + len_byte = asn1_get_length_der (der, der_len, &len_len) - 1; if (len_byte < 0) return ASN1_DER_ERROR; - *ret_len=len_byte+len_len+1; - *bit_len=len_byte*8-der[len_len]; + *ret_len = len_byte + len_len + 1; + *bit_len = len_byte * 8 - der[len_len]; if (str_size >= len_byte) - memcpy(str,der+len_len+1,len_byte); - else { - return ASN1_MEM_ERROR; - } + memcpy (str, der + len_len + 1, len_byte); + else + { + return ASN1_MEM_ERROR; + } return ASN1_SUCCESS; } @@ -290,320 +314,412 @@ asn1_get_bit_der(const unsigned char *der, int der_len, int -_asn1_extract_tag_der(node_asn *node,const unsigned char *der, int der_len,int *ret_len) +_asn1_extract_tag_der (node_asn * node, const unsigned char *der, int der_len, + int *ret_len) { node_asn *p; - int counter,len2,len3,is_tag_implicit; - unsigned long tag,tag_implicit=0; - unsigned char class,class2,class_implicit=0; - - if (der_len <= 0) return ASN1_GENERIC_ERROR; - - counter=is_tag_implicit=0; - - if(node->type&CONST_TAG){ - p=node->down; - while(p){ - if(type_field(p->type)==TYPE_TAG){ - if(p->type&CONST_APPLICATION) class2=ASN1_CLASS_APPLICATION; - else if(p->type&CONST_UNIVERSAL) class2=ASN1_CLASS_UNIVERSAL; - else if(p->type&CONST_PRIVATE) class2=ASN1_CLASS_PRIVATE; - else class2=ASN1_CLASS_CONTEXT_SPECIFIC; - - if(p->type&CONST_EXPLICIT){ - if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS) - return ASN1_DER_ERROR; - if (counter+len2 > der_len) - return ASN1_DER_ERROR; - counter+=len2; - len3=asn1_get_length_der(der+counter,der_len-counter, &len2); - if (len3 < 0) - return ASN1_DER_ERROR; - counter+=len2; - if(!is_tag_implicit){ - if((class!=(class2|ASN1_CLASS_STRUCTURED)) || - (tag!=strtoul(p->value,NULL,10))) - return ASN1_TAG_ERROR; - } - else{ /* ASN1_TAG_IMPLICIT */ - if((class!=class_implicit) || (tag!=tag_implicit)) - return ASN1_TAG_ERROR; - } - - is_tag_implicit=0; - } - else{ /* ASN1_TAG_IMPLICIT */ - if(!is_tag_implicit){ - if((type_field(node->type)==TYPE_SEQUENCE) || - (type_field(node->type)==TYPE_SEQUENCE_OF) || - (type_field(node->type)==TYPE_SET) || - (type_field(node->type)==TYPE_SET_OF)) class2|=ASN1_CLASS_STRUCTURED; - class_implicit=class2; - tag_implicit=strtoul(p->value,NULL,10); - is_tag_implicit=1; - } + int counter, len2, len3, is_tag_implicit; + unsigned long tag, tag_implicit = 0; + unsigned char class, class2, class_implicit = 0; + + if (der_len <= 0) + return ASN1_GENERIC_ERROR; + + counter = is_tag_implicit = 0; + + if (node->type & CONST_TAG) + { + p = node->down; + while (p) + { + if (type_field (p->type) == TYPE_TAG) + { + if (p->type & CONST_APPLICATION) + class2 = ASN1_CLASS_APPLICATION; + else if (p->type & CONST_UNIVERSAL) + class2 = ASN1_CLASS_UNIVERSAL; + else if (p->type & CONST_PRIVATE) + class2 = ASN1_CLASS_PRIVATE; + else + class2 = ASN1_CLASS_CONTEXT_SPECIFIC; + + if (p->type & CONST_EXPLICIT) + { + if (asn1_get_tag_der + (der + counter, der_len - counter, &class, &len2, + &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter + len2 > der_len) + return ASN1_DER_ERROR; + counter += len2; + len3 = + asn1_get_length_der (der + counter, der_len - counter, + &len2); + if (len3 < 0) + return ASN1_DER_ERROR; + counter += len2; + if (!is_tag_implicit) + { + if ((class != (class2 | ASN1_CLASS_STRUCTURED)) || + (tag != strtoul ((char *) p->value, NULL, 10))) + return ASN1_TAG_ERROR; + } + else + { /* ASN1_TAG_IMPLICIT */ + if ((class != class_implicit) || (tag != tag_implicit)) + return ASN1_TAG_ERROR; + } + + is_tag_implicit = 0; + } + else + { /* ASN1_TAG_IMPLICIT */ + if (!is_tag_implicit) + { + if ((type_field (node->type) == TYPE_SEQUENCE) || + (type_field (node->type) == TYPE_SEQUENCE_OF) || + (type_field (node->type) == TYPE_SET) || + (type_field (node->type) == TYPE_SET_OF)) + class2 |= ASN1_CLASS_STRUCTURED; + class_implicit = class2; + tag_implicit = strtoul ((char *) p->value, NULL, 10); + is_tag_implicit = 1; + } + } + } + p = p->right; } - } - p=p->right; } - } - if(is_tag_implicit){ - if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS) - return ASN1_DER_ERROR; - if (counter+len2 > der_len) - return ASN1_DER_ERROR; + if (is_tag_implicit) + { + if (asn1_get_tag_der + (der + counter, der_len - counter, &class, &len2, + &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter + len2 > der_len) + return ASN1_DER_ERROR; - if((class!=class_implicit) || (tag!=tag_implicit)){ - if(type_field(node->type)==TYPE_OCTET_STRING){ - class_implicit |= ASN1_CLASS_STRUCTURED; - if((class!=class_implicit) || (tag!=tag_implicit)) - return ASN1_TAG_ERROR; - } - else - return ASN1_TAG_ERROR; - } - } - else{ - if(type_field(node->type)==TYPE_TAG){ - counter=0; - *ret_len=counter; - return ASN1_SUCCESS; + if ((class != class_implicit) || (tag != tag_implicit)) + { + if (type_field (node->type) == TYPE_OCTET_STRING) + { + class_implicit |= ASN1_CLASS_STRUCTURED; + if ((class != class_implicit) || (tag != tag_implicit)) + return ASN1_TAG_ERROR; + } + else + return ASN1_TAG_ERROR; + } } + else + { + if (type_field (node->type) == TYPE_TAG) + { + counter = 0; + *ret_len = counter; + return ASN1_SUCCESS; + } - if (asn1_get_tag_der(der+counter, der_len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) - return ASN1_DER_ERROR; - if (counter+len2 > der_len) - return ASN1_DER_ERROR; - - switch(type_field(node->type)){ - case TYPE_NULL: - if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_NULL)) return ASN1_DER_ERROR; - break; - case TYPE_BOOLEAN: - if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_BOOLEAN)) return ASN1_DER_ERROR; - break; - case TYPE_INTEGER: - if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_INTEGER)) return ASN1_DER_ERROR; - break; - case TYPE_ENUMERATED: - if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_ENUMERATED)) return ASN1_DER_ERROR; - break; - case TYPE_OBJECT_ID: - if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_OBJECT_ID)) return ASN1_DER_ERROR; - break; - case TYPE_TIME: - if(node->type&CONST_UTC){ - if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_UTCTime)) return ASN1_DER_ERROR; - } - else{ - if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_GENERALIZEDTime)) - return ASN1_DER_ERROR; - } - break; - case TYPE_OCTET_STRING: - if(((class!=ASN1_CLASS_UNIVERSAL) && (class!=(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED))) - || (tag!=ASN1_TAG_OCTET_STRING)) return ASN1_DER_ERROR; - break; - case TYPE_GENERALSTRING: - if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_GENERALSTRING)) return ASN1_DER_ERROR; - break; - case TYPE_BIT_STRING: - if((class!=ASN1_CLASS_UNIVERSAL) || (tag!=ASN1_TAG_BIT_STRING)) return ASN1_DER_ERROR; - break; - case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF: - if((class!=(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED)) || (tag!=ASN1_TAG_SEQUENCE)) + if (asn1_get_tag_der + (der + counter, der_len - counter, &class, &len2, + &tag) != ASN1_SUCCESS) return ASN1_DER_ERROR; - break; - case TYPE_SET: case TYPE_SET_OF: - if((class!=(ASN1_CLASS_UNIVERSAL|ASN1_CLASS_STRUCTURED)) || (tag!=ASN1_TAG_SET)) + if (counter + len2 > der_len) return ASN1_DER_ERROR; - break; - case TYPE_ANY: - counter-=len2; - break; - default: - return ASN1_DER_ERROR; - break; + + switch (type_field (node->type)) + { + case TYPE_NULL: + if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL)) + return ASN1_DER_ERROR; + break; + case TYPE_BOOLEAN: + if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN)) + return ASN1_DER_ERROR; + break; + case TYPE_INTEGER: + if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER)) + return ASN1_DER_ERROR; + break; + case TYPE_ENUMERATED: + if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED)) + return ASN1_DER_ERROR; + break; + case TYPE_OBJECT_ID: + if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID)) + return ASN1_DER_ERROR; + break; + case TYPE_TIME: + if (node->type & CONST_UTC) + { + if ((class != ASN1_CLASS_UNIVERSAL) + || (tag != ASN1_TAG_UTCTime)) + return ASN1_DER_ERROR; + } + else + { + if ((class != ASN1_CLASS_UNIVERSAL) + || (tag != ASN1_TAG_GENERALIZEDTime)) + return ASN1_DER_ERROR; + } + break; + case TYPE_OCTET_STRING: + if (((class != ASN1_CLASS_UNIVERSAL) + && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))) + || (tag != ASN1_TAG_OCTET_STRING)) + return ASN1_DER_ERROR; + break; + case TYPE_GENERALSTRING: + if ((class != ASN1_CLASS_UNIVERSAL) + || (tag != ASN1_TAG_GENERALSTRING)) + return ASN1_DER_ERROR; + break; + case TYPE_BIT_STRING: + if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING)) + return ASN1_DER_ERROR; + break; + case TYPE_SEQUENCE: + case TYPE_SEQUENCE_OF: + if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)) + || (tag != ASN1_TAG_SEQUENCE)) + return ASN1_DER_ERROR; + break; + case TYPE_SET: + case TYPE_SET_OF: + if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)) + || (tag != ASN1_TAG_SET)) + return ASN1_DER_ERROR; + break; + case TYPE_ANY: + counter -= len2; + break; + default: + return ASN1_DER_ERROR; + break; + } } - } - counter+=len2; - *ret_len=counter; + counter += len2; + *ret_len = counter; return ASN1_SUCCESS; } -int -_asn1_delete_not_used(node_asn *node) +int +_asn1_delete_not_used (node_asn * node) { - node_asn *p,*p2; + node_asn *p, *p2; - if(node==NULL) return ASN1_ELEMENT_NOT_FOUND; + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; - p=node; - while(p){ - if(p->type&CONST_NOT_USED){ - p2=NULL; - if(p!=node){ - p2=_asn1_find_left(p); - if(!p2) p2=_asn1_find_up(p); - } - asn1_delete_structure(&p); - p=p2; - } + p = node; + while (p) + { + if (p->type & CONST_NOT_USED) + { + p2 = NULL; + if (p != node) + { + p2 = _asn1_find_left (p); + if (!p2) + p2 = _asn1_find_up (p); + } + asn1_delete_structure (&p); + p = p2; + } - if(!p) break; /* reach node */ + if (!p) + break; /* reach node */ - if(p->down){ - p=p->down; - } - else{ - if(p==node) p=NULL; - else if(p->right) p=p->right; - else{ - while(1){ - p=_asn1_find_up(p); - if(p==node){ - p=NULL; - break; - } - if(p->right){ - p=p->right; - break; - } + if (p->down) + { + p = p->down; + } + else + { + if (p == node) + p = NULL; + else if (p->right) + p = p->right; + else + { + while (1) + { + p = _asn1_find_up (p); + if (p == node) + { + p = NULL; + break; + } + if (p->right) + { + p = p->right; + break; + } + } + } } - } } - } return ASN1_SUCCESS; } asn1_retCode -_asn1_get_octet_string(const unsigned char* der, node_asn *node,int* len) +_asn1_get_octet_string (const unsigned char *der, node_asn * node, int *len) { - int len2,len3,counter,counter2,counter_end,tot_len,indefinite; - char *temp,*temp2; + int len2, len3, counter, counter2, counter_end, tot_len, indefinite; + unsigned char *temp, *temp2; - counter=0; + counter = 0; - if(*(der-1) & ASN1_CLASS_STRUCTURED){ - tot_len=0; - indefinite=asn1_get_length_der(der, *len, &len3); - if (indefinite < -1) - return ASN1_DER_ERROR; + if (*(der - 1) & ASN1_CLASS_STRUCTURED) + { + tot_len = 0; + indefinite = asn1_get_length_der (der, *len, &len3); + if (indefinite < -1) + return ASN1_DER_ERROR; - counter+=len3; - if(indefinite>=0) indefinite+=len3; - - while(1){ - if(counter>(*len)) return ASN1_DER_ERROR; + counter += len3; + if (indefinite >= 0) + indefinite += len3; - if(indefinite==-1){ - if((der[counter]==0) && (der[counter+1]==0)){ - counter+=2; - break; + while (1) + { + if (counter > (*len)) + return ASN1_DER_ERROR; + + if (indefinite == -1) + { + if ((der[counter] == 0) && (der[counter + 1] == 0)) + { + counter += 2; + break; + } + } + else if (counter >= indefinite) + break; + + if (der[counter] != ASN1_TAG_OCTET_STRING) + return ASN1_DER_ERROR; + + counter++; + + len2 = asn1_get_length_der (der + counter, *len - counter, &len3); + if (len2 <= 0) + return ASN1_DER_ERROR; + + counter += len3 + len2; + tot_len += len2; } - } - else if(counter>=indefinite) break; - if(der[counter] != ASN1_TAG_OCTET_STRING) return ASN1_DER_ERROR; + /* copy */ + if (node) + { + asn1_length_der (tot_len, NULL, &len2); + temp = _asn1_alloca (len2 + tot_len); + if (temp == NULL) + { + return ASN1_MEM_ALLOC_ERROR; + } - counter++; + asn1_length_der (tot_len, 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; - len2=asn1_get_length_der(der+counter,*len-counter, &len3); - if(len2 <= 0) return ASN1_DER_ERROR; + 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; + } - counter+=len3+len2; - tot_len+=len2; + _asn1_set_value (node, temp, tot_len); + _asn1_afree (temp); + } } - - /* copy */ - if(node){ - asn1_length_der(tot_len,NULL,&len2); - temp=(unsigned char *)_asn1_alloca(len2+tot_len); - if (temp==NULL){ - return ASN1_MEM_ALLOC_ERROR; - } - - asn1_length_der(tot_len,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; - - 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_afree(temp); + else + { /* NOT STRUCTURED */ + len2 = asn1_get_length_der (der, *len, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + if (len3 + len2 > *len) + return ASN1_DER_ERROR; + if (node) + _asn1_set_value (node, der, len3 + len2); + counter = len3 + len2; } - } - else{ /* NOT STRUCTURED */ - len2=asn1_get_length_der(der, *len, &len3); - if(len2 < 0) return ASN1_DER_ERROR; - if (len3+len2 > *len) return ASN1_DER_ERROR; - if(node) - _asn1_set_value(node,der,len3+len2); - counter=len3+len2; - } - - *len=counter; + + *len = counter; return ASN1_SUCCESS; } asn1_retCode -_asn1_get_indefinite_length_string(const unsigned char* der, int* len) +_asn1_get_indefinite_length_string (const unsigned char *der, int *len) { - int len2,len3,counter,indefinite; + int len2, len3, counter, indefinite; unsigned long tag; unsigned char class; - counter=indefinite=0; + counter = indefinite = 0; - while(1){ - if((*len)<counter) return ASN1_DER_ERROR; + while (1) + { + if ((*len) < counter) + return ASN1_DER_ERROR; - if((der[counter]==0) && (der[counter+1]==0)){ - counter+=2; - indefinite--; - if(indefinite<=0) break; - else continue; - } + if ((der[counter] == 0) && (der[counter + 1] == 0)) + { + counter += 2; + indefinite--; + if (indefinite <= 0) + break; + else + continue; + } - if(asn1_get_tag_der(der+counter, *len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) - return ASN1_DER_ERROR; - if (counter+len2 > *len) - return ASN1_DER_ERROR; - counter+=len2; - len2=asn1_get_length_der(der+counter, *len-counter,&len3); - if(len2 < -1) return ASN1_DER_ERROR; - if(len2 == -1){ - indefinite++; - counter+=1; - } - else{ - counter+=len2+len3; + if (asn1_get_tag_der + (der + counter, *len - counter, &class, &len2, + &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter + len2 > *len) + return ASN1_DER_ERROR; + counter += len2; + len2 = asn1_get_length_der (der + counter, *len - counter, &len3); + if (len2 < -1) + return ASN1_DER_ERROR; + if (len2 == -1) + { + indefinite++; + counter += 1; + } + else + { + counter += len2 + len3; + } } - } - *len=counter; + *len = counter; return ASN1_SUCCESS; } @@ -634,416 +750,541 @@ _asn1_get_indefinite_length_string(const unsigned char* der, int* len) **/ asn1_retCode -asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len, - char *errorDescription) +asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len, + char *errorDescription) { - node_asn *node,*p,*p2,*p3; + node_asn *node, *p, *p2, *p3; char temp[128]; - int counter,len2,len3,len4,move,ris,tlen; - unsigned char class,*temp2; + int counter, len2, len3, len4, move, ris, tlen; + unsigned char class, *temp2; unsigned long tag; int indefinite, result; - const unsigned char* der = ider; + const unsigned char *der = ider; - node=*element; + node = *element; - if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND; + if (node == ASN1_TYPE_EMPTY) + return ASN1_ELEMENT_NOT_FOUND; - if(node->type&CONST_OPTION){ - asn1_delete_structure(element); - return ASN1_GENERIC_ERROR; - } - - counter=0; - move=DOWN; - p=node; - while(1){ - ris=ASN1_SUCCESS; - if(move!=UP){ - if(p->type&CONST_SET){ - p2=_asn1_find_up(p); - len2=strtol(p2->value,NULL,10); - if(len2==-1){ - if(!der[counter] && !der[counter+1]){ - p=p2; - move=UP; - counter+=2; - continue; - } - } - else if(counter==len2){ - p=p2; - move=UP; - continue; - } - else if(counter>len2){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; - } - p2=p2->down; - while(p2){ - if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ - if(type_field(p2->type)!=TYPE_CHOICE) - ris=_asn1_extract_tag_der(p2,der+counter,len-counter, &len2); - else{ - p3=p2->down; - while(p3){ - ris=_asn1_extract_tag_der(p3,der+counter,len-counter, &len2); - if(ris==ASN1_SUCCESS) break; - p3=p3->right; - } - } - if(ris==ASN1_SUCCESS){ - p2->type&=~CONST_NOT_USED; - p=p2; - break; - } - } - p2=p2->right; - } - if(p2==NULL){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; - } - } + if (node->type & CONST_OPTION) + { + asn1_delete_structure (element); + return ASN1_GENERIC_ERROR; + } - if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){ - p2=_asn1_find_up(p); - len2=strtol(p2->value,NULL,10); - if(counter==len2){ - if(p->right){ - p2=p->right; - move=RIGHT; - } - else move=UP; + counter = 0; + move = DOWN; + p = node; + while (1) + { + ris = ASN1_SUCCESS; + if (move != UP) + { + if (p->type & CONST_SET) + { + p2 = _asn1_find_up (p); + len2 = strtol (p2->value, NULL, 10); + if (len2 == -1) + { + if (!der[counter] && !der[counter + 1]) + { + p = p2; + move = UP; + counter += 2; + continue; + } + } + else if (counter == len2) + { + p = p2; + move = UP; + continue; + } + else if (counter > len2) + { + asn1_delete_structure (element); + return ASN1_DER_ERROR; + } + p2 = p2->down; + while (p2) + { + if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) + { + if (type_field (p2->type) != TYPE_CHOICE) + ris = + _asn1_extract_tag_der (p2, der + counter, + len - counter, &len2); + else + { + p3 = p2->down; + while (p3) + { + ris = + _asn1_extract_tag_der (p3, der + counter, + len - counter, &len2); + if (ris == ASN1_SUCCESS) + break; + p3 = p3->right; + } + } + if (ris == ASN1_SUCCESS) + { + p2->type &= ~CONST_NOT_USED; + p = p2; + break; + } + } + p2 = p2->right; + } + if (p2 == NULL) + { + asn1_delete_structure (element); + return ASN1_DER_ERROR; + } + } - if(p->type&CONST_OPTION) asn1_delete_structure(&p); + if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) + { + p2 = _asn1_find_up (p); + len2 = strtol (p2->value, NULL, 10); + if (counter == len2) + { + if (p->right) + { + p2 = p->right; + move = RIGHT; + } + else + move = UP; - p=p2; - continue; - } - } + if (p->type & CONST_OPTION) + asn1_delete_structure (&p); - if(type_field(p->type)==TYPE_CHOICE){ - while(p->down){ - if(counter<len) - ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2); - else - ris=ASN1_DER_ERROR; - if(ris==ASN1_SUCCESS){ - while(p->down->right){ - p2=p->down->right; - asn1_delete_structure(&p2); + p = p2; + continue; + } } - break; - } - else if(ris==ASN1_ERROR_TYPE_ANY){ - asn1_delete_structure(element); - return ASN1_ERROR_TYPE_ANY; - } - else{ - p2=p->down; - asn1_delete_structure(&p2); - } - } - - if(p->down==NULL){ - if(!(p->type&CONST_OPTION)){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; - } - } - else - p=p->down; - } - if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){ - p2=_asn1_find_up(p); - len2=strtol(p2->value,NULL,10); - if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR; - } - - if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2); - if(ris!=ASN1_SUCCESS){ - if(p->type&CONST_OPTION){ - p->type|=CONST_NOT_USED; - move=RIGHT; - } - else if(p->type&CONST_DEFAULT) { - _asn1_set_value(p,NULL,0); - move=RIGHT; - } - else { - if (errorDescription!=NULL) - _asn1_error_description_tag_error(p,errorDescription); - - asn1_delete_structure(element); - return ASN1_TAG_ERROR; - } - } - else counter+=len2; - } + if (type_field (p->type) == TYPE_CHOICE) + { + while (p->down) + { + if (counter < len) + ris = + _asn1_extract_tag_der (p->down, der + counter, + len - counter, &len2); + else + ris = ASN1_DER_ERROR; + if (ris == ASN1_SUCCESS) + { + while (p->down->right) + { + p2 = p->down->right; + asn1_delete_structure (&p2); + } + break; + } + else if (ris == ASN1_ERROR_TYPE_ANY) + { + asn1_delete_structure (element); + return ASN1_ERROR_TYPE_ANY; + } + else + { + p2 = p->down; + asn1_delete_structure (&p2); + } + } - if(ris==ASN1_SUCCESS){ - switch(type_field(p->type)){ - case TYPE_NULL: - if(der[counter]){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; - } - counter++; - move=RIGHT; - break; - case TYPE_BOOLEAN: - if(der[counter++]!=1){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; - } - if(der[counter++]==0) _asn1_set_value(p,"F",1); - else _asn1_set_value(p,"T",1); - move=RIGHT; - break; - case TYPE_INTEGER: case TYPE_ENUMERATED: - len2=asn1_get_length_der(der+counter,len-counter, &len3); - if(len2 < 0) return ASN1_DER_ERROR; - if (len2+len3 > len-counter) return ASN1_DER_ERROR; - _asn1_set_value(p,der+counter,len3+len2); - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_OBJECT_ID: - _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp)); - tlen = strlen(temp); - if( tlen > 0) - _asn1_set_value(p,temp,tlen+1); - counter+=len2; - move=RIGHT; - break; - case TYPE_TIME: - result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1); - if (result != ASN1_SUCCESS) { - asn1_delete_structure(element); - return result; - } - tlen = strlen(temp); - if (tlen > 0) - _asn1_set_value(p,temp,tlen+1); - counter+=len2; - move=RIGHT; - break; - case TYPE_OCTET_STRING: - len3=len-counter; - ris=_asn1_get_octet_string(der+counter,p,&len3); - if(ris != ASN1_SUCCESS) return ris; - counter+=len3; - move=RIGHT; - break; - case TYPE_GENERALSTRING: - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - if (len3+len2 > len-counter) return ASN1_DER_ERROR; - _asn1_set_value(p,der+counter,len3+len2); - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_BIT_STRING: - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - if (len3+len2 > len-counter) return ASN1_DER_ERROR; - _asn1_set_value(p,der+counter,len3+len2); - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_SEQUENCE: case TYPE_SET: - if(move==UP){ - len2=strtol(p->value,NULL,10); - _asn1_set_value(p,NULL,0); - if(len2==-1){ /* indefinite length method */ - if (len-counter+1 > 0) { - if((der[counter]) || der[counter+1]){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; - } - } else return ASN1_DER_ERROR; - counter+=2; - } - else{ /* definite length method */ - if(len2!=counter){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; - } - } - move=RIGHT; - } - else{ /* move==DOWN || move==RIGHT */ - len3=asn1_get_length_der(der+counter,len-counter,&len2); - if(len3 < -1) return ASN1_DER_ERROR; - counter+=len2; - if(len3>0){ - _asn1_ltostr(counter+len3,temp); - tlen = strlen(temp); - if (tlen > 0) - _asn1_set_value(p,temp,tlen+1); - move=DOWN; - } - else if(len3==0){ - p2=p->down; - while(p2){ - if(type_field(p2->type)!=TYPE_TAG){ - p3=p2->right; - asn1_delete_structure(&p2); - p2=p3; - } + if (p->down == NULL) + { + if (!(p->type & CONST_OPTION)) + { + asn1_delete_structure (element); + return ASN1_DER_ERROR; + } + } else - p2=p2->right; - } - move=RIGHT; - } - else{ /* indefinite length method */ - _asn1_set_value(p,"-1",3); - move=DOWN; - } - } - break; - case TYPE_SEQUENCE_OF: case TYPE_SET_OF: - if(move==UP){ - len2=strtol(p->value,NULL,10); - if(len2==-1){ /* indefinite length method */ - if((counter+2)>len) return ASN1_DER_ERROR; - if((der[counter]) || der[counter+1]){ - _asn1_append_sequence_set(p); - p=p->down; - while(p->right) p=p->right; - move=RIGHT; - continue; - } - _asn1_set_value(p,NULL,0); - counter+=2; - } - else{ /* definite length method */ - if(len2>counter){ - _asn1_append_sequence_set(p); - p=p->down; - while(p->right) p=p->right; - move=RIGHT; - continue; + p = p->down; } - _asn1_set_value(p,NULL,0); - if(len2!=counter){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; + + if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) + { + p2 = _asn1_find_up (p); + len2 = strtol (p2->value, NULL, 10); + if ((len2 != -1) && (counter > len2)) + ris = ASN1_TAG_ERROR; } - } - } - else{ /* move==DOWN || move==RIGHT */ - len3=asn1_get_length_der(der+counter,len-counter,&len2); - if(len3 < -1) return ASN1_DER_ERROR; - counter+=len2; - if(len3){ - if(len3>0){ /* definite length method */ - _asn1_ltostr(counter+len3,temp); - tlen = strlen(temp); - - if (tlen > 0) - _asn1_set_value(p,temp,tlen+1); + + if (ris == ASN1_SUCCESS) + ris = + _asn1_extract_tag_der (p, der + counter, len - counter, &len2); + if (ris != ASN1_SUCCESS) + { + if (p->type & CONST_OPTION) + { + p->type |= CONST_NOT_USED; + move = RIGHT; + } + else if (p->type & CONST_DEFAULT) + { + _asn1_set_value (p, NULL, 0); + move = RIGHT; + } + else + { + if (errorDescription != NULL) + _asn1_error_description_tag_error (p, errorDescription); + + asn1_delete_structure (element); + return ASN1_TAG_ERROR; + } } - else { /* indefinite length method */ - _asn1_set_value(p,"-1",3); + else + counter += len2; + } + + if (ris == ASN1_SUCCESS) + { + switch (type_field (p->type)) + { + case TYPE_NULL: + if (der[counter]) + { + asn1_delete_structure (element); + return ASN1_DER_ERROR; + } + counter++; + move = RIGHT; + break; + case TYPE_BOOLEAN: + if (der[counter++] != 1) + { + asn1_delete_structure (element); + return ASN1_DER_ERROR; + } + if (der[counter++] == 0) + _asn1_set_value (p, "F", 1); + else + _asn1_set_value (p, "T", 1); + move = RIGHT; + break; + case TYPE_INTEGER: + case TYPE_ENUMERATED: + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + if (len2 + len3 > len - counter) + return ASN1_DER_ERROR; + _asn1_set_value (p, der + counter, len3 + len2); + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_OBJECT_ID: + _asn1_get_objectid_der (der + counter, len - counter, &len2, + temp, sizeof (temp)); + tlen = strlen (temp); + if (tlen > 0) + _asn1_set_value (p, temp, tlen + 1); + counter += len2; + move = RIGHT; + break; + case TYPE_TIME: + result = + _asn1_get_time_der (der + counter, len - counter, &len2, temp, + sizeof (temp) - 1); + if (result != ASN1_SUCCESS) + { + asn1_delete_structure (element); + return result; + } + tlen = strlen (temp); + if (tlen > 0) + _asn1_set_value (p, temp, tlen + 1); + counter += len2; + move = RIGHT; + break; + case TYPE_OCTET_STRING: + len3 = len - counter; + ris = _asn1_get_octet_string (der + counter, p, &len3); + if (ris != ASN1_SUCCESS) + return ris; + counter += len3; + move = RIGHT; + break; + case TYPE_GENERALSTRING: + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + if (len3 + len2 > len - counter) + return ASN1_DER_ERROR; + _asn1_set_value (p, der + counter, len3 + len2); + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_BIT_STRING: + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + if (len3 + len2 > len - counter) + return ASN1_DER_ERROR; + _asn1_set_value (p, der + counter, len3 + len2); + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_SEQUENCE: + case TYPE_SET: + if (move == UP) + { + len2 = strtol (p->value, NULL, 10); + _asn1_set_value (p, NULL, 0); + if (len2 == -1) + { /* indefinite length method */ + if (len - counter + 1 > 0) + { + if ((der[counter]) || der[counter + 1]) + { + asn1_delete_structure (element); + return ASN1_DER_ERROR; + } + } + else + return ASN1_DER_ERROR; + counter += 2; + } + else + { /* definite length method */ + if (len2 != counter) + { + asn1_delete_structure (element); + return ASN1_DER_ERROR; + } + } + move = RIGHT; + } + else + { /* move==DOWN || move==RIGHT */ + len3 = + asn1_get_length_der (der + counter, len - counter, &len2); + if (len3 < -1) + return ASN1_DER_ERROR; + counter += len2; + if (len3 > 0) + { + _asn1_ltostr (counter + len3, temp); + tlen = strlen (temp); + if (tlen > 0) + _asn1_set_value (p, temp, tlen + 1); + move = DOWN; + } + else if (len3 == 0) + { + p2 = p->down; + while (p2) + { + if (type_field (p2->type) != TYPE_TAG) + { + p3 = p2->right; + asn1_delete_structure (&p2); + p2 = p3; + } + else + p2 = p2->right; + } + move = RIGHT; + } + else + { /* indefinite length method */ + _asn1_set_value (p, "-1", 3); + move = DOWN; + } + } + break; + case TYPE_SEQUENCE_OF: + case TYPE_SET_OF: + if (move == UP) + { + len2 = strtol (p->value, NULL, 10); + if (len2 == -1) + { /* indefinite length method */ + if ((counter + 2) > len) + return ASN1_DER_ERROR; + if ((der[counter]) || der[counter + 1]) + { + _asn1_append_sequence_set (p); + p = p->down; + while (p->right) + p = p->right; + move = RIGHT; + continue; + } + _asn1_set_value (p, NULL, 0); + counter += 2; + } + else + { /* definite length method */ + if (len2 > counter) + { + _asn1_append_sequence_set (p); + p = p->down; + while (p->right) + p = p->right; + move = RIGHT; + continue; + } + _asn1_set_value (p, NULL, 0); + if (len2 != counter) + { + asn1_delete_structure (element); + return ASN1_DER_ERROR; + } + } + } + else + { /* move==DOWN || move==RIGHT */ + len3 = + asn1_get_length_der (der + counter, len - counter, &len2); + if (len3 < -1) + return ASN1_DER_ERROR; + counter += len2; + if (len3) + { + if (len3 > 0) + { /* definite length method */ + _asn1_ltostr (counter + len3, temp); + tlen = strlen (temp); + + if (tlen > 0) + _asn1_set_value (p, temp, tlen + 1); + } + else + { /* indefinite length method */ + _asn1_set_value (p, "-1", 3); + } + p2 = p->down; + while ((type_field (p2->type) == TYPE_TAG) + || (type_field (p2->type) == TYPE_SIZE)) + p2 = p2->right; + if (p2->right == NULL) + _asn1_append_sequence_set (p); + p = p2; + } + } + move = RIGHT; + break; + case TYPE_ANY: + if (asn1_get_tag_der + (der + counter, len - counter, &class, &len2, + &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter + len2 > len) + return ASN1_DER_ERROR; + len4 = + asn1_get_length_der (der + counter + len2, + len - counter - len2, &len3); + if (len4 < -1) + return ASN1_DER_ERROR; + if (len4 > len - counter + len2 + len3) + return ASN1_DER_ERROR; + if (len4 != -1) + { + len2 += len4; + asn1_length_der (len2 + len3, NULL, &len4); + temp2 = (unsigned char *) _asn1_alloca (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_afree (temp2); + counter += len2 + len3; + } + else + { /* indefinite length */ + /* Check indefinite lenth method in an EXPLICIT TAG */ + if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80)) + indefinite = 1; + else + indefinite = 0; + + len2 = len - counter; + ris = + _asn1_get_indefinite_length_string (der + counter, &len2); + if (ris != ASN1_SUCCESS) + { + asn1_delete_structure (element); + return ris; + } + asn1_length_der (len2, NULL, &len4); + temp2 = (unsigned char *) _asn1_alloca (len2 + len4); + if (temp2 == NULL) + { + asn1_delete_structure (element); + return ASN1_MEM_ALLOC_ERROR; + } + + asn1_octet_der (der + counter, len2, temp2, &len4); + _asn1_set_value (p, temp2, len4); + _asn1_afree (temp2); + counter += len2; + + /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with + an indefinite length method. */ + if (indefinite) + { + if (!der[counter] && !der[counter + 1]) + { + counter += 2; + } + else + { + asn1_delete_structure (element); + return ASN1_DER_ERROR; + } + } + } + move = RIGHT; + break; + default: + move = (move == UP) ? RIGHT : DOWN; + break; } - p2=p->down; - while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right; - if(p2->right==NULL) _asn1_append_sequence_set(p); - p=p2; - } } - move=RIGHT; + + if (p == node && move != DOWN) break; - case TYPE_ANY: - if(asn1_get_tag_der(der+counter,len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) - return ASN1_DER_ERROR; - if (counter+len2 > len) - return ASN1_DER_ERROR; - len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3); - if(len4 < -1) return ASN1_DER_ERROR; - if(len4 > len-counter+len2+len3) return ASN1_DER_ERROR; - if(len4 != -1){ - len2+=len4; - asn1_length_der(len2+len3,NULL,&len4); - temp2=(unsigned char *)_asn1_alloca(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_afree(temp2); - counter+=len2+len3; + + if (move == DOWN) + { + if (p->down) + p = p->down; + else + move = RIGHT; } - else{ /* indefinite length */ - /* Check indefinite lenth method in an EXPLICIT TAG */ - if((p->type&CONST_TAG) && (der[counter-1]==0x80)) - indefinite=1; + if ((move == RIGHT) && !(p->type & CONST_SET)) + { + if (p->right) + p = p->right; else - indefinite=0; - - len2=len-counter; - ris=_asn1_get_indefinite_length_string(der+counter,&len2); - if(ris != ASN1_SUCCESS){ - asn1_delete_structure(element); - return ris; - } - asn1_length_der(len2,NULL,&len4); - temp2=(unsigned char *)_asn1_alloca(len2+len4); - if (temp2==NULL){ - asn1_delete_structure(element); - return ASN1_MEM_ALLOC_ERROR; - } - - asn1_octet_der(der+counter,len2,temp2,&len4); - _asn1_set_value(p,temp2,len4); - _asn1_afree(temp2); - counter+=len2; - - /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with - an indefinite length method. */ - if(indefinite){ - if(!der[counter] && !der[counter+1]){ - counter+=2; - } - else{ - asn1_delete_structure(element); - return ASN1_DER_ERROR; - } - } + move = UP; } - move=RIGHT; - break; - default: - move=(move==UP)?RIGHT:DOWN; - break; - } + if (move == UP) + p = _asn1_find_up (p); } - if(p==node && move!=DOWN) break; + _asn1_delete_not_used (*element); - if(move==DOWN){ - if(p->down) p=p->down; - else move=RIGHT; - } - if((move==RIGHT) && !(p->type&CONST_SET)){ - if(p->right) p=p->right; - else move=UP; + if (counter != len) + { + asn1_delete_structure (element); + return ASN1_DER_ERROR; } - if(move==UP) p=_asn1_find_up(p); - } - - _asn1_delete_not_used(*element); - - if(counter != len){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; - } return ASN1_SUCCESS; } @@ -1082,582 +1323,761 @@ asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len, * **/ asn1_retCode -asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName, - const void *ider,int len,char *errorDescription) +asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName, + const void *ider, int len, char *errorDescription) { - node_asn *node,*p,*p2,*p3,*nodeFound=ASN1_TYPE_EMPTY; - char temp[128],currentName[MAX_NAME_SIZE*10],*dot_p,*char_p; - int nameLen=MAX_NAME_SIZE*10-1,state; - int counter,len2,len3,len4,move,ris, tlen; - unsigned char class,*temp2; + node_asn *node, *p, *p2, *p3, *nodeFound = ASN1_TYPE_EMPTY; + char temp[128], currentName[MAX_NAME_SIZE * 10], *dot_p, *char_p; + int nameLen = MAX_NAME_SIZE * 10 - 1, state; + int counter, len2, len3, len4, move, ris, tlen; + unsigned char class, *temp2; unsigned long tag; int indefinite, result; - const unsigned char* der = ider; + const unsigned char *der = ider; - node=*structure; + node = *structure; - if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND; - - if(elementName == NULL){ - asn1_delete_structure(structure); + if (node == ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND; - } - - if(node->type&CONST_OPTION){ - asn1_delete_structure(structure); - return ASN1_GENERIC_ERROR; - } - if((*structure)->name){ /* Has *structure got a name? */ - nameLen-=strlen((*structure)->name); - if(nameLen>0) strcpy(currentName,(*structure)->name); - else{ - asn1_delete_structure(structure); - return ASN1_MEM_ERROR; - } - if(!(strcmp(currentName,elementName))){ - state=FOUND; - nodeFound=*structure; + if (elementName == NULL) + { + asn1_delete_structure (structure); + return ASN1_ELEMENT_NOT_FOUND; } - else if(!memcmp(currentName,elementName,strlen(currentName))) - state=SAME_BRANCH; - else - state=OTHER_BRANCH; - } - else{ /* *structure doesn't have a name? */ - currentName[0]=0; - if(elementName[0]==0){ - state=FOUND; - nodeFound=*structure; + + if (node->type & CONST_OPTION) + { + asn1_delete_structure (structure); + return ASN1_GENERIC_ERROR; } - else{ - state=SAME_BRANCH; + + if ((*structure)->name) + { /* Has *structure got a name? */ + nameLen -= strlen ((*structure)->name); + if (nameLen > 0) + strcpy (currentName, (*structure)->name); + else + { + asn1_delete_structure (structure); + return ASN1_MEM_ERROR; + } + if (!(strcmp (currentName, elementName))) + { + state = FOUND; + nodeFound = *structure; + } + else if (!memcmp (currentName, elementName, strlen (currentName))) + state = SAME_BRANCH; + else + state = OTHER_BRANCH; } - } - - counter=0; - move=DOWN; - p=node; - while(1){ - - ris=ASN1_SUCCESS; - - if(move!=UP){ - if(p->type&CONST_SET){ - p2=_asn1_find_up(p); - len2=strtol(p2->value,NULL,10); - if(counter==len2){ - p=p2; - move=UP; - continue; + else + { /* *structure doesn't have a name? */ + currentName[0] = 0; + if (elementName[0] == 0) + { + state = FOUND; + nodeFound = *structure; } - else if(counter>len2){ - asn1_delete_structure(structure); - return ASN1_DER_ERROR; + else + { + state = SAME_BRANCH; } - p2=p2->down; - while(p2){ - if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ - if(type_field(p2->type)!=TYPE_CHOICE) - ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2); - else{ - p3=p2->down; - while(p3){ - ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2); - if(ris==ASN1_SUCCESS) break; - p3=p3->right; - } + } + + counter = 0; + move = DOWN; + p = node; + while (1) + { + + ris = ASN1_SUCCESS; + + if (move != UP) + { + if (p->type & CONST_SET) + { + p2 = _asn1_find_up (p); + len2 = strtol (p2->value, NULL, 10); + if (counter == len2) + { + p = p2; + move = UP; + continue; + } + else if (counter > len2) + { + asn1_delete_structure (structure); + return ASN1_DER_ERROR; + } + p2 = p2->down; + while (p2) + { + if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) + { + if (type_field (p2->type) != TYPE_CHOICE) + ris = + _asn1_extract_tag_der (p2, der + counter, + len - counter, &len2); + else + { + p3 = p2->down; + while (p3) + { + ris = + _asn1_extract_tag_der (p3, der + counter, + len - counter, &len2); + if (ris == ASN1_SUCCESS) + break; + p3 = p3->right; + } + } + if (ris == ASN1_SUCCESS) + { + p2->type &= ~CONST_NOT_USED; + p = p2; + break; + } + } + p2 = p2->right; + } + if (p2 == NULL) + { + asn1_delete_structure (structure); + return ASN1_DER_ERROR; + } } - if(ris==ASN1_SUCCESS){ - p2->type&=~CONST_NOT_USED; - p=p2; - break; + + if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) + { + p2 = _asn1_find_up (p); + len2 = strtol (p2->value, NULL, 10); + if (counter == len2) + { + if (p->right) + { + p2 = p->right; + move = RIGHT; + } + else + move = UP; + + if (p->type & CONST_OPTION) + asn1_delete_structure (&p); + + p = p2; + continue; + } } - } - p2=p2->right; - } - if(p2==NULL){ - asn1_delete_structure(structure); - return ASN1_DER_ERROR; - } - } - if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){ - p2=_asn1_find_up(p); - len2=strtol(p2->value,NULL,10); - if(counter==len2){ - if(p->right){ - p2=p->right; - move=RIGHT; - } - else move=UP; + if (type_field (p->type) == TYPE_CHOICE) + { + while (p->down) + { + if (counter < len) + ris = + _asn1_extract_tag_der (p->down, der + counter, + len - counter, &len2); + else + ris = ASN1_DER_ERROR; + if (ris == ASN1_SUCCESS) + { + while (p->down->right) + { + p2 = p->down->right; + asn1_delete_structure (&p2); + } + break; + } + else if (ris == ASN1_ERROR_TYPE_ANY) + { + asn1_delete_structure (structure); + return ASN1_ERROR_TYPE_ANY; + } + else + { + p2 = p->down; + asn1_delete_structure (&p2); + } + } + + if (p->down == NULL) + { + if (!(p->type & CONST_OPTION)) + { + asn1_delete_structure (structure); + return ASN1_DER_ERROR; + } + } + else + p = p->down; + } - if(p->type&CONST_OPTION) asn1_delete_structure(&p); + if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT)) + { + p2 = _asn1_find_up (p); + len2 = strtol (p2->value, NULL, 10); + if (counter > len2) + ris = ASN1_TAG_ERROR; + } - p=p2; - continue; - } - } + if (ris == ASN1_SUCCESS) + ris = + _asn1_extract_tag_der (p, der + counter, len - counter, &len2); + if (ris != ASN1_SUCCESS) + { + if (p->type & CONST_OPTION) + { + p->type |= CONST_NOT_USED; + move = RIGHT; + } + else if (p->type & CONST_DEFAULT) + { + _asn1_set_value (p, NULL, 0); + move = RIGHT; + } + else + { + if (errorDescription != NULL) + _asn1_error_description_tag_error (p, errorDescription); - if(type_field(p->type)==TYPE_CHOICE){ - while(p->down){ - if(counter<len) - ris=_asn1_extract_tag_der(p->down,der+counter,len-counter,&len2); - else - ris=ASN1_DER_ERROR; - if(ris==ASN1_SUCCESS){ - while(p->down->right){ - p2=p->down->right; - asn1_delete_structure(&p2); + asn1_delete_structure (structure); + return ASN1_TAG_ERROR; + } } - break; - } - else if(ris==ASN1_ERROR_TYPE_ANY){ - asn1_delete_structure(structure); - return ASN1_ERROR_TYPE_ANY; - } - else{ - p2=p->down; - asn1_delete_structure(&p2); - } - } + else + counter += len2; + } + + if (ris == ASN1_SUCCESS) + { + switch (type_field (p->type)) + { + case TYPE_NULL: + if (der[counter]) + { + asn1_delete_structure (structure); + return ASN1_DER_ERROR; + } - if(p->down==NULL){ - if(!(p->type&CONST_OPTION)){ - asn1_delete_structure(structure); - return ASN1_DER_ERROR; - } - } - else - p=p->down; - } + if (p == nodeFound) + state = EXIT; - if((p->type&CONST_OPTION) || (p->type&CONST_DEFAULT)){ - p2=_asn1_find_up(p); - len2=strtol(p2->value,NULL,10); - if(counter>len2) ris=ASN1_TAG_ERROR; - } + counter++; + move = RIGHT; + break; + case TYPE_BOOLEAN: + if (der[counter++] != 1) + { + asn1_delete_structure (structure); + return ASN1_DER_ERROR; + } - if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2); - if(ris!=ASN1_SUCCESS){ - if(p->type&CONST_OPTION){ - p->type|=CONST_NOT_USED; - move=RIGHT; - } - else if(p->type&CONST_DEFAULT) { - _asn1_set_value(p,NULL,0); - move=RIGHT; - } - else { - if (errorDescription!=NULL) - _asn1_error_description_tag_error(p,errorDescription); - - asn1_delete_structure(structure); - return ASN1_TAG_ERROR; - } - } - else counter+=len2; - } + if (state == FOUND) + { + if (der[counter++] == 0) + _asn1_set_value (p, "F", 1); + else + _asn1_set_value (p, "T", 1); - if(ris==ASN1_SUCCESS){ - switch(type_field(p->type)){ - case TYPE_NULL: - if(der[counter]){ - asn1_delete_structure(structure); - return ASN1_DER_ERROR; - } - - if(p==nodeFound) state=EXIT; - - counter++; - move=RIGHT; - break; - case TYPE_BOOLEAN: - if(der[counter++]!=1){ - asn1_delete_structure(structure); - return ASN1_DER_ERROR; - } + if (p == nodeFound) + state = EXIT; - if(state==FOUND){ - if(der[counter++]==0) _asn1_set_value(p,"F",1); - else _asn1_set_value(p,"T",1); - - if(p==nodeFound) state=EXIT; + } + else + counter++; - } - else - counter++; + move = RIGHT; + break; + case TYPE_INTEGER: + case TYPE_ENUMERATED: + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + if (state == FOUND) + { + if (len3 + len2 > len - counter) + return ASN1_DER_ERROR; + _asn1_set_value (p, der + counter, len3 + len2); + + if (p == nodeFound) + state = EXIT; + } + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_OBJECT_ID: + if (state == FOUND) + { + _asn1_get_objectid_der (der + counter, len - counter, &len2, + temp, sizeof (temp)); + tlen = strlen (temp); + + if (tlen > 0) + _asn1_set_value (p, temp, tlen + 1); + + if (p == nodeFound) + state = EXIT; + } + else + { + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + len2 += len3; + } - move=RIGHT; - break; - case TYPE_INTEGER: case TYPE_ENUMERATED: - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - if(state==FOUND){ - if (len3+len2 > len-counter) return ASN1_DER_ERROR; - _asn1_set_value(p,der+counter,len3+len2); - - if(p==nodeFound) state=EXIT; - } - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_OBJECT_ID: - if(state==FOUND){ - _asn1_get_objectid_der(der+counter,len-counter,&len2, temp, sizeof(temp)); - tlen = strlen(temp); - - if (tlen > 0) - _asn1_set_value(p,temp,tlen+1); - - if(p==nodeFound) state=EXIT; - } - else{ - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - len2+=len3; - } + counter += len2; + move = RIGHT; + break; + case TYPE_TIME: + if (state == FOUND) + { + result = + _asn1_get_time_der (der + counter, len - counter, &len2, + temp, sizeof (temp) - 1); + if (result != ASN1_SUCCESS) + { + asn1_delete_structure (structure); + return result; + } - counter+=len2; - move=RIGHT; - break; - case TYPE_TIME: - if(state==FOUND){ - result = _asn1_get_time_der(der+counter,len-counter,&len2,temp,sizeof(temp)-1); - if (result != ASN1_SUCCESS) { - asn1_delete_structure(structure); - return result; - } - - tlen = strlen(temp); - if (tlen > 0) - _asn1_set_value(p,temp,tlen+1); - - if(p==nodeFound) state=EXIT; - } - else{ - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - len2+=len3; - } + tlen = strlen (temp); + if (tlen > 0) + _asn1_set_value (p, temp, tlen + 1); - counter+=len2; - move=RIGHT; - break; - case TYPE_OCTET_STRING: - len3=len-counter; - if(state==FOUND){ - ris=_asn1_get_octet_string(der+counter,p,&len3); - if(p==nodeFound) state=EXIT; - } - else - ris=_asn1_get_octet_string(der+counter,NULL,&len3); + if (p == nodeFound) + state = EXIT; + } + else + { + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + len2 += len3; + } - if(ris != ASN1_SUCCESS) return ris; - counter+=len3; - move=RIGHT; - break; - case TYPE_GENERALSTRING: - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - if(state==FOUND){ - if (len3+len2 > len-counter) return ASN1_DER_ERROR; - _asn1_set_value(p,der+counter,len3+len2); - - if(p==nodeFound) state=EXIT; - } - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_BIT_STRING: - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - if(state==FOUND){ - if (len3+len2 > len-counter) return ASN1_DER_ERROR; - _asn1_set_value(p,der+counter,len3+len2); - - if(p==nodeFound) state=EXIT; - } - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_SEQUENCE: case TYPE_SET: - if(move==UP){ - len2=strtol(p->value,NULL,10); - _asn1_set_value(p,NULL,0); - if(len2==-1){ /* indefinite length method */ - if((der[counter]) || der[counter+1]){ - asn1_delete_structure(structure); - return ASN1_DER_ERROR; - } - counter+=2; - } - else{ /* definite length method */ - if(len2!=counter){ - asn1_delete_structure(structure); - return ASN1_DER_ERROR; - } - } - if(p==nodeFound) state=EXIT; - move=RIGHT; - } - else{ /* move==DOWN || move==RIGHT */ - if(state==OTHER_BRANCH){ - len3=asn1_get_length_der(der+counter,len-counter,&len2); - if(len3 < 0) return ASN1_DER_ERROR; - counter+=len2+len3; - move=RIGHT; - } - else { /* state==SAME_BRANCH or state==FOUND */ - len3=asn1_get_length_der(der+counter,len-counter,&len2); - if(len3 < 0) return ASN1_DER_ERROR; - counter+=len2; - if(len3>0){ - _asn1_ltostr(counter+len3,temp); - tlen = strlen(temp); - - if(tlen > 0) - _asn1_set_value(p,temp,tlen+1); - move=DOWN; - } - else if(len3==0){ - p2=p->down; - while(p2){ - if(type_field(p2->type)!=TYPE_TAG){ - p3=p2->right; - asn1_delete_structure(&p2); - p2=p3; - } - else - p2=p2->right; - } - move=RIGHT; - } - else{ /* indefinite length method */ - _asn1_set_value(p,"-1",3); - move=DOWN; - } - } - } - break; - case TYPE_SEQUENCE_OF: case TYPE_SET_OF: - if(move==UP){ - len2=strtol(p->value,NULL,10); - if(len2>counter){ - _asn1_append_sequence_set(p); - p=p->down; - while(p->right) p=p->right; - move=RIGHT; - continue; - } - _asn1_set_value(p,NULL,0); - if(len2!=counter){ - asn1_delete_structure(structure); - return ASN1_DER_ERROR; - } + counter += len2; + move = RIGHT; + break; + case TYPE_OCTET_STRING: + len3 = len - counter; + if (state == FOUND) + { + ris = _asn1_get_octet_string (der + counter, p, &len3); + if (p == nodeFound) + state = EXIT; + } + else + ris = _asn1_get_octet_string (der + counter, NULL, &len3); - if(p==nodeFound) state=EXIT; - } - else{ /* move==DOWN || move==RIGHT */ - if(state==OTHER_BRANCH){ - len3=asn1_get_length_der(der+counter,len-counter,&len2); - if(len3 < 0) return ASN1_DER_ERROR; - counter+=len2+len3; - move=RIGHT; - } - else{ /* state==FOUND or state==SAME_BRANCH */ - len3=asn1_get_length_der(der+counter,len-counter,&len2); - if(len3 < 0) return ASN1_DER_ERROR; - counter+=len2; - if(len3){ - _asn1_ltostr(counter+len3,temp); - tlen = strlen(temp); - - if (tlen > 0) - _asn1_set_value(p,temp,tlen+1); - p2=p->down; - while((type_field(p2->type)==TYPE_TAG) || (type_field(p2->type)==TYPE_SIZE)) p2=p2->right; - if(p2->right==NULL) _asn1_append_sequence_set(p); - p=p2; - state=FOUND; + if (ris != ASN1_SUCCESS) + return ris; + counter += len3; + move = RIGHT; + break; + case TYPE_GENERALSTRING: + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + if (state == FOUND) + { + if (len3 + len2 > len - counter) + return ASN1_DER_ERROR; + _asn1_set_value (p, der + counter, len3 + len2); + + if (p == nodeFound) + state = EXIT; + } + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_BIT_STRING: + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + if (state == FOUND) + { + if (len3 + len2 > len - counter) + return ASN1_DER_ERROR; + _asn1_set_value (p, der + counter, len3 + len2); + + if (p == nodeFound) + state = EXIT; + } + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_SEQUENCE: + case TYPE_SET: + if (move == UP) + { + len2 = strtol (p->value, NULL, 10); + _asn1_set_value (p, NULL, 0); + if (len2 == -1) + { /* indefinite length method */ + if ((der[counter]) || der[counter + 1]) + { + asn1_delete_structure (structure); + return ASN1_DER_ERROR; + } + counter += 2; + } + else + { /* definite length method */ + if (len2 != counter) + { + asn1_delete_structure (structure); + return ASN1_DER_ERROR; + } + } + if (p == nodeFound) + state = EXIT; + move = RIGHT; + } + else + { /* move==DOWN || move==RIGHT */ + if (state == OTHER_BRANCH) + { + len3 = + asn1_get_length_der (der + counter, len - counter, + &len2); + if (len3 < 0) + return ASN1_DER_ERROR; + counter += len2 + len3; + move = RIGHT; + } + else + { /* state==SAME_BRANCH or state==FOUND */ + len3 = + asn1_get_length_der (der + counter, len - counter, + &len2); + if (len3 < 0) + return ASN1_DER_ERROR; + counter += len2; + if (len3 > 0) + { + _asn1_ltostr (counter + len3, temp); + tlen = strlen (temp); + + if (tlen > 0) + _asn1_set_value (p, temp, tlen + 1); + move = DOWN; + } + else if (len3 == 0) + { + p2 = p->down; + while (p2) + { + if (type_field (p2->type) != TYPE_TAG) + { + p3 = p2->right; + asn1_delete_structure (&p2); + p2 = p3; + } + else + p2 = p2->right; + } + move = RIGHT; + } + else + { /* indefinite length method */ + _asn1_set_value (p, "-1", 3); + move = DOWN; + } + } + } + break; + case TYPE_SEQUENCE_OF: + case TYPE_SET_OF: + if (move == UP) + { + len2 = strtol (p->value, NULL, 10); + if (len2 > counter) + { + _asn1_append_sequence_set (p); + p = p->down; + while (p->right) + p = p->right; + move = RIGHT; + continue; + } + _asn1_set_value (p, NULL, 0); + if (len2 != counter) + { + asn1_delete_structure (structure); + return ASN1_DER_ERROR; + } + + if (p == nodeFound) + state = EXIT; + } + else + { /* move==DOWN || move==RIGHT */ + if (state == OTHER_BRANCH) + { + len3 = + asn1_get_length_der (der + counter, len - counter, + &len2); + if (len3 < 0) + return ASN1_DER_ERROR; + counter += len2 + len3; + move = RIGHT; + } + else + { /* state==FOUND or state==SAME_BRANCH */ + len3 = + asn1_get_length_der (der + counter, len - counter, + &len2); + if (len3 < 0) + return ASN1_DER_ERROR; + counter += len2; + if (len3) + { + _asn1_ltostr (counter + len3, temp); + tlen = strlen (temp); + + if (tlen > 0) + _asn1_set_value (p, temp, tlen + 1); + p2 = p->down; + while ((type_field (p2->type) == TYPE_TAG) + || (type_field (p2->type) == TYPE_SIZE)) + p2 = p2->right; + if (p2->right == NULL) + _asn1_append_sequence_set (p); + p = p2; + state = FOUND; + } + } + } + + break; + case TYPE_ANY: + if (asn1_get_tag_der + (der + counter, len - counter, &class, &len2, + &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter + len2 > len) + return ASN1_DER_ERROR; + + len4 = + asn1_get_length_der (der + counter + len2, + len - counter - len2, &len3); + if (len4 < -1) + return ASN1_DER_ERROR; + + if (len4 != -1) + { + len2 += len4; + if (state == FOUND) + { + asn1_length_der (len2 + len3, NULL, &len4); + temp2 = + (unsigned char *) _asn1_alloca (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_afree (temp2); + + if (p == nodeFound) + state = EXIT; + } + counter += len2 + len3; + } + else + { /* indefinite length */ + /* Check indefinite lenth method in an EXPLICIT TAG */ + if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80)) + indefinite = 1; + else + indefinite = 0; + + len2 = len - counter; + ris = + _asn1_get_indefinite_length_string (der + counter, &len2); + if (ris != ASN1_SUCCESS) + { + asn1_delete_structure (structure); + return ris; + } + + if (state == FOUND) + { + asn1_length_der (len2, NULL, &len4); + temp2 = (unsigned char *) _asn1_alloca (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_afree (temp2); + + if (p == nodeFound) + state = EXIT; + } + + counter += len2; + + /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with + an indefinite length method. */ + if (indefinite) + { + if (!der[counter] && !der[counter + 1]) + { + counter += 2; + } + else + { + asn1_delete_structure (structure); + return ASN1_DER_ERROR; + } + } + } + move = RIGHT; + break; + + default: + move = (move == UP) ? RIGHT : DOWN; + break; } - } } - - break; - case TYPE_ANY: - if(asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) - return ASN1_DER_ERROR; - if (counter+len2 > len) - return ASN1_DER_ERROR; - len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3); - if(len4 < -1) return ASN1_DER_ERROR; + if ((p == node && move != DOWN) || (state == EXIT)) + break; - if(len4 != -1){ - len2+=len4; - if(state==FOUND){ - asn1_length_der(len2+len3,NULL,&len4); - temp2=(unsigned char *)_asn1_alloca(len2+len3+len4); - if (temp2==NULL){ - asn1_delete_structure(structure); - return ASN1_MEM_ALLOC_ERROR; + if (move == DOWN) + { + if (p->down) + { + p = p->down; + + if (state != FOUND) + { + nameLen -= strlen (p->name) + 1; + if (nameLen > 0) + { + if (currentName[0]) + strcat (currentName, "."); + strcat (currentName, p->name); + } + else + { + asn1_delete_structure (structure); + return ASN1_MEM_ERROR; + } + if (!(strcmp (currentName, elementName))) + { + state = FOUND; + nodeFound = p; + } + else + if (!memcmp + (currentName, elementName, strlen (currentName))) + state = SAME_BRANCH; + else + state = OTHER_BRANCH; + } } - - asn1_octet_der(der+counter,len2+len3,temp2,&len4); - _asn1_set_value(p,temp2,len4); - _asn1_afree(temp2); - - if(p==nodeFound) state=EXIT; - } - counter+=len2+len3; - } - else{ /* indefinite length */ - /* Check indefinite lenth method in an EXPLICIT TAG */ - if((p->type&CONST_TAG) && (der[counter-1]==0x80)) - indefinite=1; else - indefinite=0; - - len2=len-counter; - ris=_asn1_get_indefinite_length_string(der+counter,&len2); - if(ris != ASN1_SUCCESS){ - asn1_delete_structure(structure); - return ris; - } - - if(state==FOUND){ - asn1_length_der(len2,NULL,&len4); - temp2=(unsigned char *)_asn1_alloca(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_afree(temp2); + move = RIGHT; + } + + if ((move == RIGHT) && !(p->type & CONST_SET)) + { + if (p->right) + { + p = p->right; + + if (state != FOUND) + { + dot_p = char_p = currentName; + while ((char_p = strchr (char_p, '.'))) + { + dot_p = char_p++; + dot_p++; + } - if(p==nodeFound) state=EXIT; - } + nameLen += strlen (currentName) - (dot_p - currentName); + *dot_p = 0; - counter+=len2; + nameLen -= strlen (p->name); + if (nameLen > 0) + strcat (currentName, p->name); + else + { + asn1_delete_structure (structure); + return ASN1_MEM_ERROR; + } - /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with - an indefinite length method. */ - if(indefinite){ - if(!der[counter] && !der[counter+1]){ - counter+=2; - } - else{ - asn1_delete_structure(structure); - return ASN1_DER_ERROR; + if (!(strcmp (currentName, elementName))) + { + state = FOUND; + nodeFound = p; + } + else + if (!memcmp + (currentName, elementName, strlen (currentName))) + state = SAME_BRANCH; + else + state = OTHER_BRANCH; + } } - } + else + move = UP; } - move=RIGHT; - break; - - default: - move=(move==UP)?RIGHT:DOWN; - break; - } - } - if((p==node && move!=DOWN) || (state==EXIT)) break; - - if(move==DOWN){ - if(p->down){ - p=p->down; - - if(state != FOUND){ - nameLen-=strlen(p->name)+1; - if(nameLen>0){ - if(currentName[0]) strcat(currentName,"."); - strcat(currentName,p->name); - } - else{ - asn1_delete_structure(structure); - return ASN1_MEM_ERROR; - } - if(!(strcmp(currentName,elementName))){ - state=FOUND; - nodeFound=p; - } - else if(!memcmp(currentName,elementName,strlen(currentName))) - state=SAME_BRANCH; - else - state=OTHER_BRANCH; - } - } - else move=RIGHT; - } + if (move == UP) + { + p = _asn1_find_up (p); - if((move==RIGHT) && !(p->type&CONST_SET)){ - if(p->right){ - p=p->right; - - if(state != FOUND){ - dot_p=char_p=currentName; - while((char_p=strchr(char_p,'.'))){ - dot_p=char_p++; - dot_p++; - } - - nameLen+=strlen(currentName)-(dot_p-currentName); - *dot_p=0; - - nameLen-=strlen(p->name); - if(nameLen>0) strcat(currentName,p->name); - else{ - asn1_delete_structure(structure); - return ASN1_MEM_ERROR; - } - - if(!(strcmp(currentName,elementName))){ - state=FOUND; - nodeFound=p; - } - else if(!memcmp(currentName,elementName,strlen(currentName))) - state=SAME_BRANCH; - else - state=OTHER_BRANCH; - } - } - else move=UP; - } + if (state != FOUND) + { + dot_p = char_p = currentName; + while ((char_p = strchr (char_p, '.'))) + { + dot_p = char_p++; + dot_p++; + } - if(move==UP){ - p=_asn1_find_up(p); + nameLen += strlen (currentName) - (dot_p - currentName); + *dot_p = 0; - if(state != FOUND){ - dot_p=char_p=currentName; - while((char_p=strchr(char_p,'.'))){ - dot_p=char_p++; - dot_p++; - } - - nameLen+=strlen(currentName)-(dot_p-currentName); - *dot_p=0; - - if(!(strcmp(currentName,elementName))){ - state=FOUND; - nodeFound=p; + if (!(strcmp (currentName, elementName))) + { + state = FOUND; + nodeFound = p; + } + else + if (!memcmp (currentName, elementName, strlen (currentName))) + state = SAME_BRANCH; + else + state = OTHER_BRANCH; + } } - else if(!memcmp(currentName,elementName,strlen(currentName))) - state=SAME_BRANCH; - else - state=OTHER_BRANCH; - } } - } - _asn1_delete_not_used(*structure); + _asn1_delete_not_used (*structure); - if(counter > len){ - asn1_delete_structure(structure); - return ASN1_DER_ERROR; - } + if (counter > len) + { + asn1_delete_structure (structure); + return ASN1_DER_ERROR; + } return ASN1_SUCCESS; } @@ -1695,242 +2115,322 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName, * **/ asn1_retCode -asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len, - const char *name_element,int *start, int *end) +asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len, + const char *name_element, int *start, int *end) { - node_asn *node,*node_to_find,*p,*p2,*p3; - int counter,len2,len3,len4,move,ris; + node_asn *node, *node_to_find, *p, *p2, *p3; + int counter, len2, len3, len4, move, ris; unsigned char class; unsigned long tag; int indefinite; - const unsigned char* der = ider; - - node=element; - - if(node==ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND; - - node_to_find=asn1_find_node(node,name_element); - - if(node_to_find==NULL) return ASN1_ELEMENT_NOT_FOUND; - - if(node_to_find==node){ - *start=0; - *end=len-1; - return ASN1_SUCCESS; - } - - if(node->type&CONST_OPTION) return ASN1_GENERIC_ERROR; - - counter=0; - move=DOWN; - p=node; - while(1){ - ris=ASN1_SUCCESS; - - if(move!=UP){ - if(p->type&CONST_SET){ - p2=_asn1_find_up(p); - len2=strtol(p2->value,NULL,10); - if(len2==-1){ - if(!der[counter] && !der[counter+1]){ - p=p2; - move=UP; - counter+=2; - continue; - } - } - else if(counter==len2){ - p=p2; - move=UP; - continue; - } - else if(counter>len2) return ASN1_DER_ERROR; - p2=p2->down; - while(p2){ - if((p2->type&CONST_SET) && (p2->type&CONST_NOT_USED)){ /* CONTROLLARE */ - if(type_field(p2->type)!=TYPE_CHOICE) - ris=_asn1_extract_tag_der(p2,der+counter,len-counter,&len2); - else{ - p3=p2->down; - ris=_asn1_extract_tag_der(p3,der+counter,len-counter,&len2); - } - if(ris==ASN1_SUCCESS){ - p2->type&=~CONST_NOT_USED; - p=p2; - break; - } - } - p2=p2->right; - } - if(p2==NULL) return ASN1_DER_ERROR; - } + const unsigned char *der = ider; - if(p==node_to_find) *start=counter; + node = element; - if(type_field(p->type)==TYPE_CHOICE){ - p=p->down; - ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2); - if(p==node_to_find) *start=counter; - } + if (node == ASN1_TYPE_EMPTY) + return ASN1_ELEMENT_NOT_FOUND; - if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,len-counter,&len2); - if(ris!=ASN1_SUCCESS){ - if(p->type&CONST_OPTION){ - p->type|=CONST_NOT_USED; - move=RIGHT; - } - else if(p->type&CONST_DEFAULT) { - move=RIGHT; - } - else { - return ASN1_TAG_ERROR; - } - } - else counter+=len2; + node_to_find = asn1_find_node (node, name_element); + + if (node_to_find == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + if (node_to_find == node) + { + *start = 0; + *end = len - 1; + return ASN1_SUCCESS; } - if(ris==ASN1_SUCCESS){ - switch(type_field(p->type)){ - case TYPE_NULL: - if(der[counter]) return ASN1_DER_ERROR; - counter++; - move=RIGHT; - break; - case TYPE_BOOLEAN: - if(der[counter++]!=1) return ASN1_DER_ERROR; - counter++; - move=RIGHT; - break; - case TYPE_INTEGER: case TYPE_ENUMERATED: - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_OBJECT_ID: - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - counter+=len2+len3; - move=RIGHT; - break; - case TYPE_TIME: - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - counter+=len2+len3; - move=RIGHT; - break; - case TYPE_OCTET_STRING: - len3=len-counter; - ris=_asn1_get_octet_string(der+counter,NULL,&len3); - if(ris != ASN1_SUCCESS) return ris; - counter+=len3; - move=RIGHT; - break; - case TYPE_GENERALSTRING: - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_BIT_STRING: - len2=asn1_get_length_der(der+counter,len-counter,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - counter+=len3+len2; - move=RIGHT; - break; - case TYPE_SEQUENCE: case TYPE_SET: - if(move!=UP){ - len3=asn1_get_length_der(der+counter,len-counter,&len2); - if(len3 < -1) return ASN1_DER_ERROR; - counter+=len2; - if(len3==0) move=RIGHT; - else move=DOWN; - } - else{ - if(!der[counter] && !der[counter+1]) /* indefinite length method */ - counter+=2; - move=RIGHT; - } - break; - case TYPE_SEQUENCE_OF: case TYPE_SET_OF: - if(move!=UP){ - len3=asn1_get_length_der(der+counter,len-counter,&len2); - if(len3 < -1) return ASN1_DER_ERROR; - counter+=len2; - if((len3==-1) && !der[counter] && !der[counter+1]) - counter+=2; - else if(len3){ - p2=p->down; - while((type_field(p2->type)==TYPE_TAG) || - (type_field(p2->type)==TYPE_SIZE)) p2=p2->right; - p=p2; - } - } - else{ - if(!der[counter] && !der[counter+1]) /* indefinite length method */ - counter+=2; - } - move=RIGHT; - break; - case TYPE_ANY: - if (asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) - return ASN1_DER_ERROR; - if (counter+len2 > len) - return ASN1_DER_ERROR; + if (node->type & CONST_OPTION) + return ASN1_GENERIC_ERROR; + + counter = 0; + move = DOWN; + p = node; + while (1) + { + ris = ASN1_SUCCESS; + + if (move != UP) + { + if (p->type & CONST_SET) + { + p2 = _asn1_find_up (p); + len2 = strtol (p2->value, NULL, 10); + if (len2 == -1) + { + if (!der[counter] && !der[counter + 1]) + { + p = p2; + move = UP; + counter += 2; + continue; + } + } + else if (counter == len2) + { + p = p2; + move = UP; + continue; + } + else if (counter > len2) + return ASN1_DER_ERROR; + p2 = p2->down; + while (p2) + { + if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) + { /* CONTROLLARE */ + if (type_field (p2->type) != TYPE_CHOICE) + ris = + _asn1_extract_tag_der (p2, der + counter, + len - counter, &len2); + else + { + p3 = p2->down; + ris = + _asn1_extract_tag_der (p3, der + counter, + len - counter, &len2); + } + if (ris == ASN1_SUCCESS) + { + p2->type &= ~CONST_NOT_USED; + p = p2; + break; + } + } + p2 = p2->right; + } + if (p2 == NULL) + return ASN1_DER_ERROR; + } - len4=asn1_get_length_der(der+counter+len2,len-counter-len2,&len3); - if(len4 < -1) return ASN1_DER_ERROR; + if (p == node_to_find) + *start = counter; + + if (type_field (p->type) == TYPE_CHOICE) + { + p = p->down; + ris = + _asn1_extract_tag_der (p, der + counter, len - counter, + &len2); + if (p == node_to_find) + *start = counter; + } - if(len4 != -1){ - counter+=len2+len4+len3; - } - else{ /* indefinite length */ - /* Check indefinite lenth method in an EXPLICIT TAG */ - if((p->type&CONST_TAG) && (der[counter-1]==0x80)) - indefinite=1; + if (ris == ASN1_SUCCESS) + ris = + _asn1_extract_tag_der (p, der + counter, len - counter, &len2); + if (ris != ASN1_SUCCESS) + { + if (p->type & CONST_OPTION) + { + p->type |= CONST_NOT_USED; + move = RIGHT; + } + else if (p->type & CONST_DEFAULT) + { + move = RIGHT; + } + else + { + return ASN1_TAG_ERROR; + } + } else - indefinite=0; - - len2=len-counter; - ris=_asn1_get_indefinite_length_string(der+counter,&len2); - if(ris != ASN1_SUCCESS) - return ris; - counter+=len2; - - /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with - an indefinite length method. */ - if(indefinite){ - if(!der[counter] && !der[counter+1]) - counter+=2; - else - return ASN1_DER_ERROR; - } + counter += len2; + } + + if (ris == ASN1_SUCCESS) + { + switch (type_field (p->type)) + { + case TYPE_NULL: + if (der[counter]) + return ASN1_DER_ERROR; + counter++; + move = RIGHT; + break; + case TYPE_BOOLEAN: + if (der[counter++] != 1) + return ASN1_DER_ERROR; + counter++; + move = RIGHT; + break; + case TYPE_INTEGER: + case TYPE_ENUMERATED: + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_OBJECT_ID: + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + counter += len2 + len3; + move = RIGHT; + break; + case TYPE_TIME: + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + counter += len2 + len3; + move = RIGHT; + break; + case TYPE_OCTET_STRING: + len3 = len - counter; + ris = _asn1_get_octet_string (der + counter, NULL, &len3); + if (ris != ASN1_SUCCESS) + return ris; + counter += len3; + move = RIGHT; + break; + case TYPE_GENERALSTRING: + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_BIT_STRING: + len2 = + asn1_get_length_der (der + counter, len - counter, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + counter += len3 + len2; + move = RIGHT; + break; + case TYPE_SEQUENCE: + case TYPE_SET: + if (move != UP) + { + len3 = + asn1_get_length_der (der + counter, len - counter, &len2); + if (len3 < -1) + return ASN1_DER_ERROR; + counter += len2; + if (len3 == 0) + move = RIGHT; + else + move = DOWN; + } + else + { + if (!der[counter] && !der[counter + 1]) /* indefinite length method */ + counter += 2; + move = RIGHT; + } + break; + case TYPE_SEQUENCE_OF: + case TYPE_SET_OF: + if (move != UP) + { + len3 = + asn1_get_length_der (der + counter, len - counter, &len2); + if (len3 < -1) + return ASN1_DER_ERROR; + counter += len2; + if ((len3 == -1) && !der[counter] && !der[counter + 1]) + counter += 2; + else if (len3) + { + p2 = p->down; + while ((type_field (p2->type) == TYPE_TAG) || + (type_field (p2->type) == TYPE_SIZE)) + p2 = p2->right; + p = p2; + } + } + else + { + if (!der[counter] && !der[counter + 1]) /* indefinite length method */ + counter += 2; + } + move = RIGHT; + break; + case TYPE_ANY: + if (asn1_get_tag_der + (der + counter, len - counter, &class, &len2, + &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + if (counter + len2 > len) + return ASN1_DER_ERROR; + + len4 = + asn1_get_length_der (der + counter + len2, + len - counter - len2, &len3); + if (len4 < -1) + return ASN1_DER_ERROR; + + if (len4 != -1) + { + counter += len2 + len4 + len3; + } + else + { /* indefinite length */ + /* Check indefinite lenth method in an EXPLICIT TAG */ + if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80)) + indefinite = 1; + else + indefinite = 0; + + len2 = len - counter; + ris = + _asn1_get_indefinite_length_string (der + counter, &len2); + if (ris != ASN1_SUCCESS) + return ris; + counter += len2; + + /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with + an indefinite length method. */ + if (indefinite) + { + if (!der[counter] && !der[counter + 1]) + counter += 2; + else + return ASN1_DER_ERROR; + } + } + move = RIGHT; + break; + default: + move = (move == UP) ? RIGHT : DOWN; + break; + } } - move=RIGHT; - break; - default: - move=(move==UP)?RIGHT:DOWN; - break; - } - } - if((p==node_to_find) && (move==RIGHT)){ - *end=counter-1; - return ASN1_SUCCESS; - } + if ((p == node_to_find) && (move == RIGHT)) + { + *end = counter - 1; + return ASN1_SUCCESS; + } - if(p==node && move!=DOWN) break; + if (p == node && move != DOWN) + break; - if(move==DOWN){ - if(p->down) p=p->down; - else move=RIGHT; - } - if((move==RIGHT) && !(p->type&CONST_SET)){ - if(p->right) p=p->right; - else move=UP; + if (move == DOWN) + { + if (p->down) + p = p->down; + else + move = RIGHT; + } + if ((move == RIGHT) && !(p->type & CONST_SET)) + { + if (p->right) + p = p->right; + else + move = UP; + } + if (move == UP) + p = _asn1_find_up (p); } - if(move==UP) p=_asn1_find_up(p); - } return ASN1_ELEMENT_NOT_FOUND; } @@ -1959,173 +2459,213 @@ asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len, **/ asn1_retCode -asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element) +asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element) { - char definitionsName[MAX_NAME_SIZE],name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE]; - asn1_retCode retCode=ASN1_SUCCESS,result; - int len,len2,len3; - ASN1_TYPE p,p2,p3,aux=ASN1_TYPE_EMPTY; + char definitionsName[MAX_NAME_SIZE], name[2 * MAX_NAME_SIZE + 1], + value[MAX_NAME_SIZE]; + asn1_retCode retCode = ASN1_SUCCESS, result; + int len, len2, len3; + ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY; char errorDescription[MAX_ERROR_DESCRIPTION_SIZE]; - if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY)) + if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY)) return ASN1_ELEMENT_NOT_FOUND; - strcpy(definitionsName,definitions->name); - strcat(definitionsName,"."); - - p=*element; - while(p){ - - switch(type_field(p->type)){ - case TYPE_ANY: - if((p->type&CONST_DEFINED_BY) && (p->value)){ - /* search the "DEF_BY" element */ - p2=p->down; - while((p2) && (type_field(p2->type)!=TYPE_CONSTANT)) - p2=p2->right; - - if(!p2){ - retCode=ASN1_ERROR_TYPE_ANY; - break; - } - - p3=_asn1_find_up(p); - - if(!p3){ - retCode=ASN1_ERROR_TYPE_ANY; - break; - } + strcpy (definitionsName, definitions->name); + strcat (definitionsName, "."); - p3=p3->down; - while(p3){ - if((p3->name) && !(strcmp(p3->name,p2->name))) break; - p3=p3->right; - } - - if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) || - (p3->value==NULL)){ + p = *element; + while (p) + { + + switch (type_field (p->type)) + { + case TYPE_ANY: + if ((p->type & CONST_DEFINED_BY) && (p->value)) + { + /* search the "DEF_BY" element */ + p2 = p->down; + while ((p2) && (type_field (p2->type) != TYPE_CONSTANT)) + p2 = p2->right; + + if (!p2) + { + retCode = ASN1_ERROR_TYPE_ANY; + break; + } - p3=_asn1_find_up(p); - p3=_asn1_find_up(p3); + p3 = _asn1_find_up (p); - if(!p3){ - retCode=ASN1_ERROR_TYPE_ANY; - break; - } - - p3=p3->down; - - while(p3){ - if((p3->name) && !(strcmp(p3->name,p2->name))) break; - p3=p3->right; - } - - if((!p3) || (type_field(p3->type)!=TYPE_OBJECT_ID) || - (p3->value==NULL)){ - retCode=ASN1_ERROR_TYPE_ANY; - break; - } - } - - /* search the OBJECT_ID into definitions */ - p2=definitions->down; - while(p2){ - if((type_field(p2->type)==TYPE_OBJECT_ID) && - (p2->type & CONST_ASSIGN)){ - strcpy(name,definitionsName); - strcat(name,p2->name); - - len=MAX_NAME_SIZE; - result=asn1_read_value(definitions,name,value,&len); - - if((result == ASN1_SUCCESS) && (!strcmp(p3->value,value))){ - p2=p2->right; /* pointer to the structure to - use for expansion */ - while((p2) && (p2->type & CONST_ASSIGN)) - p2=p2->right; - - if(p2){ - strcpy(name,definitionsName); - strcat(name,p2->name); - - result=asn1_create_element(definitions,name,&aux); - if(result == ASN1_SUCCESS){ - _asn1_set_name(aux,p->name); - len2=asn1_get_length_der(p->value,p->value_len,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - - result=asn1_der_decoding(&aux,p->value+len3,len2, - errorDescription); - if(result == ASN1_SUCCESS){ - - _asn1_set_right(aux,p->right); - _asn1_set_right(p,aux); - - result=asn1_delete_structure(&p); - if(result == ASN1_SUCCESS){ - p=aux; - aux=ASN1_TYPE_EMPTY; + if (!p3) + { + retCode = ASN1_ERROR_TYPE_ANY; + break; + } + + p3 = p3->down; + while (p3) + { + if ((p3->name) && !(strcmp (p3->name, p2->name))) + break; + p3 = p3->right; + } + + if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) || + (p3->value == NULL)) + { + + p3 = _asn1_find_up (p); + p3 = _asn1_find_up (p3); + + if (!p3) + { + retCode = ASN1_ERROR_TYPE_ANY; break; } - else{ /* error with asn1_delete_structure */ - asn1_delete_structure(&aux); - retCode=result; + + p3 = p3->down; + + while (p3) + { + if ((p3->name) && !(strcmp (p3->name, p2->name))) + break; + p3 = p3->right; + } + + if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) || + (p3->value == NULL)) + { + retCode = ASN1_ERROR_TYPE_ANY; break; } - } - else{/* error with asn1_der_decoding */ - retCode=result; - break; - } } - else{/* error with asn1_create_element */ - retCode=result; + + /* search the OBJECT_ID into definitions */ + p2 = definitions->down; + while (p2) + { + if ((type_field (p2->type) == TYPE_OBJECT_ID) && + (p2->type & CONST_ASSIGN)) + { + strcpy (name, definitionsName); + strcat (name, p2->name); + + len = MAX_NAME_SIZE; + result = + asn1_read_value (definitions, name, value, &len); + + if ((result == ASN1_SUCCESS) + && (!strcmp (p3->value, value))) + { + p2 = p2->right; /* pointer to the structure to + use for expansion */ + while ((p2) && (p2->type & CONST_ASSIGN)) + p2 = p2->right; + + if (p2) + { + strcpy (name, definitionsName); + strcat (name, p2->name); + + result = + asn1_create_element (definitions, name, &aux); + if (result == ASN1_SUCCESS) + { + _asn1_set_name (aux, p->name); + len2 = + asn1_get_length_der (p->value, + p->value_len, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + + result = + asn1_der_decoding (&aux, p->value + len3, + len2, + errorDescription); + if (result == ASN1_SUCCESS) + { + + _asn1_set_right (aux, p->right); + _asn1_set_right (p, aux); + + result = asn1_delete_structure (&p); + if (result == ASN1_SUCCESS) + { + p = aux; + aux = ASN1_TYPE_EMPTY; + break; + } + else + { /* error with asn1_delete_structure */ + asn1_delete_structure (&aux); + retCode = result; + break; + } + } + else + { /* error with asn1_der_decoding */ + retCode = result; + break; + } + } + else + { /* error with asn1_create_element */ + retCode = result; + break; + } + } + else + { /* error with the pointer to the structure to exapand */ + retCode = ASN1_ERROR_TYPE_ANY; + break; + } + } + } + p2 = p2->right; + } /* end while */ + + if (!p2) + { + retCode = ASN1_ERROR_TYPE_ANY; break; } - } - else{/* error with the pointer to the structure to exapand */ - retCode=ASN1_ERROR_TYPE_ANY; - break; - } + } - } - p2=p2->right; - } /* end while */ - - if(!p2){ - retCode=ASN1_ERROR_TYPE_ANY; + break; + default: break; } - - } - break; - default: - break; - } - - if(p->down){ - p=p->down; - } - else if(p==*element){ - p=NULL; - break; - } - else if(p->right) p=p->right; - else{ - while(1){ - p=_asn1_find_up(p); - if(p==*element){ - p=NULL; - break; + + if (p->down) + { + p = p->down; } - if(p->right){ - p=p->right; + else if (p == *element) + { + p = NULL; break; } - } + else if (p->right) + p = p->right; + else + { + while (1) + { + p = _asn1_find_up (p); + if (p == *element) + { + p = NULL; + break; + } + if (p->right) + { + p = p->right; + break; + } + } + } } - } return retCode; } @@ -2157,109 +2697,125 @@ asn1_expand_any_defined_by(ASN1_TYPE definitions,ASN1_TYPE *element) * other errors: result of der decoding process. **/ asn1_retCode -asn1_expand_octet_string(ASN1_TYPE definitions,ASN1_TYPE *element, - const char *octetName,const char *objectName) +asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element, + const char *octetName, const char *objectName) { - char name[2*MAX_NAME_SIZE+1],value[MAX_NAME_SIZE]; - asn1_retCode retCode=ASN1_SUCCESS,result; - int len,len2,len3; - ASN1_TYPE p2,aux=ASN1_TYPE_EMPTY; - ASN1_TYPE octetNode=ASN1_TYPE_EMPTY,objectNode=ASN1_TYPE_EMPTY; + char name[2 * MAX_NAME_SIZE + 1], value[MAX_NAME_SIZE]; + asn1_retCode retCode = ASN1_SUCCESS, result; + int len, len2, len3; + ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY; + ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY; char errorDescription[MAX_ERROR_DESCRIPTION_SIZE]; - if((definitions==ASN1_TYPE_EMPTY) || (*element==ASN1_TYPE_EMPTY)) + if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY)) return ASN1_ELEMENT_NOT_FOUND; - octetNode=asn1_find_node(*element,octetName); - if(octetNode==ASN1_TYPE_EMPTY) + octetNode = asn1_find_node (*element, octetName); + if (octetNode == ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND; - if(type_field(octetNode->type)!=TYPE_OCTET_STRING) + if (type_field (octetNode->type) != TYPE_OCTET_STRING) return ASN1_ELEMENT_NOT_FOUND; - if(octetNode->value==NULL) + if (octetNode->value == NULL) return ASN1_VALUE_NOT_FOUND; - objectNode=asn1_find_node(*element,objectName); - if(objectNode==ASN1_TYPE_EMPTY) + objectNode = asn1_find_node (*element, objectName); + if (objectNode == ASN1_TYPE_EMPTY) return ASN1_ELEMENT_NOT_FOUND; - if(type_field(objectNode->type)!=TYPE_OBJECT_ID) + if (type_field (objectNode->type) != TYPE_OBJECT_ID) return ASN1_ELEMENT_NOT_FOUND; - if(objectNode->value==NULL) + if (objectNode->value == NULL) return ASN1_VALUE_NOT_FOUND; - + /* search the OBJECT_ID into definitions */ - p2=definitions->down; - while(p2){ - if((type_field(p2->type)==TYPE_OBJECT_ID) && - (p2->type & CONST_ASSIGN)){ - strcpy(name,definitions->name); - strcat(name,"."); - strcat(name,p2->name); - - len = sizeof(value); - result=asn1_read_value(definitions,name,value,&len); - - if((result == ASN1_SUCCESS) && (!strcmp(objectNode->value,value))){ - - p2=p2->right; /* pointer to the structure to - use for expansion */ - while((p2) && (p2->type & CONST_ASSIGN)) - p2=p2->right; - - if(p2){ - strcpy(name,definitions->name); - strcat(name,"."); - strcat(name,p2->name); - - result=asn1_create_element(definitions,name,&aux); - if(result == ASN1_SUCCESS){ - _asn1_set_name(aux,octetNode->name); - len2=asn1_get_length_der(octetNode->value,octetNode->value_len,&len3); - if(len2 < 0) return ASN1_DER_ERROR; - - result=asn1_der_decoding(&aux,octetNode->value+len3,len2, - errorDescription); - if(result == ASN1_SUCCESS){ - - _asn1_set_right(aux,octetNode->right); - _asn1_set_right(octetNode,aux); - - result=asn1_delete_structure(&octetNode); - if(result == ASN1_SUCCESS){ - aux=ASN1_TYPE_EMPTY; - break; - } - else{ /* error with asn1_delete_structure */ - asn1_delete_structure(&aux); - retCode=result; - break; - } - } - else{/* error with asn1_der_decoding */ - retCode=result; - break; + p2 = definitions->down; + while (p2) + { + if ((type_field (p2->type) == TYPE_OBJECT_ID) && + (p2->type & CONST_ASSIGN)) + { + strcpy (name, definitions->name); + strcat (name, "."); + strcat (name, p2->name); + + len = sizeof (value); + result = asn1_read_value (definitions, name, value, &len); + + if ((result == ASN1_SUCCESS) + && (!strcmp (objectNode->value, value))) + { + + p2 = p2->right; /* pointer to the structure to + use for expansion */ + while ((p2) && (p2->type & CONST_ASSIGN)) + p2 = p2->right; + + if (p2) + { + strcpy (name, definitions->name); + strcat (name, "."); + strcat (name, p2->name); + + result = asn1_create_element (definitions, name, &aux); + if (result == ASN1_SUCCESS) + { + _asn1_set_name (aux, octetNode->name); + len2 = + asn1_get_length_der (octetNode->value, + octetNode->value_len, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + + result = + asn1_der_decoding (&aux, octetNode->value + len3, + len2, errorDescription); + if (result == ASN1_SUCCESS) + { + + _asn1_set_right (aux, octetNode->right); + _asn1_set_right (octetNode, aux); + + result = asn1_delete_structure (&octetNode); + if (result == ASN1_SUCCESS) + { + aux = ASN1_TYPE_EMPTY; + break; + } + else + { /* error with asn1_delete_structure */ + asn1_delete_structure (&aux); + retCode = result; + break; + } + } + else + { /* error with asn1_der_decoding */ + retCode = result; + break; + } + } + else + { /* error with asn1_create_element */ + retCode = result; + break; + } + } + else + { /* error with the pointer to the structure to exapand */ + retCode = ASN1_VALUE_NOT_VALID; + break; + } } - } - else{/* error with asn1_create_element */ - retCode=result; - break; - } - } - else{/* error with the pointer to the structure to exapand */ - retCode=ASN1_VALUE_NOT_VALID; - break; } - } - } - - p2=p2->right; - } + p2 = p2->right; - if(!p2) retCode=ASN1_VALUE_NOT_VALID; + } + + if (!p2) + retCode = ASN1_VALUE_NOT_VALID; return retCode; } - diff --git a/lib/minitasn1/element.c b/lib/minitasn1/element.c index afc1423d20..fd66f248aa 100644 --- a/lib/minitasn1/element.c +++ b/lib/minitasn1/element.c @@ -34,27 +34,29 @@ #include "structure.h" void -_asn1_hierarchical_name(node_asn *node,char *name,int name_size) +_asn1_hierarchical_name (node_asn * node, char *name, int name_size) { node_asn *p; char tmp_name[64]; - p=node; + p = node; - name[0]=0; + name[0] = 0; - while(p != NULL){ - if(p->name != NULL){ - _asn1_str_cpy(tmp_name,sizeof(tmp_name),name), - - _asn1_str_cpy(name,name_size,p->name); - _asn1_str_cat(name,name_size,"."); - _asn1_str_cat(name,name_size,tmp_name); + while (p != NULL) + { + if (p->name != NULL) + { + _asn1_str_cpy (tmp_name, sizeof (tmp_name), name), + _asn1_str_cpy (name, name_size, p->name); + _asn1_str_cat (name, name_size, "."); + _asn1_str_cat (name, name_size, tmp_name); + } + p = _asn1_find_up (p); } - p=_asn1_find_up(p); - } - if(name[0]==0) _asn1_str_cpy(name,name_size,"ROOT"); + if (name[0] == 0) + _asn1_str_cpy (name, name_size, "ROOT"); } @@ -73,45 +75,52 @@ _asn1_hierarchical_name(node_asn *node,char *name,int name_size) /* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */ /******************************************************************/ asn1_retCode -_asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_size, int *len) +_asn1_convert_integer (const char *value, unsigned char *value_out, + int value_out_size, int *len) { char negative; unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; long valtmp; - int k,k2; + int k, k2; - valtmp=strtol(value,NULL,10); - - for(k=0;k<SIZEOF_UNSIGNED_LONG_INT;k++){ - val[SIZEOF_UNSIGNED_LONG_INT-k-1]=(valtmp >> (8*k)) & 0xFF; - } + valtmp = strtol (value, NULL, 10); - if(val[0]&0x80) negative=1; - else negative=0; + for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) + { + val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF; + } - for(k=0;k<SIZEOF_UNSIGNED_LONG_INT-1;k++){ - if(negative && (val[k]!=0xFF)) break; - else if(!negative && val[k]) break; - } - - if((negative && !(val[k]&0x80)) || - (!negative && (val[k]&0x80))) k--; + if (val[0] & 0x80) + negative = 1; + else + negative = 0; - *len=SIZEOF_UNSIGNED_LONG_INT-k; + for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++) + { + if (negative && (val[k] != 0xFF)) + break; + else if (!negative && val[k]) + break; + } + + if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80))) + k--; - if (SIZEOF_UNSIGNED_LONG_INT-k> value_out_size) + *len = SIZEOF_UNSIGNED_LONG_INT - k; + + if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size) /* VALUE_OUT is too short to contain the value conversion */ return ASN1_MEM_ERROR; - for(k2=k;k2<SIZEOF_UNSIGNED_LONG_INT;k2++) - value_out[k2-k]=val[k2]; + for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++) + value_out[k2 - k] = val[k2]; #ifdef LIBTASN1_DEBUG_INTEGER - _libtasn1_log("_asn1_convert_integer: valueIn=%s, lenOut=%d",value,*len); - for(k=0;k<SIZEOF_UNSIGNED_LONG_INT;k++) - _libtasn1_log(", vOut[%d]=%d",k,value_out[k]); - _libtasn1_log("\n"); + _libtasn1_log ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len); + for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++) + _libtasn1_log (", vOut[%d]=%d", k, value_out[k]); + _libtasn1_log ("\n"); #endif @@ -119,29 +128,35 @@ _asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_s } -int -_asn1_append_sequence_set(node_asn *node) +int +_asn1_append_sequence_set (node_asn * node) { - node_asn *p,*p2; + node_asn *p, *p2; char temp[10]; long n; - if(!node || !(node->down)) return ASN1_GENERIC_ERROR; - - p=node->down; - while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right; - p2=_asn1_copy_structure3(p); - while(p->right) p=p->right; - _asn1_set_right(p,p2); - - if(p->name==NULL) _asn1_str_cpy(temp,sizeof(temp),"?1"); - else{ - n=strtol(p->name+1,NULL,0); - n++; - temp[0]='?'; - _asn1_ltostr(n,temp+1); - } - _asn1_set_name(p2,temp); + if (!node || !(node->down)) + return ASN1_GENERIC_ERROR; + + p = node->down; + while ((type_field (p->type) == TYPE_TAG) + || (type_field (p->type) == TYPE_SIZE)) + p = p->right; + p2 = _asn1_copy_structure3 (p); + while (p->right) + p = p->right; + _asn1_set_right (p, p2); + + if (p->name == NULL) + _asn1_str_cpy (temp, sizeof (temp), "?1"); + else + { + n = strtol (p->name + 1, NULL, 0); + n++; + temp[0] = '?'; + _asn1_ltostr (n, temp + 1); + } + _asn1_set_name (p2, temp); /* p2->type |= CONST_OPTION; */ return ASN1_SUCCESS; @@ -260,262 +275,362 @@ _asn1_append_sequence_set(node_asn *node) * **/ asn1_retCode -asn1_write_value(ASN1_TYPE node_root,const char *name, - const void *ivalue,int len) +asn1_write_value (ASN1_TYPE node_root, const char *name, + const void *ivalue, int len) { - node_asn *node,*p,*p2; - unsigned char *temp,*value_temp=NULL,*default_temp=NULL; - int len2,k,k2,negative; - const unsigned char* value = ivalue; - - node=asn1_find_node(node_root,name); - if(node==NULL) return ASN1_ELEMENT_NOT_FOUND; - - if((node->type & CONST_OPTION) && (value==NULL) && (len==0)){ - asn1_delete_structure(&node); - return ASN1_SUCCESS; - } - - if((type_field(node->type) == TYPE_SEQUENCE_OF) && (value == NULL) && (len==0)){ - p=node->down; - while((type_field(p->type)==TYPE_TAG) || (type_field(p->type)==TYPE_SIZE)) p=p->right; - - while(p->right) - asn1_delete_structure(&p->right); - - return ASN1_SUCCESS; - } - - switch(type_field(node->type)){ - case TYPE_BOOLEAN: - if(!strcmp(value,"TRUE")){ - if(node->type&CONST_DEFAULT){ - p=node->down; - while(type_field(p->type)!=TYPE_DEFAULT) p=p->right; - if(p->type&CONST_TRUE) _asn1_set_value(node,NULL,0); - else _asn1_set_value(node,"T",1); - } - else _asn1_set_value(node,"T",1); + node_asn *node, *p, *p2; + unsigned char *temp, *value_temp = NULL, *default_temp = NULL; + int len2, k, k2, negative; + const unsigned char *value = ivalue; + + node = asn1_find_node (node_root, name); + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0)) + { + asn1_delete_structure (&node); + return ASN1_SUCCESS; } - else if(!strcmp(value,"FALSE")){ - if(node->type&CONST_DEFAULT){ - p=node->down; - while(type_field(p->type)!=TYPE_DEFAULT) p=p->right; - if(p->type&CONST_FALSE) _asn1_set_value(node,NULL,0); - else _asn1_set_value(node,"F",1); - } - else _asn1_set_value(node,"F",1); - } - else return ASN1_VALUE_NOT_VALID; - break; - case TYPE_INTEGER: case TYPE_ENUMERATED: - if(len==0){ - if((isdigit(value[0])) || (value[0]=='-')){ - value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT); - if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR; - - _asn1_convert_integer(value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len); - } - else{ /* is an identifier like v1 */ - if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID; - p=node->down; - while(p){ - if(type_field(p->type)==TYPE_CONSTANT){ - if((p->name) && (!strcmp(p->name,value))){ - value_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT); - if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR; - - _asn1_convert_integer(p->value,value_temp,SIZEOF_UNSIGNED_LONG_INT, &len); - break; - } - } - p=p->right; - } - if(p==NULL) return ASN1_VALUE_NOT_VALID; - } - } - else{ /* len != 0 */ - value_temp=(unsigned char *)_asn1_alloca(len); - if (value_temp==NULL) return ASN1_MEM_ALLOC_ERROR; - memcpy(value_temp,value,len); - } - - - if(value_temp[0]&0x80) negative=1; - else negative=0; - if(negative && (type_field(node->type)==TYPE_ENUMERATED)) - {_asn1_afree(value_temp);return ASN1_VALUE_NOT_VALID;} + if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL) + && (len == 0)) + { + p = node->down; + while ((type_field (p->type) == TYPE_TAG) + || (type_field (p->type) == TYPE_SIZE)) + p = p->right; - for(k=0;k<len-1;k++) - if(negative && (value_temp[k]!=0xFF)) break; - else if(!negative && value_temp[k]) break; + while (p->right) + asn1_delete_structure (&p->right); - if((negative && !(value_temp[k]&0x80)) || - (!negative && (value_temp[k]&0x80))) k--; + return ASN1_SUCCESS; + } - asn1_length_der(len-k,NULL,&len2); - temp=(unsigned char *)_asn1_alloca(len-k+len2); - if (temp==NULL) return ASN1_MEM_ALLOC_ERROR; + switch (type_field (node->type)) + { + case TYPE_BOOLEAN: + if (!strcmp (value, "TRUE")) + { + if (node->type & CONST_DEFAULT) + { + p = node->down; + while (type_field (p->type) != TYPE_DEFAULT) + p = p->right; + if (p->type & CONST_TRUE) + _asn1_set_value (node, NULL, 0); + else + _asn1_set_value (node, "T", 1); + } + else + _asn1_set_value (node, "T", 1); + } + else if (!strcmp (value, "FALSE")) + { + if (node->type & CONST_DEFAULT) + { + p = node->down; + while (type_field (p->type) != TYPE_DEFAULT) + p = p->right; + if (p->type & CONST_FALSE) + _asn1_set_value (node, NULL, 0); + else + _asn1_set_value (node, "F", 1); + } + else + _asn1_set_value (node, "F", 1); + } + else + return ASN1_VALUE_NOT_VALID; + break; + case TYPE_INTEGER: + case TYPE_ENUMERATED: + if (len == 0) + { + if ((isdigit (value[0])) || (value[0] == '-')) + { + value_temp = + (unsigned char *) _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT); + if (value_temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + _asn1_convert_integer (value, value_temp, + SIZEOF_UNSIGNED_LONG_INT, &len); + } + else + { /* is an identifier like v1 */ + if (!(node->type & CONST_LIST)) + return ASN1_VALUE_NOT_VALID; + p = node->down; + while (p) + { + if (type_field (p->type) == TYPE_CONSTANT) + { + if ((p->name) && (!strcmp (p->name, value))) + { + value_temp = + (unsigned char *) + _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT); + if (value_temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + _asn1_convert_integer (p->value, + value_temp, + SIZEOF_UNSIGNED_LONG_INT, + &len); + break; + } + } + p = p->right; + } + if (p == NULL) + return ASN1_VALUE_NOT_VALID; + } + } + else + { /* len != 0 */ + value_temp = (unsigned char *) _asn1_alloca (len); + if (value_temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + memcpy (value_temp, value, len); + } - asn1_octet_der(value_temp+k,len-k,temp,&len2); - _asn1_set_value(node,temp,len2); - _asn1_afree(temp); + if (value_temp[0] & 0x80) + negative = 1; + else + negative = 0; + if (negative && (type_field (node->type) == TYPE_ENUMERATED)) + { + _asn1_afree (value_temp); + return ASN1_VALUE_NOT_VALID; + } - if(node->type&CONST_DEFAULT){ - p=node->down; - while(type_field(p->type)!=TYPE_DEFAULT) p=p->right; - if((isdigit(p->value[0])) || (p->value[0]=='-')){ - default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT); - if (default_temp==NULL) return ASN1_MEM_ALLOC_ERROR; + for (k = 0; k < len - 1; k++) + if (negative && (value_temp[k] != 0xFF)) + break; + else if (!negative && value_temp[k]) + break; + + if ((negative && !(value_temp[k] & 0x80)) || + (!negative && (value_temp[k] & 0x80))) + k--; + + asn1_length_der (len - k, NULL, &len2); + temp = (unsigned char *) _asn1_alloca (len - k + len2); + if (temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + asn1_octet_der (value_temp + k, len - k, temp, &len2); + _asn1_set_value (node, temp, len2); + + _asn1_afree (temp); + + + if (node->type & CONST_DEFAULT) + { + p = node->down; + while (type_field (p->type) != TYPE_DEFAULT) + p = p->right; + if ((isdigit (p->value[0])) || (p->value[0] == '-')) + { + default_temp = + (unsigned char *) _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT); + if (default_temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + _asn1_convert_integer (p->value, default_temp, + SIZEOF_UNSIGNED_LONG_INT, &len2); + } + else + { /* is an identifier like v1 */ + if (!(node->type & CONST_LIST)) + return ASN1_VALUE_NOT_VALID; + p2 = node->down; + while (p2) + { + if (type_field (p2->type) == TYPE_CONSTANT) + { + if ((p2->name) && (!strcmp (p2->name, p->value))) + { + default_temp = + (unsigned char *) + _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT); + if (default_temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + _asn1_convert_integer (p2->value, + default_temp, + SIZEOF_UNSIGNED_LONG_INT, + &len2); + break; + } + } + p2 = p2->right; + } + if (p2 == NULL) + return ASN1_VALUE_NOT_VALID; + } - _asn1_convert_integer(p->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2); - } - else{ /* is an identifier like v1 */ - if(!(node->type&CONST_LIST)) return ASN1_VALUE_NOT_VALID; - p2=node->down; - while(p2){ - if(type_field(p2->type)==TYPE_CONSTANT){ - if((p2->name) && (!strcmp(p2->name,p->value))){ - default_temp=(unsigned char *)_asn1_alloca(SIZEOF_UNSIGNED_LONG_INT); - if (default_temp==NULL) return ASN1_MEM_ALLOC_ERROR; - _asn1_convert_integer(p2->value,default_temp,SIZEOF_UNSIGNED_LONG_INT,&len2); + if ((len - k) == len2) + { + for (k2 = 0; k2 < len2; k2++) + if (value_temp[k + k2] != default_temp[k2]) + { + break; + } + if (k2 == len2) + _asn1_set_value (node, NULL, 0); + } + _asn1_afree (default_temp); + } + _asn1_afree (value_temp); + break; + case TYPE_OBJECT_ID: + for (k = 0; k < strlen (value); k++) + if ((!isdigit (value[k])) && (value[k] != '.') && (value[k] != '+')) + return ASN1_VALUE_NOT_VALID; + if (node->type & CONST_DEFAULT) + { + p = node->down; + while (type_field (p->type) != TYPE_DEFAULT) + p = p->right; + if (!strcmp (value, p->value)) + { + _asn1_set_value (node, NULL, 0); break; } - } - p2=p2->right; } - if(p2==NULL) return ASN1_VALUE_NOT_VALID; - } - - - if((len-k)==len2){ - for(k2=0;k2<len2;k2++) - if(value_temp[k+k2]!=default_temp[k2]){ - break; - } - if(k2==len2) _asn1_set_value(node,NULL,0); - } - _asn1_afree(default_temp); - } - _asn1_afree(value_temp); - break; - case TYPE_OBJECT_ID: - for(k=0;k<strlen(value);k++) - if((!isdigit(value[k])) && (value[k]!='.') && (value[k]!='+')) - return ASN1_VALUE_NOT_VALID; - if(node->type&CONST_DEFAULT){ - p=node->down; - while(type_field(p->type)!=TYPE_DEFAULT) p=p->right; - if(!strcmp(value,p->value)){ - _asn1_set_value(node,NULL,0); - break; - } - } - _asn1_set_value(node,value,strlen(value)+1); - break; - case TYPE_TIME: - if(node->type&CONST_UTC){ - if(strlen(value)<11) return ASN1_VALUE_NOT_VALID; - for(k=0;k<10;k++) - if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID; - switch(strlen(value)){ - case 11: - if(value[10]!='Z') return ASN1_VALUE_NOT_VALID; + _asn1_set_value (node, value, strlen (value) + 1); break; - case 13: - if((!isdigit(value[10])) || (!isdigit(value[11])) || - (value[12]!='Z')) return ASN1_VALUE_NOT_VALID; - break; - case 15: - if((value[10]!='+') && (value[10]!='-')) return ASN1_VALUE_NOT_VALID; - for(k=11;k<15;k++) - if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID; - break; - case 17: - if((!isdigit(value[10])) || (!isdigit(value[11]))) - return ASN1_VALUE_NOT_VALID; - if((value[12]!='+') && (value[12]!='-')) return ASN1_VALUE_NOT_VALID; - for(k=13;k<17;k++) - if(!isdigit(value[k])) return ASN1_VALUE_NOT_VALID; - break; - default: - return ASN1_VALUE_NOT_FOUND; - } - _asn1_set_value(node,value,strlen(value)+1); - } - else{ /* GENERALIZED TIME */ - if(value) _asn1_set_value(node,value,strlen(value)+1); - } - break; - case TYPE_OCTET_STRING: - if(len==0) - len=strlen(value); - asn1_length_der(len,NULL,&len2); - temp=(unsigned char *)_asn1_alloca(len+len2); - if (temp==NULL) return ASN1_MEM_ALLOC_ERROR; - - asn1_octet_der(value,len,temp,&len2); - _asn1_set_value(node,temp,len2); - _asn1_afree(temp); - break; - case TYPE_GENERALSTRING: - if(len==0) - len=strlen(value); - asn1_length_der(len,NULL,&len2); - temp=(unsigned char *)_asn1_alloca(len+len2); - if (temp==NULL) return ASN1_MEM_ALLOC_ERROR; - - asn1_octet_der(value,len,temp,&len2); - _asn1_set_value(node,temp,len2); - _asn1_afree(temp); - break; - case TYPE_BIT_STRING: - if(len==0) - len=strlen(value); - asn1_length_der((len>>3)+2,NULL,&len2); - temp=(unsigned char *)_asn1_alloca((len>>3)+2+len2); - if (temp==NULL) return ASN1_MEM_ALLOC_ERROR; - - asn1_bit_der(value,len,temp,&len2); - _asn1_set_value(node,temp,len2); - _asn1_afree(temp); - break; - case TYPE_CHOICE: - p=node->down; - while(p){ - if(!strcmp(p->name,value)){ - p2=node->down; - while(p2){ - if(p2!=p){asn1_delete_structure(&p2); p2=node->down;} - else p2=p2->right; + case TYPE_TIME: + if (node->type & CONST_UTC) + { + if (strlen (value) < 11) + return ASN1_VALUE_NOT_VALID; + for (k = 0; k < 10; k++) + if (!isdigit (value[k])) + return ASN1_VALUE_NOT_VALID; + switch (strlen (value)) + { + case 11: + if (value[10] != 'Z') + return ASN1_VALUE_NOT_VALID; + break; + case 13: + if ((!isdigit (value[10])) || (!isdigit (value[11])) || + (value[12] != 'Z')) + return ASN1_VALUE_NOT_VALID; + break; + case 15: + if ((value[10] != '+') && (value[10] != '-')) + return ASN1_VALUE_NOT_VALID; + for (k = 11; k < 15; k++) + if (!isdigit (value[k])) + return ASN1_VALUE_NOT_VALID; + break; + case 17: + if ((!isdigit (value[10])) || (!isdigit (value[11]))) + return ASN1_VALUE_NOT_VALID; + if ((value[12] != '+') && (value[12] != '-')) + return ASN1_VALUE_NOT_VALID; + for (k = 13; k < 17; k++) + if (!isdigit (value[k])) + return ASN1_VALUE_NOT_VALID; + break; + default: + return ASN1_VALUE_NOT_FOUND; + } + _asn1_set_value (node, value, strlen (value) + 1); } - break; - } - p=p->right; + else + { /* GENERALIZED TIME */ + if (value) + _asn1_set_value (node, value, strlen (value) + 1); + } + break; + case TYPE_OCTET_STRING: + if (len == 0) + len = strlen (value); + asn1_length_der (len, NULL, &len2); + temp = (unsigned char *) _asn1_alloca (len + len2); + if (temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + asn1_octet_der (value, len, temp, &len2); + _asn1_set_value (node, temp, len2); + _asn1_afree (temp); + break; + case TYPE_GENERALSTRING: + if (len == 0) + len = strlen (value); + asn1_length_der (len, NULL, &len2); + temp = (unsigned char *) _asn1_alloca (len + len2); + if (temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + asn1_octet_der (value, len, temp, &len2); + _asn1_set_value (node, temp, len2); + _asn1_afree (temp); + break; + case TYPE_BIT_STRING: + if (len == 0) + len = strlen (value); + asn1_length_der ((len >> 3) + 2, NULL, &len2); + temp = (unsigned char *) _asn1_alloca ((len >> 3) + 2 + len2); + if (temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + asn1_bit_der (value, len, temp, &len2); + _asn1_set_value (node, temp, len2); + _asn1_afree (temp); + break; + case TYPE_CHOICE: + p = node->down; + while (p) + { + if (!strcmp (p->name, value)) + { + p2 = node->down; + while (p2) + { + if (p2 != p) + { + asn1_delete_structure (&p2); + p2 = node->down; + } + else + p2 = p2->right; + } + break; + } + p = p->right; + } + if (!p) + return ASN1_ELEMENT_NOT_FOUND; + break; + case TYPE_ANY: + asn1_length_der (len, NULL, &len2); + temp = (unsigned char *) _asn1_alloca (len + len2); + if (temp == NULL) + return ASN1_MEM_ALLOC_ERROR; + + asn1_octet_der (value, len, temp, &len2); + _asn1_set_value (node, temp, len2); + _asn1_afree (temp); + break; + case TYPE_SEQUENCE_OF: + case TYPE_SET_OF: + if (strcmp (value, "NEW")) + return ASN1_VALUE_NOT_VALID; + _asn1_append_sequence_set (node); + break; + default: + return ASN1_ELEMENT_NOT_FOUND; + break; } - if(!p) return ASN1_ELEMENT_NOT_FOUND; - break; - case TYPE_ANY: - asn1_length_der(len,NULL,&len2); - temp=(unsigned char *)_asn1_alloca(len+len2); - if (temp==NULL) return ASN1_MEM_ALLOC_ERROR; - - asn1_octet_der(value,len,temp,&len2); - _asn1_set_value(node,temp,len2); - _asn1_afree(temp); - break; - case TYPE_SEQUENCE_OF: case TYPE_SET_OF: - if(strcmp(value,"NEW")) return ASN1_VALUE_NOT_VALID; - _asn1_append_sequence_set(node); - break; - default: - return ASN1_ELEMENT_NOT_FOUND; - break; - } return ASN1_SUCCESS; } @@ -537,7 +652,7 @@ asn1_write_value(ASN1_TYPE node_root,const char *name, /* this strcpy is checked */ \ strcpy(ptr, data); \ } - + #define ADD_STR_VALUE( ptr, ptr_size, data) \ *len = strlen(data) + 1; \ if (ptr_size < strlen(ptr)+(*len)) { \ @@ -614,124 +729,164 @@ asn1_write_value(ASN1_TYPE node_root,const char *name, * **/ asn1_retCode -asn1_read_value(ASN1_TYPE root,const char *name,void* ivalue, int *len) +asn1_read_value (ASN1_TYPE root, const char *name, void *ivalue, int *len) { - node_asn *node,*p,*p2; - int len2,len3; + node_asn *node, *p, *p2; + int len2, len3; int value_size = *len; - unsigned char* value = ivalue; + unsigned char *value = ivalue; - node=asn1_find_node(root,name); - if(node==NULL) return ASN1_ELEMENT_NOT_FOUND; + node = asn1_find_node (root, name); + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; - if((type_field(node->type)!=TYPE_NULL) && - (type_field(node->type)!=TYPE_CHOICE) && - !(node->type&CONST_DEFAULT) && !(node->type&CONST_ASSIGN) && - (node->value==NULL)) + if ((type_field (node->type) != TYPE_NULL) && + (type_field (node->type) != TYPE_CHOICE) && + !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) && + (node->value == NULL)) return ASN1_VALUE_NOT_FOUND; - switch(type_field(node->type)){ - case TYPE_NULL: - PUT_STR_VALUE( value, value_size, "NULL"); - break; - case TYPE_BOOLEAN: - if((node->type&CONST_DEFAULT) && (node->value==NULL)){ - p=node->down; - while(type_field(p->type)!=TYPE_DEFAULT) p=p->right; - if(p->type&CONST_TRUE) { - PUT_STR_VALUE( value, value_size, "TRUE"); - } else { - PUT_STR_VALUE(value, value_size, "FALSE"); - } - } - else if(node->value[0]=='T') { - PUT_STR_VALUE(value, value_size, "TRUE"); - } - else { - PUT_STR_VALUE(value, value_size, "FALSE"); - } - break; - case TYPE_INTEGER: case TYPE_ENUMERATED: - if((node->type&CONST_DEFAULT) && (node->value==NULL)){ - p=node->down; - while(type_field(p->type)!=TYPE_DEFAULT) p=p->right; - if((isdigit(p->value[0])) || (p->value[0]=='-') || (p->value[0]=='+')){ - if (_asn1_convert_integer(p->value,value,value_size, len) != - ASN1_SUCCESS) - return ASN1_MEM_ERROR; - } - else{ /* is an identifier like v1 */ - p2=node->down; - while(p2){ - if(type_field(p2->type)==TYPE_CONSTANT){ - if((p2->name) && (!strcmp(p2->name,p->value))){ - if (_asn1_convert_integer(p2->value,value,value_size, len) != - ASN1_SUCCESS) + switch (type_field (node->type)) + { + case TYPE_NULL: + PUT_STR_VALUE (value, value_size, "NULL"); + break; + case TYPE_BOOLEAN: + if ((node->type & CONST_DEFAULT) && (node->value == NULL)) + { + p = node->down; + while (type_field (p->type) != TYPE_DEFAULT) + p = p->right; + if (p->type & CONST_TRUE) + { + PUT_STR_VALUE (value, value_size, "TRUE"); + } + else + { + PUT_STR_VALUE (value, value_size, "FALSE"); + } + } + else if (node->value[0] == 'T') + { + PUT_STR_VALUE (value, value_size, "TRUE"); + } + else + { + PUT_STR_VALUE (value, value_size, "FALSE"); + } + break; + case TYPE_INTEGER: + case TYPE_ENUMERATED: + if ((node->type & CONST_DEFAULT) && (node->value == NULL)) + { + p = node->down; + while (type_field (p->type) != TYPE_DEFAULT) + p = p->right; + if ((isdigit (p->value[0])) || (p->value[0] == '-') + || (p->value[0] == '+')) + { + if (_asn1_convert_integer + (p->value, value, value_size, len) != ASN1_SUCCESS) return ASN1_MEM_ERROR; - break; } - } - p2=p2->right; + else + { /* is an identifier like v1 */ + p2 = node->down; + while (p2) + { + if (type_field (p2->type) == TYPE_CONSTANT) + { + if ((p2->name) && (!strcmp (p2->name, p->value))) + { + if (_asn1_convert_integer + (p2->value, value, value_size, + len) != ASN1_SUCCESS) + return ASN1_MEM_ERROR; + break; + } + } + p2 = p2->right; + } + } } - } - } - else{ - len2=-1; - if (asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; - } - break; - case TYPE_OBJECT_ID: - if(node->type&CONST_ASSIGN){ - value[0]=0; - p=node->down; - while(p){ - if(type_field(p->type)==TYPE_CONSTANT){ - ADD_STR_VALUE(value,value_size,p->value); - if(p->right) { - ADD_STR_VALUE(value,value_size,"."); - } + else + { + len2 = -1; + if (asn1_get_octet_der + (node->value, node->value_len, &len2, value, value_size, + len) != ASN1_SUCCESS) + return ASN1_MEM_ERROR; + } + break; + case TYPE_OBJECT_ID: + if (node->type & CONST_ASSIGN) + { + value[0] = 0; + p = node->down; + while (p) + { + if (type_field (p->type) == TYPE_CONSTANT) + { + ADD_STR_VALUE (value, value_size, p->value); + if (p->right) + { + ADD_STR_VALUE (value, value_size, "."); + } + } + p = p->right; + } + *len = strlen (value) + 1; + } + else if ((node->type & CONST_DEFAULT) && (node->value == NULL)) + { + p = node->down; + while (type_field (p->type) != TYPE_DEFAULT) + p = p->right; + PUT_STR_VALUE (value, value_size, p->value); } - p=p->right; - } - *len = strlen(value) + 1; - } - else if((node->type&CONST_DEFAULT) && (node->value==NULL)){ - p=node->down; - while(type_field(p->type)!=TYPE_DEFAULT) p=p->right; - PUT_STR_VALUE(value, value_size, p->value); - } - else { - PUT_STR_VALUE(value, value_size, node->value); + else + { + PUT_STR_VALUE (value, value_size, node->value); + } + break; + case TYPE_TIME: + PUT_STR_VALUE (value, value_size, node->value); + break; + case TYPE_OCTET_STRING: + len2 = -1; + if (asn1_get_octet_der + (node->value, node->value_len, &len2, value, value_size, + len) != ASN1_SUCCESS) + return ASN1_MEM_ERROR; + break; + case TYPE_GENERALSTRING: + len2 = -1; + if (asn1_get_octet_der + (node->value, node->value_len, &len2, value, value_size, + len) != ASN1_SUCCESS) + return ASN1_MEM_ERROR; + break; + case TYPE_BIT_STRING: + len2 = -1; + if (asn1_get_bit_der + (node->value, node->value_len, &len2, value, value_size, + len) != ASN1_SUCCESS) + return ASN1_MEM_ERROR; + break; + case TYPE_CHOICE: + PUT_STR_VALUE (value, value_size, node->down->name); + break; + case TYPE_ANY: + len3 = -1; + len2 = asn1_get_length_der (node->value, node->value_len, &len3); + if (len2 < 0) + return ASN1_DER_ERROR; + PUT_VALUE (value, value_size, node->value + len3, len2); + break; + default: + return ASN1_ELEMENT_NOT_FOUND; + break; } - break; - case TYPE_TIME: - PUT_STR_VALUE( value, value_size, node->value); - break; - case TYPE_OCTET_STRING: - len2=-1; - if (asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; - break; - case TYPE_GENERALSTRING: - len2=-1; - if (asn1_get_octet_der(node->value,node->value_len,&len2,value, value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; - break; - case TYPE_BIT_STRING: - len2=-1; - if (asn1_get_bit_der(node->value,node->value_len,&len2,value,value_size,len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; - break; - case TYPE_CHOICE: - PUT_STR_VALUE( value, value_size, node->down->name); - break; - case TYPE_ANY: - len3=-1; - len2=asn1_get_length_der(node->value,node->value_len,&len3); - if (len2 < 0) return ASN1_DER_ERROR; - PUT_VALUE( value, value_size, node->value+len3, len2); - break; - default: - return ASN1_ELEMENT_NOT_FOUND; - break; - } return ASN1_SUCCESS; } @@ -755,76 +910,102 @@ asn1_read_value(ASN1_TYPE root,const char *name,void* ivalue, int *len) * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element. * **/ -asn1_retCode -asn1_read_tag(node_asn *root,const char *name,int *tagValue, int *classValue) +asn1_retCode +asn1_read_tag (node_asn * root, const char *name, int *tagValue, + int *classValue) { - node_asn *node,*p,*pTag; - - node=asn1_find_node(root,name); - if(node==NULL) return ASN1_ELEMENT_NOT_FOUND; + node_asn *node, *p, *pTag; - p=node->down; + node = asn1_find_node (root, name); + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + p = node->down; /* pTag will points to the IMPLICIT TAG */ - pTag=NULL; - if(node->type&CONST_TAG){ - while(p){ - if(type_field(p->type)==TYPE_TAG){ - if((p->type&CONST_IMPLICIT) && (pTag==NULL)) - pTag=p; - else if(p->type&CONST_EXPLICIT) - pTag=NULL; - } - p=p->right; + pTag = NULL; + if (node->type & CONST_TAG) + { + while (p) + { + if (type_field (p->type) == TYPE_TAG) + { + if ((p->type & CONST_IMPLICIT) && (pTag == NULL)) + pTag = p; + else if (p->type & CONST_EXPLICIT) + pTag = NULL; + } + p = p->right; + } } - } - - if(pTag){ - *tagValue=strtoul(pTag->value,NULL,10); - - if(pTag->type&CONST_APPLICATION) *classValue=ASN1_CLASS_APPLICATION; - else if(pTag->type&CONST_UNIVERSAL) *classValue=ASN1_CLASS_UNIVERSAL; - else if(pTag->type&CONST_PRIVATE) *classValue=ASN1_CLASS_PRIVATE; - else *classValue=ASN1_CLASS_CONTEXT_SPECIFIC; - } - else{ - *classValue=ASN1_CLASS_UNIVERSAL; - - switch(type_field(node->type)){ - case TYPE_NULL: - *tagValue=ASN1_TAG_NULL;break; - case TYPE_BOOLEAN: - *tagValue=ASN1_TAG_BOOLEAN;break; - case TYPE_INTEGER: - *tagValue=ASN1_TAG_INTEGER;break; - case TYPE_ENUMERATED: - *tagValue=ASN1_TAG_ENUMERATED;break; - case TYPE_OBJECT_ID: - *tagValue=ASN1_TAG_OBJECT_ID;break; - case TYPE_TIME: - if(node->type&CONST_UTC){ - *tagValue=ASN1_TAG_UTCTime; - } - else *tagValue=ASN1_TAG_GENERALIZEDTime; - break; - case TYPE_OCTET_STRING: - *tagValue=ASN1_TAG_OCTET_STRING;break; - case TYPE_GENERALSTRING: - *tagValue=ASN1_TAG_GENERALSTRING;break; - case TYPE_BIT_STRING: - *tagValue=ASN1_TAG_BIT_STRING;break; - case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF: - *tagValue=ASN1_TAG_SEQUENCE;break; - case TYPE_SET: case TYPE_SET_OF: - *tagValue=ASN1_TAG_SET;break; - case TYPE_TAG: - case TYPE_CHOICE: - case TYPE_ANY: - break; - default: - break; + + if (pTag) + { + *tagValue = strtoul (pTag->value, NULL, 10); + + if (pTag->type & CONST_APPLICATION) + *classValue = ASN1_CLASS_APPLICATION; + else if (pTag->type & CONST_UNIVERSAL) + *classValue = ASN1_CLASS_UNIVERSAL; + else if (pTag->type & CONST_PRIVATE) + *classValue = ASN1_CLASS_PRIVATE; + else + *classValue = ASN1_CLASS_CONTEXT_SPECIFIC; + } + else + { + *classValue = ASN1_CLASS_UNIVERSAL; + + switch (type_field (node->type)) + { + case TYPE_NULL: + *tagValue = ASN1_TAG_NULL; + break; + case TYPE_BOOLEAN: + *tagValue = ASN1_TAG_BOOLEAN; + break; + case TYPE_INTEGER: + *tagValue = ASN1_TAG_INTEGER; + break; + case TYPE_ENUMERATED: + *tagValue = ASN1_TAG_ENUMERATED; + break; + case TYPE_OBJECT_ID: + *tagValue = ASN1_TAG_OBJECT_ID; + break; + case TYPE_TIME: + if (node->type & CONST_UTC) + { + *tagValue = ASN1_TAG_UTCTime; + } + else + *tagValue = ASN1_TAG_GENERALIZEDTime; + break; + case TYPE_OCTET_STRING: + *tagValue = ASN1_TAG_OCTET_STRING; + break; + case TYPE_GENERALSTRING: + *tagValue = ASN1_TAG_GENERALSTRING; + break; + case TYPE_BIT_STRING: + *tagValue = ASN1_TAG_BIT_STRING; + break; + case TYPE_SEQUENCE: + case TYPE_SEQUENCE_OF: + *tagValue = ASN1_TAG_SEQUENCE; + break; + case TYPE_SET: + case TYPE_SET_OF: + *tagValue = ASN1_TAG_SET; + break; + case TYPE_TAG: + case TYPE_CHOICE: + case TYPE_ANY: + break; + default: + break; + } } - } return ASN1_SUCCESS; diff --git a/lib/minitasn1/errors.c b/lib/minitasn1/errors.c index b1224da03a..0d3e4a2b22 100644 --- a/lib/minitasn1/errors.c +++ b/lib/minitasn1/errors.c @@ -30,32 +30,33 @@ #define LIBTASN1_ERROR_ENTRY(name) \ { #name, name } -struct libtasn1_error_entry { - const char *name; - int number; +struct libtasn1_error_entry +{ + const char *name; + int number; }; typedef struct libtasn1_error_entry libtasn1_error_entry; static const libtasn1_error_entry error_algorithms[] = { - LIBTASN1_ERROR_ENTRY( ASN1_SUCCESS ), - LIBTASN1_ERROR_ENTRY( ASN1_FILE_NOT_FOUND ), - LIBTASN1_ERROR_ENTRY( ASN1_ELEMENT_NOT_FOUND ), - LIBTASN1_ERROR_ENTRY( ASN1_IDENTIFIER_NOT_FOUND ), - LIBTASN1_ERROR_ENTRY( ASN1_DER_ERROR ), - LIBTASN1_ERROR_ENTRY( ASN1_VALUE_NOT_FOUND ), - LIBTASN1_ERROR_ENTRY( ASN1_GENERIC_ERROR ), - LIBTASN1_ERROR_ENTRY( ASN1_VALUE_NOT_VALID ), - LIBTASN1_ERROR_ENTRY( ASN1_TAG_ERROR ), - LIBTASN1_ERROR_ENTRY( ASN1_TAG_IMPLICIT ), - LIBTASN1_ERROR_ENTRY( ASN1_ERROR_TYPE_ANY ), - LIBTASN1_ERROR_ENTRY( ASN1_SYNTAX_ERROR ), - LIBTASN1_ERROR_ENTRY( ASN1_MEM_ERROR ), - LIBTASN1_ERROR_ENTRY( ASN1_MEM_ALLOC_ERROR ), - LIBTASN1_ERROR_ENTRY( ASN1_DER_OVERFLOW ), - LIBTASN1_ERROR_ENTRY( ASN1_NAME_TOO_LONG ), - LIBTASN1_ERROR_ENTRY( ASN1_ARRAY_ERROR ), - LIBTASN1_ERROR_ENTRY( ASN1_ELEMENT_NOT_EMPTY ), - {0} + LIBTASN1_ERROR_ENTRY (ASN1_SUCCESS), + LIBTASN1_ERROR_ENTRY (ASN1_FILE_NOT_FOUND), + LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_FOUND), + LIBTASN1_ERROR_ENTRY (ASN1_IDENTIFIER_NOT_FOUND), + LIBTASN1_ERROR_ENTRY (ASN1_DER_ERROR), + LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_FOUND), + LIBTASN1_ERROR_ENTRY (ASN1_GENERIC_ERROR), + LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_VALID), + LIBTASN1_ERROR_ENTRY (ASN1_TAG_ERROR), + LIBTASN1_ERROR_ENTRY (ASN1_TAG_IMPLICIT), + LIBTASN1_ERROR_ENTRY (ASN1_ERROR_TYPE_ANY), + LIBTASN1_ERROR_ENTRY (ASN1_SYNTAX_ERROR), + LIBTASN1_ERROR_ENTRY (ASN1_MEM_ERROR), + LIBTASN1_ERROR_ENTRY (ASN1_MEM_ALLOC_ERROR), + LIBTASN1_ERROR_ENTRY (ASN1_DER_OVERFLOW), + LIBTASN1_ERROR_ENTRY (ASN1_NAME_TOO_LONG), + LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR), + LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY), + {0} }; #define LIBTASN1_ERROR_LOOP(b) \ @@ -74,16 +75,16 @@ static const libtasn1_error_entry error_algorithms[] = { * This function is like perror(). The only difference is that it * accepts an error returned by a libtasn1 function. **/ -void libtasn1_perror(asn1_retCode error) +void +libtasn1_perror (asn1_retCode error) { - const char *ret = NULL; + const char *ret = NULL; + + /* avoid prefix */ + LIBTASN1_ERROR_ALG_LOOP (ret = p->name + sizeof ("ASN1_") - 1); - /* avoid prefix */ - LIBTASN1_ERROR_ALG_LOOP(ret = - p->name + sizeof("ASN1_") - 1); + fprintf (stderr, "LIBTASN1 ERROR: %s\n", ret); - _libtasn1_log( "LIBTASN1 ERROR: %s\n", ret); - } @@ -97,34 +98,38 @@ void libtasn1_perror(asn1_retCode error) * Returns: Pointer to static zero-terminated string describing error * code. **/ -const char* libtasn1_strerror(asn1_retCode error) +const char * +libtasn1_strerror (asn1_retCode error) { - const char *ret = NULL; + const char *ret = NULL; - /* avoid prefix */ - LIBTASN1_ERROR_ALG_LOOP(ret = - p->name + sizeof("ASN1_") - 1); + /* avoid prefix */ + LIBTASN1_ERROR_ALG_LOOP (ret = p->name + sizeof ("ASN1_") - 1); - return ret; + return ret; } /* this function will output a message. */ #ifdef LIBTASN1_DEBUG -void _libtasn1_log( const char *fmt, ...) { - va_list args; - char str[MAX_LOG_SIZE]; +void +_libtasn1_log (const char *fmt, ...) +{ + va_list args; + char str[MAX_LOG_SIZE]; - va_start(args,fmt); - vsprintf( str,fmt,args); /* Flawfinder: ignore */ - va_end(args); + va_start (args, fmt); + vsprintf (str, fmt, args); /* Flawfinder: ignore */ + va_end (args); - fprintf(stderr, str); + fprintf (stderr, str); - return; + return; } #else /* not DEBUG */ -void _libtasn1_log( const char *fmt, ...) { +void +_libtasn1_log (const char *fmt, ...) +{ return; } #endif /* DEBUG */ diff --git a/lib/minitasn1/gstr.c b/lib/minitasn1/gstr.c index 7946b3ec56..a09364315b 100644 --- a/lib/minitasn1/gstr.c +++ b/lib/minitasn1/gstr.c @@ -28,29 +28,41 @@ * * They should be used only with null terminated strings. */ -void _asn1_str_cat( char* dest, size_t dest_tot_size, const char* src) { -size_t str_size = strlen(src); -size_t dest_size = strlen(dest); +void +_asn1_str_cat (char *dest, size_t dest_tot_size, const char *src) +{ + size_t str_size = strlen (src); + size_t dest_size = strlen (dest); - if ( dest_tot_size - dest_size > str_size) { - strcat( dest, src); - } else { - if ( dest_tot_size - dest_size > 0) { - strncat( dest, src, (dest_tot_size - dest_size) -1); - dest[dest_tot_size-1] = 0; - } + if (dest_tot_size - dest_size > str_size) + { + strcat (dest, src); + } + else + { + if (dest_tot_size - dest_size > 0) + { + strncat (dest, src, (dest_tot_size - dest_size) - 1); + dest[dest_tot_size - 1] = 0; } + } } -void _asn1_str_cpy( char* dest, size_t dest_tot_size, const char* src) { -size_t str_size = strlen(src); +void +_asn1_str_cpy (char *dest, size_t dest_tot_size, const char *src) +{ + size_t str_size = strlen (src); - if ( dest_tot_size > str_size) { - strcpy( dest, src); - } else { - if ( dest_tot_size > 0) { - strncpy( dest, src, (dest_tot_size) -1); - dest[dest_tot_size-1] = 0; - } + if (dest_tot_size > str_size) + { + strcpy (dest, src); + } + else + { + if (dest_tot_size > 0) + { + strncpy (dest, src, (dest_tot_size) - 1); + dest[dest_tot_size - 1] = 0; } + } } diff --git a/lib/minitasn1/libtasn1.h b/lib/minitasn1/libtasn1.h index 1c2509aa95..95d598a638 100644 --- a/lib/minitasn1/libtasn1.h +++ b/lib/minitasn1/libtasn1.h @@ -31,7 +31,7 @@ extern "C" { #endif -#define LIBTASN1_VERSION "0.3.2" +#define LIBTASN1_VERSION "0.3.4" #include <sys/types.h> #include <time.h> @@ -124,9 +124,9 @@ extern "C" struct static_struct_asn { - char *name; /* Node name */ + const char *name; /* Node name */ unsigned int type; /* Node type */ - unsigned char *value; /* Node value */ + const void *value; /* Node value */ }; typedef struct static_struct_asn ASN1_ARRAY_TYPE; @@ -210,7 +210,7 @@ extern "C" /* DER utility functions. */ int asn1_get_tag_der (const unsigned char *der, int der_len, - unsigned char *class, int *len, unsigned long *tag); + unsigned char *cls, int *len, unsigned long *tag); void asn1_octet_der (const unsigned char *str, int str_len, unsigned char *der, int *der_len); diff --git a/lib/minitasn1/parser_aux.c b/lib/minitasn1/parser_aux.c index 05048162e1..fbb6a8005b 100644 --- a/lib/minitasn1/parser_aux.c +++ b/lib/minitasn1/parser_aux.c @@ -27,21 +27,22 @@ #include "structure.h" #include "element.h" -char _asn1_identifierMissing[MAX_NAME_SIZE+1]; /* identifier name not found */ +char _asn1_identifierMissing[MAX_NAME_SIZE + 1]; /* identifier name not found */ /***********************************************/ /* Type: list_type */ /* Description: type used in the list during */ /* the structure creation. */ /***********************************************/ -typedef struct list_struct{ - node_asn *node; +typedef struct list_struct +{ + node_asn *node; struct list_struct *next; } list_type; /* Pointer to the first element of the list */ -list_type *firstElement=NULL; +list_type *firstElement = NULL; /******************************************************/ /* Function : _asn1_add_node */ @@ -53,30 +54,27 @@ list_type *firstElement=NULL; /* Return: pointer to the new element. */ /******************************************************/ node_asn * -_asn1_add_node(unsigned int type) +_asn1_add_node (unsigned int type) { list_type *listElement; node_asn *punt; - punt=(node_asn *) _asn1_malloc(sizeof(node_asn)); - if (punt==NULL) return NULL; - - listElement=(list_type *) _asn1_malloc(sizeof(list_type)); - if(listElement==NULL){ - _asn1_free(punt); + punt = (node_asn *) _asn1_calloc (1, sizeof (node_asn)); + if (punt == NULL) return NULL; - } - listElement->node=punt; - listElement->next=firstElement; - firstElement=listElement; + listElement = (list_type *) _asn1_malloc (sizeof (list_type)); + if (listElement == NULL) + { + _asn1_free (punt); + return NULL; + } + + listElement->node = punt; + listElement->next = firstElement; + firstElement = listElement; - punt->left=NULL; - punt->name=NULL; - punt->type=type; - punt->value=NULL; - punt->down=NULL; - punt->right=NULL; + punt->type = type; return punt; } @@ -94,75 +92,97 @@ _asn1_add_node(unsigned int type) * Return value: the searching result. NULL if not found. **/ ASN1_TYPE -asn1_find_node(ASN1_TYPE pointer, const char *name) +asn1_find_node (ASN1_TYPE pointer, const char *name) { node_asn *p; - char *n_end,n[MAX_NAME_SIZE+1]; + char *n_end, n[MAX_NAME_SIZE + 1]; const char *n_start; - if(pointer == NULL) return NULL; + if (pointer == NULL) + return NULL; - if(name==NULL) return NULL; + if (name == NULL) + return NULL; - p=pointer; - n_start=name; + p = pointer; + n_start = name; - if(p->name != NULL){ /* has *pointer got a name ? */ - n_end=strchr(n_start,'.'); /* search the first dot */ - if(n_end){ - memcpy(n,n_start,n_end-n_start); - n[n_end-n_start]=0; - n_start=n_end; - n_start++; - } - else{ - _asn1_str_cpy(n,sizeof(n),n_start); - n_start=NULL; - } - - while(p){ - if((p->name) && (!strcmp(p->name,n))) break; - else p=p->right; - } /* while */ - - if(p==NULL) return NULL; - } - else{ /* *pointer doesn't have a name */ - if(n_start[0]==0) - return p; - } - - while(n_start){ /* Has the end of NAME been reached? */ - n_end=strchr(n_start,'.'); /* search the next dot */ - if(n_end){ - memcpy(n,n_start,n_end-n_start); - n[n_end-n_start]=0; - n_start=n_end; - n_start++; + if (p->name != NULL) + { /* has *pointer got a name ? */ + n_end = strchr (n_start, '.'); /* search the first dot */ + if (n_end) + { + memcpy (n, n_start, n_end - n_start); + n[n_end - n_start] = 0; + n_start = n_end; + n_start++; + } + else + { + _asn1_str_cpy (n, sizeof (n), n_start); + n_start = NULL; + } + + while (p) + { + if ((p->name) && (!strcmp (p->name, n))) + break; + else + p = p->right; + } /* while */ + + if (p == NULL) + return NULL; } - else{ - _asn1_str_cpy(n,sizeof(n),n_start); - n_start=NULL; + else + { /* *pointer doesn't have a name */ + if (n_start[0] == 0) + return p; } - if(p->down==NULL) return NULL; + while (n_start) + { /* Has the end of NAME been reached? */ + n_end = strchr (n_start, '.'); /* search the next dot */ + if (n_end) + { + memcpy (n, n_start, n_end - n_start); + n[n_end - n_start] = 0; + n_start = n_end; + n_start++; + } + else + { + _asn1_str_cpy (n, sizeof (n), n_start); + n_start = NULL; + } + + if (p->down == NULL) + return NULL; - p=p->down; + p = p->down; - /* The identifier "?LAST" indicates the last element - in the right chain. */ - if(!strcmp(n,"?LAST")){ - if(p==NULL) return NULL; - while(p->right) p=p->right; - } - else{ /* no "?LAST" */ - while(p){ - if((p->name) && (!strcmp(p->name,n))) break; - else p=p->right; - } - if(p==NULL) return NULL; - } - } /* while */ + /* The identifier "?LAST" indicates the last element + in the right chain. */ + if (!strcmp (n, "?LAST")) + { + if (p == NULL) + return NULL; + while (p->right) + p = p->right; + } + else + { /* no "?LAST" */ + while (p) + { + if ((p->name) && (!strcmp (p->name, n))) + break; + else + p = p->right; + } + if (p == NULL) + return NULL; + } + } /* while */ return p; } @@ -179,21 +199,26 @@ 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 unsigned char *value,unsigned int len) +_asn1_set_value (node_asn * node, const void *_value, unsigned int len) { - - if(node==NULL) return node; - if(node->value){ - _asn1_free(node->value); - node->value=NULL; - node->value_len = 0; - } - if(!len) return node; - node->value=(unsigned char *) _asn1_malloc(len); - if (node->value==NULL) return NULL; + const unsigned char *value = _value; + + if (node == NULL) + return node; + if (node->value) + { + _asn1_free (node->value); + node->value = NULL; + node->value_len = 0; + } + if (!len) + return node; + node->value = (unsigned char *) _asn1_malloc (len); + if (node->value == NULL) + return NULL; node->value_len = len; - - memcpy(node->value,value,len); + + memcpy (node->value, value, len); return node; } @@ -208,23 +233,28 @@ _asn1_set_value(node_asn *node,const unsigned char *value,unsigned int len) /* Return: pointer to the NODE_ASN element. */ /******************************************************************/ node_asn * -_asn1_set_name(node_asn *node,const char *name) +_asn1_set_name (node_asn * node, const char *name) { - if(node==NULL) return node; + if (node == NULL) + return node; - if(node->name){ - _asn1_free(node->name); - node->name=NULL; - } + if (node->name) + { + _asn1_free (node->name); + node->name = NULL; + } - if(name==NULL) return node; + if (name == NULL) + return node; - if(strlen(name)) - { - node->name=(char *) _asn1_strdup( name); - if (node->name==NULL) return NULL; - } - else node->name=NULL; + if (strlen (name)) + { + node->name = (char *) _asn1_strdup (name); + if (node->name == NULL) + return NULL; + } + else + node->name = NULL; return node; } @@ -238,11 +268,13 @@ _asn1_set_name(node_asn *node,const char *name) /* Return: pointer to *NODE. */ /******************************************************************/ node_asn * -_asn1_set_right(node_asn *node,node_asn *right) +_asn1_set_right (node_asn * node, node_asn * right) { - if(node==NULL) return node; - node->right=right; - if(right) right->left=node; + if (node == NULL) + return node; + node->right = right; + if (right) + right->left = node; return node; } @@ -255,9 +287,10 @@ _asn1_set_right(node_asn *node,node_asn *right) /* Return: field RIGHT of NODE. */ /******************************************************************/ node_asn * -_asn1_get_right(node_asn *node) +_asn1_get_right (node_asn * node) { - if(node==NULL) return NULL; + if (node == NULL) + return NULL; return node->right; } @@ -269,13 +302,15 @@ _asn1_get_right(node_asn *node) /* Return: pointer to the last element along the right chain. */ /******************************************************************/ node_asn * -_asn1_get_last_right(node_asn *node) +_asn1_get_last_right (node_asn * node) { node_asn *p; - if(node==NULL) return NULL; - p=node; - while(p->right) p=p->right; + if (node == NULL) + return NULL; + p = node; + while (p->right) + p = p->right; return p; } @@ -289,11 +324,13 @@ _asn1_get_last_right(node_asn *node) /* Return: pointer to *NODE. */ /******************************************************************/ node_asn * -_asn1_set_down(node_asn *node,node_asn *down) +_asn1_set_down (node_asn * node, node_asn * down) { - if(node==NULL) return node; - node->down=down; - if(down) down->left=node; + if (node == NULL) + return node; + node->down = down; + if (down) + down->left = node; return node; } @@ -306,9 +343,10 @@ _asn1_set_down(node_asn *node,node_asn *down) /* Return: field DOWN of NODE. */ /******************************************************************/ node_asn * -_asn1_get_down(node_asn *node) +_asn1_get_down (node_asn * node) { - if(node==NULL) return NULL; + if (node == NULL) + return NULL; return node->down; } @@ -320,9 +358,10 @@ _asn1_get_down(node_asn *node) /* Return: a null terminated string. */ /******************************************************************/ char * -_asn1_get_name(node_asn *node) +_asn1_get_name (node_asn * node) { - if(node==NULL) return NULL; + if (node == NULL) + return NULL; return node->name; } @@ -338,10 +377,11 @@ _asn1_get_name(node_asn *node) /* Return: NODE pointer. */ /******************************************************************/ node_asn * -_asn1_mod_type(node_asn *node,unsigned int value) +_asn1_mod_type (node_asn * node, unsigned int value) { - if(node==NULL) return node; - node->type|=value; + if (node == NULL) + return node; + node->type |= value; return node; } @@ -354,15 +394,16 @@ _asn1_mod_type(node_asn *node,unsigned int value) /* node: NODE_ASN element pointer. */ /******************************************************************/ void -_asn1_remove_node(node_asn *node) +_asn1_remove_node (node_asn * node) { - if(node==NULL) return; - - if (node->name!=NULL) - _asn1_free(node->name); - if (node->value!=NULL) - _asn1_free(node->value); - _asn1_free(node); + if (node == NULL) + return; + + if (node->name != NULL) + _asn1_free (node->name); + if (node->value != NULL) + _asn1_free (node->value); + _asn1_free (node); } /******************************************************************/ @@ -373,15 +414,17 @@ _asn1_remove_node(node_asn *node) /* Return: Null if not found. */ /******************************************************************/ node_asn * -_asn1_find_up(node_asn *node) +_asn1_find_up (node_asn * node) { node_asn *p; - if(node==NULL) return NULL; + if (node == NULL) + return NULL; - p=node; + p = node; - while((p->left!=NULL) && (p->left->right==p)) p=p->left; + while ((p->left != NULL) && (p->left->right == p)) + p = p->left; return p->left; } @@ -392,15 +435,16 @@ _asn1_find_up(node_asn *node) /* pointed by them). */ /******************************************************************/ void -_asn1_delete_list(void) +_asn1_delete_list (void) { list_type *listElement; - while(firstElement){ - listElement=firstElement; - firstElement=firstElement->next; - _asn1_free(listElement); - } + while (firstElement) + { + listElement = firstElement; + firstElement = firstElement->next; + _asn1_free (listElement); + } } /******************************************************************/ @@ -409,44 +453,50 @@ _asn1_delete_list(void) /* pointed by them. */ /******************************************************************/ void -_asn1_delete_list_and_nodes(void) +_asn1_delete_list_and_nodes (void) { list_type *listElement; - while(firstElement){ - listElement=firstElement; - firstElement=firstElement->next; - _asn1_remove_node(listElement->node); - _asn1_free(listElement); - } + while (firstElement) + { + listElement = firstElement; + firstElement = firstElement->next; + _asn1_remove_node (listElement->node); + _asn1_free (listElement); + } } char * -_asn1_ltostr(long v,char *str) +_asn1_ltostr (long v, char *str) { - long d,r; + long d, r; char temp[20]; - int count,k,start; - - if(v<0){ - str[0]='-'; - start=1; - v=-v; - } - else start=0; - - count=0; - do{ - d=v/10; - r=v-d*10; - temp[start+count]='0'+(char)r; - count++; - v=d; - }while(v); - - for(k=0;k<count;k++) str[k+start]=temp[start+count-k-1]; - str[count+start]=0; + int count, k, start; + + if (v < 0) + { + str[0] = '-'; + start = 1; + v = -v; + } + else + start = 0; + + count = 0; + do + { + d = v / 10; + r = v - d * 10; + temp[start + count] = '0' + (char) r; + count++; + v = d; + } + while (v); + + for (k = 0; k < count; k++) + str[k + start] = temp[start + count - k - 1]; + str[count + start] = 0; return str; } @@ -461,47 +511,59 @@ _asn1_ltostr(long v,char *str) /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ /* otherwise ASN1_SUCCESS */ /******************************************************************/ -asn1_retCode -_asn1_change_integer_value(ASN1_TYPE node) +asn1_retCode +_asn1_change_integer_value (ASN1_TYPE node) { node_asn *p; unsigned char val[SIZEOF_UNSIGNED_LONG_INT]; - unsigned char val2[SIZEOF_UNSIGNED_LONG_INT+1]; + unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1]; int len; - if(node==NULL) return ASN1_ELEMENT_NOT_FOUND; + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; - p=node; - while(p){ - if((type_field(p->type)==TYPE_INTEGER) && (p->type&CONST_ASSIGN)){ - if(p->value){ - _asn1_convert_integer(p->value,val,sizeof(val), &len); - asn1_octet_der(val,len,val2,&len); - _asn1_set_value(p,val2,len); - } - } + p = node; + while (p) + { + if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN)) + { + if (p->value) + { + _asn1_convert_integer (p->value, val, sizeof (val), &len); + asn1_octet_der (val, len, val2, &len); + _asn1_set_value (p, val2, len); + } + } - if(p->down){ - p=p->down; - } - else{ - if(p==node) p=NULL; - else if(p->right) p=p->right; - else{ - while(1){ - p=_asn1_find_up(p); - if(p==node){ - p=NULL; - break; - } - if(p->right){ - p=p->right; - break; - } + if (p->down) + { + p = p->down; + } + else + { + if (p == node) + p = NULL; + else if (p->right) + p = p->right; + else + { + while (1) + { + p = _asn1_find_up (p); + if (p == node) + { + p = NULL; + break; + } + if (p->right) + { + p = p->right; + break; + } + } + } } - } } - } return ASN1_SUCCESS; } @@ -517,127 +579,171 @@ _asn1_change_integer_value(ASN1_TYPE node) /* otherwise ASN1_SUCCESS */ /******************************************************************/ asn1_retCode -_asn1_expand_object_id(ASN1_TYPE node) +_asn1_expand_object_id (ASN1_TYPE node) { - node_asn *p,*p2,*p3,*p4,*p5; - char name_root[MAX_NAME_SIZE],name2[2*MAX_NAME_SIZE+1]; + node_asn *p, *p2, *p3, *p4, *p5; + char name_root[MAX_NAME_SIZE], name2[2 * MAX_NAME_SIZE + 1]; int move, tlen; - - if(node==NULL) return ASN1_ELEMENT_NOT_FOUND; - - _asn1_str_cpy(name_root, sizeof(name_root), node->name); - - p=node; - move=DOWN; - - while(!((p==node) && (move==UP))){ - if(move!=UP){ - if((type_field(p->type)==TYPE_OBJECT_ID) && (p->type&CONST_ASSIGN)){ - p2=p->down; - if(p2 && (type_field(p2->type)==TYPE_CONSTANT)){ - if(p2->value && !isdigit(p2->value[0])){ - _asn1_str_cpy(name2, sizeof(name2), name_root); - _asn1_str_cat(name2, sizeof(name2), "."); - _asn1_str_cat(name2, sizeof(name2), p2->value); - p3=asn1_find_node(node,name2); - if(!p3 || (type_field(p3->type)!=TYPE_OBJECT_ID) || - !(p3->type&CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND; - _asn1_set_down(p,p2->right); - _asn1_remove_node(p2); - p2=p; - p4=p3->down; - while(p4){ - if(type_field(p4->type)==TYPE_CONSTANT){ - p5=_asn1_add_node_only(TYPE_CONSTANT); - _asn1_set_name(p5,p4->name); - tlen = strlen( p4->value); - if (tlen > 0) - _asn1_set_value(p5,p4->value,tlen+1); - if(p2==p){ - _asn1_set_right(p5,p->down); - _asn1_set_down(p,p5); - } - else{ - _asn1_set_right(p5,p2->right); - _asn1_set_right(p2,p5); + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + _asn1_str_cpy (name_root, sizeof (name_root), node->name); + + p = node; + move = DOWN; + + while (!((p == node) && (move == UP))) + { + if (move != UP) + { + if ((type_field (p->type) == TYPE_OBJECT_ID) + && (p->type & CONST_ASSIGN)) + { + p2 = p->down; + if (p2 && (type_field (p2->type) == TYPE_CONSTANT)) + { + if (p2->value && !isdigit (p2->value[0])) + { + _asn1_str_cpy (name2, sizeof (name2), name_root); + _asn1_str_cat (name2, sizeof (name2), "."); + _asn1_str_cat (name2, sizeof (name2), p2->value); + p3 = asn1_find_node (node, name2); + if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) || + !(p3->type & CONST_ASSIGN)) + return ASN1_ELEMENT_NOT_FOUND; + _asn1_set_down (p, p2->right); + _asn1_remove_node (p2); + p2 = p; + p4 = p3->down; + while (p4) + { + if (type_field (p4->type) == TYPE_CONSTANT) + { + p5 = _asn1_add_node_only (TYPE_CONSTANT); + _asn1_set_name (p5, p4->name); + tlen = strlen (p4->value); + if (tlen > 0) + _asn1_set_value (p5, p4->value, tlen + 1); + if (p2 == p) + { + _asn1_set_right (p5, p->down); + _asn1_set_down (p, p5); + } + else + { + _asn1_set_right (p5, p2->right); + _asn1_set_right (p2, p5); + } + p2 = p5; + } + p4 = p4->right; + } + move = DOWN; + continue; + } } - p2=p5; - } - p4=p4->right; } - move=DOWN; - continue; - } + move = DOWN; } - } - move=DOWN; - } - else move=RIGHT; + else + move = RIGHT; - if(move==DOWN){ - if(p->down) p=p->down; - else move=RIGHT; - } - - if(p==node) {move=UP; continue;} + 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 (p == node) + { + move = UP; + continue; + } + + if (move == RIGHT) + { + if (p->right) + p = p->right; + else + move = UP; + } + if (move == UP) + p = _asn1_find_up (p); } - if(move==UP) p=_asn1_find_up(p); - } /*******************************/ /* expand DEFAULT */ /*******************************/ - p=node; - move=DOWN; - - while(!((p==node) && (move==UP))){ - if(move!=UP){ - if((type_field(p->type)==TYPE_OBJECT_ID) && - (p->type&CONST_DEFAULT)){ - p2=p->down; - if(p2 && (type_field(p2->type)==TYPE_DEFAULT)){ - _asn1_str_cpy(name2, sizeof(name2), name_root); - _asn1_str_cat(name2, sizeof(name2), "."); - _asn1_str_cat(name2, sizeof(name2), p2->value); - p3=asn1_find_node(node,name2); - if(!p3 || (type_field(p3->type)!=TYPE_OBJECT_ID) || - !(p3->type&CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND; - p4=p3->down; - name2[0]=0; - while(p4){ - if(type_field(p4->type)==TYPE_CONSTANT){ - if(name2[0]) _asn1_str_cat(name2,sizeof(name2),"."); - _asn1_str_cat(name2,sizeof(name2),p4->value); + p = node; + move = DOWN; + + while (!((p == node) && (move == UP))) + { + if (move != UP) + { + if ((type_field (p->type) == TYPE_OBJECT_ID) && + (p->type & CONST_DEFAULT)) + { + p2 = p->down; + if (p2 && (type_field (p2->type) == TYPE_DEFAULT)) + { + _asn1_str_cpy (name2, sizeof (name2), name_root); + _asn1_str_cat (name2, sizeof (name2), "."); + _asn1_str_cat (name2, sizeof (name2), p2->value); + p3 = asn1_find_node (node, name2); + if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) || + !(p3->type & CONST_ASSIGN)) + return ASN1_ELEMENT_NOT_FOUND; + p4 = p3->down; + name2[0] = 0; + while (p4) + { + if (type_field (p4->type) == TYPE_CONSTANT) + { + if (name2[0]) + _asn1_str_cat (name2, sizeof (name2), "."); + _asn1_str_cat (name2, sizeof (name2), p4->value); + } + p4 = p4->right; + } + tlen = strlen (name2); + if (tlen > 0) + _asn1_set_value (p2, name2, tlen + 1); + } } - p4=p4->right; - } - tlen = strlen(name2); - if (tlen > 0) - _asn1_set_value(p2,name2,tlen+1); + move = DOWN; } - } - move=DOWN; - } - else move=RIGHT; + else + move = RIGHT; - if(move==DOWN){ - if(p->down) p=p->down; - else move=RIGHT; - } - - if(p==node) {move=UP; continue;} + if (move == DOWN) + { + if (p->down) + p = p->down; + else + move = RIGHT; + } + + if (p == node) + { + move = UP; + continue; + } - if(move==RIGHT){ - if(p->right) p=p->right; - else move=UP; + if (move == RIGHT) + { + if (p->right) + p = p->right; + else + move = UP; + } + if (move == UP) + p = _asn1_find_up (p); } - if(move==UP) p=_asn1_find_up(p); - } return ASN1_SUCCESS; } @@ -653,44 +759,61 @@ _asn1_expand_object_id(ASN1_TYPE node) /* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */ /* otherwise ASN1_SUCCESS */ /******************************************************************/ -asn1_retCode -_asn1_type_set_config(ASN1_TYPE node) +asn1_retCode +_asn1_type_set_config (ASN1_TYPE node) { - node_asn *p,*p2; + node_asn *p, *p2; int move; - - if(node==NULL) return ASN1_ELEMENT_NOT_FOUND; - - p=node; - move=DOWN; - - while(!((p==node) && (move==UP))){ - if(move!=UP){ - if(type_field(p->type)==TYPE_SET){ - p2=p->down; - while(p2){ - if(type_field(p2->type)!=TYPE_TAG) - p2->type|=CONST_SET|CONST_NOT_USED; - p2=p2->right; + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + p = node; + move = DOWN; + + while (!((p == node) && (move == UP))) + { + if (move != UP) + { + if (type_field (p->type) == TYPE_SET) + { + p2 = p->down; + while (p2) + { + if (type_field (p2->type) != TYPE_TAG) + p2->type |= CONST_SET | CONST_NOT_USED; + p2 = p2->right; + } + } + move = DOWN; } - } - move=DOWN; - } - else move=RIGHT; + else + move = RIGHT; - if(move==DOWN){ - if(p->down) p=p->down; - else move=RIGHT; - } + if (move == DOWN) + { + if (p->down) + p = p->down; + else + move = RIGHT; + } - if(p==node) {move=UP; continue;} + if (p == node) + { + move = UP; + continue; + } - if(move==RIGHT){ - if(p->right) p=p->right; - else move=UP; + if (move == RIGHT) + { + if (p->right) + p = p->right; + else + move = UP; + } + if (move == UP) + p = _asn1_find_up (p); } - if(move==UP) p=_asn1_find_up(p); - } return ASN1_SUCCESS; } @@ -709,79 +832,94 @@ _asn1_type_set_config(ASN1_TYPE node) /* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */ /* otherwise ASN1_SUCCESS */ /******************************************************************/ -asn1_retCode -_asn1_check_identifier(ASN1_TYPE node) +asn1_retCode +_asn1_check_identifier (ASN1_TYPE node) { - node_asn *p,*p2; - char name2[MAX_NAME_SIZE*2+2]; - - if(node==NULL) return ASN1_ELEMENT_NOT_FOUND; - - p=node; - while(p){ - if(type_field(p->type)==TYPE_IDENTIFIER){ - _asn1_str_cpy(name2, sizeof(name2), node->name); - _asn1_str_cat(name2, sizeof(name2), "."); - _asn1_str_cat(name2, sizeof(name2), p->value); - p2=asn1_find_node(node,name2); - if(p2==NULL){ - strcpy(_asn1_identifierMissing,p->value); - return ASN1_IDENTIFIER_NOT_FOUND; - } - } - else if((type_field(p->type)==TYPE_OBJECT_ID) && - (p->type&CONST_DEFAULT)){ - p2=p->down; - if(p2 && (type_field(p2->type)==TYPE_DEFAULT)){ - _asn1_str_cpy(name2, sizeof(name2), node->name); - _asn1_str_cat(name2, sizeof(name2), "."); - _asn1_str_cat(name2, sizeof(name2), p2->value); - strcpy(_asn1_identifierMissing,p2->value); - p2=asn1_find_node(node,name2); - if(!p2 || (type_field(p2->type)!=TYPE_OBJECT_ID) || - !(p2->type&CONST_ASSIGN)) - return ASN1_IDENTIFIER_NOT_FOUND; - else - _asn1_identifierMissing[0]=0; - } - } - else if((type_field(p->type)==TYPE_OBJECT_ID) && - (p->type&CONST_ASSIGN)){ - p2=p->down; - if(p2 && (type_field(p2->type)==TYPE_CONSTANT)){ - if(p2->value && !isdigit(p2->value[0])){ - _asn1_str_cpy(name2, sizeof(name2), node->name); - _asn1_str_cat(name2, sizeof(name2), "."); - _asn1_str_cat(name2, sizeof(name2), p2->value); - strcpy(_asn1_identifierMissing,p2->value); - p2=asn1_find_node(node,name2); - if(!p2 || (type_field(p2->type)!=TYPE_OBJECT_ID) || - !(p2->type&CONST_ASSIGN)) - return ASN1_IDENTIFIER_NOT_FOUND; - else - _asn1_identifierMissing[0]=0; + node_asn *p, *p2; + char name2[MAX_NAME_SIZE * 2 + 2]; + + if (node == NULL) + return ASN1_ELEMENT_NOT_FOUND; + + p = node; + while (p) + { + if (type_field (p->type) == TYPE_IDENTIFIER) + { + _asn1_str_cpy (name2, sizeof (name2), node->name); + _asn1_str_cat (name2, sizeof (name2), "."); + _asn1_str_cat (name2, sizeof (name2), p->value); + p2 = asn1_find_node (node, name2); + if (p2 == NULL) + { + strcpy (_asn1_identifierMissing, p->value); + return ASN1_IDENTIFIER_NOT_FOUND; + } } - } - } - - if(p->down){ - p=p->down; - } - else if(p->right) p=p->right; - else{ - while(1){ - p=_asn1_find_up(p); - if(p==node){ - p=NULL; - break; + else if ((type_field (p->type) == TYPE_OBJECT_ID) && + (p->type & CONST_DEFAULT)) + { + p2 = p->down; + if (p2 && (type_field (p2->type) == TYPE_DEFAULT)) + { + _asn1_str_cpy (name2, sizeof (name2), node->name); + _asn1_str_cat (name2, sizeof (name2), "."); + _asn1_str_cat (name2, sizeof (name2), p2->value); + strcpy (_asn1_identifierMissing, p2->value); + p2 = asn1_find_node (node, name2); + if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) || + !(p2->type & CONST_ASSIGN)) + return ASN1_IDENTIFIER_NOT_FOUND; + else + _asn1_identifierMissing[0] = 0; + } + } + else if ((type_field (p->type) == TYPE_OBJECT_ID) && + (p->type & CONST_ASSIGN)) + { + p2 = p->down; + if (p2 && (type_field (p2->type) == TYPE_CONSTANT)) + { + if (p2->value && !isdigit (p2->value[0])) + { + _asn1_str_cpy (name2, sizeof (name2), node->name); + _asn1_str_cat (name2, sizeof (name2), "."); + _asn1_str_cat (name2, sizeof (name2), p2->value); + strcpy (_asn1_identifierMissing, p2->value); + p2 = asn1_find_node (node, name2); + if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) || + !(p2->type & CONST_ASSIGN)) + return ASN1_IDENTIFIER_NOT_FOUND; + else + _asn1_identifierMissing[0] = 0; + } + } + } + + if (p->down) + { + p = p->down; } - if(p->right){ - p=p->right; - break; + else if (p->right) + p = p->right; + else + { + while (1) + { + p = _asn1_find_up (p); + if (p == node) + { + p = NULL; + break; + } + if (p->right) + { + p = p->right; + break; + } + } } - } } - } return ASN1_SUCCESS; } @@ -798,79 +936,89 @@ _asn1_check_identifier(ASN1_TYPE node) /* a DEFINITIONS element, */ /* otherwise ASN1_SUCCESS */ /******************************************************************/ -asn1_retCode -_asn1_set_default_tag(ASN1_TYPE node) +asn1_retCode +_asn1_set_default_tag (ASN1_TYPE node) { node_asn *p; - if((node==NULL) || (type_field(node->type)!=TYPE_DEFINITIONS)) - return ASN1_ELEMENT_NOT_FOUND; + if ((node == NULL) || (type_field (node->type) != TYPE_DEFINITIONS)) + return ASN1_ELEMENT_NOT_FOUND; - p=node; - while(p){ - if((type_field(p->type)==TYPE_TAG) && - !(p->type&CONST_EXPLICIT) && - !(p->type&CONST_IMPLICIT)){ - if(node->type&CONST_EXPLICIT) p->type|=CONST_EXPLICIT; - else p->type|=CONST_IMPLICIT; - } + p = node; + while (p) + { + if ((type_field (p->type) == TYPE_TAG) && + !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT)) + { + if (node->type & CONST_EXPLICIT) + p->type |= CONST_EXPLICIT; + else + p->type |= CONST_IMPLICIT; + } - if(p->down){ - p=p->down; - } - else if(p->right) p=p->right; - else{ - while(1){ - p=_asn1_find_up(p); - if(p==node){ - p=NULL; - break; - } - if(p->right){ - p=p->right; - break; - } - } + if (p->down) + { + p = p->down; + } + else if (p->right) + p = p->right; + else + { + while (1) + { + p = _asn1_find_up (p); + if (p == node) + { + p = NULL; + break; + } + if (p->right) + { + p = p->right; + break; + } + } + } } - } return ASN1_SUCCESS; } -static const char* -parse_version_number( const char *s, int *number ) +static const char * +parse_version_number (const char *s, int *number) { - int val = 0; - - if( *s == '0' && isdigit(s[1]) ) - return NULL; /* leading zeros are not allowed */ - for ( ; isdigit(*s); s++ ) { - val *= 10; - val += *s - '0'; + int val = 0; + + if (*s == '0' && isdigit (s[1])) + return NULL; /* leading zeros are not allowed */ + for (; isdigit (*s); s++) + { + val *= 10; + val += *s - '0'; } - *number = val; - return val < 0? NULL : s; + *number = val; + return val < 0 ? NULL : s; } /* The parse version functions were copied from libgcrypt. */ static const char * -parse_version_string( const char *s, int *major, int *minor, int *micro ) +parse_version_string (const char *s, int *major, int *minor, int *micro) { - s = parse_version_number( s, major ); - if( !s || *s != '.' ) - return NULL; - s++; - s = parse_version_number( s, minor ); - if( !s || *s != '.' ) - return NULL; - s++; - s = parse_version_number( s, micro ); - if( !s ) - return NULL; - return s; /* patchlevel */ + s = parse_version_number (s, major); + if (!s || *s != '.') + return NULL; + s++; + s = parse_version_number (s, minor); + if (!s || *s != '.') + return NULL; + s++; + s = parse_version_number (s, micro); + if (!s) + return NULL; + return s; /* patchlevel */ } /** @@ -888,32 +1036,32 @@ parse_version_string( const char *s, int *major, int *minor, int *micro ) * run-time library does not meet the required version number. */ const char * -asn1_check_version( const char *req_version ) +asn1_check_version (const char *req_version) { - const char *ver = LIBTASN1_VERSION; - int my_major, my_minor, my_micro; - int rq_major, rq_minor, rq_micro; - const char *my_plvl, *rq_plvl; - - if ( !req_version ) - return ver; - - my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro ); - if ( !my_plvl ) - return NULL; /* very strange our own version is bogus */ - rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor, - &rq_micro ); - if ( !rq_plvl ) - return NULL; /* req version string is invalid */ - - if ( my_major > rq_major - || (my_major == rq_major && my_minor > rq_minor) - || (my_major == rq_major && my_minor == rq_minor - && my_micro > rq_micro) - || (my_major == rq_major && my_minor == rq_minor - && my_micro == rq_micro - && strcmp( my_plvl, rq_plvl ) >= 0) ) { - return ver; + const char *ver = LIBTASN1_VERSION; + int my_major, my_minor, my_micro; + int rq_major, rq_minor, rq_micro; + const char *my_plvl, *rq_plvl; + + if (!req_version) + return ver; + + my_plvl = parse_version_string (ver, &my_major, &my_minor, &my_micro); + if (!my_plvl) + return NULL; /* very strange our own version is bogus */ + rq_plvl = parse_version_string (req_version, &rq_major, &rq_minor, + &rq_micro); + if (!rq_plvl) + return NULL; /* req version string is invalid */ + + if (my_major > rq_major + || (my_major == rq_major && my_minor > rq_minor) + || (my_major == rq_major && my_minor == rq_minor + && my_micro > rq_micro) + || (my_major == rq_major && my_minor == rq_minor + && my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0)) + { + return ver; } - return NULL; + return NULL; } diff --git a/lib/minitasn1/parser_aux.h b/lib/minitasn1/parser_aux.h index 6edf67aac8..3055510cbe 100644 --- a/lib/minitasn1/parser_aux.h +++ b/lib/minitasn1/parser_aux.h @@ -10,7 +10,7 @@ node_asn * _asn1_add_node(unsigned int type); node_asn * -_asn1_set_value(node_asn *node,const unsigned char *value,unsigned int len); +_asn1_set_value(node_asn *node,const void *value,unsigned int len); node_asn * _asn1_set_name(node_asn *node,const char *name); diff --git a/lib/minitasn1/structure.c b/lib/minitasn1/structure.c index 70bc17246f..4b2ee5099e 100644 --- a/lib/minitasn1/structure.c +++ b/lib/minitasn1/structure.c @@ -51,16 +51,11 @@ _asn1_add_node_only (unsigned int type) { node_asn *punt; - punt = (node_asn *) _asn1_malloc (sizeof (node_asn)); + punt = (node_asn *) _asn1_calloc (1, sizeof (node_asn)); if (punt == NULL) return NULL; - punt->left = NULL; - punt->name = NULL; punt->type = type; - punt->value = NULL; - punt->down = NULL; - punt->right = NULL; return punt; } |