diff --git a/components/mbedtls/port/dynamic/esp_ssl_srv.c b/components/mbedtls/port/dynamic/esp_ssl_srv.c index 84bbd59682..eadd2e4117 100644 --- a/components/mbedtls/port/dynamic/esp_ssl_srv.c +++ b/components/mbedtls/port/dynamic/esp_ssl_srv.c @@ -12,6 +12,24 @@ int __wrap_mbedtls_ssl_handshake_server_step(mbedtls_ssl_context *ssl); static const char *TAG = "SSL Server"; +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA +/** + * Check if ciphersuite uses rsa key exchange methods. + */ +static bool ssl_ciphersuite_uses_rsa_key_ex(mbedtls_ssl_context *ssl) +{ + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->handshake->ciphersuite_info; + + if (ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK) { + return true; + } else { + return false; + } +} +#endif + static int manage_resource(mbedtls_ssl_context *ssl, bool add) { int state = add ? ssl->state : ssl->state - 1; @@ -65,7 +83,13 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) CHECK_OK(esp_mbedtls_add_tx_buffer(ssl, buffer_len)); } else { #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA - esp_mbedtls_free_keycert_cert(ssl); + /** + * Not free keycert->cert until MBEDTLS_SSL_CLIENT_KEY_EXCHANGE for rsa key exchange methods. + * For ssl server will use keycert->cert to parse client key exchange. + */ + if (!ssl_ciphersuite_uses_rsa_key_ex(ssl)) { + esp_mbedtls_free_keycert_cert(ssl); + } #endif } break; @@ -77,8 +101,14 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) } else { #ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA esp_mbedtls_free_dhm(ssl); - esp_mbedtls_free_keycert_key(ssl); - esp_mbedtls_free_keycert(ssl); + /** + * Not free keycert->key and keycert until MBEDTLS_SSL_CLIENT_KEY_EXCHANGE for rsa key exchange methods. + * For ssl server will use keycert->key to parse client key exchange. + */ + if (!ssl_ciphersuite_uses_rsa_key_ex(ssl)) { + esp_mbedtls_free_keycert_key(ssl); + esp_mbedtls_free_keycert(ssl); + } #endif } break; @@ -114,6 +144,18 @@ static int manage_resource(mbedtls_ssl_context *ssl, bool add) CHECK_OK(esp_mbedtls_add_rx_buffer(ssl)); } else { CHECK_OK(esp_mbedtls_free_rx_buffer(ssl)); + +#ifdef CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA + /** + * Free keycert after MBEDTLS_SSL_CLIENT_KEY_EXCHANGE for rsa key exchange methods. + * For ssl server will use keycert->cert and keycert->key to parse client key exchange. + */ + if (ssl_ciphersuite_uses_rsa_key_ex(ssl)) { + esp_mbedtls_free_keycert_cert(ssl); + esp_mbedtls_free_keycert_key(ssl); + esp_mbedtls_free_keycert(ssl); + } +#endif } break; case MBEDTLS_SSL_CERTIFICATE_VERIFY: diff --git a/examples/protocols/https_server/simple/example_test.py b/examples/protocols/https_server/simple/example_test.py index b159042033..9a3a4083ba 100644 --- a/examples/protocols/https_server/simple/example_test.py +++ b/examples/protocols/https_server/simple/example_test.py @@ -132,6 +132,57 @@ def test_examples_protocol_https_server_simple(env, extra_data): # type: (tiny_ ssl_context.load_cert_chain(certfile=CLIENT_CERT_FILE, keyfile=CLIENT_KEY_FILE) + conn = http.client.HTTPSConnection(got_ip, got_port, context=ssl_context) + Utility.console_log('Performing SSL handshake with the server') + conn.request('GET','/') + resp = conn.getresponse() + dut1.expect('performing session handshake') + got_resp = resp.read().decode('utf-8') + if got_resp != success_response: + Utility.console_log('Response obtained does not match with correct response') + raise RuntimeError('Failed to test SSL connection') + + # Close the connection + conn.close() + + Utility.console_log('Checking user callback: Obtaining client certificate...') + + serial_number = dut1.expect(re.compile(r'serial number(.*)'), timeout=5)[0] + issuer_name = dut1.expect(re.compile(r'issuer name(.*)'), timeout=5)[0] + expiry = dut1.expect(re.compile(r'expires on(.*)'), timeout=5)[0] + + Utility.console_log('Serial No.' + serial_number) + Utility.console_log('Issuer Name' + issuer_name) + Utility.console_log('Expires on' + expiry) + + Utility.console_log('Correct response obtained') + Utility.console_log('SSL connection test successful\nClosing the connection') + + # Test with mbedTLS dynamic buffer feature + dut1 = env.get_dut('https_server_simple', 'examples/protocols/https_server/simple', dut_class=ttfw_idf.ESP32DUT, app_config_name='dynamic_buffer') + + # start test + dut1.start_app() + # Parse IP address and port of the server + dut1.expect(re.compile(r'Starting server')) + got_port = dut1.expect(re.compile(r'Server listening on port (\d+)'), timeout=30)[0] + Utility.console_log('Waiting to connect with AP') + + got_ip = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] + # Expected logs + + Utility.console_log('Got IP : ' + got_ip) + Utility.console_log('Got Port : ' + got_port) + + Utility.console_log('Performing GET request over an SSL connection with the server') + + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2) + ssl_context.verify_mode = ssl.CERT_REQUIRED + ssl_context.check_hostname = False + ssl_context.load_verify_locations(cadata=server_cert_pem) + + ssl_context.load_cert_chain(certfile=CLIENT_CERT_FILE, keyfile=CLIENT_KEY_FILE) + os.remove(CLIENT_CERT_FILE) os.remove(CLIENT_KEY_FILE) @@ -146,6 +197,9 @@ def test_examples_protocol_https_server_simple(env, extra_data): # type: (tiny_ Utility.console_log('Response obtained does not match with correct response') raise RuntimeError('Failed to test SSL connection') + # Close the connection + conn.close() + Utility.console_log('Checking user callback: Obtaining client certificate...') serial_number = dut1.expect(re.compile(r'serial number(.*)'), timeout=5)[0] @@ -158,7 +212,6 @@ def test_examples_protocol_https_server_simple(env, extra_data): # type: (tiny_ Utility.console_log('Correct response obtained') Utility.console_log('SSL connection test successful\nClosing the connection') - conn.close() if __name__ == '__main__': diff --git a/examples/protocols/https_server/simple/sdkconfig.ci.dynamic_buffer b/examples/protocols/https_server/simple/sdkconfig.ci.dynamic_buffer new file mode 100644 index 0000000000..fecf79651d --- /dev/null +++ b/examples/protocols/https_server/simple/sdkconfig.ci.dynamic_buffer @@ -0,0 +1,6 @@ +CONFIG_ESP_HTTPS_SERVER_ENABLE=y +CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK=y +CONFIG_MBEDTLS_DYNAMIC_BUFFER=y +CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y +CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y +CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT=y