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: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Filippo Valsorda <hi@filippo.io>
This commit is contained in:
parent
5dbe3480aa
commit
b189f06b5c
27
common.go
27
common.go
@ -14,6 +14,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@ -238,6 +239,32 @@ type ClientHelloInfo struct {
|
|||||||
// is being used (see
|
// is being used (see
|
||||||
// http://tools.ietf.org/html/rfc4492#section-5.1.2).
|
// http://tools.ietf.org/html/rfc4492#section-5.1.2).
|
||||||
SupportedPoints []uint8
|
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
|
// RenegotiationSupport enumerates the different levels of support for TLS
|
||||||
|
@ -19,19 +19,20 @@ import (
|
|||||||
// serverHandshakeState contains details of a server handshake in progress.
|
// serverHandshakeState contains details of a server handshake in progress.
|
||||||
// It's discarded once the handshake has completed.
|
// It's discarded once the handshake has completed.
|
||||||
type serverHandshakeState struct {
|
type serverHandshakeState struct {
|
||||||
c *Conn
|
c *Conn
|
||||||
clientHello *clientHelloMsg
|
clientHello *clientHelloMsg
|
||||||
hello *serverHelloMsg
|
hello *serverHelloMsg
|
||||||
suite *cipherSuite
|
suite *cipherSuite
|
||||||
ellipticOk bool
|
ellipticOk bool
|
||||||
ecdsaOk bool
|
ecdsaOk bool
|
||||||
rsaDecryptOk bool
|
rsaDecryptOk bool
|
||||||
rsaSignOk bool
|
rsaSignOk bool
|
||||||
sessionState *sessionState
|
sessionState *sessionState
|
||||||
finishedHash finishedHash
|
finishedHash finishedHash
|
||||||
masterSecret []byte
|
masterSecret []byte
|
||||||
certsFromClient [][]byte
|
certsFromClient [][]byte
|
||||||
cert *Certificate
|
cert *Certificate
|
||||||
|
cachedClientHelloInfo *ClientHelloInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// serverHandshake performs a TLS handshake as a server.
|
// 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)
|
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 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)
|
c.sendAlert(alertInternalError)
|
||||||
return false, err
|
return false, err
|
||||||
} else if newConfig != nil {
|
} 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 {
|
if err != nil {
|
||||||
c.sendAlert(alertInternalError)
|
c.sendAlert(alertInternalError)
|
||||||
return false, err
|
return false, err
|
||||||
@ -812,3 +806,37 @@ func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites
|
|||||||
}
|
}
|
||||||
return false
|
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
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user