@@ -37,11 +37,9 @@ type serverHandshakeState struct {
37
37
// serverHandshake performs a TLS handshake as a server.
38
38
// c.out.Mutex <= L; c.handshakeMutex <= L.
39
39
func (c * Conn ) serverHandshake () error {
40
- config := c .config
41
-
42
40
// If this is the first server handshake, we generate a random key to
43
41
// encrypt the tickets with.
44
- config .serverInitOnce .Do (config .serverInit )
42
+ c . config .serverInitOnce .Do (c . config .serverInit )
45
43
46
44
hs := serverHandshakeState {
47
45
c : c ,
@@ -112,7 +110,6 @@ func (c *Conn) serverHandshake() error {
112
110
// readClientHello reads a ClientHello message from the client and decides
113
111
// whether we will perform session resumption.
114
112
func (hs * serverHandshakeState ) readClientHello () (isResume bool , err error ) {
115
- config := hs .c .config
116
113
c := hs .c
117
114
118
115
msg , err := c .readHandshake ()
@@ -125,7 +122,29 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
125
122
c .sendAlert (alertUnexpectedMessage )
126
123
return false , unexpectedMessageError (hs .clientHello , msg )
127
124
}
128
- c .vers , ok = config .mutualVersion (hs .clientHello .vers )
125
+
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
+ if c .config .GetConfigForClient != nil {
134
+ if newConfig , err := c .config .GetConfigForClient (clientHelloInfo ); err != nil {
135
+ c .sendAlert (alertInternalError )
136
+ return false , err
137
+ } else if newConfig != nil {
138
+ newConfig .mutex .Lock ()
139
+ newConfig .originalConfig = c .config
140
+ newConfig .mutex .Unlock ()
141
+
142
+ newConfig .serverInitOnce .Do (newConfig .serverInit )
143
+ c .config = newConfig
144
+ }
145
+ }
146
+
147
+ c .vers , ok = c .config .mutualVersion (hs .clientHello .vers )
129
148
if ! ok {
130
149
c .sendAlert (alertProtocolVersion )
131
150
return false , fmt .Errorf ("tls: client offered an unsupported, maximum protocol version of %x" , hs .clientHello .vers )
@@ -135,7 +154,7 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
135
154
hs .hello = new (serverHelloMsg )
136
155
137
156
supportedCurve := false
138
- preferredCurves := config .curvePreferences ()
157
+ preferredCurves := c . config .curvePreferences ()
139
158
Curves:
140
159
for _ , curve := range hs .clientHello .supportedCurves {
141
160
for _ , supported := range preferredCurves {
@@ -171,7 +190,7 @@ Curves:
171
190
172
191
hs .hello .vers = c .vers
173
192
hs .hello .random = make ([]byte , 32 )
174
- _ , err = io .ReadFull (config .rand (), hs .hello .random )
193
+ _ , err = io .ReadFull (c . config .rand (), hs .hello .random )
175
194
if err != nil {
176
195
c .sendAlert (alertInternalError )
177
196
return false , err
@@ -196,20 +215,15 @@ Curves:
196
215
} else {
197
216
// Although sending an empty NPN extension is reasonable, Firefox has
198
217
// had a bug around this. Best to send nothing at all if
199
- // config.NextProtos is empty. See
218
+ // c. config.NextProtos is empty. See
200
219
// https://golang.org/issue/5445.
201
- if hs .clientHello .nextProtoNeg && len (config .NextProtos ) > 0 {
220
+ if hs .clientHello .nextProtoNeg && len (c . config .NextProtos ) > 0 {
202
221
hs .hello .nextProtoNeg = true
203
- hs .hello .nextProtos = config .NextProtos
222
+ hs .hello .nextProtos = c . config .NextProtos
204
223
}
205
224
}
206
225
207
- hs .cert , err = config .getCertificate (& ClientHelloInfo {
208
- CipherSuites : hs .clientHello .cipherSuites ,
209
- ServerName : hs .clientHello .serverName ,
210
- SupportedCurves : hs .clientHello .supportedCurves ,
211
- SupportedPoints : hs .clientHello .supportedPoints ,
212
- })
226
+ hs .cert , err = c .config .getCertificate (clientHelloInfo )
213
227
if err != nil {
214
228
c .sendAlert (alertInternalError )
215
229
return false , err
@@ -354,18 +368,17 @@ func (hs *serverHandshakeState) doResumeHandshake() error {
354
368
}
355
369
356
370
func (hs * serverHandshakeState ) doFullHandshake () error {
357
- config := hs .c .config
358
371
c := hs .c
359
372
360
373
if hs .clientHello .ocspStapling && len (hs .cert .OCSPStaple ) > 0 {
361
374
hs .hello .ocspStapling = true
362
375
}
363
376
364
- hs .hello .ticketSupported = hs .clientHello .ticketSupported && ! config .SessionTicketsDisabled
377
+ hs .hello .ticketSupported = hs .clientHello .ticketSupported && ! c . config .SessionTicketsDisabled
365
378
hs .hello .cipherSuite = hs .suite .id
366
379
367
380
hs .finishedHash = newFinishedHash (hs .c .vers , hs .suite )
368
- if config .ClientAuth == NoClientCert {
381
+ if c . config .ClientAuth == NoClientCert {
369
382
// No need to keep a full record of the handshake if client
370
383
// certificates won't be used.
371
384
hs .finishedHash .discardHandshakeBuffer ()
@@ -394,7 +407,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
394
407
}
395
408
396
409
keyAgreement := hs .suite .ka (c .vers )
397
- skx , err := keyAgreement .generateServerKeyExchange (config , hs .cert , hs .clientHello , hs .hello )
410
+ skx , err := keyAgreement .generateServerKeyExchange (c . config , hs .cert , hs .clientHello , hs .hello )
398
411
if err != nil {
399
412
c .sendAlert (alertHandshakeFailure )
400
413
return err
@@ -406,7 +419,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
406
419
}
407
420
}
408
421
409
- if config .ClientAuth >= RequestClientCert {
422
+ if c . config .ClientAuth >= RequestClientCert {
410
423
// Request a client certificate
411
424
certReq := new (certificateRequestMsg )
412
425
certReq .certificateTypes = []byte {
@@ -423,8 +436,8 @@ func (hs *serverHandshakeState) doFullHandshake() error {
423
436
// to our request. When we know the CAs we trust, then
424
437
// we can send them down, so that the client can choose
425
438
// an appropriate certificate to give to us.
426
- if config .ClientCAs != nil {
427
- certReq .certificateAuthorities = config .ClientCAs .Subjects ()
439
+ if c . config .ClientCAs != nil {
440
+ certReq .certificateAuthorities = c . config .ClientCAs .Subjects ()
428
441
}
429
442
hs .finishedHash .Write (certReq .marshal ())
430
443
if _ , err := c .writeRecord (recordTypeHandshake , certReq .marshal ()); err != nil {
@@ -452,7 +465,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
452
465
var ok bool
453
466
// If we requested a client certificate, then the client must send a
454
467
// certificate message, even if it's empty.
455
- if config .ClientAuth >= RequestClientCert {
468
+ if c . config .ClientAuth >= RequestClientCert {
456
469
if certMsg , ok = msg .(* certificateMsg ); ! ok {
457
470
c .sendAlert (alertUnexpectedMessage )
458
471
return unexpectedMessageError (certMsg , msg )
@@ -461,7 +474,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
461
474
462
475
if len (certMsg .certificates ) == 0 {
463
476
// The client didn't actually send a certificate
464
- switch config .ClientAuth {
477
+ switch c . config .ClientAuth {
465
478
case RequireAnyClientCert , RequireAndVerifyClientCert :
466
479
c .sendAlert (alertBadCertificate )
467
480
return errors .New ("tls: client didn't provide a certificate" )
@@ -487,13 +500,13 @@ func (hs *serverHandshakeState) doFullHandshake() error {
487
500
}
488
501
hs .finishedHash .Write (ckx .marshal ())
489
502
490
- preMasterSecret , err := keyAgreement .processClientKeyExchange (config , hs .cert , ckx , c .vers )
503
+ preMasterSecret , err := keyAgreement .processClientKeyExchange (c . config , hs .cert , ckx , c .vers )
491
504
if err != nil {
492
505
c .sendAlert (alertHandshakeFailure )
493
506
return err
494
507
}
495
508
hs .masterSecret = masterFromPreMasterSecret (c .vers , hs .suite , preMasterSecret , hs .clientHello .random , hs .hello .random )
496
- if err := config .writeKeyLog (hs .clientHello .random , hs .masterSecret ); err != nil {
509
+ if err := c . config .writeKeyLog (hs .clientHello .random , hs .masterSecret ); err != nil {
497
510
c .sendAlert (alertInternalError )
498
511
return err
499
512
}
0 commit comments