Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tlsio_mbedtls.c and mbedTLS v3.6.0 #665

Open
ASeidelt opened this issue Aug 14, 2024 · 0 comments
Open

tlsio_mbedtls.c and mbedTLS v3.6.0 #665

ASeidelt opened this issue Aug 14, 2024 · 0 comments

Comments

@ASeidelt
Copy link

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 by size_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 by mbedtls_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]

#include "mbedtls/certs.h"

[3]
size_t max_len = mbedtls_ssl_get_max_frag_len(&tls_io_instance->ssl);

[4]
mbedtls_ssl_conf_min_version(&tls_io_instance->config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); // v1.2

[5]
else if (mbedtls_pk_parse_key(&tls_io_instance->pKey, (const unsigned char *)temp_key, (int)(strlen(temp_key) + 1), NULL, 0) != 0)

[6]
mbedtls_ssl_conf_renegotiation(&tls_io_instance->config, set_renegotiation ? 1 : 0);

[7]
static int decode_ssl_received_bytes(TLS_IO_INSTANCE *tls_io_instance)

[8]
static int on_io_send(void *context, const unsigned char *buf, size_t sz)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant