diff --git a/ChangeLog b/ChangeLog index f06f582d1..a8cb94a20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,10 +4,13 @@ PolarSSL ChangeLog (Sorted per branch, date) Security * Fix remotely-triggerable uninitialised pointer dereference caused by - crafted X.509 certificate (server is not affected if it doesn't ask for a + crafted X.509 certificate (TLS server is not affected if it doesn't ask for a client certificate) (found using Codenomicon Defensics). * Fix remotely-triggerable memory leak caused by crafted X.509 certificates - (server is not affected if it doesn't ask for a client certificate) + (TLS server is not affected if it doesn't ask for a client certificate) + (found using Codenomicon Defensics). + * Fix potential stack overflow while parsing crafted X.509 certificates + (TLS server is not affected if it doesn't ask for a client certificate) (found using Codenomicon Defensics). Features diff --git a/library/x509.c b/library/x509.c index 941472c9d..89ba7633d 100644 --- a/library/x509.c +++ b/library/x509.c @@ -421,35 +421,39 @@ int x509_get_name( unsigned char **p, const unsigned char *end, size_t set_len; const unsigned char *end_set; - /* - * parse first SET, restricted to 1 element - */ - if( ( ret = asn1_get_tag( p, end, &set_len, - ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 ) - return( POLARSSL_ERR_X509_INVALID_NAME + ret ); + /* don't use recursion, we'd risk stack overflow if not optimized */ + while( 1 ) + { + /* + * parse first SET, restricted to 1 element + */ + if( ( ret = asn1_get_tag( p, end, &set_len, + ASN1_CONSTRUCTED | ASN1_SET ) ) != 0 ) + return( POLARSSL_ERR_X509_INVALID_NAME + ret ); - end_set = *p + set_len; + end_set = *p + set_len; - if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) - return( ret ); + if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) + return( ret ); - if( *p != end_set ) - return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); + if( *p != end_set ) + return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); - /* - * recurse until end of SEQUENCE is reached - */ - if( *p == end ) - return( 0 ); + /* + * continue until end of SEQUENCE is reached + */ + if( *p == end ) + return( 0 ); - cur->next = (x509_name *) polarssl_malloc( sizeof( x509_name ) ); + cur->next = (x509_name *) polarssl_malloc( sizeof( x509_name ) ); - if( cur->next == NULL ) - return( POLARSSL_ERR_X509_MALLOC_FAILED ); + if( cur->next == NULL ) + return( POLARSSL_ERR_X509_MALLOC_FAILED ); - memset( cur->next, 0, sizeof( x509_name ) ); + memset( cur->next, 0, sizeof( x509_name ) ); - return( x509_get_name( p, end, cur->next ) ); + cur = cur->next; + } } /*