Score:0

SNI header missing from TLS Client Hello when using HTTP proxy

ar flag

I'm debugging a problem with a Java-based application that retrieves a JSON payload (the CVE list from NIST) over HTTPS. When I connect directly to NIST, I retrieve the data successfully. When I use an HTTP proxy, I get a TLS "unrecognized name" error suggesting a problem with Server Name Indication.

I don't have access to the Java application's code and have minimal ability to mess with JVM settings. Hence, I've been doing some separate testing using openssl directly, and I'm able to reproduce the issue to some extent with this.

When I tcpdump the following call, I can see the server_name extension present in the Client Hello packet:

openssl s_client -connect services.nvd.nist.gov:443

Wireshark showing server name extension

However, if I send this via my Squid proxy and dump the packets between the proxy and the target server with the following, there is no server_name extension present in the Client Hello packet:

openssl s_client -connect services.nvd.nist.gov:443 -proxy myproxy:3128

The response from openssl is:

140012895368512:error:14094458:SSL routines:ssl3_read_bytes:tlsv1 unrecognized name:../ssl/record/rec_layer_s3.c:1543:SSL alert number 112
---
no peer certificate available
---

And we can see that there's no server_name entry in the packet:

WireShark showing missing extension

I believe this is the reason the target server returns the error (though from what I understand it's supposed to return a default certificate in this situation).

Now I can make this work using the proxy by manually specifying the servername:

openssl s_client -connect services.nvd.nist.gov:443 -proxy myproxy:3128 -servername nvd.nist.gov

My understanding is that the proxy just tunnels the TLS data and shouldn't amend it, so it suggests that openssl is choosing not to send the servername extension information when a proxy is in use. Why would this be?

(Obviously in the openssl case I can just specify the servername parameter, but with the Java application I don't have this luxury. I'm hoping if I can understand why openssl chooses not to send the SNI details through a proxy, it might shed some light on why Java seems to do the same.)

Steffen Ullrich avatar
se flag
Looks like a bug to me that `openssl s_client` is not sending servername by default when proxy is used. But I can reproduce the issue with OpenSSL 1.1.1h and 1.1.1f. But s_client is not Java so I would argue that these problems have different causes.
Gordon Mckeown avatar
ar flag
Thanks for taking the time to reproduce the issue, @SteffenUllrich. Agreed, they could well have different causes; it just seems an odd coincidence that they both seem to exhibit the same behaviour, so I wondered if there was something about using a proxy that dictated different TLS behaviour. Also, it was a lot easier to test and explain the issue using openssl :). I have opened a [bug](https://github.com/openssl/openssl/issues/17232) against openssl.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.