crypto/tls: enforce ALPN overlap when negotiated on both sides

During the TLS handshake if the server doesn't support any of the
application protocols requested by the client, send the
no_application_protocol alert and abort the handshake on the server
side. This enforces the requirements of RFC 7301.

Change-Id: Iced2bb5c6efc607497de1c40ee3de9c2b393fa5d
Reviewed-on: https://go-review.googlesource.com/c/go/+/289209
Trust: Roland Shoemaker <roland@golang.org>
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Roland Shoemaker <roland@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
Roland Shoemaker 2021-02-02 12:58:30 -08:00
parent 9c1e414b7a
commit 7d3285645e
9 changed files with 295 additions and 179 deletions

View file

@ -11,6 +11,7 @@ import (
"crypto/hmac"
"crypto/rsa"
"errors"
"fmt"
"hash"
"io"
"sync/atomic"
@ -567,11 +568,14 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
encryptedExtensions := new(encryptedExtensionsMsg)
if len(hs.clientHello.alpnProtocols) > 0 {
if selectedProto := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); selectedProto != "" {
encryptedExtensions.alpnProtocol = selectedProto
c.clientProtocol = selectedProto
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)
}
encryptedExtensions.alpnProtocol = selectedProto
c.clientProtocol = selectedProto
}
hs.transcript.Write(encryptedExtensions.marshal())