From 0b694f3b2ae54571462ab7b7f1b0ed4ca73d10b1 Mon Sep 17 00:00:00 2001 From: Fabio Fiorina Date: Tue, 25 Feb 2003 22:07:40 +0000 Subject: [PATCH] add vector length check --- NEWS | 5 + configure.in | 2 +- lib/coding.c | 242 ++++++++++++++++++++++++++++++++++----------- lib/decoding.c | 9 +- lib/element.c | 41 +++++--- lib/int.h | 2 + lib/libtasn1.h | 4 +- lib/parser_aux.c | 75 ++++++++++++++ src/CertificateExample.c | 16 ++- src/CrlExample.c | 11 ++- src/asn1Coding.c | 1 + tests/Test_tree.asn | 2 +- tests/Test_tree.c | 90 ++++++++++++----- tests/Test_tree_asn1_tab.c | 87 +++++++++++++++- 14 files changed, 479 insertions(+), 108 deletions(-) diff --git a/NEWS b/NEWS index 39ebade..3bbff87 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +Version 0.2.2 +- Add vector length check in asn1_der_coding function +- Add vector length check in asn1_read_value function +- Add asn1_check_version function + Version 0.2.1 - Add asn1_find_structure_from_oid function - Add asn1_read_tag function diff --git a/configure.in b/configure.in index e0e2e2e..2c94553 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=1 +ASN1_MICRO_VERSION=2 ASN1_VERSION=$ASN1_MAJOR_VERSION.$ASN1_MINOR_VERSION.$ASN1_MICRO_VERSION AC_DEFINE_UNQUOTED(ASN1_VERSION, "$ASN1_VERSION") diff --git a/lib/coding.c b/lib/coding.c index 3f6fdef..ea21141 100644 --- a/lib/coding.c +++ b/lib/coding.c @@ -32,6 +32,8 @@ #include #include "element.h" +#define MAX_TAG_LEN 16 + /******************************************************/ /* Function : _asn1_error_description_value_not_found */ /* Description: creates the ErrorDescription string */ @@ -159,18 +161,29 @@ _asn1_octet_der(const unsigned char *str,int str_len,unsigned char *der,int *der /* str: TIME null-terminated string. */ /* der: string returned. */ /* der_len: number of meanful bytes of DER */ -/* (der[0]..der[ans_len-1]). */ +/* (der[0]..der[ans_len-1]). Initially it */ +/* if must store the lenght of DER. */ /* Return: */ +/* ASN1_MEM_ERROR when DER isn't big enough */ +/* ASN1_SUCCESS otherwise */ /******************************************************/ -void +asn1_retCode _asn1_time_der(unsigned char *str,unsigned char *der,int *der_len) { int len_len; + int max_len; - if(der==NULL) return; + max_len=*der_len; + + if(der==NULL) return ASN1_SUCCESS; _asn1_length_der(strlen(str),der,&len_len); - memcpy(der+len_len,str,strlen(str)); + if((len_len+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; + + return ASN1_SUCCESS; } @@ -217,18 +230,23 @@ _asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str) /* str: OBJECT IDENTIFIER null-terminated string. */ /* der: string returned. */ /* der_len: number of meanful bytes of DER */ -/* (der[0]..der[ans_len-1]). */ +/* (der[0]..der[ans_len-1]). Initially it */ +/* if must store the lenght of DER. */ /* Return: */ +/* ASN1_MEM_ERROR when DER isn't big enough */ +/* ASN1_SUCCESS otherwise */ /******************************************************/ -void +asn1_retCode _asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len) { - int len_len,counter,k,first; + int len_len,counter,k,first,max_len; char *temp,*n_end,*n_start; unsigned char bit7; unsigned long val,val1=0; - if(der==NULL) return; + if(der==NULL) return ASN1_SUCCESS; + + max_len=*der_len; temp=(char *) malloc(strlen(str)+2); @@ -244,7 +262,8 @@ _asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len) if(counter==1) val1=val; else if(counter==2){ - der[0]=40*val1+val; + if(max_len>0) + der[0]=40*val1+val; *der_len=1; } else{ @@ -253,7 +272,8 @@ _asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len) bit7=(val>>(k*7))&0x7F; if(bit7 || first || !k){ if(k) bit7|=0x80; - der[*der_len]=bit7; + if(max_len>(*der_len)) + der[*der_len]=bit7; (*der_len)++; first=1; } @@ -264,11 +284,17 @@ _asn1_objectid_der(unsigned char *str,unsigned char *der,int *der_len) } _asn1_length_der(*der_len,NULL,&len_len); - memmove(der+len_len,der,*der_len); - _asn1_length_der(*der_len,der,&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; free(temp); + + if(max_len<(*der_len)) return ASN1_MEM_ERROR; + + return ASN1_SUCCESS; } @@ -313,10 +339,13 @@ _asn1_bit_der(const unsigned char *str,int bit_len,unsigned char *der,int *der_l /* der: string with the DER coding of the whole tree*/ /* counter: number of meanful bytes of DER */ /* (der[0]..der[*counter-1]). */ +/* max_len: size of der vector */ /* Return: */ +/* ASN1_MEM_ERROR if der vector isn't big enough, */ +/* otherwise ASN1_SUCCESS. */ /******************************************************/ -void -_asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter) +asn1_retCode +_asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter,int *max_len) { node_asn *p; int is_tag_implicit,len2,len3; @@ -339,8 +368,11 @@ _asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter) len2=strtol(p->name,NULL,10); _asn1_set_name(p,NULL); _asn1_length_der(*counter-len2,temp,&len3); - memmove(der+len2+len3,der+len2,*counter-len2); - memcpy(der+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; } @@ -353,6 +385,10 @@ _asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter) p=p->left; } } + + if(*max_len<0) return ASN1_MEM_ERROR; + + return ASN1_SUCCESS; } @@ -365,17 +401,20 @@ _asn1_complete_explicit_tag(node_asn *node,unsigned char *der,int *counter) /* der: string returned */ /* counter: number of meanful bytes of DER */ /* (counter[0]..der[*counter-1]). */ +/* max_len: size of der vector */ /* Return: */ /* ASN1_GENERIC_ERROR if the type is unknown, */ +/* ASN1_MEM_ERROR if der vector isn't big enough, */ /* otherwise ASN1_SUCCESS. */ /******************************************************/ -int -_asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter) +asn1_retCode +_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; + char tag_der[MAX_TAG_LEN]; is_tag_implicit=0; @@ -390,10 +429,15 @@ _asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter) if(p->type&CONST_EXPLICIT){ if(is_tag_implicit) - _asn1_tag_der(class_implicit,tag_implicit,der+*counter,&tag_len); + _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len); else - _asn1_tag_der(class|STRUCTURED,strtoul(p->value,NULL,10),der+*counter,&tag_len); + _asn1_tag_der(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); @@ -416,45 +460,45 @@ _asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter) } if(is_tag_implicit){ - _asn1_tag_der(class_implicit,tag_implicit,der+*counter,&tag_len); + _asn1_tag_der(class_implicit,tag_implicit,tag_der,&tag_len); } else{ switch(type_field(node->type)){ case TYPE_NULL: - _asn1_tag_der(UNIVERSAL,TAG_NULL,der+*counter,&tag_len); + _asn1_tag_der(UNIVERSAL,TAG_NULL,tag_der,&tag_len); break; case TYPE_BOOLEAN: - _asn1_tag_der(UNIVERSAL,TAG_BOOLEAN,der+*counter,&tag_len); + _asn1_tag_der(UNIVERSAL,TAG_BOOLEAN,tag_der,&tag_len); break; case TYPE_INTEGER: - _asn1_tag_der(UNIVERSAL,TAG_INTEGER,der+*counter,&tag_len); + _asn1_tag_der(UNIVERSAL,TAG_INTEGER,tag_der,&tag_len); break; case TYPE_ENUMERATED: - _asn1_tag_der(UNIVERSAL,TAG_ENUMERATED,der+*counter,&tag_len); + _asn1_tag_der(UNIVERSAL,TAG_ENUMERATED,tag_der,&tag_len); break; case TYPE_OBJECT_ID: - _asn1_tag_der(UNIVERSAL,TAG_OBJECT_ID,der+*counter,&tag_len); + _asn1_tag_der(UNIVERSAL,TAG_OBJECT_ID,tag_der,&tag_len); break; case TYPE_TIME: if(node->type&CONST_UTC){ - _asn1_tag_der(UNIVERSAL,TAG_UTCTime,der+*counter,&tag_len); + _asn1_tag_der(UNIVERSAL,TAG_UTCTime,tag_der,&tag_len); } - else _asn1_tag_der(UNIVERSAL,TAG_GENERALIZEDTime,der+*counter,&tag_len); + else _asn1_tag_der(UNIVERSAL,TAG_GENERALIZEDTime,tag_der,&tag_len); break; case TYPE_OCTET_STRING: - _asn1_tag_der(UNIVERSAL,TAG_OCTET_STRING,der+*counter,&tag_len); + _asn1_tag_der(UNIVERSAL,TAG_OCTET_STRING,tag_der,&tag_len); break; case TYPE_GENERALSTRING: - _asn1_tag_der(UNIVERSAL,TAG_GENERALSTRING,der+*counter,&tag_len); + _asn1_tag_der(UNIVERSAL,TAG_GENERALSTRING,tag_der,&tag_len); break; case TYPE_BIT_STRING: - _asn1_tag_der(UNIVERSAL,TAG_BIT_STRING,der+*counter,&tag_len); + _asn1_tag_der(UNIVERSAL,TAG_BIT_STRING,tag_der,&tag_len); break; case TYPE_SEQUENCE: case TYPE_SEQUENCE_OF: - _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SEQUENCE,der+*counter,&tag_len); + _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SEQUENCE,tag_der,&tag_len); break; case TYPE_SET: case TYPE_SET_OF: - _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SET,der+*counter,&tag_len); + _asn1_tag_der(UNIVERSAL|STRUCTURED,TAG_SET,tag_der,&tag_len); break; case TYPE_TAG: tag_len=0; @@ -469,9 +513,14 @@ _asn1_insert_tag_der(node_asn *node,unsigned char *der,int *counter) 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) return ASN1_MEM_ERROR; + return ASN1_SUCCESS; } @@ -670,7 +719,7 @@ _asn1_ordering_set_of(unsigned char *der,node_asn *node) * @element: pointer to an ASN1 element * @name: the name of the structure you want to encode (it must be inside *POINTER). * @der: vector that will contain the DER encoding. DER must be a pointer to memory cells already allocated. - * @len: number of bytes of *der: der[0]..der[len-1] + * @len: number of bytes of *der: der[0]..der[len-1], Initialy holds the sizeof of der vector. * @errorDescription : return the error description or an empty string if success. * Description: * @@ -683,6 +732,10 @@ _asn1_ordering_set_of(unsigned char *der,node_asn *node) * ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element. * * ASN1_VALUE_NOT_FOUND\: there is an element without a value. + * + * ASN1_MEM_ERROR\: der vector isn't big enough. Also in this case LEN + * will contain the length needed. + * **/ asn1_retCode asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len, @@ -690,72 +743,123 @@ asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len, { node_asn *node,*p; char temp[SIZEOF_UNSIGNED_LONG_INT*3+1]; - int counter,counter_old,len2,len3,move,ris; + int counter,counter_old,len2,len3,move,max_len,max_len_old; + asn1_retCode ris; node=_asn1_find_node(element,name); if(node==NULL) return ASN1_ELEMENT_NOT_FOUND; + max_len=*len; + counter=0; move=DOWN; p=node; while(1){ counter_old=counter; - if(move!=UP) ris=_asn1_insert_tag_der(p,der,&counter); - + max_len_old=max_len; + if(move!=UP){ + ris=_asn1_insert_tag_der(p,der,&counter,&max_len); + } switch(type_field(p->type)){ case TYPE_NULL: - der[counter]=0; - counter++; + 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; + if((p->type&CONST_DEFAULT) && (p->value==NULL)){ + counter=counter_old; + max_len=max_len_old; + } else{ - der[counter++]=1; - if(p->value[0]=='F') der[counter++]=0; - else der[counter++]=0xFF; + if(p->value==NULL){ + _asn1_error_description_value_not_found(p,ErrorDescription); + return ASN1_VALUE_NOT_FOUND; + } + max_len -= 2; + if(max_len>=0){ + der[counter++]=1; + if(p->value[0]=='F') der[counter++]=0; + else der[counter++]=0xFF; + } } move=RIGHT; break; case TYPE_INTEGER: case TYPE_ENUMERATED: - if((p->type&CONST_DEFAULT) && (p->value==NULL)) counter=counter_old; + 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); return ASN1_VALUE_NOT_FOUND; } len2=_asn1_get_length_der(p->value,&len3); - memcpy(der+counter,p->value,len3+len2); + 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: - _asn1_objectid_der(p->value,der+counter,&len2); + if(p->value==NULL){ + _asn1_error_description_value_not_found(p,ErrorDescription); + return ASN1_VALUE_NOT_FOUND; + } + len2=max_len; + ris=_asn1_objectid_der(p->value,der+counter,&len2); + max_len-=len2; counter+=len2; move=RIGHT; break; case TYPE_TIME: - _asn1_time_der(p->value,der+counter,&len2); + if(p->value==NULL){ + _asn1_error_description_value_not_found(p,ErrorDescription); + return ASN1_VALUE_NOT_FOUND; + } + len2=max_len; + ris=_asn1_time_der(p->value,der+counter,&len2); + max_len-=len2; counter+=len2; move=RIGHT; break; case TYPE_OCTET_STRING: + if(p->value==NULL){ + _asn1_error_description_value_not_found(p,ErrorDescription); + return ASN1_VALUE_NOT_FOUND; + } len2=_asn1_get_length_der(p->value,&len3); - memcpy(der+counter,p->value,len3+len2); + 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); + return ASN1_VALUE_NOT_FOUND; + } len2=_asn1_get_length_der(p->value,&len3); - memcpy(der+counter,p->value,len3+len2); + 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); + return ASN1_VALUE_NOT_FOUND; + } len2=_asn1_get_length_der(p->value,&len3); - memcpy(der+counter,p->value,len3+len2); + max_len-=len2+len3; + if(max_len>=0) + memcpy(der+counter,p->value,len3+len2); counter+=len3+len2; move=RIGHT; break; @@ -768,10 +872,14 @@ asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len, else{ /* move==UP */ len2=strtol(p->value,NULL,10); _asn1_set_value(p,NULL,0); - if(type_field(p->type)==TYPE_SET) _asn1_ordering_set(der+len2,p); + if((type_field(p->type)==TYPE_SET) && (max_len>=0)) + _asn1_ordering_set(der+len2,p); _asn1_length_der(counter-len2,temp,&len3); - memmove(der+len2+len3,der+len2,counter-len2); - memcpy(der+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; } @@ -793,17 +901,27 @@ asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len, if(move==UP){ len2=strtol(p->value,NULL,10); _asn1_set_value(p,NULL,0); - if(type_field(p->type)==TYPE_SET_OF) _asn1_ordering_set_of(der+len2,p); + if((type_field(p->type)==TYPE_SET_OF) && (max_len>=0)) + _asn1_ordering_set_of(der+len2,p); _asn1_length_der(counter-len2,temp,&len3); - memmove(der+len2+len3,der+len2,counter-len2); - memcpy(der+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); + return ASN1_VALUE_NOT_FOUND; + } len2=_asn1_get_length_der(p->value,&len3); - memcpy(der+counter,p->value+len3,len2); + max_len-=len2; + if(max_len>=0) + memcpy(der+counter,p->value+len3,len2); counter+=len2; move=RIGHT; break; @@ -812,8 +930,9 @@ asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len, break; } - if((move!=DOWN) && (counter!=counter_old)) - _asn1_complete_explicit_tag(p,der,&counter); + if((move!=DOWN) && (counter!=counter_old)){ + ris=_asn1_complete_explicit_tag(p,der,&counter,&max_len); + } if(p==node && move!=DOWN) break; @@ -829,6 +948,9 @@ asn1_der_coding(ASN1_TYPE element,const char *name,unsigned char *der,int *len, } *len=counter; + + if(max_len<0) return ASN1_MEM_ERROR; + return ASN1_SUCCESS; } diff --git a/lib/decoding.c b/lib/decoding.c index 811a476..0001388 100644 --- a/lib/decoding.c +++ b/lib/decoding.c @@ -102,14 +102,15 @@ _asn1_get_octet_der(const unsigned char *der,int *der_len,unsigned char *str,int { int len_len; - if(str==NULL) return ASN1_SUCCESS; + /* if(str==NULL) return ASN1_SUCCESS; */ *str_len=_asn1_get_length_der(der,&len_len); + + *der_len=*str_len+len_len; if ( str_size >= *str_len) memcpy(str,der+len_len,*str_len); else { return ASN1_MEM_ERROR; } - *der_len=*str_len+len_len; return ASN1_SUCCESS; } @@ -171,14 +172,14 @@ _asn1_get_bit_der(const unsigned char *der,int *der_len,unsigned char *str, int if(str==NULL) return ASN1_SUCCESS; len_byte=_asn1_get_length_der(der,&len_len)-1; - + + *der_len=len_byte+len_len+1; 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]; - *der_len=len_byte+len_len+1; return ASN1_SUCCESS; } diff --git a/lib/element.c b/lib/element.c index c38c8b9..8b71d05 100644 --- a/lib/element.c +++ b/lib/element.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000,2001 Fabio Fiorina + * Copyright (C) 2000,2001,2002,2003 Fabio Fiorina * * This file is part of LIBASN1. * @@ -69,7 +69,7 @@ _asn1_hierarchical_name(node_asn *node,char *name,int name_size) /* allocated). */ /* value_out_size: number of bytes of value_out. */ /* len: number of significant byte of value_out. */ -/* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */ +/* 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) @@ -87,7 +87,7 @@ _asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_s if(val[0]&0x80) negative=1; else negative=0; - + for(k=0;k value_out_size) /* VALUE_OUT is too short to contain the value convertion */ return ASN1_MEM_ERROR; @@ -103,8 +105,6 @@ _asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_s for(k2=k;k2type&CONST_DEFAULT) && (node->value==NULL)){ p=node->down; while(type_field(p->type)!=TYPE_DEFAULT) p=p->right; - if (_asn1_convert_integer(p->value,value,value_size, len)!=ASN1_SUCCESS) return ASN1_MEM_ERROR; + 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) + return ASN1_MEM_ERROR; + break; + } + } + p2=p2->right; + } + } } else{ len2=-1; @@ -636,11 +657,9 @@ asn1_read_value(node_asn *root,const char *name,unsigned char *value, int *len) p=node->down; while(p){ if(type_field(p->type)==TYPE_CONSTANT){ - value_size-=strlen(p->value)+1; - if(value_size<1) return ASN1_MEM_ERROR; - strcat(value,p->value); + ADD_STR_VALUE(value,value_size,p->value); if(p->right) { - strcat(value,"."); + ADD_STR_VALUE(value,value_size,"."); } } p=p->right; diff --git a/lib/int.h b/lib/int.h index f9c62b3..2c37e27 100644 --- a/lib/int.h +++ b/lib/int.h @@ -32,6 +32,8 @@ #include +#define LIBTASN1_VERSION "0.2.2" + #define MAX32 4294967295 #define MAX24 16777215 #define MAX16 65535 diff --git a/lib/libtasn1.h b/lib/libtasn1.h index 31ceee3..b687ece 100644 --- a/lib/libtasn1.h +++ b/lib/libtasn1.h @@ -28,7 +28,7 @@ extern "C" { #endif -#define LIBASN1_VERSION "0.2.1" +#define LIBTASN1_VERSION "0.2.2" #include #include @@ -176,6 +176,8 @@ asn1_retCode asn1_read_tag(node_asn *root,const char *name,int *tag, asn1_retCode asn1_find_structure_from_oid(ASN1_TYPE definitions, const char *oidValue,char *structureName); +const char *asn1_check_version( const char *req_version ); + const char* libtasn1_strerror(asn1_retCode error); void libtasn1_perror(asn1_retCode error); diff --git a/lib/parser_aux.c b/lib/parser_aux.c index a0f7775..2444f3d 100644 --- a/lib/parser_aux.c +++ b/lib/parser_aux.c @@ -768,4 +768,79 @@ _asn1_set_default_tag(ASN1_TYPE node) +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'; + } + *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 ) +{ + 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 */ +} + +/** + * asn1_check_version - This function checks the library's version + * @req_version: the version to check + * + * Check that the the version of the library is at minimum the requested one + * and return the version string; return NULL if the condition is not + * satisfied. If a NULL is passed to this function, no check is done, + * but the version string is simply returned. + * + **/ +const char * +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; + } + return NULL; +} + diff --git a/src/CertificateExample.c b/src/CertificateExample.c index 2f3bf96..fc60cf9 100644 --- a/src/CertificateExample.c +++ b/src/CertificateExample.c @@ -186,6 +186,9 @@ create_certificate(node_asn *cert_def,unsigned char *der,int *der_len) ASN1_TYPE param=ASN1_TYPE_EMPTY; ASN1_TYPE constr=ASN1_TYPE_EMPTY; char errorDescription[MAX_ERROR_DESCRIPTION_SIZE]; + int max_len; + + max_len=*der_len; result=asn1_create_element(cert_def,"PKIX1Implicit88.Certificate",&cert1); @@ -222,6 +225,7 @@ create_certificate(node_asn *cert_def,unsigned char *der,int *der_len) result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName", &value); result=asn1_write_value(value,"","US",2); + *der_len = max_len; result=asn1_der_coding(value,"",der,der_len,errorDescription); asn1_delete_structure(&value); result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len); @@ -237,6 +241,7 @@ create_certificate(node_asn *cert_def,unsigned char *der,int *der_len) &value); result=asn1_write_value(value,"","printableString",1); result=asn1_write_value(value,"printableString","gov",3); + *der_len = max_len; result=asn1_der_coding(value,"",der,der_len,errorDescription); asn1_delete_structure(&value); result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len); @@ -253,6 +258,7 @@ create_certificate(node_asn *cert_def,unsigned char *der,int *der_len) result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value); result=asn1_write_value(value,"","printableString",1); result=asn1_write_value(value,"printableString","nist",4); + *der_len = max_len; result=asn1_der_coding(value,"",der,der_len,errorDescription); asn1_delete_structure(&value); result=asn1_write_value(cert1,"tbsCertificate.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len); @@ -279,6 +285,7 @@ create_certificate(node_asn *cert_def,unsigned char *der,int *der_len) result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName", &value); result=asn1_write_value(value,"","US",2); + *der_len = max_len; result=asn1_der_coding(value,"",der,der_len,errorDescription); asn1_delete_structure(&value); result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len); @@ -294,6 +301,7 @@ create_certificate(node_asn *cert_def,unsigned char *der,int *der_len) &value); result=asn1_write_value(value,"","printableString",1); result=asn1_write_value(value,"printableString","gov",3); + *der_len = max_len; result=asn1_der_coding(value,"",der,der_len,errorDescription); asn1_delete_structure(&value); result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len); @@ -309,6 +317,7 @@ create_certificate(node_asn *cert_def,unsigned char *der,int *der_len) result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value); result=asn1_write_value(value,"","printableString",1); result=asn1_write_value(value,"printableString","nist",4); + *der_len = max_len; result=asn1_der_coding(value,"",der,der_len,errorDescription); asn1_delete_structure(&value); result=asn1_write_value(cert1,"tbsCertificate.subject.rdnSequence.?LAST.?LAST.value",der,*der_len); @@ -325,6 +334,7 @@ create_certificate(node_asn *cert_def,unsigned char *der,int *der_len) result=asn1_write_value(param,"q",str2,20); str2="\xd4\x38"; /* only an example */ result=asn1_write_value(param,"g",str2,128); + *der_len = max_len; result=asn1_der_coding(param,"",der,der_len,errorDescription); asn1_delete_structure(¶m); result=asn1_write_value(cert1,"tbsCertificate.subjectPublicKeyInfo.algorithm.parameters",der,*der_len); @@ -347,6 +357,7 @@ create_certificate(node_asn *cert_def,unsigned char *der,int *der_len) result=asn1_create_element(cert_def,"PKIX1Implicit88.BasicConstraints",&constr); result=asn1_write_value(constr,"cA","TRUE",1); result=asn1_write_value(constr,"pathLenConstraint",NULL,0); + *der_len = max_len; result=asn1_der_coding(constr,"",der,der_len,errorDescription); result=asn1_delete_structure(&constr); result=asn1_write_value(cert1,"tbsCertificate.extensions.?LAST.extnValue",der,*der_len); @@ -370,6 +381,7 @@ create_certificate(node_asn *cert_def,unsigned char *der,int *der_len) /* signature */ + *der_len = max_len; result=asn1_der_coding(cert1,"tbsCertificate",der,der_len ,errorDescription); if(result!=ASN1_SUCCESS){ @@ -384,7 +396,7 @@ create_certificate(node_asn *cert_def,unsigned char *der,int *der_len) asn1_visit_tree(cert1,""); printf("-----------------\n"); */ - + *der_len = max_len; result=asn1_der_coding(cert1,"",der,der_len,errorDescription); if(result!=ASN1_SUCCESS){ printf("\n'certificate' encoding creation: ERROR\n"); @@ -501,7 +513,7 @@ main(int argc,char *argv[]) asn1_visit_tree(PKIX1Implicit88,"PKIX1Implicit88"); printf("-----------------\n"); */ - + der_len=1024; create_certificate(PKIX1Implicit88,der,&der_len); get_certificate(PKIX1Implicit88,der,der_len); diff --git a/src/CrlExample.c b/src/CrlExample.c index 1aafbd7..2eba8c9 100644 --- a/src/CrlExample.c +++ b/src/CrlExample.c @@ -194,6 +194,9 @@ create_CRL(node_asn *cert_def, unsigned char *der,int *der_len) ASN1_TYPE crl=ASN1_TYPE_EMPTY; ASN1_TYPE value=ASN1_TYPE_EMPTY; char errorDescription[MAX_ERROR_DESCRIPTION_SIZE]; + int max_len; + + max_len=*der_len; result=asn1_create_element(cert_def,"PKIX1Implicit88.CertificateList",&crl); @@ -226,6 +229,7 @@ create_CRL(node_asn *cert_def, unsigned char *der,int *der_len) result=asn1_create_element(cert_def,"PKIX1Implicit88.X520countryName", &value); result=asn1_write_value(value,"","US",2); + *der_len=max_len; result=asn1_der_coding(value,"",der,der_len,errorDescription); asn1_delete_structure(&value); @@ -242,6 +246,7 @@ create_CRL(node_asn *cert_def, unsigned char *der,int *der_len) &value); result=asn1_write_value(value,"","printableString",1); result=asn1_write_value(value,"printableString","gov",3); + *der_len=max_len; result=asn1_der_coding(value,"",der,der_len,errorDescription); asn1_delete_structure(&value); result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len); @@ -257,6 +262,7 @@ create_CRL(node_asn *cert_def, unsigned char *der,int *der_len) result=asn1_create_element(cert_def,"PKIX1Implicit88.X520OrganizationalUnitName",&value); result=asn1_write_value(value,"","printableString",1); result=asn1_write_value(value,"printableString","nist",4); + *der_len=max_len; result=asn1_der_coding(value,"",der,der_len,errorDescription); asn1_delete_structure(&value); result=asn1_write_value(crl,"tbsCertList.issuer.rdnSequence.?LAST.?LAST.value",der,*der_len); @@ -298,6 +304,7 @@ create_CRL(node_asn *cert_def, unsigned char *der,int *der_len) result=asn1_write_value(crl,"signatureAlgorithm.parameters",NULL,0); /* NO OPTION */ /* signature */ + *der_len=max_len; result=asn1_der_coding(crl,"tbsCertList",der,der_len,errorDescription); if(result!=ASN1_SUCCESS){ printf("\n'tbsCertList' encoding creation: ERROR\n"); @@ -313,7 +320,7 @@ create_CRL(node_asn *cert_def, unsigned char *der,int *der_len) asn1_visit_tree(crl,""); printf("-----------------\n"); */ - + *der_len=max_len; result=asn1_der_coding(crl,"",der,der_len,errorDescription); if(result!=ASN1_SUCCESS){ printf("\n'crl1' encoding creation: ERROR\n"); @@ -424,7 +431,7 @@ main(int argc,char *argv[]) asn1_visit_tree(cert_def,"PKIX1Implicit88"); printf("-----------------\n"); */ - + der_len=1024; create_CRL(PKIX1Implicit88,der,&der_len); diff --git a/src/asn1Coding.c b/src/asn1Coding.c index 2688332..0480c77 100644 --- a/src/asn1Coding.c +++ b/src/asn1Coding.c @@ -286,6 +286,7 @@ main(int argc,char *argv[]) printf("\n"); asn1_print_structure(stdout,structure,"",ASN1_PRINT_NAME_TYPE_VALUE); + der_len=1024; asn1_result=asn1_der_coding(structure,"",der,&der_len, errorDescription); printf("\nCoding: %s\n\n",libtasn1_strerror(asn1_result)); diff --git a/tests/Test_tree.asn b/tests/Test_tree.asn index 7c36822..bd25fc7 100644 --- a/tests/Test_tree.asn +++ b/tests/Test_tree.asn @@ -19,7 +19,7 @@ SequenceTestTag ::= SEQUENCE{ Sequence1 ::= SEQUENCE{ - int1 [0] INTEGER DEFAULT -5, + int1 [0] INTEGER {v1(0),v2(1),v3(2)} DEFAULT v2, int2 INTEGER, seq SET OF INTEGER, id OBJECT IDENTIFIER, diff --git a/tests/Test_tree.c b/tests/Test_tree.c index b810c06..4270caf 100644 --- a/tests/Test_tree.c +++ b/tests/Test_tree.c @@ -52,6 +52,8 @@ #define ACT_READ_DEFINITIONS 14 #define ACT_READ_TAG_CLASS 15 #define ACT_OID_2_STRUCTURE 16 +#define ACT_READ_LENGTH 17 +#define ACT_ENCODING_LENGTH 18 typedef struct{ @@ -88,17 +90,21 @@ test_type test_array[]={ {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_DELETE,"","",0,ASN1_SUCCESS}, - /* Test: OBJECT IDENTIFIER elements */ {ACT_CREATE,"TEST_TREE.Sequence1",0,0,ASN1_SUCCESS}, + {ACT_WRITE,"int1","v2",0,ASN1_SUCCESS}, + {ACT_READ,"int1","\x01",1,ASN1_SUCCESS}, {ACT_WRITE,"int2","0",0,ASN1_SUCCESS}, {ACT_WRITE,"oct","\x02\x01\x0a",3,ASN1_SUCCESS}, {ACT_WRITE,"id","1 2 3 4 5",0,ASN1_VALUE_NOT_VALID}, {ACT_WRITE,"id","2.5.29.2",0,ASN1_SUCCESS}, {ACT_READ,"id","2.5.29.2",9,ASN1_SUCCESS}, + {ACT_READ_LENGTH,"id",NULL,9,ASN1_MEM_ERROR}, {ACT_WRITE,"any1","\x02\x01\x05",3,ASN1_SUCCESS}, {ACT_READ_DEFINITIONS,"TEST_TREE.id-anyTest","2.5.29.1",9,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING_LENGTH,"",0,20,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,19,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,200,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_DELETE,"","",0,ASN1_SUCCESS}, {ACT_CREATE,"TEST_TREE.Sequence1",0,0,ASN1_SUCCESS}, @@ -115,61 +121,67 @@ test_type test_array[]={ {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_WRITE,"","teletexString",0,ASN1_SUCCESS}, {ACT_WRITE,"teletexString","PROVA",5,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING_LENGTH,"",0,7,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,6,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,7,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_DELETE,"","",0,ASN1_SUCCESS}, {ACT_CREATE,"TEST_TREE.X520LocalityName",0,0,ASN1_SUCCESS}, {ACT_DECODING,0,0,0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_DELETE,"","",0,ASN1_SUCCESS}, - + /* Test: OPTIONAL elements */ {ACT_CREATE,"TEST_TREE.DHParameter",0,0,ASN1_SUCCESS}, {ACT_WRITE,"prime","1",0,ASN1_SUCCESS}, {ACT_WRITE,"base","2",0,ASN1_SUCCESS}, {ACT_WRITE,"privateValueLength",NULL,0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING_LENGTH,"",0,8,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,7,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,8,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_DELETE,"","",0,ASN1_SUCCESS}, {ACT_CREATE,"TEST_TREE.DHParameter",0,0,ASN1_SUCCESS}, {ACT_DECODING,0,0,0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_DELETE,"","",0,ASN1_SUCCESS}, - + /* Test: Integer */ {ACT_CREATE,"TEST_TREE.AnyTest2",0,0,ASN1_SUCCESS}, {ACT_WRITE,"","int",0,ASN1_SUCCESS}, {ACT_WRITE,"int","0",0,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING_LENGTH,"",0,3,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,2,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,3,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_WRITE,"int","-1",0,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING,"",0,1024,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_WRITE,"int","1",0,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING,"",0,1024,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_WRITE,"int","2000000000",0,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING,"",0,1024,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_WRITE,"int","-2000000000",0,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING,"",0,1024,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_WRITE,"int","-20000000000",0,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING,"",0,1024,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_WRITE,"int","20000000000",0,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING,"",0,1024,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_DELETE,"","",0,ASN1_SUCCESS}, - + /* Test: elements without names */ {ACT_CREATE,"TEST_TREE.Sequence1",0,0,ASN1_SUCCESS}, {ACT_WRITE,"int2","10",0,ASN1_SUCCESS}, @@ -181,37 +193,44 @@ test_type test_array[]={ {ACT_NUMBER_OF_ELEMENTS,"seq","",2,ASN1_SUCCESS}, {ACT_WRITE,"id","1.2.3.4",0,ASN1_SUCCESS}, {ACT_WRITE,"oct","\x30\x03\x02\x01\x15",5,ASN1_SUCCESS}, - {ACT_ENCODING,"int2",0,0,ASN1_SUCCESS}, + {ACT_ENCODING,"int2",0,1024,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, - {ACT_ENCODING,"seq.?2",0,0,ASN1_SUCCESS}, + {ACT_ENCODING,"seq.?2",0,2,ASN1_MEM_ERROR}, + {ACT_ENCODING,"seq.?2",0,3,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING_LENGTH,"",0,25,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,24,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,25,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_CREATE,"TEST_TREE.Sequence1",0,0,ASN1_SUCCESS}, {ACT_DECODING_ELEMENT,"int2",0,0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_READ,"int2","\x0a",1,ASN1_SUCCESS}, + {ACT_READ_LENGTH,"int2",NULL,1,ASN1_MEM_ERROR}, {ACT_CREATE,"TEST_TREE.Sequence1",0,0,ASN1_SUCCESS}, {ACT_DECODING,0,0,0,ASN1_SUCCESS}, {ACT_DECODING_START_END,"seq.?2","START",10,ASN1_SUCCESS}, {ACT_EXPAND_OCTET,"oct","id",0,ASN1_SUCCESS}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_DELETE,"","",0,ASN1_SUCCESS}, - + /* Test GeneralString */ {ACT_CREATE,"TEST_TREE.Test3",0,0,ASN1_SUCCESS}, {ACT_WRITE,"a","1234",0,ASN1_SUCCESS}, {ACT_WRITE,"b","prova",5,ASN1_SUCCESS}, - {ACT_ENCODING,"",0,0,ASN1_SUCCESS}, + {ACT_ENCODING_LENGTH,"",0,17,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,16,ASN1_MEM_ERROR}, + {ACT_ENCODING,"",0,17,ASN1_SUCCESS}, {ACT_PRINT_DER,0,0,0,ASN1_SUCCESS}, {ACT_DELETE,"","",0,ASN1_SUCCESS}, {ACT_CREATE,"TEST_TREE.Test3",0,0,ASN1_SUCCESS}, {ACT_DECODING,0,0,0,ASN1_SUCCESS}, {ACT_DECODING_ELEMENT,"b",0,0,ASN1_SUCCESS}, {ACT_READ,"b","prova",5,ASN1_SUCCESS}, + {ACT_READ_LENGTH,"b",NULL,5,ASN1_MEM_ERROR}, {ACT_VISIT,"","",ASN1_PRINT_ALL,ASN1_SUCCESS}, {ACT_DELETE,"","",0,ASN1_SUCCESS}, - + /* end */ @@ -239,6 +258,10 @@ main(int argc,char *argv[]) printf( "/* Test sequence : Test_tree */\n"); printf( "/****************************************/\n\n"); + /* Check version */ + if(asn1_check_version("0.2.2")==NULL) + printf("\nLibrary version check ERROR:\n actual version: %s\n\n",asn1_check_version(NULL)); + if(1) result=asn1_parser2tree("Test_tree.asn",&definitions,errorDescription); else @@ -284,9 +307,13 @@ main(int argc,char *argv[]) result=asn1_write_value(asn1_element,test->par1,test->par2,test->par3); break; case ACT_READ: - valueLen=1024; + valueLen=test->par3; result=asn1_read_value(asn1_element,test->par1,value,&valueLen); break; + case ACT_READ_LENGTH: + valueLen=0; + result=asn1_read_value(asn1_element,test->par1,NULL,&valueLen); + break; case ACT_READ_DEFINITIONS: valueLen=1024; result=asn1_read_value(definitions,test->par1,value,&valueLen); @@ -295,9 +322,15 @@ main(int argc,char *argv[]) result=asn1_read_tag(asn1_element,test->par1,&tag,&class); break; case ACT_ENCODING: + der_len=test->par3; result=asn1_der_coding(asn1_element,test->par1,der,&der_len, errorDescription); break; + case ACT_ENCODING_LENGTH: + der_len=0; + result=asn1_der_coding(asn1_element,test->par1,NULL,&der_len, + errorDescription); + break; case ACT_DECODING: result=asn1_der_decoding(&asn1_element,der,der_len, errorDescription); @@ -372,6 +405,7 @@ main(int argc,char *argv[]) } break; case ACT_NUMBER_OF_ELEMENTS: + case ACT_READ_LENGTH: if((result != test->errorNumber) || (valueLen != test->par3)){ errorCounter++; @@ -379,10 +413,22 @@ main(int argc,char *argv[]) printf(" Action %d - %s\n",test->action,test->par1); printf(" Error expected: %s - %d\n",libtasn1_strerror(test->errorNumber), test->par3); - printf("\n Error detected: %s - %d\n\n",libtasn1_strerror(result), + printf(" Error detected: %s - %d\n\n",libtasn1_strerror(result), valueLen); } break; + case ACT_ENCODING_LENGTH: + if((result != test->errorNumber) || + (der_len != test->par3)){ + errorCounter++; + printf("ERROR N. %d:\n",errorCounter); + printf(" Action %d - %s\n",test->action,test->par1); + printf(" Error expected: %s - %d\n",libtasn1_strerror(test->errorNumber), + test->par3); + printf(" Error detected: %s - %d\n\n",libtasn1_strerror(result), + der_len); + } + break; case ACT_OID_2_STRUCTURE: if((result != test->errorNumber) || ((result == ASN1_SUCCESS) && (strcmp(value,test->par2)))){ diff --git a/tests/Test_tree_asn1_tab.c b/tests/Test_tree_asn1_tab.c index 6099e09..9db663d 100644 --- a/tests/Test_tree_asn1_tab.c +++ b/tests/Test_tree_asn1_tab.c @@ -13,9 +13,88 @@ const ASN1_ARRAY_TYPE Test_tree_asn1_tab[]={ {"pkix",1073741825,"7"}, {"id-mod",1073741825,"0"}, {"id-pkix1-implicit-88",1,"2"}, - {"Sequence1",536870917,0}, - {"int1",1610645507,0}, - {0,9,"-5"}, - {"int2",3,0}, + {"SequenceTestTag",1610612741,0}, + {"int1",1610620931,0}, + {0,2056,"2"}, + {"int2",1610620931,0}, + {0,4104,"3"}, + {"str1",1610620930,"PrintableString"}, + {0,4104,"1"}, + {"str2",1073741826,"UniversalString"}, + {"str3",536879106,"UniversalString"}, + {0,2056,"2"}, + {"Sequence1",1610612741,0}, + {"int1",1610915843,0}, + {0,1073741833,"v2"}, + {0,1073745928,"0"}, + {"v1",1073741825,"0"}, + {"v2",1073741825,"1"}, + {"v3",1,"2"}, + {"int2",1073741827,0}, + {"seq",1610612751,0}, + {0,3,0}, + {"id",1073741836,0}, + {"oct",1073741831,0}, + {"any1",541081613,0}, + {"id",1,0}, + {"DHParameter",1610612741,0}, + {"prime",1073741827,0}, + {"base",1073741827,0}, + {"privateValueLength",16387,0}, + {"id-octetTest1",1879048204,0}, + {0,1073741825,"1"}, + {0,1073741825,"2"}, + {0,1073741825,"3"}, + {0,1,"4"}, + {"Sequence_octetTest1",1610612741,0}, + {"int",3,0}, + {"AnyTest2",1610612754,0}, + {"str",1073741831,0}, + {"int",3,0}, + {"id-ic",1879048204,0}, + {0,1073741825,"2"}, + {0,1,"5"}, + {"id-anyTest",1879048204,0}, + {0,1073741825,"id-ic"}, + {0,1073741825,"29"}, + {0,1,"1"}, + {"id-anyTest2",1879048204,0}, + {0,1073741825,"id-ic"}, + {0,1073741825,"29"}, + {0,1,"2"}, + {"anyTest2",1073741827,0}, + {"VisibleString",1610620935,0}, + {0,4360,"26"}, + {"NumericString",1610620935,0}, + {0,4360,"18"}, + {"IA5String",1610620935,0}, + {0,4360,"22"}, + {"TeletexString",1610620935,0}, + {0,4360,"20"}, + {"PrintableString",1610620935,0}, + {0,4360,"19"}, + {"UniversalString",1610620935,0}, + {0,4360,"28"}, + {"BMPString",1610620935,0}, + {0,4360,"30"}, + {"UTF8String",1610620935,0}, + {0,4360,"12"}, + {"Test3",1610612741,0}, + {"a",1073741827,0}, + {"b",536879106,"GeneralString2"}, + {0,2056,"1"}, + {"GeneralString2",1610620955,0}, + {0,2056,"2"}, + {"X520LocalityName",1610612754,0}, + {"teletexString",1073741826,"TeletexString"}, + {"printableString",1073741826,"PrintableString"}, + {"universalString",1073741826,"UniversalString"}, + {"utf8String",1073741826,"UTF8String"}, + {"bmpString",2,"BMPString"}, + {"id-Test",805306380,0}, + {0,1073741825,"1"}, + {0,1073741825,"2"}, + {0,1073741825,"29"}, + {0,1,"2"}, {0,0,0} }; -- 2.7.4