Skip to content
New issue

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

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

Already on GitHub? # to your account

Multiple disconnects in handshake using ssl_server with Chromium browser #10014

Open
heppth opened this issue Feb 27, 2025 · 6 comments
Open

Comments

@heppth
Copy link

heppth commented Feb 27, 2025

Summary

I noticed many errors during the TLS handshake when using a self-signed server certificate. To rule out an error on my side, I tried ssl_server.exe, which shows the same disconnections during the handshake.

System information

Mbed TLS version: 3.6.2
Operating system and version: Windows 10
Configuration: mbedtls_config.txt

Expected behavior

When requesting https://localhost:4433/ with a Chromium browser, the TLS handshake should take place without any connection interruptions.

Actual behavior

Only the 3rd attempt at a TLS handshake succeeds. This can be seen in the console output of ssl_server and via chrome netlog.

  . Waiting for a remote connection ... ok
  . Performing the SSL/TLS handshake... failed
  ! mbedtls_ssl_handshake returned -30592

  . Waiting for a remote connection ... ok
  . Performing the SSL/TLS handshake... failed
  ! mbedtls_ssl_handshake returned -30592

  . Waiting for a remote connection ... ok
  . Performing the SSL/TLS handshake... ok

Image

Steps to reproduce

Start ssl_server, open Chrome or Chromium browser and navigate to https://localhost:4433/

Additional information

Other web servers with self-signed certificates are able to perform a handshake without connection failure on the first attempt.

@davidhorstmann-arm
Copy link
Contributor

davidhorstmann-arm commented Feb 27, 2025

Hi, thanks for this report!

Looking at the netlog from Chromium, it looks like the error was ERR_CERT_AUTHORITY_INVALID. This should be expected if you're using a self-signed certificate, as Chromium does not have the CA (i.e. you) in its list of trusted CAs.

I would guess that what is happening with other servers is that they are falling back to a non-TLS (i.e. raw HTTP) connection when the TLS connection fails, hence they still display the page. Our demonstration servers don't do this since the whole point of Mbed TLS is to do TLS.

You should be able to rectify this in your browser by importing a copy of your certificate in Chromium's settings. Based on my local copy of Chromium, it looks like this can be done by going to Settings > Privacy and security > Security > Manage certificates > Authorities, but I'm no expert.

@heppth
Copy link
Author

heppth commented Feb 27, 2025

I was able to analyse via netlog and Wireshark that other TLS servers perform the TLS handshake on the first attempt, although they use a similar self-signed certificate.

In my application, a status request is sent every second. When using Chrome, this means that there are always 3 handshakes per second: 2 fail and 1 succeed.

So there must be something special with mbedTLS. Unfortunately, Chrome's netlog does not provide much information. It seems as if Chrome ignores an error on the 3rd attempt.

I was able to extract the following from the Chromium debug log:

[26912:27372:0227/162028.311:ERROR:ssl_client_socket_impl.cc(985)] handshake failed; returned -1, SSL error code 1, net_error -202
[26912:27372:0227/162030.312:ERROR:ssl_client_socket_impl.cc(985)] handshake failed; returned -1, SSL error code 1, net_error -202
[26912:27372:0227/162032.304:ERROR:ssl_client_socket_impl.cc(985)] handshake failed; returned -1, SSL error code 1, net_error -202
[26912:27372:0227/162034.312:ERROR:ssl_client_socket_impl.cc(985)] handshake failed; returned -1, SSL error code 1, net_error -202
[26912:27372:0227/162036.310:ERROR:ssl_client_socket_impl.cc(985)] handshake failed; returned -1, SSL error code 1, net_error -202
[26912:27372:0227/162038.300:ERROR:ssl_client_socket_impl.cc(985)] handshake failed; returned -1, SSL error code 1, net_error -202
[26912:27372:0227/162040.307:ERROR:ssl_client_socket_impl.cc(985)] handshake failed; returned -1, SSL error code 1, net_error -202

@davidhorstmann-arm
Copy link
Contributor

I was able to analyse via netlog and Wireshark that other TLS servers perform the TLS handshake on the first attempt, although they use a similar self-signed certificate.

Hmm, that's strange. Have you tried looking at the logs from ssl_server.exe? You can use the argument debug_level=5 to get the most output.

@heppth
Copy link
Author

heppth commented Feb 27, 2025

The debug output only shows that the server successfully sends its finish message, whereupon Chromium obviously closes the connection. After the 3rd attempt it works.

ssl_tls13_server.c:2912: Switch to handshake keys for inbound traffic ( K_recv = handshake )
ssl_tls13_server.c:2870: skip parse certificate
ssl_tls13_server.c:2871: skip parse certificate verify
ssl_msg.c:2353: => flush output
ssl_msg.c:2369: message length: 69, out_left: 69
ssl_msg.c:2374: ssl->f_send() returned 69 (-0xffffffbb)
ssl_msg.c:2401: <= flush output
ssl_tls13_server.c:3462: tls13 server state: MBEDTLS_SSL_CLIENT_FINISHED(11)
ssl_tls13_generic.c:1131: => parse finished message
ssl_msg.c:4189: => read record
ssl_msg.c:2155: => fetch input
ssl_msg.c:2297: in_left: 0, nb_want: 5
ssl_msg.c:2317: in_left: 0, nb_want: 5
ssl_msg.c:2318: ssl->f_recv(_timeout)() returned -76 (-0x004c)
ssl_msg.c:4861: mbedtls_ssl_fetch_input() returned -76 (-0x004c)
ssl_msg.c:4220: ssl_get_next_record() returned -76 (-0x004c)
ssl_tls13_generic.c:0065: mbedtls_ssl_read_record() returned -76 (-0x004c)
ssl_tls13_generic.c:1147: <= parse finished message
ssl_tls.c:4617: <= handshake
 failed
  ! mbedtls_ssl_handshake returned -76

See full log: debug.txt

@davidhorstmann-arm
Copy link
Contributor

I'm unsure if this is the issue, but have you checked that ssl_server2 is actually using your self-signed certificate? The logs seem to have it using the default PolarSSL test certificates. What command did you use to run the server?

@heppth
Copy link
Author

heppth commented Feb 27, 2025

The logs seem to have it using the default PolarSSL test certificates. What command did you use to run the server?

In my implementation I use a self-signed certificate and in the tests with ssl-server I use the PolarSSL certificate. The result is the same: 2x failed handshake, then the handshake works

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

No branches or pull requests

2 participants