Fix memory leak parsing some X.509 certs
diff --git a/ChangeLog b/ChangeLog
index 7603a39..4d6b7de 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
PolarSSL ChangeLog
+= Version 1.2.12 released 2014-10-??
+
+Security
+ * Remotely-triggerable memory leak when parsing some X.509 certificates
+ (server is not affected if it doesn't ask for a client certificate).
+ (Found using Codenomicon Defensics.)
+
+Changes
+ * X.509 certificates with more than one AttributeTypeAndValue per
+ RelativeDistinguishedName are not accepted any more.
+
= Version 1.2.11 released 2014-07-11
Features
* Entropy module now supports seed writing and reading
diff --git a/library/x509parse.c b/library/x509parse.c
index fe13b16..4052011 100644
--- a/library/x509parse.c
+++ b/library/x509parse.c
@@ -283,48 +283,38 @@
* AttributeType ::= OBJECT IDENTIFIER
*
* AttributeValue ::= ANY DEFINED BY AttributeType
+ *
+ * We restrict RelativeDistinguishedName to be a set of 1 element. This is
+ * the most common case, and our x509_name structure currently can't handle
+ * more than that.
*/
static int x509_get_name( unsigned char **p,
const unsigned char *end,
x509_name *cur )
{
int ret;
- size_t len;
- const unsigned char *end2;
- x509_name *use;
-
- if( ( ret = asn1_get_tag( p, end, &len,
+ 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_CERT_INVALID_NAME + ret );
- end2 = end;
- end = *p + len;
- use = cur;
+ end_set = *p + set_len;
- do
- {
- if( ( ret = x509_get_attr_type_value( p, end, use ) ) != 0 )
- return( ret );
-
- if( *p != end )
- {
- use->next = (x509_name *) malloc(
- sizeof( x509_name ) );
+ if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 )
+ return( ret );
- if( use->next == NULL )
- return( POLARSSL_ERR_X509_MALLOC_FAILED );
-
- memset( use->next, 0, sizeof( x509_name ) );
-
- use = use->next;
- }
- }
- while( *p != end );
+ if( *p != end_set )
+ return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE );
/*
* recurse until end of SEQUENCE is reached
*/
- if( *p == end2 )
+ if( *p == end )
return( 0 );
cur->next = (x509_name *) malloc(
@@ -335,7 +325,7 @@
memset( cur->next, 0, sizeof( x509_name ) );
- return( x509_get_name( p, end2, cur->next ) );
+ return( x509_get_name( p, end, cur->next ) );
}
/*
diff --git a/tests/suites/test_suite_x509parse.data b/tests/suites/test_suite_x509parse.data
index 22f6355..5bb73b3 100644
--- a/tests/suites/test_suite_x509parse.data
+++ b/tests/suites/test_suite_x509parse.data
@@ -462,7 +462,7 @@
x509parse_crt:"30253023a0030201028204deadbeef300d06092a864886f70d0101020500300731053003060013":"":POLARSSL_ERR_X509_CERT_INVALID_NAME + POLARSSL_ERR_ASN1_OUT_OF_DATA
X509 Certificate ASN1 (TBSCertificate, issuer, no full following string)
-x509parse_crt:"302b3029a0030201028204deadbeef300d06092a864886f70d0101020500300d310b3009060013045465737400":"":POLARSSL_ERR_X509_CERT_INVALID_NAME + POLARSSL_ERR_ASN1_UNEXPECTED_TAG
+x509parse_crt:"302b3029a0030201028204deadbeef300d06092a864886f70d0101020500300d310b3009060013045465737400":"":POLARSSL_ERR_X509_FEATURE_UNAVAILABLE
X509 Certificate ASN1 (TBSCertificate, valid issuer, no validity)
x509parse_crt:"302a3028a0030201028204deadbeef300d06092a864886f70d0101020500300c310a30080600130454657374":"":POLARSSL_ERR_X509_CERT_INVALID_DATE + POLARSSL_ERR_ASN1_OUT_OF_DATA