Merge remote-tracking branch 'restricted/pr/497' into mbedtls-2.1-restricted
diff --git a/ChangeLog b/ChangeLog
index eeb7f69..4cbc175 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,10 @@
    * Fix a potential memory leak in mbedtls_ssl_setup( ) function. An allocation
      failure could leave an unreleased buffer. A handshake init failure would
      lead to leaving two unreleased buffers.
+   * Fix an issue in the X.509 module which could lead to a buffer overread
+     during certificate extensions parsing. In case of receiving malformed
+     input (extensions length field equal to 0), an illegal read of one byte
+     beyond the input buffer is made. Found and analyzed by Nathan Crandall.
 
 Bugfix
    * Fixes an issue with MBEDTLS_CHACHAPOLY_C which would not compile if
diff --git a/library/x509_crt.c b/library/x509_crt.c
index 1eaa55b..86fba64 100644
--- a/library/x509_crt.c
+++ b/library/x509_crt.c
@@ -567,18 +567,14 @@
         end_ext_data = *p + len;
 
         /* Get extension ID */
-        extn_oid.tag = **p;
-
-        if( ( ret = mbedtls_asn1_get_tag( p, end, &extn_oid.len, MBEDTLS_ASN1_OID ) ) != 0 )
+        if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &extn_oid.len,
+                                          MBEDTLS_ASN1_OID ) ) != 0 )
             return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret );
 
+        extn_oid.tag = MBEDTLS_ASN1_OID;
         extn_oid.p = *p;
         *p += extn_oid.len;
 
-        if( ( end - *p ) < 1 )
-            return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS +
-                    MBEDTLS_ERR_ASN1_OUT_OF_DATA );
-
         /* Get optional critical */
         if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 &&
             ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) )