diff options
author | Simon Josefsson <simon@josefsson.org> | 2006-02-09 09:50:14 +0000 |
---|---|---|
committer | Simon Josefsson <simon@josefsson.org> | 2006-02-09 09:50:14 +0000 |
commit | f48456c95833f526b32226692bd2ebc2c34e9a68 (patch) | |
tree | 165622952711ab647e8d0dbc33ee14907789d854 /lib/decoding.c | |
parent | 7067a6217809bee767a4cbbf7e07affe5a02a045 (diff) | |
download | libtasn1-f48456c95833f526b32226692bd2ebc2c34e9a68.tar.gz libtasn1-f48456c95833f526b32226692bd2ebc2c34e9a68.tar.bz2 libtasn1-f48456c95833f526b32226692bd2ebc2c34e9a68.zip |
Further length fixes.
Diffstat (limited to 'lib/decoding.c')
-rw-r--r-- | lib/decoding.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/lib/decoding.c b/lib/decoding.c index 120d31d..e9a6464 100644 --- a/lib/decoding.c +++ b/lib/decoding.c @@ -104,10 +104,23 @@ _asn1_get_tag_der(const unsigned char *der, int der_len, /* Long form */ punt=1; ris=0; - while(punt <= der_len && der[punt]&128) ris=ris*128+(der[punt++]&0x7F); + while(punt <= der_len && der[punt]&128) + { + int last = ris; + ris=ris*128+(der[punt++]&0x7F); + if (ris < last) + /* wrapper around, and no bignums... */ + return ASN1_DER_ERROR; + } if (punt >= der_len) return ASN1_DER_ERROR; - ris=ris*128+(der[punt++]&0x7F); + { + int last = ris; + ris=ris*128+(der[punt++]&0x7F); + if (ris < last) + /* wrapper around, and no bignums... */ + return ASN1_DER_ERROR; + } *len=punt; } if (tag) *tag = ris; @@ -175,7 +188,7 @@ _asn1_get_objectid_der(const unsigned char *der,int der_len, int *ret_len,unsign if(str==NULL || der_len <= 0) return; len=_asn1_get_length_der(der,der_len, &len_len); - if (len < 0 || len_len > der_len) return; + if (len < 0 || len > der_len || len_len > der_len) return; val1=der[len_len]/40; val=der[len_len]-val1*40; @@ -250,6 +263,8 @@ _asn1_extract_tag_der(node_asn *node,const unsigned char *der, int der_len,int * if(p->type&CONST_EXPLICIT){ if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS) return ASN1_DER_ERROR; + if (counter+len2 > der_len) + return ASN1_DER_ERROR; counter+=len2; len3=_asn1_get_length_der(der+counter,der_len-counter, &len2); if (len3 < 0) @@ -285,6 +300,8 @@ _asn1_extract_tag_der(node_asn *node,const unsigned char *der, int der_len,int * if(is_tag_implicit){ if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2, &tag)!=ASN1_SUCCESS) return ASN1_DER_ERROR; + if (counter+len2 > der_len) + return ASN1_DER_ERROR; if((class!=class_implicit) || (tag!=tag_implicit)){ if(type_field(node->type)==TYPE_OCTET_STRING){ @@ -305,6 +322,8 @@ _asn1_extract_tag_der(node_asn *node,const unsigned char *der, int der_len,int * if (_asn1_get_tag_der(der+counter, der_len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) return ASN1_DER_ERROR; + if (counter+len2 > der_len) + return ASN1_DER_ERROR; switch(type_field(node->type)){ case TYPE_NULL: @@ -519,7 +538,8 @@ _asn1_get_indefinite_length_string(const unsigned char* der, int* len) if(_asn1_get_tag_der(der+counter, *len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) return ASN1_DER_ERROR; - + if (counter+len2 > *len) + return ASN1_DER_ERROR; counter+=len2; len2=_asn1_get_length_der(der+counter, *len-counter,&len3); if(len2 < -1) return ASN1_DER_ERROR; @@ -890,9 +910,11 @@ asn1_der_decoding(ASN1_TYPE *element,const void *ider,int len, case TYPE_ANY: if(_asn1_get_tag_der(der+counter,len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) return ASN1_DER_ERROR; - + if (counter+len2 > len) + return ASN1_DER_ERROR; len4=_asn1_get_length_der(der+counter+len2,len-counter-len2,&len3); if(len4 < -1) return ASN1_DER_ERROR; + if(len4 > len-counter+len2+len3) return ASN1_DER_ERROR; if(len4 != -1){ len2+=len4; _asn1_length_der(len2+len3,NULL,&len4); @@ -1415,6 +1437,8 @@ asn1_der_decoding_element(ASN1_TYPE *structure,const char *elementName, case TYPE_ANY: if(_asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) return ASN1_DER_ERROR; + if (counter+len2 > len) + return ASN1_DER_ERROR; len4=_asn1_get_length_der(der+counter+len2,len-counter-len2,&len3); if(len4 < -1) return ASN1_DER_ERROR; @@ -1800,6 +1824,8 @@ asn1_der_decoding_startEnd(ASN1_TYPE element,const void *ider,int len, case TYPE_ANY: if (_asn1_get_tag_der(der+counter, len-counter,&class,&len2,&tag)!=ASN1_SUCCESS) return ASN1_DER_ERROR; + if (counter+len2 > len) + return ASN1_DER_ERROR; len4=_asn1_get_length_der(der+counter+len2,len-counter-len2,&len3); if(len4 < -1) return ASN1_DER_ERROR; |