Unable to connect using TLSSocket and https

Hello,

I want to open a secure connection to httpbin.org using TLSSocket and then send GET requests.

When using TCPSocket and http, everything works, but when I try the same code with TLS Socket, I get trapped in mbed_die().

Here is the code :

SocketAddress address;
wifi.gethostbyname("httpbin.org", &address);
address.set_port(443);

// TLS socket
TLSSocket *socket = new TLSSocket();
socket->open(&wifi);
socket->set_hostname("httpbin.org");
auto ret = socket->set_root_ca_cert(SSL_CA_CERT);
if (ret != NSAPI_ERROR_OK) {
	log_info("Error when setting root ca cert : %d", ret);
	while (1) ;
}

ret = socket->connect(address);
if (ret != NSAPI_ERROR_OK) {
	log_info("Error when connecting : %d", ret);
	while (1);
}

// send GET request ...

In the socket->connect call, the program freezes because of mbed_die().
Here is the trace :

[DBG ][ESPA]: open_udp(): UDP socket 0 opened: true.
[DBG ][ESPA]: _oob_send_ok_received called for socket 0
[DBG ][ESPA]: _oob_socket0_closed(): Socket 0 closed.
[DBG ][ESPA]: close(0): socket close OK with AT+CIPCLOSE OK
[DBG ][TLSW]: mbedtls_ssl_conf_ca_chain()
[DBG ][ESPA]: open_tcp: TCP socket 0 opened: true . 
[INFO][TLSW]: Starting TLS handshake with httpbin.org
[DBG ][TLSW]: mbedtls_ssl_setup()
[DBG ][TLSW]: ssl_tls.c:5688: |2| => handshake

[DBG ][TLSW]: ssl_cli.c:4159: |2| client state: 0

[DBG ][TLSW]: ssl_msg.c:2124: |2| => flush output

[DBG ][TLSW]: ssl_msg.c:2136: |2| <= flush output

[DBG ][TLSW]: ssl_cli.c:4159: |2| client state: 1

[DBG ][TLSW]: ssl_msg.c:2124: |2| => flush output

[DBG ][TLSW]: ssl_msg.c:2136: |2| <= flush output

[DBG ][TLSW]: ssl_cli.c:0872: |2| => write client hello

[DBG ][TLSW]: ssl_msg.c:2560: |2| => write handshake message

[DBG ][TLSW]: ssl_msg.c:2719: |2| => write record

[DBG ][TLSW]: ssl_msg.c:2124: |2| => flush output

[DBG ][TLSW]: ssl_msg.c:2142: |2| message length: 150, out_left: 150

[DBG ][TLSW]: ssl_msg.c:2148: |2| ssl->f_send() returned 150 (-0xffffff6a)

[DBG ][TLSW]: ssl_msg.c:2176: |2| <= flush output

[DBG ][TLSW]: ssl_msg.c:2890: |2| <= write record

[DBG ][TLSW]: ssl_msg.c:2696: |2| <= write handshake message

[DBG ][TLSW]: ssl_cli.c:1331: |2| <= write client hello

[DBG ][TLSW]: ssl_cli.c:4159: |2| client state: 2

[DBG ][TLSW]: ssl_msg.c:2124: |2| => flush output

[DBG ][TLSW]: ssl_msg.c:2136: |2| <= flush output

[DBG ][TLSW]: ssl_cli.c:1816: |2| => parse server hello

[DBG ][TLSW]: ssl_msg.c:3922: |2| => read record

[DBG ][TLSW]: ssl_msg.c:1904: |2| => fetch input

[DBG ][TLSW]: ssl_msg.c:2065: |2| in_left: 0, nb_want: 5

[DBG ][TLSW]: ssl_msg.c:2089: |2| in_left: 0, nb_want: 5

[DBG ][TLSW]: ssl_tls.c:5698: |2| <= handshake

[DBG ][TLSW]: ssl_tls.c:5688: |2| => handshake

[DBG ][TLSW]: ssl_cli.c:4159: |2| client state: 2

[DBG ][TLSW]: ssl_msg.c:2124: |2| => flush output

[DBG ][TLSW]: ssl_msg.c:2136: |2| <= flush output

[DBG ][TLSW]: ssl_cli.c:1816: |2| => parse server hello

[DBG ][TLSW]: ssl_msg.c:3922: |2| => read record

[DBG ][TLSW]: ssl_msg.c:1904: |2| => fetch input

[DBG ][TLSW]: ssl_msg.c:2065: |2| in_left: 0, nb_want: 5

[DBG ][TLSW]: ssl_msg.c:2089: |2| in_left: 0, nb_want: 5

[DBG ][TLSW]: ssl_tls.c:5698: |2| <= handshake

[DBG ][TLSW]: ssl_tls.c:5688: |2| => handshake

[DBG ][TLSW]: ssl_cli.c:4159: |2| client state: 2

[DBG ][TLSW]: ssl_msg.c:2124: |2| => flush output

[DBG ][TLSW]: ssl_msg.c:2136: |2| <= flush output

[DBG ][TLSW]: ssl_cli.c:1816: |2| => parse server hello

[DBG ][TLSW]: ssl_msg.c:3922: |2| => read record

[DBG ][TLSW]: ssl_msg.c:1904: |2| => fetch input

[DBG ][TLSW]: ssl_msg.c:2065: |2| in_left: 0, nb_want: 5

[DBG ][ESPA]: _oob_send_ok_received called for socket 0
[DBG ][TLSW]: ssl_msg.c:2089: |2| in_left: 0, nb_want: 5

[DBG ][TLSW]: ssl_msg.c:2091: |2| ssl->f_recv(_timeout)() returned 5 (-0xfffffffb)

[DBG ][TLSW]: ssl_msg.c:2111: |2| <= fetch input

[DBG ][TLSW]: ssl_msg.c:1904: |2| => fetch input

[DBG ][TLSW]: ssl_msg.c:2065: |2| in_left: 5, nb_want: 66

[DBG ][TLSW]: ssl_msg.c:2089: |2| in_left: 5, nb_want: 66

[DBG ][TLSW]: ssl_msg.c:2091: |2| ssl->f_recv(_timeout)() returned 61 (-0xffffffc3)

[DBG ][TLSW]: ssl_msg.c:2111: |2| <= fetch input

[DBG ][TLSW]: ssl_msg.c:3996: |2| <= read record

[DBG ][TLSW]: ssl_cli.c:2128: |2| server hello, total extension length: 17

[DBG ][TLSW]: ssl_cli.c:2343: |2| <= parse server hello

[DBG ][TLSW]: ssl_cli.c:4159: |2| client state: 3

[DBG ][TLSW]: ssl_msg.c:2124: |2| => flush output

[DBG ][TLSW]: ssl_msg.c:2136: |2| <= flush output

[DBG ][TLSW]: ssl_tls.c:2725: |2| => parse certificate

[DBG ][TLSW]: ssl_msg.c:3922: |2| => read record

[DBG ][TLSW]: ssl_msg.c:1904: |2| => fetch input

[DBG ][TLSW]: ssl_msg.c:2065: |2| in_left: 0, nb_want: 5

[DBG ][TLSW]: ssl_msg.c:2089: |2| in_left: 0, nb_want: 5

[DBG ][TLSW]: ssl_msg.c:2091: |2| ssl->f_recv(_timeout)() returned 5 (-0xfffffffb)

[DBG ][TLSW]: ssl_msg.c:2111: |2| <= fetch input

[DBG ][TLSW]: ssl_msg.c:1904: |2| => fetch input

[DBG ][TLSW]: ssl_msg.c:2065: |2| in_left: 5, nb_want: 4839

[DBG ][TLSW]: ssl_msg.c:2089: |2| in_left: 5, nb_want: 4839

[DBG ][TLSW]: ssl_msg.c:2091: |2| ssl->f_recv(_timeout)() returned 2048 (-0xfffff800)

[DBG ][TLSW]: ssl_msg.c:2089: |2| in_left: 2053, nb_want: 4839

[DBG ][TLSW]: ssl_msg.c:2091: |2| ssl->f_recv(_timeout)() returned 2033 (-0xfffff80f)

[DBG ][TLSW]: ssl_msg.c:2089: |2| in_left: 4086, nb_want: 4839

[DBG ][TLSW]: ssl_msg.c:2091: |2| ssl->f_recv(_timeout)() returned 753 (-0xfffffd0f)

[DBG ][TLSW]: ssl_msg.c:2111: |2| <= fetch input

[DBG ][TLSW]: ssl_msg.c:3996: |2| <= read record

What can be the cause of this behavior ? The certificate I set should be correct (got it from my browser), I have no idea what can be the cause.

Any help is very welcome, thanks !

I recall that TLS connection had a minimum RAM requirement, perhaps 128kbytes or something. Check the ram size on your board.

1 Like

THanks for your reply,

Now that you mention it, I remember reading something about RAM indeed.

I have a custom PCB with a STM32F7 and a ESP-WROOM-02D for wifi, according to espressif documentation it has only 50kB SRAM.

But the program runs on the main STM32F7 which has 512kB SRAM + around 4MB in external SDRAM.

So, I am not sure where does the mbed TLS actually run ? on the ESP or the STM ?

1 Like

Hello,

I do not know with what you did it but I tried it with mbed-http and this test code on Nucleo-F429ZI

  • httpbin.org - error
  • https://httpbin.org - get whole page
  • https://httpbin.org/get - get headers and 200 bytes of body

BR, Jan

Well, I also was able to send a HTTPS request on a STM32F7-DISCO board connected by ethernet and it worked with no problem.
It only crashes when trying to run the program on custom pcb with STM32F7+ESP8226 via wifi.

After some debugging, I was able to locate the exact place of the crash. It always happens at state 3, when verifying the certificate.

It happens in bignum.c , in the function mbedtls_mpi_grow at this line :

if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL )

So it seems the memory allocation is causing the crash.

However, when inspecting heap size just before this call,

mbed_stats_heap_t heap_stats;
mbed_stats_heap_get(&heap_stats);
printf("Heap size: %lu / %lu bytes\r\n", heap_stats.current_size, heap_stats.reserved_size);

I get : Heap size: 53583 / 500568 bytes, so obviously I have enough memory … so why crash ??

Here is the full callstack just before the crash :

Hello,

I tried same code, what I mentioned above, with Nucleo-F429ZI and ESP8266-01 and no crash

BR, Jan

I was able to solve my problem finally.

I had to increase the main thread stack size (4096 by default) by adding

"rtos.main-thread-stack-size": 8192,

to the target_overrides field of my mbed_app.json file.

It is strange how 4096 is enough to get the TLS socket to work on the DISCO board but not on my PCB.
Anyways, I am happy I was able to solve this problem, thanks @JohnnyK .

2 Likes

Thank you for letting us know the final solution.
Any it is strange because F429ZI has also default size 4096.

BR, Jan

Hi there,

I know I’m late on this party and it’s been a long time since this post was published, but is there a chance that you still member the source of this statement regarding there is a minimun RAM requirment for TLSSocket to work?

I’m currently trying t establish a secured TLS connection to a remote host using Nucleo-L432KC platform but to no avail. My test code works great on Nucleo-L476RG platform, which has larger RAM, thus I suspect that L432KC 64KB of RAM is not sufficient .

BR,
Danial

If memory serves, 64K RAM is not enough for TLS. You can add the MBEDTLS_MEMORY_DEBUG macro to mbed_app.json to enable TLS memory debugging. Also check “Using Mbed TLS to communicate securely - Tutorials | Mbed OS 5 Documentation

1 Like