Merge branch 'development-restricted'

Conflicts:
	ChangeLog
diff --git a/ChangeLog b/ChangeLog
index b011ee4..9e62acb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,12 @@
 
 = mbed TLS 2.3.x branch released 2016-xx-xx
 
+Security
+   * Fix potential stack corruption in mbedtls_x509write_crt_der() and
+     mbedtls_x509write_csr_der() when the signature is copied to the buffer
+     without checking whether there is enough space in the destination. The
+     issue cannot be triggered remotely. (found by Jethro Beekman)
+
 Features
    * Added support for CMAC for AES and 3DES and AES-CMAC-PRF-128, as defined by
      NIST SP 800-38B, RFC-4493 and RFC-4615.
diff --git a/library/x509write_crt.c b/library/x509write_crt.c
index 9041d44..d1d9a22 100644
--- a/library/x509write_crt.c
+++ b/library/x509write_crt.c
@@ -413,6 +413,9 @@
     MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
                                         sig_oid, sig_oid_len, sig, sig_len ) );
 
+    if( len > (size_t)( c2 - buf ) )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
     c2 -= len;
     memcpy( c2, c, len );
 
diff --git a/library/x509write_csr.c b/library/x509write_csr.c
index 0b9a285..8fd856b 100644
--- a/library/x509write_csr.c
+++ b/library/x509write_csr.c
@@ -213,6 +213,9 @@
     MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
                                         sig_oid, sig_oid_len, sig, sig_len ) );
 
+    if( len > (size_t)( c2 - buf ) )
+        return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
     c2 -= len;
     memcpy( c2, c, len );
 
diff --git a/tests/suites/test_suite_x509write.function b/tests/suites/test_suite_x509write.function
index c3773ba..89be31f 100644
--- a/tests/suites/test_suite_x509write.function
+++ b/tests/suites/test_suite_x509write.function
@@ -16,10 +16,11 @@
 {
     mbedtls_pk_context key;
     mbedtls_x509write_csr req;
-    unsigned char buf[4000];
+    unsigned char buf[4096];
     unsigned char check_buf[4000];
     int ret;
     size_t olen = 0, pem_len = 0;
+    int der_len = -1;
     FILE *f;
     const char *subject_name = "C=NL,O=PolarSSL,CN=PolarSSL Server 1";
     rnd_pseudo_info rnd_info;
@@ -52,6 +53,17 @@
     TEST_ASSERT( olen >= pem_len - 1 );
     TEST_ASSERT( memcmp( buf, check_buf, pem_len - 1 ) == 0 );
 
+    der_len = mbedtls_x509write_csr_der( &req, buf, sizeof( buf ),
+                            rnd_pseudo_rand, &rnd_info );
+    TEST_ASSERT( der_len >= 0 );
+
+    if( der_len == 0 )
+        goto exit;
+
+    ret = mbedtls_x509write_csr_der( &req, buf, (size_t)( der_len - 1 ),
+                            rnd_pseudo_rand, &rnd_info );
+    TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
 exit:
     mbedtls_x509write_csr_free( &req );
     mbedtls_pk_free( &key );
@@ -68,11 +80,12 @@
 {
     mbedtls_pk_context subject_key, issuer_key;
     mbedtls_x509write_cert crt;
-    unsigned char buf[4000];
+    unsigned char buf[4096];
     unsigned char check_buf[5000];
     mbedtls_mpi serial;
     int ret;
     size_t olen = 0, pem_len = 0;
+    int der_len = -1;
     FILE *f;
     rnd_pseudo_info rnd_info;
 
@@ -125,6 +138,17 @@
     TEST_ASSERT( olen >= pem_len - 1 );
     TEST_ASSERT( memcmp( buf, check_buf, pem_len - 1 ) == 0 );
 
+    der_len = mbedtls_x509write_crt_der( &crt, buf, sizeof( buf ),
+                            rnd_pseudo_rand, &rnd_info );
+    TEST_ASSERT( der_len >= 0 );
+
+    if( der_len == 0 )
+        goto exit;
+
+    ret = mbedtls_x509write_crt_der( &crt, buf, (size_t)( der_len - 1 ),
+                            rnd_pseudo_rand, &rnd_info );
+    TEST_ASSERT( ret == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
+
 exit:
     mbedtls_x509write_crt_free( &crt );
     mbedtls_pk_free( &issuer_key );