diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-03-04 07:45:18 +0000 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2003-03-04 07:45:18 +0000 |
commit | 9a740fdabd18b2b50097023dc72123dcfb8bb28c (patch) | |
tree | 1bec8b532b662dad5cd9c1e892635c84610d41f2 | |
parent | 1ae985dc43186267ba7289e10654076faacbcee7 (diff) | |
download | gnutls-9a740fdabd18b2b50097023dc72123dcfb8bb28c.tar.gz |
updated to the new libtasn1.
-rw-r--r-- | lib/minitasn1/coding.c | 242 | ||||
-rw-r--r-- | lib/minitasn1/decoding.c | 9 | ||||
-rw-r--r-- | lib/minitasn1/element.c | 41 | ||||
-rw-r--r-- | lib/minitasn1/int.h | 2 | ||||
-rw-r--r-- | lib/minitasn1/libtasn1.h | 4 | ||||
-rw-r--r-- | lib/minitasn1/parser_aux.c | 75 |
6 files changed, 297 insertions, 76 deletions
diff --git a/lib/minitasn1/coding.c b/lib/minitasn1/coding.c index 3f6fdeffaf..ea211410a3 100644 --- a/lib/minitasn1/coding.c +++ b/lib/minitasn1/coding.c @@ -32,6 +32,8 @@ #include <gstr.h> #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/minitasn1/decoding.c b/lib/minitasn1/decoding.c index 811a4761dc..00013881ad 100644 --- a/lib/minitasn1/decoding.c +++ b/lib/minitasn1/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/minitasn1/element.c b/lib/minitasn1/element.c index c38c8b97b4..8b71d05ddf 100644 --- a/lib/minitasn1/element.c +++ b/lib/minitasn1/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<SIZEOF_UNSIGNED_LONG_INT-1;k++){ if(negative && (val[k]!=0xFF)) break; else if(!negative && val[k]) break; @@ -96,6 +96,8 @@ _asn1_convert_integer(const char *value,unsigned char *value_out,int value_out_s if((negative && !(val[k]&0x80)) || (!negative && (val[k]&0x80))) k--; + *len=SIZEOF_UNSIGNED_LONG_INT-k; + if (SIZEOF_UNSIGNED_LONG_INT-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;k2<SIZEOF_UNSIGNED_LONG_INT;k2++) value_out[k2-k]=val[k2]; - *len=SIZEOF_UNSIGNED_LONG_INT-k; - #ifdef LIBTASN1_DEBUG_INTEGER _libtasn1_log("_asn1_convert_integer: valueIn=%s, lenOut=%d",value,*len); @@ -540,6 +540,9 @@ asn1_write_value(node_asn *node_root,const char *name, * ASN1_ELEMENT_NOT_FOUND\: NAME is not a valid element. * * ASN1_VALUE_NOT_FOUND\: there isn't any value for the element selected. + * + * ASN1_MEM_ERROR\: the value vector isn't big enough to store the result. + * In this case LEN will contain the number of bytes needed. * * Examples: * a description for each type @@ -585,7 +588,7 @@ asn1_write_value(node_asn *node_root,const char *name, asn1_retCode asn1_read_value(node_asn *root,const char *name,unsigned char *value, int *len) { - node_asn *node,*p; + node_asn *node,*p,*p2; int len2,len3; int value_size = *len; @@ -623,7 +626,25 @@ asn1_read_value(node_asn *root,const char *name,unsigned char *value, int *len) if((node->type&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/minitasn1/int.h b/lib/minitasn1/int.h index f9c62b3ce0..2c37e27c00 100644 --- a/lib/minitasn1/int.h +++ b/lib/minitasn1/int.h @@ -32,6 +32,8 @@ #include <mem.h> +#define LIBTASN1_VERSION "0.2.2" + #define MAX32 4294967295 #define MAX24 16777215 #define MAX16 65535 diff --git a/lib/minitasn1/libtasn1.h b/lib/minitasn1/libtasn1.h index 31ceee317b..b687ecee98 100644 --- a/lib/minitasn1/libtasn1.h +++ b/lib/minitasn1/libtasn1.h @@ -28,7 +28,7 @@ extern "C" { #endif -#define LIBASN1_VERSION "0.2.1" +#define LIBTASN1_VERSION "0.2.2" #include <sys/types.h> #include <time.h> @@ -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/minitasn1/parser_aux.c b/lib/minitasn1/parser_aux.c index a0f7775a01..2444f3d9a4 100644 --- a/lib/minitasn1/parser_aux.c +++ b/lib/minitasn1/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; +} + |