-
Notifications
You must be signed in to change notification settings - Fork 17.5k
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
x/net/http2: call conn.Handshake before accessing ConnectionState #33304
Comments
/cc @FiloSottile |
The TLS handshake doesn't fail as far as I can tell, it just isn't complete in the tls.Conn I get from Accept. ServeConn looks at the TLS ConnectionState and checks the HandshakeComplete, which is false and then ServeConn has to drop the connection according to the spec because the TLS version doesn't appear to be TLS 1.2 or higher. If it would help I can provide a packet capture as well. |
I have the same issue. It seems it is not related to http2, but has something to do with how tls connections are established. Here is a simple server program to demonstrate the issue. package main
import (
"crypto/tls"
"encoding/base64"
"log"
)
func main() {
certPEMBlock, _ := base64.StdEncoding.DecodeString("LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJ6ekNDQVZXZ0F3SUJBZ0lVUlRvOXBnMTI5TG50SFB4Wm4zZ0dNU2swaStJd0NnWUlLb1pJemowRUF3SXcKSWpFZ01CNEdBMVVFQXd3WFEyVnlkR2xtYVdOaGRHVWdRWFYwYUc5eWFYUjVJREF3SUJjTk1Ua3dPREl5TURndwpOREV6V2hnUE1qRXhPVEE0TWpNd09EQTBNVE5hTUF3eENqQUlCZ05WQkFNTUFUQXdkakFRQmdjcWhrak9QUUlCCkJnVXJnUVFBSWdOaUFBU2RQVUZKQytiUyt4RlJzQUFHT3BkS0k4bVdVZ1VRWVZjdjNnRjlwSExZd2QrR3RxS3AKdmJIdXR0eUhQSkZHcGxHdVpUbjMyakdPV3pMMDJhQklFQjdpc3dpSVptc3hmZUxSdkFzeTdHd1B0Wkc1ZTlnQgp3TUF5WW0wTFRadjZ0VzJqWURCZU1Bd0dBMVVkRXdFQi93UUNNQUF3RVFZSllJWklBWWI0UWdFQkJBUURBZ2JBCk1BNEdBMVVkRHdFQi93UUVBd0lENkRBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3RXcKREFZRFZSMFJCQVV3QTRJQk1EQUtCZ2dxaGtqT1BRUURBZ05vQURCbEFqQWM1WlZtL0pJaVRoZTQ1Z29Va3J5NgpmeGh5Z0hjS0NyaFByQTJjZDl6ZWt0SnBwd0VXU3d5ejRRcHJRczNhTHJnQ01RRE5PZHp3b2JlUW45dDk5TmduCityYlBObC9BWmVtdElER3pQU3dFb3dXR0RONitCTms3ZmVRd2Mwbmxnb0VOV0NzPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==")
keyPEMBlock, _ := base64.StdEncoding.DecodeString("LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JRzJBZ0VBTUJBR0J5cUdTTTQ5QWdFR0JTdUJCQUFpQklHZU1JR2JBZ0VCQkRDMG1zam11TGVNSlNXZjJ6QnQKNFhpVVVMNWRkODh5d3ZueVVtQ3NCR01kZDJWSnNzdThnK2svMkdFYnc4MnhlbnFoWkFOaUFBU2RQVUZKQytiUworeEZSc0FBR09wZEtJOG1XVWdVUVlWY3YzZ0Y5cEhMWXdkK0d0cUtwdmJIdXR0eUhQSkZHcGxHdVpUbjMyakdPCld6TDAyYUJJRUI3aXN3aUlabXN4ZmVMUnZBc3k3R3dQdFpHNWU5Z0J3TUF5WW0wTFRadjZ0VzA9Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K")
cert, _ := tls.X509KeyPair(certPEMBlock, keyPEMBlock)
tlsConfig := tls.Config{
Certificates: []tls.Certificate{cert},
}
listener, _ := tls.Listen("tcp", ":8443", &tlsConfig)
for {
conn, _ := listener.Accept()
defer conn.Close()
log.Printf("server: accepted from %s", conn.RemoteAddr())
tlsConn := *conn.(*tls.Conn)
//If you uncomment the line below it works
//tlsConn.Handshake()
log.Printf("server: handshake complete: %t", tlsConn.ConnectionState().HandshakeComplete)
}
} |
No reads can happen in What looks like a problem here is that |
Adding a line to the docs would also help prevent issues like this in the future, and would have helped me diagnose my issue much faster. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I attempted to make a simple http2 only client/server but the server rejects all connections as having "INADEQUATE_SECURITY, TLS version too low". When inspecting the TLS version connection claims to have a TLS version of 0 but in Wireshark I see that a TLS 1.2 negotiation has already started.
If I manually perform the TLS handshake the http2.Server.ServeConn no longer hangs up the connection.
Here is the minimal server:
Modern versions of Chrome/Firefox should be able to test this server. Testing server.crt and server.key need to be created and I used a host file to point test.local at the loopback address.
What did you expect to see?
The connection would have already completed the TLS handshake once listen.Accept returned it for use, or http2.Server.ServerConn would be able to see that the TLS version is at least negotiated.
What did you see instead?
When passing the connection directly from Accept to the http2.Server.ServeConn, the TLS state of the connection is not set. This results in ServeConn seeing a TLS version of 0 and therefore it sends GOAWAY and kills the connection.
The text was updated successfully, but these errors were encountered: