Commit 51c959b6 authored by Filippo Valsorda's avatar Filippo Valsorda Committed by Adam Langley

crypto/tls: expand ClientHelloInfo

Fixes #17430

Change-Id: Ia1c25363d64e3091455ce00644438715aff30a0d
Reviewed-on: https://go-review.googlesource.com/31391
Run-TryBot: Adam Langley <agl@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: 's avatarFilippo Valsorda <hi@filippo.io>
parent 4b9490ee
......@@ -14,6 +14,7 @@ import (
"fmt"
"io"
"math/big"
"net"
"strings"
"sync"
"time"
......@@ -238,6 +239,32 @@ type ClientHelloInfo struct {
// is being used (see
// http://tools.ietf.org/html/rfc4492#section-5.1.2).
SupportedPoints []uint8
// SignatureSchemes lists the signature and hash schemes that the client
// is willing to verify. SignatureSchemes is set only if the Signature
// Algorithms Extension is being used (see
// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1).
SignatureSchemes []uint16
// SupportedProtos lists the application protocols supported by the client.
// SupportedProtos is set only if the Application-Layer Protocol
// Negotiation Extension is being used (see
// https://tools.ietf.org/html/rfc7301#section-3.1).
//
// Servers can select a protocol by setting Config.NextProtos in a
// GetConfigForClient return value.
SupportedProtos []string
// SupportedVersions lists the TLS versions supported by the client.
// For TLS versions less than 1.3, this is extrapolated from the max
// version advertised by the client, so values other than the greatest
// might be rejected if used.
SupportedVersions []uint16
// Conn is the underlying net.Conn for the connection. Do not read
// from, or write to, this connection; that will cause the TLS
// connection to fail.
Conn net.Conn
}
// RenegotiationSupport enumerates the different levels of support for TLS
......
......@@ -19,19 +19,20 @@ import (
// serverHandshakeState contains details of a server handshake in progress.
// It's discarded once the handshake has completed.
type serverHandshakeState struct {
c *Conn
clientHello *clientHelloMsg
hello *serverHelloMsg
suite *cipherSuite
ellipticOk bool
ecdsaOk bool
rsaDecryptOk bool
rsaSignOk bool
sessionState *sessionState
finishedHash finishedHash
masterSecret []byte
certsFromClient [][]byte
cert *Certificate
c *Conn
clientHello *clientHelloMsg
hello *serverHelloMsg
suite *cipherSuite
ellipticOk bool
ecdsaOk bool
rsaDecryptOk bool
rsaSignOk bool
sessionState *sessionState
finishedHash finishedHash
masterSecret []byte
certsFromClient [][]byte
cert *Certificate
cachedClientHelloInfo *ClientHelloInfo
}
// serverHandshake performs a TLS handshake as a server.
......@@ -123,15 +124,8 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
return false, unexpectedMessageError(hs.clientHello, msg)
}
clientHelloInfo := &ClientHelloInfo{
CipherSuites: hs.clientHello.cipherSuites,
ServerName: hs.clientHello.serverName,
SupportedCurves: hs.clientHello.supportedCurves,
SupportedPoints: hs.clientHello.supportedPoints,
}
if c.config.GetConfigForClient != nil {
if newConfig, err := c.config.GetConfigForClient(clientHelloInfo); err != nil {
if newConfig, err := c.config.GetConfigForClient(hs.clientHelloInfo()); err != nil {
c.sendAlert(alertInternalError)
return false, err
} else if newConfig != nil {
......@@ -223,7 +217,7 @@ Curves:
}
}
hs.cert, err = c.config.getCertificate(clientHelloInfo)
hs.cert, err = c.config.getCertificate(hs.clientHelloInfo())
if err != nil {
c.sendAlert(alertInternalError)
return false, err
......@@ -812,3 +806,37 @@ func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites
}
return false
}
// suppVersArray is the backing array of ClientHelloInfo.SupportedVersions
var suppVersArray = [...]uint16{VersionTLS12, VersionTLS11, VersionTLS10, VersionSSL30}
func (hs *serverHandshakeState) clientHelloInfo() *ClientHelloInfo {
if hs.cachedClientHelloInfo != nil {
return hs.cachedClientHelloInfo
}
var supportedVersions []uint16
if hs.clientHello.vers > VersionTLS12 {
supportedVersions = suppVersArray[:]
} else if hs.clientHello.vers >= VersionSSL30 {
supportedVersions = suppVersArray[VersionTLS12-hs.clientHello.vers:]
}
signatureSchemes := make([]uint16, 0, len(hs.clientHello.signatureAndHashes))
for _, sah := range hs.clientHello.signatureAndHashes {
signatureSchemes = append(signatureSchemes, uint16(sah.hash)<<8+uint16(sah.signature))
}
hs.cachedClientHelloInfo = &ClientHelloInfo{
CipherSuites: hs.clientHello.cipherSuites,
ServerName: hs.clientHello.serverName,
SupportedCurves: hs.clientHello.supportedCurves,
SupportedPoints: hs.clientHello.supportedPoints,
SignatureSchemes: signatureSchemes,
SupportedProtos: hs.clientHello.alpnProtocols,
SupportedVersions: supportedVersions,
Conn: hs.c.conn,
}
return hs.cachedClientHelloInfo
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment