tlsio_mbedtls.c and mbedTLS v3.6.0
ASeidelt opened this issue · 0 comments
Hi,
because mbedTLS 2.28.x is only supported until end of 2024 [1] I tried to compile Azure-SDK using mbedTLS 3.6.0.
I found the following issues with adapters/tlsio_mbedtls.c
and mbedTSL v3.6:
- The following includes are no longer available/needed [2]
#include "mbedtls/certs.h"
#include "mbedtls/entropy_poll.h"
- In [3]
size_t max_len = mbedtls_ssl_get_output_max_frag_len(&tls_io_instance->ssl);
must be replaced bysize_t max_len = mbedtls_ssl_get_max_out_record_payload(&tls_io_instance->ssl);
- In [4]
mbedtls_ssl_conf_min_version(&tls_io_instance->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
must be replaced bymbedtls_ssl_conf_min_tls_version(&tls_io_instance->config, MBEDTLS_SSL_VERSION_TLS1_2);
- In [5]
mbedtls_pk_parse_key(&tls_io_instance->pKey, (const unsigned char*) temp_key, (int) (strlen(temp_key) + 1), NULL, 0)
now needs an entropy source:mbedtls_pk_parse_key(&tls_io_instance->pKey, (const unsigned char*) temp_key, (int) (strlen(temp_key) + 1), NULL, 0, mbedtls_ctr_drbg_random, &tls_io_instance->ctr_drbg)
- I also changed [6] to use the constants from mbedTLS:
mbedtls_ssl_conf_renegotiation(&tls_io_instance->config, set_renegotiation ? MBEDTLS_SSL_LEGACY_ALLOW_RENEGOTIATION : MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION);
These were the easy/obvious changes. Sadly there are two more changes I'm not sure/happy about:
first
decode_ssl_received_bytes()
[7] does not report SSL-errors via indicate_error()
. I added an else block where all return values <0 and != MBEDTLS_ERR_SSL_WANT_READ
will report an error:
static int decode_ssl_received_bytes(TLS_IO_INSTANCE *tls_io_instance)
{
int result = 0;
unsigned char buffer[64];
int rcv_bytes = 1;
while (rcv_bytes > 0)
{
rcv_bytes = mbedtls_ssl_read(&tls_io_instance->ssl, buffer, sizeof(buffer));
if (rcv_bytes > 0)
{
if (tls_io_instance->on_bytes_received != NULL)
{
tls_io_instance->on_bytes_received(tls_io_instance->on_bytes_received_context, buffer, rcv_bytes);
}
}
else
{
if (rcv_bytes != MBEDTLS_ERR_SSL_WANT_READ)
{ // no data is not an error
LogError("ERROR for mbedtls_ssl_read() := 0x%04X", -rcv_bytes);
indicate_error(tls_io_instance);
}
}
}
return result;
}
This now does reliably report TLS errors for us. Did I miss something here?
second
The other problem is a change in policy for some of the variables in mbedTLS structures. These are 'private' now.
on_io_send()
[8] does access tls_io_instance->ssl.out_msgtype
to access the type of the TLS message it sends. I'm not sure why this is necessary and only messages of type MBEDTLS_SSL_MSG_APPLICATION_DATA
shall report an on_send_complete()
, but I found the following hack to get it to work:
#define MBEDTLS_ALLOW_PRIVATE_ACCESS // emulate mbedTLS 2 API access level
#include "mbedtls/private_access.h"
[...]
static int on_io_send(void *context, const unsigned char *buf, size_t sz)
{
[...]
// Only allow Application data type message to send on_send_complete callback.
// note: visibility of out_msgtype was changed to private in mbedTLS 2->3
if (tls_io_instance->ssl.MBEDTLS_PRIVATE(out_msgtype) == MBEDTLS_SSL_MSG_APPLICATION_DATA)
{
on_complete_callback = on_send_complete;
context = tls_io_instance;
}
[...]
Can someone give me some reasoning why this check for the TLS message type is necessary? I asume it has something to do with mbedTLS' behaviour of only accepting 16KiB blocks of data when mbedtls_ssl_write()
is called?
What would be an appropriate solution w/o accessing the now private out_msgtype
?
Thanks Andre
[1] https://github.com/Mbed-TLS/mbedtls/releases/tag/v2.28.8
[2]
[3]
[4]
[5]
azure-c-shared-utility/adapters/tlsio_mbedtls.c
Line 1001 in 51d6f3f
[6]
azure-c-shared-utility/adapters/tlsio_mbedtls.c
Line 1046 in 51d6f3f
[7]
[8]