wolfSSL / wolfssl

The wolfSSL library is a small, fast, portable implementation of TLS/SSL for embedded devices to the cloud. wolfSSL supports up to TLS 1.3 and DTLS 1.3!
https://www.wolfssl.com
GNU General Public License v2.0
2.37k stars 834 forks source link

middlebox compatibility mode and ECH #6774

Open sftcd opened 1 year ago

sftcd commented 1 year ago

Version

git cloned code from yesterday

Description

Hi,

I've been implementing encrypted client hello (ECH) in OpenSSL and have a proof of concept implementation of using that in curl [1] as well as in various servers (nginx, apache etc.)

It was suggested that I try curl+WolfSSL+ECH so I did that and ran into an issue with middlebox compatibility mode that caused curl+WolfSSL+ECH to fail when talking to my (OpenSSL using) servers at e.g. https://defo.ie/ech-check.php, even though curl+WolfSSL+ECH worked when talking to Cloudflare's server (https://crypto.cloudflare.com/cdn-cgi/trace).

Note that curl+WolfSSL+ECH also fails when attempting to talk to https://tls-ech.dev/ (I forget who built that last server or how, sorry).

The issue is that WolfSSL doesn't follow RFC8446 Appendix D.4 (at least in my build), whereas my ECH code assumed D.4 would be followed when reconstructing the innerClientHello. I think WolfSSL is conforming to the spec though so I've changed my server code to be more tolerant, which I guess is what Cloudflare did to start with. (I'll push that to my various servers next day or so once I've tested it a bit more.)

Given RFC8446 is 5 years old now, I'm not sure if ignoring D.4 is or is not a problem today, but given that this causes an issue with 2 of the 3 ECH-enabled servers deployed (that I know about) it might be worth considering following D.4 as the default.

Lastly, I'm not sure if WolfSSL is typically built as I've done, so it could be that more "normal" builds/releases do follow D.4 in which case this issue wouldn't have arisen.

Cheers, S.

[1] https://github.com/sftcd/openssl/blob/ECH-draft-13c/esnistuff/building-curl-openssl-with-ech.md#wolfssl

anhu commented 1 year ago

Hi @sftcd , My name is Anthony Hu and I am a member of the wolfSSL team. Section D.4 of the RFC discuss middlebox compatibility. While I have not read over in great detail nor tried to reproduce what you have observed, I wanted to reply in a timely manor.

Have you tried compiling wolfSSL with WOLFSSL_TLS13_MIDDLEBOX_COMPAT defined in your CFLAGS? I'm not entirely certain it will fix your issue, but I think it might be worth a try.

Warm regards, Anthony.

sftcd commented 1 year ago

Hi Anthony,

I've not tried that yet, but will (tomorrow, here:-). My reading of the specs so far is that WolfSSL is compliant, so I think the bug was on my side anyway, (and hopefully I've fixed that now), the only question for WolfSSL I think it whether or not it'd be wise or unwise to make adhering to D.4 the default when using ECH or not.

Cheers (and thanks for the speedy response), S.

sftcd commented 1 year ago

Hi,

I did that build with WOLFSSL_TLS13_MIDDLEBX_COMPAT and it didn't work, and in this case I think that does show a bug in WolfSSL. section 5.1 of the ECH spec says to use a zero length legacy_session_id within the EncodedInnerClientHello, but when WolfSSL is in middlebox mode it sends a 0x20 length session ID in both outer ClientHello and EncodedInnerClientHello.

You can see the 1st 100 octets of an EncodedInnerClientHello (the output of HPKE decryption) below (with a bit of formatting to show the 0x20 length of legacy_session_id

 p/x opd[0]@100
$5 = {0x3, 0x3, 0xe, 0xc, 0xb7, 0xc6, 0xf5,                                   0x1e, 0x58, 0x6d, 0x9a, 0xe6, 0x28, 0x49, 0x9b, 
          0x1a, 0x89, 0x28, 0xea, 0xf9, 0xee, 0x64, 0x87,               0x13, 0x77, 0x5a, 0xf6, 0x1a, 0x6f, 0x53, 0x83, 
          0xa9, 0x1a, 0x68, **0x20**, 0x2f, 0x1b, 0xcf, 0xb8,                0x49, 0xfb, 0x63, 0x18, 0x8e, 0xe5, 0x6b, 0xc1, 
          0xc2, 0xd6, 0x68, 0x16, 0x96, 0xee, 0x9c, 0xf8,                0x8a, 0xf1, 0xbb, 0x67, 0xd6, 0x7b, 0x76, 0xb2, 
          0x31, 0x32, 0xfe, 0xbf, 0x0, 0x36, 0x13, 0x1,                    0x13, 0x2, 0x13, 0x3, 0xc0, 0x2c, 0xc0, 0x2b, 
          0xc0, 0x30, 0xc0, 0x2f, 0x0, 0x9f, 0x0, 0x9e, 0xcc,           0xa9, 0xcc, 0xa8, 0xcc, 0xaa, 0xc0, 0x27, 0xc0, 
          0x23, 0xc0, 0x28, 0xc0}

I think the error is maybe around this code where it probably needs to make an exception for the case where you're doing the inner ClientHello.

So, to summarise: without WOLFSSL_TLS13_MIDDLEBOX_COMPAT your standard build showed up a bug in my code (that I think I've fixed); with WOLFSSL_TLS13_MIDDLEBOX_COMPAT that shows up a bug in your code (I think). If that's right, it's nicely symmetric:-)

Cheers, S.

anhu commented 1 year ago

@sftcd ,

Thank you so much. I'm so glad I asked you to try it. I'll need to check with the original author about your findings. Obviously, this bug that you have discovered is not affecting your development so I will not give it a high priority.

I imagine that from your perspective, the matter is closed, but I shall leave this bug open for a while in case we have some questions about your setup.

Warm regards, Anthony

sftcd commented 1 year ago

That's fine. I would though also recommend re-considering whether or not to make middlebox mode your default in future, when doing ECH. (ECH already involves sending so many octets saving 32 doesn't seem that compelling;-) I suspect (but don't know for sure) that'd lead to better interop for WolfSSL+ECH and perhaps better deployment of ECH.