-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: net/http: allow use of external TLS stacks #21753
Comments
I'll add that I'm also quite interested in this. It would make rolling out TLS 1.3 at scale much easier without having to endanger the reputation of the Go standard library with an experimental TLS version. Re: The TLSNextProto map's reliance on concrete Following that line of thought, is it feasible to add an interface field or "setter" method for an unexported interface field on the
or maybe:
Where |
Would also be nice to run http2 over something different than the default TLS, ex NoiseSocket. The ordinary HTTP runs fine, but h2 uses *tls.Conn explicitly |
Just wanted to chime in with support for this. It would make our usage of https://github.com/spacemonkeygo/openssl much easier. Initially we forked net/http but now we use a lot of unsafe stuff to get to the underlying *openssl.Conn |
This looks like #21336 and I came to the same conclusion you did ("client logic should be more like the server"). |
I think that if external TLS stacks need to be supported, they should plug into the |
@FiloSottile, is this proposal purely about net/http? If so, I would like to decline this. I don't want to deal with any additional complexity in net/http for this. The BoringCrypto branch (https://go.googlesource.com/go/+/dev.boringcrypto) also seems to suggest this abstraction isn't necessarily needed. BoringCrypto seems to be patched in elsewhere such that each package using crypto/tls doesn't need to change. |
It is about net/http, as it seems to be the most tightly coupled. What other packages depend on crypto/tls types? I think BoringCrypto is an example of why this is needed, not the opposite. That effort required maintaining a fork of the standard library, just like tls-tris, which is not an option for most users. (Also, BoringCrypto changes most primitives, but leaves most of the TLS logic alone, so it's different from tls-tris.) |
I think modifying the standard library is an acceptable cost for both of those examples. BoringCrypto does not exist for technical reasons, and tls-tris seems to be just a staging ground to get TLS 1.3 into the standard library, so that one will go away. I do not want extra complexity in net/http (at least in Go 1.x) if the only benefit is to fracture the ecosystem and push the decision of what TLS stack to use to the users. We should make our TLS stack good instead. I'll tag this for Go 2 instead, for if/when there's an net/http/v2 package. |
crypto/tls has a strict complexity budget, so it does not work for certain advanced users. Forking the entire standard library is a very high cost alternative, while having the opportunity to fork only the package would reduce pressure to add features to crypto/tls. Agreed it probably makes sense for Go 2, though. |
I'm not necessarily saying it makes sense for Go 2, FWIW. But it definitely doesn't for Go 1. |
Folding this into #5465. |
net/http is hardcoded to work with crypto/tls, and it's currently impossible to use any other TLS stack. That meant that for example to develop the tls-tris fork of crypto/tls with TLS 1.3 support I had to do horrible things which made life pretty hard for other developers on the project.
@rsc mentioned he'd be interested in making it possible to use non-crypto/tls stacks with net/http. While I don't think we should necessarily encourage it (it's good that "what TLS stack do I want?" is not a question a Go developer has to ask themselves), I agree it would be nice to at least make it possible.
Here's a survey of the coupling points, and proposals on how to fix (most) of them.
/cc @agl @bradfitz @rsc @mholt
Server side
Request.TLS
has type*tls.ConnectionState
ConnectionState
typeserve
type-asserts*tls.Conn
to detect a TLS connection and callHandshake()
andConnectionState()
Server.TLSNextProto
has typemap[string]func(*Server, *tls.Conn, Handler)
*tls.Conn
, and there is code out there written with this assumption, including the standard http2 libraryServeTLS
andListenAndServeTLS
Server.TLSConfig
has type*tls.Config
ServeTLS
/ListenAndServeTLS
and for some auto-HTTP/2 logicClient side
Client
assertstls.RecordHeaderError
to detect a mistaken plain HTTP responseResponse.TLS
has type*tls.ConnectionState
ConnectionState
typeTransport.TLSClientConfig
has type*tls.Config
DialTLS
, so it's basically part of a helperDialTLS
being sett.DialTLS != nil
) or the TLS Config is available (t.TLSClientConfig != nil
) andh2
is enabled (this might be a separate issue)Transport.TLSNextProto
has typemap[string]func(authority string, c *tls.Conn) RoundTripper
Server.TLSNextProto
, this is a problemdialConn
type-asserts*tls.Conn
Conclusion
The main problem are the two
TLSNextProto
, for which I have no good solution. The auto-HTTP/2 logic might also need attention. Other parts can be either ignored as helpers, or discreetly fixed.The text was updated successfully, but these errors were encountered: