diff options
| author | Filippo Valsorda <filippo@golang.org> | 2021-06-07 08:24:22 -0400 |
|---|---|---|
| committer | Filippo Valsorda <filippo@golang.org> | 2021-06-10 12:41:37 +0000 |
| commit | dc00dc6c6bf3b5554e37f60799aec092276ff807 (patch) | |
| tree | bd898aa5183cbc0f8f94f9157826ad9e3411ca51 /src/crypto/tls/handshake_server.go | |
| parent | 27f83723e98d8e3795a07bdca2b3a8155b0d72b3 (diff) | |
| download | go1.17beta1.tar.xz | |
crypto/tls: let HTTP/1.1 clients connect to servers with NextProtos "h2"go1.17beta1
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>
Diffstat (limited to 'src/crypto/tls/handshake_server.go')
| -rw-r--r-- | src/crypto/tls/handshake_server.go | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go index b231981e09..43f30e2fef 100644 --- a/src/crypto/tls/handshake_server.go +++ b/src/crypto/tls/handshake_server.go @@ -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 { |
