@@ -19,19 +19,20 @@ import (
19
19
// serverHandshakeState contains details of a server handshake in progress.
20
20
// It's discarded once the handshake has completed.
21
21
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
35
36
}
36
37
37
38
// serverHandshake performs a TLS handshake as a server.
@@ -123,15 +124,8 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
123
124
return false , unexpectedMessageError (hs .clientHello , msg )
124
125
}
125
126
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
-
133
127
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 {
135
129
c .sendAlert (alertInternalError )
136
130
return false , err
137
131
} else if newConfig != nil {
@@ -223,7 +217,7 @@ Curves:
223
217
}
224
218
}
225
219
226
- hs .cert , err = c .config .getCertificate (clientHelloInfo )
220
+ hs .cert , err = c .config .getCertificate (hs . clientHelloInfo () )
227
221
if err != nil {
228
222
c .sendAlert (alertInternalError )
229
223
return false , err
@@ -812,3 +806,37 @@ func (hs *serverHandshakeState) setCipherSuite(id uint16, supportedCipherSuites
812
806
}
813
807
return false
814
808
}
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