diff --git a/ChangeLog b/ChangeLog index b011ee42a..9e62acbfc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,12 @@ mbed TLS ChangeLog (Sorted per branch, date) = 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 9041d440f..d1d9a22a7 100644 --- a/library/x509write_crt.c +++ b/library/x509write_crt.c @@ -413,6 +413,9 @@ int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, 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 0b9a2851e..8fd856b2a 100644 --- a/library/x509write_csr.c +++ b/library/x509write_csr.c @@ -213,6 +213,9 @@ int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, s 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 c3773ba54..89be31f9a 100644 --- a/tests/suites/test_suite_x509write.function +++ b/tests/suites/test_suite_x509write.function @@ -16,10 +16,11 @@ void x509_csr_check( char *key_file, char *cert_req_check_file, { 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 @@ void x509_csr_check( char *key_file, char *cert_req_check_file, 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 @@ void x509_crt_check( char *subject_key_file, char *subject_pwd, { 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 @@ void x509_crt_check( char *subject_key_file, char *subject_pwd, 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 );