"fmt"
"io"
"math/big"
+ "net"
"strings"
"sync"
"time"
// 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
// 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.
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 {
}
}
- hs.cert, err = c.config.getCertificate(clientHelloInfo)
+ hs.cert, err = c.config.getCertificate(hs.clientHelloInfo())
if err != nil {
c.sendAlert(alertInternalError)
return false, err
}
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
+}