From 0c2575a5727ddf32aa597ad1de52941161d9ca90 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Thu, 26 Jun 2003 21:56:49 +0000 Subject: added new Fabio's fixes. --- lib/minitasn1/decoding.c | 217 ++++++++++++++++++++++++++++++++++++++++------- lib/minitasn1/element.c | 8 +- 2 files changed, 192 insertions(+), 33 deletions(-) diff --git a/lib/minitasn1/decoding.c b/lib/minitasn1/decoding.c index ac3804c7a9..5cbc22e343 100644 --- a/lib/minitasn1/decoding.c +++ b/lib/minitasn1/decoding.c @@ -37,7 +37,7 @@ void _asn1_error_description_tag_error(node_asn *node,char *ErrorDescription) { - Estrcpy(ErrorDescription,":: tag error near element ' "); + Estrcpy(ErrorDescription,":: tag error near element '"); _asn1_hierarchical_name(node,ErrorDescription+strlen(ErrorDescription), MAX_ERROR_DESCRIPTION_SIZE-40); Estrcat(ErrorDescription,"'"); @@ -246,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){ @@ -282,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; @@ -359,6 +368,116 @@ _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 */ + _asn1_length_der(tot_len,NULL,&len2); + temp=(unsigned char *)_asn1_alloca(len2+tot_len); + if (temp==NULL){ + return ASN1_MEM_ALLOC_ERROR; + } + + _asn1_length_der(tot_len,temp,&len2); + tot_len+=len2; + temp2=temp+len2; + len2=_asn1_get_length_der(der,&len3); + counter2=len3+1; + + if(indefinite==-1) counter_end=counter-2; + else counter_end=counter; + + while(counter2type)==TYPE_CHOICE){ while(p->down){ - ris=_asn1_extract_tag_der(p->down,der+counter,&len2); + if(counterdown,der+counter,&len2); + else + ris=ASN1_DER_ERROR; if(ris==ASN1_SUCCESS){ while(p->down->right){ p2=p->down->right; @@ -474,11 +596,15 @@ 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)){ @@ -546,9 +672,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: @@ -666,23 +793,48 @@ asn1_der_decoding(ASN1_TYPE *element,const unsigned char *der,int len, 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. */ + a indefinite length method. */ if(indefinite){ - if(!der[counter] && !der[counter+1]) + if(!der[counter] && !der[counter+1]){ counter+=2; + } else{ asn1_delete_structure(element); return ASN1_DER_ERROR; @@ -852,7 +1004,10 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName, if(type_field(p->type)==TYPE_CHOICE){ while(p->down){ - ris=_asn1_extract_tag_der(p->down,der+counter,&len2); + if(counterdown,der+counter,&len2); + else + ris=ASN1_DER_ERROR; if(ris==ASN1_SUCCESS){ while(p->down->right){ p2=p->down->right; @@ -869,11 +1024,15 @@ 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)){ diff --git a/lib/minitasn1/element.c b/lib/minitasn1/element.c index 004b88b177..d36672b44a 100644 --- a/lib/minitasn1/element.c +++ b/lib/minitasn1/element.c @@ -37,14 +37,14 @@ _asn1_hierarchical_name(node_asn *node,char *name,int name_size) { node_asn *p; char tmp_name[64]; - + p=node; name[0]=0; while(p != NULL){ if(p->name != NULL){ - _asn1_str_cpy(tmp_name,sizeof(tmp_name),name); + _asn1_str_cpy(tmp_name,sizeof(tmp_name),name), _asn1_str_cpy(name,name_size,p->name); _asn1_str_cat(name,name_size,"."); @@ -52,8 +52,8 @@ _asn1_hierarchical_name(node_asn *node,char *name,int name_size) } p=_asn1_find_up(p); } - - if (name[0]==0) _asn1_str_cpy(name,name_size, "ROOT"); + + if(name[0]==0) _asn1_str_cpy(name,name_size,"ROOT"); } -- cgit v1.2.1