CVE-2013-4623: Improper Input Validation (CWE-20)
value: The x509parse_crt function in x509.h in PolarSSL 1.1.x before 1.1.7 and 1.2.x before 1.2.8 does not properly parse certificate messages during the SSL/TLS handshake, which allows remote attackers to cause a denial of service (infinite loop and CPU consumption) via a certificate message that contains a PEM encoded certificate.
CWE description: The product receives input or data, but it does
        not validate or incorrectly validates that the input has the
        properties that are required to process the data safely and
        correctly.
Published: 2013-09-30T22:55Z
Repository: https://github.com/polarssl/polarssl
Language: Other
Files changed: ChangeLog, include/polarssl/x509.h, library/ssl_tls.c
Commit date: 2013-06-06 15:11:16 +0200
Commit message: ssl_parse_certificate() now calls x509parse_crt_der() directly

Diff: diff --git a/ChangeLog b/ChangeLog
index 59be48b..7561aba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,10 +8,13 @@ Bugfix
    * Secure renegotiation extension should only be sent in case client
      supports secure renegotiation
    * Fixed offset for cert_type list in ssl_parse_certificate_request()
    * Fixed const correctness issues that have no impact on the ABI
    * x509parse_crt() now better handles PEM error situations
+   * ssl_parse_certificate() now calls x509parse_crt_der() directly
+     instead of the x509parse_crt() wrapper that can also parse PEM
+	 certificates
 
 = Version 1.2.7 released 2013-04-13
 Features
    * Ability to specify allowed ciphersuites based on the protocol version.
 
diff --git a/include/polarssl/x509.h b/include/polarssl/x509.h
index 87151c9..296925f 100644
--- a/include/polarssl/x509.h
+++ b/include/polarssl/x509.h
@@ -422,10 +422,22 @@ extern "C" {
  * \name Functions to read in DHM parameters, a certificate, CRL or private RSA key
  * \{
  */
 
 /** \ingroup x509_module */
+/**
+ * \brief          Parse a single DER formatted certificate and add it
+ *                 to the chained list.
+ *
+ * \param chain    points to the start of the chain
+ * \param buf      buffer holding the certificate DER data
+ * \param buflen   size of the buffer
+ *
+ * \return         0 if successful, or a specific X509 or PEM error code
+ */
+int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen );
+
 /**
  * \brief          Parse one or more certificates and add them
  *                 to the chained list. Parses permissively. If some
  *                 certificates can be parsed, the result is the number
  *                 of failed certificates it encountered. If none complete
diff --git a/library/ssl_tls.c b/library/ssl_tls.c
index 9087ab4..e0cddf8 100644
--- a/library/ssl_tls.c
+++ b/library/ssl_tls.c
@@ -2373,12 +2373,12 @@ int ssl_parse_certificate( ssl_context *ssl )
         {
             SSL_DEBUG_MSG( 1, ( "bad certificate message" ) );
             return( POLARSSL_ERR_SSL_BAD_HS_CERTIFICATE );
         }
 
-        ret = x509parse_crt( ssl->session_negotiate->peer_cert, ssl->in_msg + i,
-                             n );
+        ret = x509parse_crt_der( ssl->session_negotiate->peer_cert,
+                                 ssl->in_msg + i, n );
         if( ret != 0 )
         {
             SSL_DEBUG_RET( 1, " x509parse_crt", ret );
             return( ret );
         }

Vulnerable code:         ret = x509parse_crt( ssl->session_negotiate->peer_cert, ssl->in_msg + i,
                             n );
Fixed code:    * ssl_parse_certificate() now calls x509parse_crt_der() directly
     instead of the x509parse_crt() wrapper that can also parse PEM
	 certificates
/**
 * \brief          Parse a single DER formatted certificate and add it
 *                 to the chained list.
 *
 * \param chain    points to the start of the chain
 * \param buf      buffer holding the certificate DER data
 * \param buflen   size of the buffer
 *
 * \return         0 if successful, or a specific X509 or PEM error code
 */
int x509parse_crt_der( x509_cert *chain, const unsigned char *buf, size_t buflen );

        ret = x509parse_crt_der( ssl->session_negotiate->peer_cert,
                                 ssl->in_msg + i, n );