Fix potential stack overflow
diff --git a/ChangeLog b/ChangeLog
index f06f582..a8cb94a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,10 +4,13 @@
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 941472c..89ba763 100644
--- a/library/x509.c
+++ b/library/x509.c
@@ -421,35 +421,39 @@
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;
+ }
}
/*