Mbed-TLS / mbedtls

An open source, portable, easy to use, readable and flexible TLS library, and reference implementation of the PSA Cryptography API. Releases are on a varying cadence, typically around 3 - 6 months between releases.
https://www.trustedfirmware.org/projects/mbed-tls/
Other
5.21k stars 2.55k forks source link

Error when client receive HelloRetryRequest with cookie extension #9543

Open zea408 opened 1 week ago

zea408 commented 1 week ago

This is the first time I summit a bug report, please let me know if anything is missing or wrong.

Summary

Receiving HelloRetryRequest(to change key share) with cookie extension result with a response of Alert (Fatal, Unsupported Extension).

System information

MBed TLS V3.6.0

Expected behavior

According to RFC 8446 Section 4.2, Implementations MUST NOT send extension responses if the remote endpoint did not send the corresponding extension requests, with the exception of the "cookie" extension in the HelloRetryRequest. Upon receiving such an extension, an endpoint MUST abort the handshake with an "unsupported_extension" alert. Client should respond with Client Hello with the "cookie" extension from the HRR with the new key share.

Actual behavior

Client respond with Alert(Fatal, Unsupported Extension).

Steps to reproduce

  1. Make client (MBed TLS) send a Client Hello using key share unsupported by the server.
  2. Server responed with a HRR that contain cookie extension requesting for a different key share.
  3. Client send out Alert (Fatal, Unsupported Extension).

Temporary Fix

Add in exception for cookie extension on message type HRR in mbedtls_ssl_tls13_check_received_extension in ssl_tls13_generic.c.

Additional information

  1. Client Hello: Transport Layer Security TLSv1.3 Record Layer: Handshake Protocol: Client Hello Content Type: Handshake (22) Version: TLS 1.2 (0x0303) Length: 181 Handshake Protocol: Client Hello Handshake Type: Client Hello (1) Length: 177 Version: TLS 1.2 (0x0303) Random: 18ff81074e1b40e459cd36ab7f7f3bf80a889fad45534f2e04abc6efcad7ff94 Session ID Length: 32 Session ID: 5a31fb2b5be8efb035e774894024f795da36ef097d41bdddf171c901e295490f Cipher Suites Length: 10 Cipher Suites (5 suites) Compression Methods Length: 1 Compression Methods (1 method) Extensions Length: 94 Extension: supported_versions (len=3) TLS 1.3 Extension: key_share (len=38) x25519 Extension: psk_key_exchange_modes (len=3) Type: psk_key_exchange_modes (45) Length: 3 PSK Key Exchange Modes Length: 2 PSK Key Exchange Mode: PSK with (EC)DHE key establishment (psk_dhe_ke) (1) PSK Key Exchange Mode: PSK-only key establishment (psk_ke) (0) Extension: supported_groups (len=10) Type: supported_groups (10) Length: 10 Supported Groups List Length: 8 Supported Groups (4 groups) Extension: signature_algorithms (len=20) Type: signature_algorithms (13) Length: 20 Signature Hash Algorithms Length: 18 Signature Hash Algorithms (9 algorithms)
  2. HelloRetryRequest: Transport Layer Security TLSv1.3 Record Layer: Handshake Protocol: Hello Retry Request Content Type: Handshake (22) Version: TLS 1.2 (0x0303) Length: 193 Handshake Protocol: Hello Retry Request Handshake Type: Server Hello (2) Length: 189 Version: TLS 1.2 (0x0303) Random: cf21ad74e59a6111be1d8c021e65b891c2a211167abb8c5e079e09e2c8a8339c (HelloRetryRequest magic) Session ID Length: 32 Session ID: 5a31fb2b5be8efb035e774894024f795da36ef097d41bdddf171c901e295490f Cipher Suite: TLS_AES_256_GCM_SHA384 (0x1302) Compression Method: null (0) Extensions Length: 117 Extension: supported_versions (len=2) TLS 1.3 Extension: cookie (len=101) Extension: key_share (len=2) secp256r1
  3. Alert: Transport Layer Security TLSv1.3 Record Layer: Alert (Level: Fatal, Description: Unsupported Extension) Content Type: Alert (21) Version: TLS 1.2 (0x0303) Length: 2 Alert Message
gilles-peskine-arm commented 1 week ago

Thanks for the report! We've just released Mbed TLS 3.6.1, which fixes several bugs and limitation in TLS 1.3 support. Can you please try version 3.6.1? I don't think we've fixed this, but it might have happened as part of another fix.

If you can still reproduce the problem with 3.6.1, would you mind sharing the client code to reproduce the problem?

zea408 commented 1 week ago

After switching to 3.6.1, the issue still persist. I can't share my client code due to company policy, however, I do able to use the ssl_client1 example to duplicate the issue as long the server reply HelloRetryRequest with a cookie extension.

gilles-peskine-arm commented 1 week ago

All right, thanks! Hopefully that'll be enough for us to reproduce the issue.

gilles-peskine-arm commented 1 week ago

A couple more things: could you share what server and server settings cause a server to send a cookie extension? I'm not personally familiar with the TLS 1.3 ecosystem. Is this a common thing?

(In 3.5.1, ssl_client1 works against a plain openssl s_server, but we're not testing more sophisticated things.)

Also, is the behavior of ssl_client2 different? Maybe with an extra command line option (sorry, I don't know what that option would be).

ronald-cron-arm commented 1 week ago

I've had a quick look and my understanding is that we have a bug in mbedtls_ssl_tls13_check_received_extension() when hs_msg_type == MBEDTLS_SSL_TLS1_3_HS_HELLO_RETRY_REQUEST and received_extension_type == MBEDTLS_SSL_EXT_ID_COOKIE. In that particular case we should not check that we have sent the extension in our previous client hello: switch line 1637.

We does not seem to have some test for the echoing of the server HRR cookie in the second client hello. When we added the echoing we decided to postpone the testing of it (but fail to do so): see https://github.com/Mbed-TLS/mbedtls/pull/5369#pullrequestreview-877146112. I guess it is because it is not easy to do. Our TLS 1.3 server implementation does not support sending a cookie extension in the HRR. Looking at OpenSSL s_server it seems that the option --stateless is related to that. I've tried it with our ssl-opt.sh HRR test: "TLS 1.3 m->O: HRR secp256r1 -> secp384r1" but it does not seem to work.