summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabio Fiorina <fiorinaf@gnutls.org>2003-07-30 19:50:34 +0000
committerFabio Fiorina <fiorinaf@gnutls.org>2003-07-30 19:50:34 +0000
commitf75e8e5f5e3f77b6b19bdfe625abb94ae3664088 (patch)
tree647f366e88b27253e7037f007ca4f4fb0e997d74
parent84f25fcf992e5d7285c6d5d9734c1f88539dc50e (diff)
downloadlibtasn1_0_2_5.tar.gz
Add BER decodinglibtasn1_0_2_5
-rw-r--r--NEWS14
-rw-r--r--configure.in2
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/coding.c32
-rw-r--r--lib/decoding.c581
-rw-r--r--lib/der.h2
-rw-r--r--lib/element.c16
-rw-r--r--lib/int.h2
-rw-r--r--lib/libtasn1.h2
-rw-r--r--src/CertificateExample.c1
-rw-r--r--src/CrlExample.c1
-rw-r--r--src/asn1Coding.c2
-rw-r--r--src/asn1Decoding.c48
-rw-r--r--src/asn1Parser.c2
-rw-r--r--src/asn1c.c1
-rw-r--r--tests/Test_parser.c1
-rw-r--r--tests/Test_tree.asn45
-rw-r--r--tests/Test_tree.c113
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(counter2<counter_end){
+ len2=_asn1_get_length_der(der+counter2,&len3);
+ 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,&len3);
+ if(node)
+ _asn1_set_value(node,der,len3+len2);
+ counter=len3+len2;
+ }
+
+ *len=counter;
+ return ASN1_SUCCESS;
+
+}
+
+
+asn1_retCode
+_asn1_get_indefinite_length_string(const unsigned char* der,int* len)
+{
+ int len2,len3,counter,indefinite;
+ unsigned int tag;
+ unsigned char class;
+
+ counter=indefinite=0;
+
+ 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;
+ }
+
+ tag=_asn1_get_tag_der(der+counter,&class,&len2);
+ counter+=len2;
+ len2=_asn1_get_length_der(der+counter,&len3);
+ if(len2 == -1){
+ indefinite++;
+ counter+=1;
+ }
+ else{
+ counter+=len2+len3;
+ }
+ }
+
+ *len=counter;
+ return ASN1_SUCCESS;
+
+}
+
/**
* asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
@@ -383,6 +512,7 @@ asn1_der_decoding(ASN1_TYPE *element,const unsigned char *der,int len,
int counter,len2,len3,len4,move,ris;
unsigned char class,*temp2;
unsigned int tag;
+ int indefinite;
node=*element;
@@ -398,12 +528,19 @@ asn1_der_decoding(ASN1_TYPE *element,const unsigned char *der,int len,
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){
+ 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(counter<len)
+ ris=_asn1_extract_tag_der(p->down,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(counter<len)
+ ris=_asn1_extract_tag_der(p->down,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 <mem.h>
-#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 <sys/types.h>
#include <time.h>
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 <stdio.h>
#include <string.h>
+#include <stdlib.h>
#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 <stdio.h>
#include <string.h>
+#include <stdlib.h>
#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 <stdio.h>
#include <string.h>
#include <libtasn1.h>
-#include <malloc.h>
+#include <stdlib.h>
#include <config.h>
#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 <stdio.h>
#include <string.h>
#include <libtasn1.h>
-#include <malloc.h>
+#include <stdlib.h>
#include <config.h>
#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 <stdio.h>
#include <string.h>
#include <libtasn1.h>
-#include <malloc.h>
+#include <stdlib.h>
#include <config.h>
#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 <stdio.h>
#include <string.h>
+#include <stdlib.h>
#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 <stdio.h>
#include <string.h>
+#include <stdlib.h>
#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 <stdio.h>
#include <string.h>
+#include <stdlib.h>
#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;k<valueLen;k++)
+ case ACT_READ_BIT:
+ if(test->action==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;k<class;k++)
if(test->par2[k] != value[k]){
k=-1;
break;