[squid-users] Resolved: Peek-and-splice not working when mixing TLS1.3 servers and TLS1.2 clients

John eype69 at gmail.com
Thu Dec 12 17:29:09 UTC 2019

Hi Nikolaus

I have taken your patch, applied it to squid
http://http.debian.net/debian/pool/main/s/squid/squid_4.9-2.dsc, built
it as a deb package and tested it.

In use I am getting many errors of the form:
2019/12/12 16:50:19 kid1| Error parsing SSL Server Hello Message on FD 15

Turning on debug, the relevant section of the log seems to be:
2019/12/12 16:50:16.711 kid1| 24,7| BinaryTokenizer.cc(65) got:
Handshake.msg_type=2 occupying 1 bytes @0 in 0x55cd92e91c18.
2019/12/12 16:50:16.711 kid1| 24,7| BinaryTokenizer.cc(65) got:
Handshake.msg_body.length=87 occupying 3 bytes @1 in 0x55cd92e91c18.
2019/12/12 16:50:16.711 kid1| 24,7| BinaryTokenizer.cc(74) got:
Handshake.msg_body.octets= occupying 87 bytes @4 in 0x55cd92e91c18.
2019/12/12 16:50:16.711 kid1| 24,7| BinaryTokenizer.cc(57) got:
Handshake occupying 91 bytes @0 in 0x55cd92e91c18.
2019/12/12 16:50:16.711 kid1| 0,3| Handshake.cc(324)
parseHandshakeMessage: check failed: state < atHelloReceived
    exception location: Handshake.cc(324) parseHandshakeMessage

2019/12/12 16:50:16.711 kid1| 83,2| bio.cc(318) readAndParse: parsing
error on FD 15: check failed: state < atHelloReceived
    exception location: Handshake.cc(324) parseHandshakeMessage

2019/12/12 16:50:16.711 kid1| 83,7| bio.cc(324) readAndParse: Hold
flag is set, retry latter. (Hold 5bytes)
2019/12/12 16:50:16.711 kid1| 83,7| bio.cc(166) stateChanged: FD 15
now: 0x1002 TWCH (SSLv3/TLS write client hello)
2019/12/12 16:50:16.711 kid1| 83,5| PeerConnector.cc(462)
noteWantRead: local= remote= FD 15
2019/12/12 16:50:16.711 kid1| Error parsing SSL Server Hello Message on FD 15

However... functionally, the patch does seem to be working, allowing
TLS 1.2 traffic from the client inside my network to connect to a TLS
1.3 server (www.google.com) when the site is in the whitelist and
terminating the connection when it is removed from the whitelist.

It is unclear to me if the "Error parsing SSL Server Hello Message"
are benign or not.


On Sat, 7 Dec 2019 at 13:54, Nikolaus <dc.sqml at ntcomputer.de> wrote:
> I was able to solve the issue, fixing both squid-side "error:1425F175:SSL routines:ssl_choose_client_version:inappropriate fallback (1/-1/0)" and client-side certificate verification errors when attempting to contact TLS 1.3 server over a TLS 1.3-enabled squid from a TLS 1.2 client. I will first explain what causes the issue before presenting my solution, which involves changes of the squid code base, for anybody who is affected by the same problem.
> I have inspected the squid source code and noticed that TLS peeking works roughly like this:
> 1. The client sends a client_hello, which is parsed by squid using a custom handshake parser.  <-- Uses TLS 1.2
> 2. Squid creates an OpenSSL TLS session for the peeked connection  <-- Uses TLS 1.3!
> 3. Squid forwards the original client_hello handshake message to the server <-- TLS 1.2
> 4. Squid passes the received server_hello response to the OpenSSL session created previously  <-- Response uses TLS 1.2 - Problem!
> Now, the "problem" is that TLS 1.3 defines a set of new protocol downgrade attack prevention mechanisms (can be found e.g. here: https://blog.gypsyengineer.com/en/security/how-does-tls-1-3-protect-against-downgrade-attacks.html). Both OpenSSL and most likely the server implement these. This includes that the server random in the TLS 1.2 server_hello contains an indicator that the server is TL 1.3-capable. The OpenSSL session created by squid detects this, notices that it is TLS 1.3-capable itself, and closes the connection because it assumes a protocol downgrade attack! Little does it know, that our client actually only supports TLS 1.2, so we *want* the lower protocol version.
> My solution includes setting the maximum TLS version of the OpenSSL session to the version received from the client. This proved a little bit difficult, since the way TLS versions are negotiated has also been changed by the TLS 1.3 specification, and the squid handshake parser was not yet able to detect TLS 1.3 correctly - I have therefore also implemented parsing of the SupportedVersions TLS Extension and a preliminary support for sparse version ranges. You can find all these changes at https://github.com/nthuemmel/squid/tree/tls_downgrade_compatibility , which is a fork of squid 4.9. Feel free to compile & test it if you have a transparent peek-and-splice setup and are affected by the "inappropriate fallback" problem.
> I would of course be glad if the fix could be merged into the main squid repository. If you are a dev, please let me know what you think and if I should open a pull request. There are still some TODOs left, because I wasn't sure what the best way is to integrate some of the changes. Notably, there was also a comment which discourages setting a maximum version for the OpenSSL session to improve peek+bump compatibility - I don't have a setup to which this applies, so I don't know how big of an impact this is or if it is still relevant.
> Best Regards
> Nikolaus
> _______________________________________________
> squid-users mailing list
> squid-users at lists.squid-cache.org
> http://lists.squid-cache.org/listinfo/squid-users

More information about the squid-users mailing list