1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
18 // serverHandshakeState contains details of a server handshake in progress.
19 // It's discarded once the handshake has completed.
20 type serverHandshakeState
struct {
22 clientHello
*clientHelloMsg
27 sessionState
*sessionState
28 finishedHash finishedHash
30 certsFromClient
[][]byte
34 // serverHandshake performs a TLS handshake as a server.
35 func (c
*Conn
) serverHandshake() error
{
38 // If this is the first server handshake, we generate a random key to
39 // encrypt the tickets with.
40 config
.serverInitOnce
.Do(config
.serverInit
)
42 hs
:= serverHandshakeState
{
45 isResume
, err
:= hs
.readClientHello()
50 // For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3
52 // The client has included a session ticket and so we do an abbreviated handshake.
53 if err
:= hs
.doResumeHandshake(); err
!= nil {
56 if err
:= hs
.establishKeys(); err
!= nil {
59 if err
:= hs
.sendFinished(); err
!= nil {
62 if err
:= hs
.readFinished(); err
!= nil {
67 // The client didn't include a session ticket, or it wasn't
68 // valid so we do a full handshake.
69 if err
:= hs
.doFullHandshake(); err
!= nil {
72 if err
:= hs
.establishKeys(); err
!= nil {
75 if err
:= hs
.readFinished(); err
!= nil {
78 if err
:= hs
.sendSessionTicket(); err
!= nil {
81 if err
:= hs
.sendFinished(); err
!= nil {
85 c
.handshakeComplete
= true
90 // readClientHello reads a ClientHello message from the client and decides
91 // whether we will perform session resumption.
92 func (hs
*serverHandshakeState
) readClientHello() (isResume
bool, err error
) {
96 msg
, err
:= c
.readHandshake()
101 hs
.clientHello
, ok
= msg
.(*clientHelloMsg
)
103 return false, c
.sendAlert(alertUnexpectedMessage
)
105 c
.vers
, ok
= config
.mutualVersion(hs
.clientHello
.vers
)
107 return false, c
.sendAlert(alertProtocolVersion
)
111 hs
.finishedHash
= newFinishedHash(c
.vers
)
112 hs
.finishedHash
.Write(hs
.clientHello
.marshal())
114 hs
.hello
= new(serverHelloMsg
)
116 supportedCurve
:= false
118 for _
, curve
:= range hs
.clientHello
.supportedCurves
{
120 case curveP256
, curveP384
, curveP521
:
121 supportedCurve
= true
126 supportedPointFormat
:= false
127 for _
, pointFormat
:= range hs
.clientHello
.supportedPoints
{
128 if pointFormat
== pointFormatUncompressed
{
129 supportedPointFormat
= true
133 hs
.ellipticOk
= supportedCurve
&& supportedPointFormat
135 foundCompression
:= false
136 // We only support null compression, so check that the client offered it.
137 for _
, compression
:= range hs
.clientHello
.compressionMethods
{
138 if compression
== compressionNone
{
139 foundCompression
= true
144 if !foundCompression
{
145 return false, c
.sendAlert(alertHandshakeFailure
)
148 hs
.hello
.vers
= c
.vers
149 t
:= uint32(config
.time().Unix())
150 hs
.hello
.random
= make([]byte, 32)
151 hs
.hello
.random
[0] = byte(t
>> 24)
152 hs
.hello
.random
[1] = byte(t
>> 16)
153 hs
.hello
.random
[2] = byte(t
>> 8)
154 hs
.hello
.random
[3] = byte(t
)
155 _
, err
= io
.ReadFull(config
.rand(), hs
.hello
.random
[4:])
157 return false, c
.sendAlert(alertInternalError
)
159 hs
.hello
.compressionMethod
= compressionNone
160 if len(hs
.clientHello
.serverName
) > 0 {
161 c
.serverName
= hs
.clientHello
.serverName
163 // Although sending an empty NPN extension is reasonable, Firefox has
164 // had a bug around this. Best to send nothing at all if
165 // config.NextProtos is empty. See
166 // https://code.google.com/p/go/issues/detail?id=5445.
167 if hs
.clientHello
.nextProtoNeg
&& len(config
.NextProtos
) > 0 {
168 hs
.hello
.nextProtoNeg
= true
169 hs
.hello
.nextProtos
= config
.NextProtos
172 if len(config
.Certificates
) == 0 {
173 return false, c
.sendAlert(alertInternalError
)
175 hs
.cert
= &config
.Certificates
[0]
176 if len(hs
.clientHello
.serverName
) > 0 {
177 hs
.cert
= config
.getCertificateForName(hs
.clientHello
.serverName
)
180 _
, hs
.ecdsaOk
= hs
.cert
.PrivateKey
.(*ecdsa
.PrivateKey
)
182 if hs
.checkForResumption() {
186 var preferenceList
, supportedList
[]uint16
187 if c
.config
.PreferServerCipherSuites
{
188 preferenceList
= c
.config
.cipherSuites()
189 supportedList
= hs
.clientHello
.cipherSuites
191 preferenceList
= hs
.clientHello
.cipherSuites
192 supportedList
= c
.config
.cipherSuites()
195 for _
, id
:= range preferenceList
{
196 if hs
.suite
= c
.tryCipherSuite(id
, supportedList
, c
.vers
, hs
.ellipticOk
, hs
.ecdsaOk
); hs
.suite
!= nil {
202 return false, c
.sendAlert(alertHandshakeFailure
)
208 // checkForResumption returns true if we should perform resumption on this connection.
209 func (hs
*serverHandshakeState
) checkForResumption() bool {
213 if hs
.sessionState
, ok
= c
.decryptTicket(hs
.clientHello
.sessionTicket
); !ok
{
217 if hs
.sessionState
.vers
> hs
.clientHello
.vers
{
220 if vers
, ok
:= c
.config
.mutualVersion(hs
.sessionState
.vers
); !ok || vers
!= hs
.sessionState
.vers
{
224 cipherSuiteOk
:= false
225 // Check that the client is still offering the ciphersuite in the session.
226 for _
, id
:= range hs
.clientHello
.cipherSuites
{
227 if id
== hs
.sessionState
.cipherSuite
{
236 // Check that we also support the ciphersuite from the session.
237 hs
.suite
= c
.tryCipherSuite(hs
.sessionState
.cipherSuite
, c
.config
.cipherSuites(), hs
.sessionState
.vers
, hs
.ellipticOk
, hs
.ecdsaOk
)
242 sessionHasClientCerts
:= len(hs
.sessionState
.certificates
) != 0
243 needClientCerts
:= c
.config
.ClientAuth
== RequireAnyClientCert || c
.config
.ClientAuth
== RequireAndVerifyClientCert
244 if needClientCerts
&& !sessionHasClientCerts
{
247 if sessionHasClientCerts
&& c
.config
.ClientAuth
== NoClientCert
{
254 func (hs
*serverHandshakeState
) doResumeHandshake() error
{
257 hs
.hello
.cipherSuite
= hs
.suite
.id
258 // We echo the client's session ID in the ServerHello to let it know
259 // that we're doing a resumption.
260 hs
.hello
.sessionId
= hs
.clientHello
.sessionId
261 hs
.finishedHash
.Write(hs
.hello
.marshal())
262 c
.writeRecord(recordTypeHandshake
, hs
.hello
.marshal())
264 if len(hs
.sessionState
.certificates
) > 0 {
265 if _
, err
:= hs
.processCertsFromClient(hs
.sessionState
.certificates
); err
!= nil {
270 hs
.masterSecret
= hs
.sessionState
.masterSecret
275 func (hs
*serverHandshakeState
) doFullHandshake() error
{
276 config
:= hs
.c
.config
279 if hs
.clientHello
.ocspStapling
&& len(hs
.cert
.OCSPStaple
) > 0 {
280 hs
.hello
.ocspStapling
= true
283 hs
.hello
.ticketSupported
= hs
.clientHello
.ticketSupported
&& !config
.SessionTicketsDisabled
284 hs
.hello
.cipherSuite
= hs
.suite
.id
285 hs
.finishedHash
.Write(hs
.hello
.marshal())
286 c
.writeRecord(recordTypeHandshake
, hs
.hello
.marshal())
288 certMsg
:= new(certificateMsg
)
289 certMsg
.certificates
= hs
.cert
.Certificate
290 hs
.finishedHash
.Write(certMsg
.marshal())
291 c
.writeRecord(recordTypeHandshake
, certMsg
.marshal())
293 if hs
.hello
.ocspStapling
{
294 certStatus
:= new(certificateStatusMsg
)
295 certStatus
.statusType
= statusTypeOCSP
296 certStatus
.response
= hs
.cert
.OCSPStaple
297 hs
.finishedHash
.Write(certStatus
.marshal())
298 c
.writeRecord(recordTypeHandshake
, certStatus
.marshal())
301 keyAgreement
:= hs
.suite
.ka(c
.vers
)
302 skx
, err
:= keyAgreement
.generateServerKeyExchange(config
, hs
.cert
, hs
.clientHello
, hs
.hello
)
304 c
.sendAlert(alertHandshakeFailure
)
308 hs
.finishedHash
.Write(skx
.marshal())
309 c
.writeRecord(recordTypeHandshake
, skx
.marshal())
312 if config
.ClientAuth
>= RequestClientCert
{
313 // Request a client certificate
314 certReq
:= new(certificateRequestMsg
)
315 certReq
.certificateTypes
= []byte{
316 byte(certTypeRSASign
),
317 byte(certTypeECDSASign
),
319 if c
.vers
>= VersionTLS12
{
320 certReq
.hasSignatureAndHash
= true
321 certReq
.signatureAndHashes
= supportedClientCertSignatureAlgorithms
324 // An empty list of certificateAuthorities signals to
325 // the client that it may send any certificate in response
326 // to our request. When we know the CAs we trust, then
327 // we can send them down, so that the client can choose
328 // an appropriate certificate to give to us.
329 if config
.ClientCAs
!= nil {
330 certReq
.certificateAuthorities
= config
.ClientCAs
.Subjects()
332 hs
.finishedHash
.Write(certReq
.marshal())
333 c
.writeRecord(recordTypeHandshake
, certReq
.marshal())
336 helloDone
:= new(serverHelloDoneMsg
)
337 hs
.finishedHash
.Write(helloDone
.marshal())
338 c
.writeRecord(recordTypeHandshake
, helloDone
.marshal())
340 var pub crypto
.PublicKey
// public key for client auth, if any
342 msg
, err
:= c
.readHandshake()
348 // If we requested a client certificate, then the client must send a
349 // certificate message, even if it's empty.
350 if config
.ClientAuth
>= RequestClientCert
{
351 if certMsg
, ok
= msg
.(*certificateMsg
); !ok
{
352 return c
.sendAlert(alertHandshakeFailure
)
354 hs
.finishedHash
.Write(certMsg
.marshal())
356 if len(certMsg
.certificates
) == 0 {
357 // The client didn't actually send a certificate
358 switch config
.ClientAuth
{
359 case RequireAnyClientCert
, RequireAndVerifyClientCert
:
360 c
.sendAlert(alertBadCertificate
)
361 return errors
.New("tls: client didn't provide a certificate")
365 pub
, err
= hs
.processCertsFromClient(certMsg
.certificates
)
370 msg
, err
= c
.readHandshake()
376 // Get client key exchange
377 ckx
, ok
:= msg
.(*clientKeyExchangeMsg
)
379 return c
.sendAlert(alertUnexpectedMessage
)
381 hs
.finishedHash
.Write(ckx
.marshal())
383 // If we received a client cert in response to our certificate request message,
384 // the client will send us a certificateVerifyMsg immediately after the
385 // clientKeyExchangeMsg. This message is a digest of all preceding
386 // handshake-layer messages that is signed using the private key corresponding
387 // to the client's certificate. This allows us to verify that the client is in
388 // possession of the private key of the certificate.
389 if len(c
.peerCertificates
) > 0 {
390 msg
, err
= c
.readHandshake()
394 certVerify
, ok
:= msg
.(*certificateVerifyMsg
)
396 return c
.sendAlert(alertUnexpectedMessage
)
399 switch key
:= pub
.(type) {
400 case *ecdsa
.PublicKey
:
401 ecdsaSig
:= new(ecdsaSignature
)
402 if _
, err
= asn1
.Unmarshal(certVerify
.signature
, ecdsaSig
); err
!= nil {
405 if ecdsaSig
.R
.Sign() <= 0 || ecdsaSig
.S
.Sign() <= 0 {
406 err
= errors
.New("ECDSA signature contained zero or negative values")
409 digest
, _
, _
:= hs
.finishedHash
.hashForClientCertificate(signatureECDSA
)
410 if !ecdsa
.Verify(key
, digest
, ecdsaSig
.R
, ecdsaSig
.S
) {
411 err
= errors
.New("ECDSA verification failure")
415 digest
, hashFunc
, _
:= hs
.finishedHash
.hashForClientCertificate(signatureRSA
)
416 err
= rsa
.VerifyPKCS1v15(key
, hashFunc
, digest
, certVerify
.signature
)
419 c
.sendAlert(alertBadCertificate
)
420 return errors
.New("could not validate signature of connection nonces: " + err
.Error())
423 hs
.finishedHash
.Write(certVerify
.marshal())
426 preMasterSecret
, err
:= keyAgreement
.processClientKeyExchange(config
, hs
.cert
, ckx
, c
.vers
)
428 c
.sendAlert(alertHandshakeFailure
)
431 hs
.masterSecret
= masterFromPreMasterSecret(c
.vers
, preMasterSecret
, hs
.clientHello
.random
, hs
.hello
.random
)
436 func (hs
*serverHandshakeState
) establishKeys() error
{
439 clientMAC
, serverMAC
, clientKey
, serverKey
, clientIV
, serverIV
:=
440 keysFromMasterSecret(c
.vers
, hs
.masterSecret
, hs
.clientHello
.random
, hs
.hello
.random
, hs
.suite
.macLen
, hs
.suite
.keyLen
, hs
.suite
.ivLen
)
442 var clientCipher
, serverCipher
interface{}
443 var clientHash
, serverHash macFunction
445 if hs
.suite
.aead
== nil {
446 clientCipher
= hs
.suite
.cipher(clientKey
, clientIV
, true /* for reading */)
447 clientHash
= hs
.suite
.mac(c
.vers
, clientMAC
)
448 serverCipher
= hs
.suite
.cipher(serverKey
, serverIV
, false /* not for reading */)
449 serverHash
= hs
.suite
.mac(c
.vers
, serverMAC
)
451 clientCipher
= hs
.suite
.aead(clientKey
, clientIV
)
452 serverCipher
= hs
.suite
.aead(serverKey
, serverIV
)
455 c
.in
.prepareCipherSpec(c
.vers
, clientCipher
, clientHash
)
456 c
.out
.prepareCipherSpec(c
.vers
, serverCipher
, serverHash
)
461 func (hs
*serverHandshakeState
) readFinished() error
{
464 c
.readRecord(recordTypeChangeCipherSpec
)
465 if err
:= c
.error(); err
!= nil {
469 if hs
.hello
.nextProtoNeg
{
470 msg
, err
:= c
.readHandshake()
474 nextProto
, ok
:= msg
.(*nextProtoMsg
)
476 return c
.sendAlert(alertUnexpectedMessage
)
478 hs
.finishedHash
.Write(nextProto
.marshal())
479 c
.clientProtocol
= nextProto
.proto
482 msg
, err
:= c
.readHandshake()
486 clientFinished
, ok
:= msg
.(*finishedMsg
)
488 return c
.sendAlert(alertUnexpectedMessage
)
491 verify
:= hs
.finishedHash
.clientSum(hs
.masterSecret
)
492 if len(verify
) != len(clientFinished
.verifyData
) ||
493 subtle
.ConstantTimeCompare(verify
, clientFinished
.verifyData
) != 1 {
494 return c
.sendAlert(alertHandshakeFailure
)
497 hs
.finishedHash
.Write(clientFinished
.marshal())
501 func (hs
*serverHandshakeState
) sendSessionTicket() error
{
502 if !hs
.hello
.ticketSupported
{
507 m
:= new(newSessionTicketMsg
)
510 state
:= sessionState
{
512 cipherSuite
: hs
.suite
.id
,
513 masterSecret
: hs
.masterSecret
,
514 certificates
: hs
.certsFromClient
,
516 m
.ticket
, err
= c
.encryptTicket(&state
)
521 hs
.finishedHash
.Write(m
.marshal())
522 c
.writeRecord(recordTypeHandshake
, m
.marshal())
527 func (hs
*serverHandshakeState
) sendFinished() error
{
530 c
.writeRecord(recordTypeChangeCipherSpec
, []byte{1})
532 finished
:= new(finishedMsg
)
533 finished
.verifyData
= hs
.finishedHash
.serverSum(hs
.masterSecret
)
534 hs
.finishedHash
.Write(finished
.marshal())
535 c
.writeRecord(recordTypeHandshake
, finished
.marshal())
537 c
.cipherSuite
= hs
.suite
.id
542 // processCertsFromClient takes a chain of client certificates either from a
543 // Certificates message or from a sessionState and verifies them. It returns
544 // the public key of the leaf certificate.
545 func (hs
*serverHandshakeState
) processCertsFromClient(certificates
[][]byte) (crypto
.PublicKey
, error
) {
548 hs
.certsFromClient
= certificates
549 certs
:= make([]*x509
.Certificate
, len(certificates
))
551 for i
, asn1Data
:= range certificates
{
552 if certs
[i
], err
= x509
.ParseCertificate(asn1Data
); err
!= nil {
553 c
.sendAlert(alertBadCertificate
)
554 return nil, errors
.New("tls: failed to parse client certificate: " + err
.Error())
558 if c
.config
.ClientAuth
>= VerifyClientCertIfGiven
&& len(certs
) > 0 {
559 opts
:= x509
.VerifyOptions
{
560 Roots
: c
.config
.ClientCAs
,
561 CurrentTime
: c
.config
.time(),
562 Intermediates
: x509
.NewCertPool(),
563 KeyUsages
: []x509
.ExtKeyUsage
{x509
.ExtKeyUsageClientAuth
},
566 for _
, cert
:= range certs
[1:] {
567 opts
.Intermediates
.AddCert(cert
)
570 chains
, err
:= certs
[0].Verify(opts
)
572 c
.sendAlert(alertBadCertificate
)
573 return nil, errors
.New("tls: failed to verify client's certificate: " + err
.Error())
577 for _
, ku
:= range certs
[0].ExtKeyUsage
{
578 if ku
== x509
.ExtKeyUsageClientAuth
{
584 c
.sendAlert(alertHandshakeFailure
)
585 return nil, errors
.New("tls: client's certificate's extended key usage doesn't permit it to be used for client authentication")
588 c
.verifiedChains
= chains
592 var pub crypto
.PublicKey
593 switch key
:= certs
[0].PublicKey
.(type) {
594 case *ecdsa
.PublicKey
, *rsa
.PublicKey
:
597 return nil, c
.sendAlert(alertUnsupportedCertificate
)
599 c
.peerCertificates
= certs
606 // tryCipherSuite returns a cipherSuite with the given id if that cipher suite
607 // is acceptable to use.
608 func (c
*Conn
) tryCipherSuite(id
uint16, supportedCipherSuites
[]uint16, version
uint16, ellipticOk
, ecdsaOk
bool) *cipherSuite
{
609 for _
, supported
:= range supportedCipherSuites
{
611 var candidate
*cipherSuite
613 for _
, s
:= range cipherSuites
{
619 if candidate
== nil {
622 // Don't select a ciphersuite which we can't
623 // support for this client.
624 if (candidate
.flags
&suiteECDHE
!= 0) && !ellipticOk
{
627 if (candidate
.flags
&suiteECDSA
!= 0) != ecdsaOk
{
630 if version
< VersionTLS12
&& candidate
.flags
&suiteTLS12
!= 0 {