mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-03 20:17:36 +03:00
crypto/tls: let HTTP/1.1 clients connect to servers with NextProtos "h2"
Fixes #46310 Change-Id: Idd5e30f05c439f736ae6f3904cbb9cc2ba772315 Reviewed-on: https://go-review.googlesource.com/c/go/+/325432 Trust: Filippo Valsorda <filippo@golang.org> Run-TryBot: Filippo Valsorda <filippo@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org>
This commit is contained in:
parent
ff7a45e2ab
commit
3c6b6127c0
7 changed files with 277 additions and 50 deletions
|
@ -217,15 +217,13 @@ func (hs *serverHandshakeState) processClientHello() error {
|
|||
c.serverName = hs.clientHello.serverName
|
||||
}
|
||||
|
||||
if len(c.config.NextProtos) > 0 && len(hs.clientHello.alpnProtocols) > 0 {
|
||||
selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos)
|
||||
if selectedProto == "" {
|
||||
c.sendAlert(alertNoApplicationProtocol)
|
||||
return fmt.Errorf("tls: client requested unsupported application protocols (%s)", hs.clientHello.alpnProtocols)
|
||||
}
|
||||
hs.hello.alpnProtocol = selectedProto
|
||||
c.clientProtocol = selectedProto
|
||||
selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
|
||||
if err != nil {
|
||||
c.sendAlert(alertNoApplicationProtocol)
|
||||
return err
|
||||
}
|
||||
hs.hello.alpnProtocol = selectedProto
|
||||
c.clientProtocol = selectedProto
|
||||
|
||||
hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
|
||||
if err != nil {
|
||||
|
@ -277,6 +275,34 @@ func (hs *serverHandshakeState) processClientHello() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// negotiateALPN picks a shared ALPN protocol that both sides support in server
|
||||
// preference order. If ALPN is not configured or the peer doesn't support it,
|
||||
// it returns "" and no error.
|
||||
func negotiateALPN(serverProtos, clientProtos []string) (string, error) {
|
||||
if len(serverProtos) == 0 || len(clientProtos) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
var http11fallback bool
|
||||
for _, s := range serverProtos {
|
||||
for _, c := range clientProtos {
|
||||
if s == c {
|
||||
return s, nil
|
||||
}
|
||||
if s == "h2" && c == "http/1.1" {
|
||||
http11fallback = true
|
||||
}
|
||||
}
|
||||
}
|
||||
// As a special case, let http/1.1 clients connect to h2 servers as if they
|
||||
// didn't support ALPN. We used not to enforce protocol overlap, so over
|
||||
// time a number of HTTP servers were configured with only "h2", but
|
||||
// expected to accept connections from "http/1.1" clients. See Issue 46310.
|
||||
if http11fallback {
|
||||
return "", nil
|
||||
}
|
||||
return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", clientProtos)
|
||||
}
|
||||
|
||||
// supportsECDHE returns whether ECDHE key exchanges can be used with this
|
||||
// pre-TLS 1.3 client.
|
||||
func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue