ooni / probe

OONI Probe network measurement tool for detecting internet censorship
https://ooni.org/install
BSD 3-Clause "New" or "Revised" License
754 stars 142 forks source link

NewHTTPTransportWithOptions with proxy uses the wrong TLS stack #2536

Open bassosimone opened 1 year ago

bassosimone commented 1 year ago

Consider this scenario:

  1. You use netxlite.NewHTTPTransportWithOptions passing it a model.TLSDialer and you also use the netxlite.HTTPTransportOptionProxyURL to configure an HTTPS proxy.

  2. The *Transport you are using, which is implemented by github.com/ooni/oohttp, uses the model.TLSDialer to establish the connection with the proxy.

  3. Assuming the URL to fetch is https://www.example.com, the proxy will dial with www.example.com:443 and then the *Transport will have this nice TLS tunnel over which to TLS handshake again.

  4. However, the semantics available to the *Transport is .DialTLSContext, which cannot be used over an already established connection with the proxy, so the oohttp stack falls back on the second best, which is using the .TLSClientFactory to make a TLS connection over the proxy connection.

  5. The default of .TLSClientFactory is to use the crypto/tls stack.

This means that you're using a crypto/tls instead of using the TLSDialer in this scenario.

Normally, you would not notice this issue. But, if you're using ./internal/netemx the second TLS handshake would break, because it would not have access to the same certificates configured inside the model.UnderlyingNetwork.

This is technical debt for the engine that I am documenting so that I can reference it. Because currently this issue only impacts netem based testing, I am going to commit a simple workaround referencing this issue for the details.

A more proper fix is to modify the .TLSClientFactory to use the TLS stack also used for .DialTLSContext.