Skip to content

Commit 51c959b

Browse files
FiloSottileagl
authored andcommitted
crypto/tls: expand ClientHelloInfo
Fixes #17430 Change-Id: Ia1c25363d64e3091455ce00644438715aff30a0d Reviewed-on: https://go-review.googlesource.com/31391 Run-TryBot: Adam Langley <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]> Reviewed-by: Filippo Valsorda <[email protected]>
1 parent 4b9490e commit 51c959b

File tree

2 files changed

+77
-22
lines changed

2 files changed

+77
-22
lines changed

src/crypto/tls/common.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"fmt"
1515
"io"
1616
"math/big"
17+
"net"
1718
"strings"
1819
"sync"
1920
"time"
@@ -238,6 +239,32 @@ type ClientHelloInfo struct {
238239
// is being used (see
239240
// http://tools.ietf.org/html/rfc4492#section-5.1.2).
240241
SupportedPoints []uint8
242+
243+
// SignatureSchemes lists the signature and hash schemes that the client
244+
// is willing to verify. SignatureSchemes is set only if the Signature
245+
// Algorithms Extension is being used (see
246+
// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1).
247+
SignatureSchemes []uint16
248+
249+
// SupportedProtos lists the application protocols supported by the client.
250+
// SupportedProtos is set only if the Application-Layer Protocol
251+
// Negotiation Extension is being used (see
252+
// https://tools.ietf.org/html/rfc7301#section-3.1).
253+
//
254+
// Servers can select a protocol by setting Config.NextProtos in a
255+
// GetConfigForClient return value.
256+
SupportedProtos []string
257+
258+
// SupportedVersions lists the TLS versions supported by the client.
259+
// For TLS versions less than 1.3, this is extrapolated from the max
260+
// version advertised by the client, so values other than the greatest
261+
// might be rejected if used.
262+
SupportedVersions []uint16
263+
264+
// Conn is the underlying net.Conn for the connection. Do not read
265+
// from, or write to, this connection; that will cause the TLS
266+
// connection to fail.
267+
Conn net.Conn
241268
}
242269

243270
// RenegotiationSupport enumerates the different levels of support for TLS

src/crypto/tls/handshake_server.go

Lines changed: 50 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,20 @@ import (
1919
// serverHandshakeState contains details of a server handshake in progress.
2020
// It's discarded once the handshake has completed.
2121
type serverHandshakeState struct {
22-
c *Conn
23-
clientHello *clientHelloMsg
24-
hello *serverHelloMsg
25-
suite *cipherSuite
26-
ellipticOk bool
27-
ecdsaOk bool
28-
rsaDecryptOk bool
29-
rsaSignOk bool
30-
sessionState *sessionState
31-
finishedHash finishedHash
32-
masterSecret []byte
33-
certsFromClient [][]byte
34-
cert *Certificate
22+
c *Conn
23+
clientHello *clientHelloMsg
24+
hello *serverHelloMsg
25+
suite *cipherSuite
26+
ellipticOk bool
27+
ecdsaOk bool
28+
rsaDecryptOk bool
29+
rsaSignOk bool
30+
sessionState *sessionState
31+
finishedHash finishedHash
32+
masterSecret []byte
33+
certsFromClient [][]byte
34+
cert *Certificate
35+
cachedClientHelloInfo *ClientHelloInfo
3536
}
3637

3738
// serverHandshake performs a TLS handshake as a server.
@@ -123,15 +124,8 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
123124
return false, unexpectedMessageError(hs.clientHello, msg)
124125
}
125126

126-
clientHelloInfo := &ClientHelloInfo{
127-
CipherSuites: hs.clientHello.cipherSuites,
128-
ServerName: hs.clientHello.serverName,
129-
SupportedCurves: hs.clientHello.supportedCurves,
130-
SupportedPoints: hs.clientHello.supportedPoints,
131-
}
132-
133127
if c.config.GetConfigForClient != nil {
134-
if newConfig, err := c.config.GetConfigForClient(clientHelloInfo); err != nil {
128+
if newConfig, err := c.config.GetConfigForClient(hs.clientHelloInfo()); err != nil {
135129
c.sendAlert(alertInternalError)
136130
return false, err
137131
} else if newConfig != nil {
@@ -223,7 +217,7 @@ Curves:
223217
}
224218
}
225219

226-
hs.cert, err = c.config.getCertificate(clientHelloInfo)
220+
hs.cert, err = c.config.getCertificate(hs.clientHelloInfo())
227221
if err != nil {
228222
c.sendAlert(alertInternalError)
229223
return false, err
@@ -812,3 +806,37 @@ func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites
812806
}
813807
return false
814808
}
809+
810+
// suppVersArray is the backing array of ClientHelloInfo.SupportedVersions
811+
var suppVersArray = [...]uint16{VersionTLS12, VersionTLS11, VersionTLS10, VersionSSL30}
812+
813+
func (hs *serverHandshakeState) clientHelloInfo() *ClientHelloInfo {
814+
if hs.cachedClientHelloInfo != nil {
815+
return hs.cachedClientHelloInfo
816+
}
817+
818+
var supportedVersions []uint16
819+
if hs.clientHello.vers > VersionTLS12 {
820+
supportedVersions = suppVersArray[:]
821+
} else if hs.clientHello.vers >= VersionSSL30 {
822+
supportedVersions = suppVersArray[VersionTLS12-hs.clientHello.vers:]
823+
}
824+
825+
signatureSchemes := make([]uint16, 0, len(hs.clientHello.signatureAndHashes))
826+
for _, sah := range hs.clientHello.signatureAndHashes {
827+
signatureSchemes = append(signatureSchemes, uint16(sah.hash)<<8+uint16(sah.signature))
828+
}
829+
830+
hs.cachedClientHelloInfo = &ClientHelloInfo{
831+
CipherSuites: hs.clientHello.cipherSuites,
832+
ServerName: hs.clientHello.serverName,
833+
SupportedCurves: hs.clientHello.supportedCurves,
834+
SupportedPoints: hs.clientHello.supportedPoints,
835+
SignatureSchemes: signatureSchemes,
836+
SupportedProtos: hs.clientHello.alpnProtocols,
837+
SupportedVersions: supportedVersions,
838+
Conn: hs.c.conn,
839+
}
840+
841+
return hs.cachedClientHelloInfo
842+
}

0 commit comments

Comments
 (0)