From f75e8e5f5e3f77b6b19bdfe625abb94ae3664088 Mon Sep 17 00:00:00 2001 From: Fabio Fiorina Date: Wed, 30 Jul 2003 19:50:34 +0000 Subject: [PATCH] Add BER decoding --- NEWS | 14 ++ configure.in | 2 +- lib/Makefile.am | 2 +- lib/coding.c | 32 ++- lib/decoding.c | 581 +++++++++++++++++++++++++++++++++++++++-------- lib/der.h | 2 +- lib/element.c | 16 +- lib/int.h | 2 +- lib/libtasn1.h | 2 +- src/CertificateExample.c | 1 + src/CrlExample.c | 1 + src/asn1Coding.c | 2 +- src/asn1Decoding.c | 48 +++- src/asn1Parser.c | 2 +- src/asn1c.c | 1 + tests/Test_parser.c | 1 + tests/Test_tree.asn | 45 +++- tests/Test_tree.c | 113 ++++++++- 18 files changed, 743 insertions(+), 124 deletions(-) diff --git a/NEWS b/NEWS index be38cd2..041ea42 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,17 @@ +Version 0.2.5 +- Bug fix in ordering procedure for SET OF and SEQUENCE OF + types coding. +- Manage structured format (BER encoding) in + asn1_der_decoding, asn1_decoding_element and + asn1_der_decoding_startEnd for OCTET STRING type. +- Manage SEQUENCE and SET empty structure. +- Manage "indefinite length method" in asn1_der_decoding, + asn1_decoding_element and asn1_der_decoding_startEnd + for the following types: + SEQUENCE, SEQUENCE OF, SET, and SET OF. +- Bug fix in asn1_read_value with NULL parameter in case + of BIT STRING + Version 0.2.4 - Bug fix in asn1_der_coding with NULL parameter - Manage DEFAULT option with OBJECT IDENTIFIER diff --git a/configure.in b/configure.in index 261c3e9..a197fc3 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ AC_DEFINE_UNQUOTED(T_OS, "$target_os") dnl libtasn1 Version ASN1_MAJOR_VERSION=0 ASN1_MINOR_VERSION=2 -ASN1_MICRO_VERSION=4 +ASN1_MICRO_VERSION=5 ASN1_VERSION=$ASN1_MAJOR_VERSION.$ASN1_MINOR_VERSION.$ASN1_MICRO_VERSION AC_DEFINE_UNQUOTED(ASN1_VERSION, "$ASN1_VERSION") diff --git a/lib/Makefile.am b/lib/Makefile.am index 15d24b5..06738f5 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -12,7 +12,7 @@ COBJECTS = ASN1.y decoding.c gstr.c errors.c parser_aux.c \ libtasn1_la_SOURCES = $(COBJECTS) -libtasn1_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) +libtasn1_la_LDFLAGS = -no-undefined -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) asn1-api.tex: $(COBJECTS) @echo "% \\newpage" > asn1-api.tex diff --git a/lib/coding.c b/lib/coding.c index ed38411..d46dc7b 100644 --- a/lib/coding.c +++ b/lib/coding.c @@ -111,7 +111,7 @@ _asn1_tag_der(unsigned char class,unsigned int tag_value,unsigned char *ans,int int k; unsigned char temp[SIZEOF_UNSIGNED_INT]; - if(tag_value<30){ + if(tag_value<31){ /* short form */ ans[0]=(class&0xE0) + ((unsigned char)(tag_value&0x1F)); *ans_len=1; @@ -592,8 +592,8 @@ _asn1_ordering_set(unsigned char *der,node_asn *node) if (temp==NULL) return; memcpy(temp,der+counter,p_vet->end-counter); - memmove(der+counter,der+p_vet->end,p2_vet->end-p_vet->end); - memcpy(der+p_vet->end,temp,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; @@ -693,9 +693,9 @@ _asn1_ordering_set_of(unsigned char *der,node_asn *node) temp=(unsigned char *)_asn1_alloca(p_vet->end-counter); if (temp==NULL) return; - memcpy(temp,der+counter,p_vet->end-counter); - memmove(der+counter,der+p_vet->end,p2_vet->end-p_vet->end); - memcpy(der+p_vet->end,temp,p_vet->end-counter); + 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); @@ -740,7 +740,7 @@ asn1_retCode asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len, char *ErrorDescription) { - node_asn *node,*p; + node_asn *node,*p,*p2; char temp[SIZEOF_UNSIGNED_LONG_INT*3+1]; int counter,counter_old,len2,len3,move,max_len,max_len_old; asn1_retCode ris; @@ -875,7 +875,21 @@ asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len, if(move!=UP){ _asn1_ltostr(counter,temp); _asn1_set_value(p,temp,strlen(temp)+1); - move=DOWN; + 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); @@ -892,7 +906,7 @@ asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len, move=RIGHT; } break; - case TYPE_SEQUENCE_OF: case TYPE_SET_OF: + case TYPE_SEQUENCE_OF: case TYPE_SET_OF: if(move!=UP){ _asn1_ltostr(counter,temp); _asn1_set_value(p,temp,strlen(temp)+1); diff --git a/lib/decoding.c b/lib/decoding.c index 29dc9c9..3e3e9d8 100644 --- a/lib/decoding.c +++ b/lib/decoding.c @@ -17,7 +17,7 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + /*****************************************************/ /* File: decoding.c */ @@ -45,7 +45,7 @@ _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription) } -unsigned long +signed long _asn1_get_length_der(const unsigned char *der,int *len) { unsigned long ans; @@ -60,9 +60,14 @@ _asn1_get_length_der(const unsigned char *der,int *len) /* Long form */ k=der[0]&0x7F; punt=1; - ans=0; - while(punt<=k) ans=ans*256+der[punt++]; - + if(k){ /* definite length method */ + ans=0; + while(punt<=k) ans=ans*256+der[punt++]; + } + else{ /* indefinite lenght method */ + ans=-1; + } + *len=punt; return ans; } @@ -170,17 +175,17 @@ _asn1_get_bit_der(const unsigned char *der,int *der_len,unsigned char *str, int { int len_len,len_byte; - if(str==NULL) return ASN1_SUCCESS; len_byte=_asn1_get_length_der(der,&len_len)-1; *der_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; } - *bit_len=len_byte*8-der[len_len]; - + return ASN1_SUCCESS; } @@ -195,7 +200,9 @@ _asn1_extract_tag_der(node_asn *node,const unsigned char *der,int *der_len) unsigned long tag,tag_implicit=0; unsigned char class,class2,class_implicit=0; + counter=is_tag_implicit=0; + if(node->type&CONST_TAG){ p=node->down; while(p){ @@ -239,7 +246,15 @@ _asn1_extract_tag_der(node_asn *node,const unsigned char *der,int *der_len) if(is_tag_implicit){ tag=_asn1_get_tag_der(der+counter,&class,&len2); - if((class!=class_implicit) || (tag!=tag_implicit)) return ASN1_TAG_ERROR; + if((class!=class_implicit) || (tag!=tag_implicit)){ + if(type_field(node->type)==TYPE_OCTET_STRING){ + class_implicit |= 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){ @@ -275,7 +290,8 @@ _asn1_extract_tag_der(node_asn *node,const unsigned char *der,int *der_len) } break; case TYPE_OCTET_STRING: - if((class!=UNIVERSAL) || (tag!=TAG_OCTET_STRING)) return ASN1_DER_ERROR; + if(((class!=UNIVERSAL) && (class!=(UNIVERSAL|STRUCTURED))) + || (tag!=TAG_OCTET_STRING)) return ASN1_DER_ERROR; break; case TYPE_GENERALSTRING: if((class!=UNIVERSAL) || (tag!=TAG_GENERALSTRING)) return ASN1_DER_ERROR; @@ -352,6 +368,119 @@ _asn1_delete_not_used(node_asn *node) } +asn1_retCode +_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; + + counter=0; + + if(*(der-1) & STRUCTURED){ + tot_len=0; + indefinite=_asn1_get_length_der(der,&len3); + + counter+=len3; + if(indefinite>=0) indefinite+=len3; + + while(1){ + if(counter>(*len)) return ASN1_DER_ERROR; + + if(indefinite==-1){ + if((der[counter]==0) && (der[counter+1]==0)){ + counter+=2; + break; + } + } + else if(counter>=indefinite) break; + + if(der[counter] != TAG_OCTET_STRING) return ASN1_DER_ERROR; + + counter++; + + len2=_asn1_get_length_der(der+counter,&len3); + if(len2 <= 0) return ASN1_DER_ERROR; + + counter+=len3+len2; + tot_len+=len2; + } + + /* 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,&len3); + counter2=len3+1; + + if(indefinite==-1) counter_end=counter-2; + else counter_end=counter; + + while(counter2type&CONST_SET){ p2=_asn1_find_up(p); len2=strtol(p2->value,NULL,10); - if(counter==len2){ + 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; @@ -439,9 +576,29 @@ asn1_der_decoding(ASN1_TYPE *element,const unsigned char *der,int len, } } + 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; + } + } + if(type_field(p->type)==TYPE_CHOICE){ while(p->down){ - ris=_asn1_extract_tag_der(p->down,der+counter,&len2); + if(counterdown,der+counter,&len2); + else + ris=ASN1_DER_ERROR; if(ris==ASN1_SUCCESS){ while(p->down->right){ p2=p->down->right; @@ -458,19 +615,23 @@ asn1_der_decoding(ASN1_TYPE *element,const unsigned char *der,int len, asn1_delete_structure(&p2); } } - if(p->down==NULL){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; + + if(p->down==NULL){ + if(!(p->type&CONST_OPTION)){ + asn1_delete_structure(element); + return ASN1_DER_ERROR; + } } - p=p->down; + 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(counter>=len2) ris=ASN1_TAG_ERROR; + if((len2!=-1) && (counter>len2)) ris=ASN1_TAG_ERROR; } - + if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2); if(ris!=ASN1_SUCCESS){ if(p->type&CONST_OPTION){ @@ -530,9 +691,10 @@ asn1_der_decoding(ASN1_TYPE *element,const unsigned char *der,int len, move=RIGHT; break; case TYPE_OCTET_STRING: - len2=_asn1_get_length_der(der+counter,&len3); - _asn1_set_value(p,der+counter,len3+len2); - counter+=len3+len2; + 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: @@ -551,42 +713,89 @@ asn1_der_decoding(ASN1_TYPE *element,const unsigned char *der,int len, if(move==UP){ len2=strtol(p->value,NULL,10); _asn1_set_value(p,NULL,0); - if(len2!=counter){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; + if(len2==-1){ /* indefinite length method */ + if((der[counter]) || der[counter+1]){ + asn1_delete_structure(element); + 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,&len2); counter+=len2; - _asn1_ltostr(counter+len3,temp); - _asn1_set_value(p,temp,strlen(temp)+1); - move=DOWN; + if(len3>0){ + _asn1_ltostr(counter+len3,temp); + _asn1_set_value(p,temp,strlen(temp)+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; + 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; } - _asn1_set_value(p,NULL,0); - if(len2!=counter){ - asn1_delete_structure(element); - return ASN1_DER_ERROR; + 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,&len2); counter+=len2; if(len3){ + if(len3>0){ /* definite length method */ _asn1_ltostr(counter+len3,temp); _asn1_set_value(p,temp,strlen(temp)+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); @@ -596,19 +805,60 @@ asn1_der_decoding(ASN1_TYPE *element,const unsigned char *der,int len, move=RIGHT; break; case TYPE_ANY: + /* Check indefinite lenth method in a EXPLICIT TAG */ + if((p->type&CONST_TAG) && (der[counter-1]==0x80)) + indefinite=1; + else + indefinite=0; + tag=_asn1_get_tag_der(der+counter,&class,&len2); - len2+=_asn1_get_length_der(der+counter+len2,&len3); - _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; - } + len4=_asn1_get_length_der(der+counter+len2,&len3); + + 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; + _asn1_octet_der(der+counter,len2+len3,temp2,&len4); + _asn1_set_value(p,temp2,len4); + _asn1_afree(temp2); + counter+=len2+len3; + } + else{ /* indefinite length */ + 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 + a 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: @@ -681,6 +931,7 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName, int counter,len2,len3,len4,move,ris; unsigned char class,*temp2; unsigned int tag; + int indefinite; node=*structure; @@ -770,9 +1021,29 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName, } } + 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; + } + } + if(type_field(p->type)==TYPE_CHOICE){ while(p->down){ - ris=_asn1_extract_tag_der(p->down,der+counter,&len2); + if(counterdown,der+counter,&len2); + else + ris=ASN1_DER_ERROR; if(ris==ASN1_SUCCESS){ while(p->down->right){ p2=p->down->right; @@ -789,17 +1060,21 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName, asn1_delete_structure(&p2); } } - if(p->down==NULL){ - 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; + } } - p=p->down; + 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(counter>=len2) ris=ASN1_TAG_ERROR; + if(counter>len2) ris=ASN1_TAG_ERROR; } if(ris==ASN1_SUCCESS) ris=_asn1_extract_tag_der(p,der+counter,&len2); @@ -895,13 +1170,16 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName, move=RIGHT; break; case TYPE_OCTET_STRING: - len2=_asn1_get_length_der(der+counter,&len3); + len3=len-counter; if(state==FOUND){ - _asn1_set_value(p,der+counter,len3+len2); - + ris=_asn1_get_octet_string(der+counter,p,&len3); if(p==nodeFound) state=EXIT; } - counter+=len3+len2; + else + ris=_asn1_get_octet_string(der+counter,NULL,&len3); + + if(ris != ASN1_SUCCESS) return ris; + counter+=len3; move=RIGHT; break; case TYPE_GENERALSTRING: @@ -927,14 +1205,21 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName, case TYPE_SEQUENCE: case TYPE_SET: if(move==UP){ len2=strtol(p->value,NULL,10); - _asn1_set_value(p,NULL,0); - if(len2!=counter){ - asn1_delete_structure(structure); - return ASN1_DER_ERROR; + _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; } - - if(p==nodeFound) state=EXIT; - + 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 */ @@ -946,11 +1231,29 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName, else { /* state==SAME_BRANCH or state==FOUND */ len3=_asn1_get_length_der(der+counter,&len2); counter+=len2; - _asn1_ltostr(counter+len3,temp); - _asn1_set_value(p,temp,strlen(temp)+1); - move=DOWN; + if(len3>0){ + _asn1_ltostr(counter+len3,temp); + _asn1_set_value(p,temp,strlen(temp)+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: @@ -994,26 +1297,73 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName, break; case TYPE_ANY: + /* Check indefinite lenth method in a EXPLICIT TAG */ + if((p->type&CONST_TAG) && (der[counter-1]==0x80)) + indefinite=1; + else + indefinite=0; + tag=_asn1_get_tag_der(der+counter,&class,&len2); - len2+=_asn1_get_length_der(der+counter+len2,&len3); - if(state==FOUND){ - _asn1_length_der(len2+len3,NULL,&len4); - temp2=(unsigned char *)_asn1_alloca(len2+len3+len4); - if (temp2==NULL){ + len4=_asn1_get_length_der(der+counter+len2,&len3); + + 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 */ + len2=len-counter; + ris=_asn1_get_indefinite_length_string(der+counter,&len2); + if(ris != ASN1_SUCCESS){ asn1_delete_structure(structure); - return ASN1_MEM_ALLOC_ERROR; + 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+len3,temp2,&len4); - _asn1_set_value(p,temp2,len4); - _asn1_afree(temp2); - - if(p==nodeFound) state=EXIT; + _asn1_octet_der(der+counter,len2,temp2,&len4); + _asn1_set_value(p,temp2,len4); + _asn1_afree(temp2); + + if(p==nodeFound) state=EXIT; + } + + counter+=len2; } - counter+=len2+len3; + /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with + a 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; @@ -1150,9 +1500,10 @@ asn1_der_decoding_startEnd(ASN1_TYPE element,const unsigned char *der,int len, const char *name_element,int *start, int *end) { node_asn *node,*node_to_find,*p,*p2,*p3; - int counter,len2,len3,move,ris; + int counter,len2,len3,len4,move,ris; unsigned char class; unsigned int tag; + int indefinite; node=element; @@ -1180,7 +1531,15 @@ asn1_der_decoding_startEnd(ASN1_TYPE element,const unsigned char *der,int len, if(p->type&CONST_SET){ p2=_asn1_find_up(p); len2=strtol(p2->value,NULL,10); - if(counter==len2){ + 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; @@ -1258,8 +1617,10 @@ asn1_der_decoding_startEnd(ASN1_TYPE element,const unsigned char *der,int len, move=RIGHT; break; case TYPE_OCTET_STRING: - len2=_asn1_get_length_der(der+counter,&len3); - counter+=len3+len2; + 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: @@ -1276,28 +1637,64 @@ asn1_der_decoding_startEnd(ASN1_TYPE element,const unsigned char *der,int len, if(move!=UP){ len3=_asn1_get_length_der(der+counter,&len2); counter+=len2; - move=DOWN; + if(len3==0) move=RIGHT; + else move=DOWN; + } + else{ + if(!der[counter] && !der[counter+1]) /* indefinite length method */ + counter+=2; + move=RIGHT; } - else move=RIGHT; break; case TYPE_SEQUENCE_OF: case TYPE_SET_OF: if(move!=UP){ len3=_asn1_get_length_der(der+counter,&len2); counter+=len2; - if(len3){ + 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: + /* Check indefinite lenth method in a EXPLICIT TAG */ + if((p->type&CONST_TAG) && (der[counter-1]==0x80)) + indefinite=1; + else + indefinite=0; + tag=_asn1_get_tag_der(der+counter,&class,&len2); - len2+=_asn1_get_length_der(der+counter+len2,&len3); - counter+=len3+len2; - move=RIGHT; + len4=_asn1_get_length_der(der+counter+len2,&len3); + + if(len4 != -1){ + counter+=len2+len4+len3; + } + else{ /* indefinite length */ + 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 + a 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; diff --git a/lib/der.h b/lib/der.h index 078b53c..3af8cc7 100644 --- a/lib/der.h +++ b/lib/der.h @@ -44,7 +44,7 @@ asn1_retCode _asn1_get_bit_der(const unsigned char *der, int *der_len,unsigned char *str, int str_size, int *bit_len); -unsigned long _asn1_get_length_der(const unsigned char *der,int *len); +signed long _asn1_get_length_der(const unsigned char *der,int *len); void _asn1_length_der(unsigned long len,unsigned char *ans,int *ans_len); diff --git a/lib/element.c b/lib/element.c index 207ff67..c2a71d9 100644 --- a/lib/element.c +++ b/lib/element.c @@ -35,25 +35,25 @@ void _asn1_hierarchical_name(node_asn *node,char *name,int name_size) { - char *aux; node_asn *p; - + char tmp_name[64]; + p=node; name[0]=0; while(p != NULL){ if(p->name != NULL){ - aux=(char*)malloc(strlen(name)+1); - strcpy(aux,name); + _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,aux); - free(aux); + _asn1_str_cat(name,name_size,tmp_name); } p=_asn1_find_up(p); } - name[strlen(name)-1]=0; + + if(name[0]==0) _asn1_str_cpy(name,name_size,"ROOT"); } @@ -141,7 +141,7 @@ _asn1_append_sequence_set(node_asn *node) _asn1_ltostr(n,temp+1); } _asn1_set_name(p2,temp); - p2->type |= CONST_OPTION; + /* p2->type |= CONST_OPTION; */ return ASN1_SUCCESS; } diff --git a/lib/int.h b/lib/int.h index 0daed1d..9aa0543 100644 --- a/lib/int.h +++ b/lib/int.h @@ -32,7 +32,7 @@ #include -#define LIBTASN1_VERSION "0.2.4" +#define LIBTASN1_VERSION "0.2.5" #define MAX32 4294967295 #define MAX24 16777215 diff --git a/lib/libtasn1.h b/lib/libtasn1.h index 89f73e1..e1bb380 100644 --- a/lib/libtasn1.h +++ b/lib/libtasn1.h @@ -28,7 +28,7 @@ extern "C" { #endif -#define LIBTASN1_VERSION "0.2.4" +#define LIBTASN1_VERSION "0.2.5" #include #include diff --git a/src/CertificateExample.c b/src/CertificateExample.c index fc60cf9..1c1c868 100644 --- a/src/CertificateExample.c +++ b/src/CertificateExample.c @@ -27,6 +27,7 @@ #include #include +#include #include "libtasn1.h" diff --git a/src/CrlExample.c b/src/CrlExample.c index 2eba8c9..8c5d400 100644 --- a/src/CrlExample.c +++ b/src/CrlExample.c @@ -27,6 +27,7 @@ #include #include +#include #include "libtasn1.h" diff --git a/src/asn1Coding.c b/src/asn1Coding.c index 0480c77..aaefe07 100644 --- a/src/asn1Coding.c +++ b/src/asn1Coding.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #ifdef HAVE_UNISTD_H diff --git a/src/asn1Decoding.c b/src/asn1Decoding.c index 780ab9c..903e145 100644 --- a/src/asn1Decoding.c +++ b/src/asn1Decoding.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #ifdef HAVE_UNISTD_H @@ -92,8 +92,9 @@ main(int argc,char *argv[]) char errorDescription[MAX_ERROR_DESCRIPTION_SIZE]; int asn1_result=ASN1_SUCCESS; FILE *inputFile; - unsigned char der[1024]; + unsigned char der[100*1024]; int der_len=0; + /* FILE *outputFile; */ opterr=0; /* disable error messages from getopt */ @@ -192,7 +193,7 @@ main(int argc,char *argv[]) inputFile=fopen(inputFileDerName,"r"); - + if(inputFile==NULL){ printf("asn1Decoding: file '%s' not found\n",inputFileDerName); asn1_delete_structure(&definitions); @@ -203,13 +204,33 @@ main(int argc,char *argv[]) exit(1); } - while(fscanf(inputFile,"%c",der+der_len) != EOF) - der_len++; + /*****************************************/ + /* ONLY FOR TEST */ + /*****************************************/ + /* + der_len=0; + outputFile=fopen("data.p12","w"); + while(fscanf(inputFile,"%c",der+der_len) != EOF){ + if((der_len>=0x11) && (der_len<=(0xe70))) + fprintf(outputFile,"%c",der[der_len]); + der_len++; + } + fclose(outputFile); fclose(inputFile); + */ + + while(fscanf(inputFile,"%c",der+der_len) != EOF){ + der_len++; + } + fclose(inputFile); + asn1_result=asn1_create_element(definitions,typeName,&structure); + /* asn1_print_structure(stdout,structure,"",ASN1_PRINT_ALL); */ + + if(asn1_result != ASN1_SUCCESS){ printf("Structure creation: %s\n",libtasn1_strerror(asn1_result)); asn1_delete_structure(&definitions); @@ -228,6 +249,21 @@ main(int argc,char *argv[]) printf("\nDECODING RESULT:\n"); asn1_print_structure(stdout,structure,"",ASN1_PRINT_NAME_TYPE_VALUE); + /*****************************************/ + /* ONLY FOR TEST */ + /*****************************************/ + /* + der_len=10000; + option_index=0; + asn1_result=asn1_read_value(structure,"?2.content",der,&der_len); + outputFile=fopen("encryptedData.p12","w"); + while(der_len>0){ + fprintf(outputFile,"%c",der[option_index]); + der_len--; + option_index++; + } + fclose(outputFile); + */ asn1_delete_structure(&definitions); asn1_delete_structure(&structure); @@ -246,3 +282,5 @@ main(int argc,char *argv[]) + + diff --git a/src/asn1Parser.c b/src/asn1Parser.c index e071ad9..009ccff 100644 --- a/src/asn1Parser.c +++ b/src/asn1Parser.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #ifdef HAVE_UNISTD_H diff --git a/src/asn1c.c b/src/asn1c.c index 8c9b43f..dc75dd9 100644 --- a/src/asn1c.c +++ b/src/asn1c.c @@ -27,6 +27,7 @@ #include #include +#include #include "libtasn1.h" int diff --git a/tests/Test_parser.c b/tests/Test_parser.c index 5d6b638..7a0688e 100644 --- a/tests/Test_parser.c +++ b/tests/Test_parser.c @@ -27,6 +27,7 @@ #include #include +#include #include "libtasn1.h" typedef struct{ diff --git a/tests/Test_tree.asn b/tests/Test_tree.asn index a918456..a294ebf 100644 --- a/tests/Test_tree.asn +++ b/tests/Test_tree.asn @@ -9,6 +9,48 @@ DEFINITIONS IMPLICIT TAGS ::= BEGIN +KrbError ::= [APPLICATION 30] SEQUENCE { + pvno[0] INTEGER +} + + +CertTemplate ::= SEQUENCE { + version [0] INTEGER OPTIONAL, + issuer [3] Name OPTIONAL, + validity [4] INTEGER OPTIONAL +} + +Name ::= CHOICE { + rdnSequence RDNSequence } + +RDNSequence ::= RelativeDistinguishedName + +RelativeDistinguishedName ::= + + SET SIZE (1 .. MAX) OF AttributeTypeAndValue + +AttributeTypeAndValue ::= SEQUENCE { + type AttributeType, + value AttributeValue } + +AttributeType ::= OBJECT IDENTIFIER +AttributeValue ::= ANY + + +sequenceEmpty ::= SEQUENCE{ + int1 INTEGER, + seq1 [1] IMPLICIT Sequence_octetTest1, + set1 [2] EXPLICIT SET OF INTEGER +} + + +IndefiniteLengthTest ::= SEQUENCE{ + seq1 [1] IMPLICIT Sequence_octetTest1, + set1 SET OF OBJECT IDENTIFIER, + int1 INTEGER +} + + OidTest ::= SEQUENCE{ oid3 [3] OBJECT IDENTIFIER DEFAULT id-Test, oid [1] OBJECT IDENTIFIER DEFAULT id-anyTest2, @@ -56,7 +98,7 @@ DHParameter ::= SEQUENCE { id-octetTest1 OBJECT IDENTIFIER ::= {1 2 3 4} Sequence_octetTest1 ::= SEQUENCE{ - int INTEGER + int INTEGER OPTIONAL } @@ -112,6 +154,7 @@ X520LocalityName ::= CHOICE { id-Test OBJECT IDENTIFIER ::= {1 2 29 2} + END diff --git a/tests/Test_tree.c b/tests/Test_tree.c index 0252ffd..ea367c1 100644 --- a/tests/Test_tree.c +++ b/tests/Test_tree.c @@ -31,6 +31,7 @@ #include #include +#include #include "libtasn1.h" #include "Test_tree_asn1_tab.c" @@ -54,6 +55,8 @@ #define ACT_OID_2_STRUCTURE 16 #define ACT_READ_LENGTH 17 #define ACT_ENCODING_LENGTH 18 +#define ACT_READ_BIT 19 +#define ACT_SET_DER 20 typedef struct{ @@ -69,6 +72,95 @@ test_type test_array[]={ {ACT_DELETE,"","",0,ASN1_ELEMENT_NOT_FOUND}, + /* Test: APPLICATION 30 */ + {ACT_CREATE,"TEST_TREE.KrbError",0,0,ASN1_SUCCESS}, + {ACT_WRITE,"pvno","5",0,ASN1_SUCCESS}, + {ACT_ENCODING_LENGTH,"",0,5,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,4,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,5,ASN1_SUCCESS}, + {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, + {ACT_CREATE,"TEST_TREE.KrbError",0,0,ASN1_SUCCESS}, + {ACT_DECODING,0,0,0,ASN1_SUCCESS}, + {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, + {ACT_DELETE,"","",0,ASN1_SUCCESS}, + + /* Test: CHOICE */ + {ACT_CREATE,"TEST_TREE.CertTemplate",0,0,ASN1_SUCCESS}, + {ACT_WRITE,"version",0,0,ASN1_SUCCESS}, + {ACT_WRITE,"validity",0,0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer","rdnSequence",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence","NEW",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.type","2.5.4.3",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.value","\x0c\x18\x71\x75\x61\x73\x61\x72\x2e\x6c\x61\x73\x2e\x69\x63\x2e\x75\x6e\x69\x63\x61\x6d\x70\x2e\x62\x72",26,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence","NEW",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.type","2.5.4.7",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.value","\x0c\x08\x43\x61\x6d\x70\x69\x6e\x61\x73",10,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence","NEW",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.type","2.5.4.6",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.value","\x13\x06\x42\x72\x61\x73\x69\x6c",8,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence","NEW",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.type","2.5.4.10",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.value","\x0c\x02\x49\x43",4,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence","NEW",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.type","2.5.4.11",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.value","\x0c\x03\x4c\x41\x53",5,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence","NEW",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.type","2.5.4.8",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.value","\x0c\x09\x53\x61\x6f\x20\x50\x61\x75\x6c\x6f",11,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence","NEW",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.type","1.2.840.113549.1.9.1",0,ASN1_SUCCESS}, + {ACT_WRITE,"issuer.rdnSequence.?LAST.value","\x16\x19\x65\x64\x75\x61\x72\x64\x6f\x40\x6c\x61\x73\x2e\x69\x63\x2e\x75\x6e\x69\x63\x61\x6d\x70\x2e\x62\x72",27,ASN1_SUCCESS}, + {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, + {ACT_ENCODING_LENGTH,"",0,152,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,151,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,152,ASN1_SUCCESS}, + {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, + {ACT_DELETE,"","",0,ASN1_SUCCESS}, + {ACT_CREATE,"TEST_TREE.CertTemplate",0,0,ASN1_SUCCESS}, + {ACT_DECODING,0,0,0,ASN1_SUCCESS}, + {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, + {ACT_DELETE,"","",0,ASN1_SUCCESS}, + + /* Test: Empty sequnces */ + {ACT_CREATE,"TEST_TREE.sequenceEmpty",0,0,ASN1_SUCCESS}, + {ACT_WRITE,"int1","1",0,ASN1_SUCCESS}, + {ACT_WRITE,"seq1.int",NULL,0,ASN1_SUCCESS}, + {ACT_ENCODING_LENGTH,"",0,11,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,10,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,11,ASN1_SUCCESS}, + {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, + {ACT_DELETE,"","",0,ASN1_SUCCESS}, + {ACT_CREATE,"TEST_TREE.sequenceEmpty",0,0,ASN1_SUCCESS}, + {ACT_DECODING,0,0,0,ASN1_SUCCESS}, + {ACT_DECODING_START_END,"seq1","START",5,ASN1_SUCCESS}, + {ACT_DECODING_START_END,"seq1","END",6,ASN1_SUCCESS}, + {ACT_DECODING_START_END,"set1","START",7,ASN1_SUCCESS}, + {ACT_DECODING_START_END,"set1","END",10,ASN1_SUCCESS}, + {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, + {ACT_DELETE,"","",0,ASN1_SUCCESS}, + + /* Test: Indefinite Length */ + {ACT_CREATE,"TEST_TREE.IndefiniteLengthTest",0,0,ASN1_SUCCESS}, + {ACT_WRITE,"int1","1",0,ASN1_SUCCESS}, + {ACT_WRITE,"seq1.int","2",0,ASN1_SUCCESS}, + {ACT_WRITE,"set1","NEW",0,ASN1_SUCCESS}, + {ACT_WRITE,"set1.?LAST","1.2.3.4",0,ASN1_SUCCESS}, + {ACT_WRITE,"set1","NEW",0,ASN1_SUCCESS}, + {ACT_WRITE,"set1.?LAST","1.2.5.6",0,ASN1_SUCCESS}, + {ACT_ENCODING,"",0,255,ASN1_SUCCESS}, + {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, + {ACT_SET_DER,"\x30\x18\xa1\x80\x02\x01\x02\x00\x00\x31\x80\x06\x03\x2a\x03\x04\x06\x03\x2a\x05\x06\x00\x00\x02\x01\x01", + 0,26,ASN1_SUCCESS}, + {ACT_DELETE,"","",0,ASN1_SUCCESS}, + {ACT_CREATE,"TEST_TREE.IndefiniteLengthTest",0,0,ASN1_SUCCESS}, + {ACT_DECODING,0,0,0,ASN1_SUCCESS}, + {ACT_DECODING_START_END,"seq1","START",2,ASN1_SUCCESS}, + {ACT_DECODING_START_END,"seq1","END",8,ASN1_SUCCESS}, + {ACT_DECODING_START_END,"set1","START",9,ASN1_SUCCESS}, + {ACT_DECODING_START_END,"set1","END",22,ASN1_SUCCESS}, + {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, + {ACT_DELETE,"","",0,ASN1_SUCCESS}, + /* Test: OID */ {ACT_CREATE,"TEST_TREE.OidTest",0,0,ASN1_SUCCESS}, {ACT_READ_LENGTH,"oid",NULL,9,ASN1_MEM_ERROR}, @@ -116,6 +208,8 @@ test_type test_array[]={ {ACT_READ_LENGTH,"enum",NULL,1,ASN1_MEM_ERROR}, {ACT_READ_LENGTH,"any",NULL,3,ASN1_MEM_ERROR}, {ACT_READ_LENGTH,"gen",NULL,5,ASN1_MEM_ERROR}, + {ACT_READ_LENGTH,"bit",NULL,10,ASN1_MEM_ERROR}, + {ACT_READ_BIT,"bit","1\xC0",10,ASN1_SUCCESS}, {ACT_ENCODING_LENGTH,"",0,79,ASN1_MEM_ERROR}, {ACT_ENCODING,"",0,78,ASN1_MEM_ERROR}, {ACT_ENCODING,"",0,79,ASN1_SUCCESS}, @@ -317,7 +411,7 @@ main(int argc,char *argv[]) printf( "/****************************************/\n\n"); /* Check version */ - if(asn1_check_version("0.2.4")==NULL) + if(asn1_check_version("0.2.5")==NULL) printf("\nLibrary version check ERROR:\n actual version: %s\n\n",asn1_check_version(NULL)); if(1) @@ -365,6 +459,7 @@ main(int argc,char *argv[]) result=asn1_write_value(asn1_element,test->par1,test->par2,test->par3); break; case ACT_READ: + case ACT_READ_BIT: valueLen=test->par3; result=asn1_read_value(asn1_element,test->par1,value,&valueLen); break; @@ -424,6 +519,11 @@ main(int argc,char *argv[]) printf("\n\n"); result=ASN1_SUCCESS; break; + case ACT_SET_DER: + der_len=test->par3; + memcpy(der,test->par1,der_len); + result=ASN1_SUCCESS; + break; case ACT_NUMBER_OF_ELEMENTS: result=asn1_number_of_elements(asn1_element,test->par1,&valueLen); break; @@ -442,6 +542,7 @@ main(int argc,char *argv[]) case ACT_PRINT_DER: case ACT_EXPAND_ANY: case ACT_EXPAND_OCTET: + case ACT_SET_DER: if(result != test->errorNumber){ errorCounter++; printf("ERROR N. %d:\n",errorCounter); @@ -531,7 +632,15 @@ main(int argc,char *argv[]) case ACT_READ: case ACT_READ_DEFINITIONS: - for(k=0;kaction==ACT_READ_BIT){ + if((valueLen-(valueLen/8.0))==0) tag=valueLen/8; + else tag=(valueLen/8)+1; + if((test->par3-(test->par3/8.0))==0) class=test->par3/8; + else class=(test->par3/8)+1; + } + + for(k=0;kpar2[k] != value[k]){ k=-1; break; -- 2.7.4