d78e767b52de4b3006232fda63cca15627af7628
[platform/framework/web/crosswalk.git] / src / third_party / boringssl / src / ssl / test / runner / handshake_client.go
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.
4
5 package main
6
7 import (
8         "bytes"
9         "crypto"
10         "crypto/ecdsa"
11         "crypto/elliptic"
12         "crypto/rsa"
13         "crypto/subtle"
14         "crypto/x509"
15         "encoding/asn1"
16         "errors"
17         "fmt"
18         "io"
19         "math/big"
20         "net"
21         "strconv"
22 )
23
24 type clientHandshakeState struct {
25         c            *Conn
26         serverHello  *serverHelloMsg
27         hello        *clientHelloMsg
28         suite        *cipherSuite
29         finishedHash finishedHash
30         masterSecret []byte
31         session      *ClientSessionState
32 }
33
34 func (c *Conn) clientHandshake() error {
35         if c.config == nil {
36                 c.config = defaultConfig()
37         }
38
39         if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
40                 return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
41         }
42
43         c.sendHandshakeSeq = 0
44         c.recvHandshakeSeq = 0
45
46         nextProtosLength := 0
47         for _, proto := range c.config.NextProtos {
48                 if l := len(proto); l == 0 || l > 255 {
49                         return errors.New("tls: invalid NextProtos value")
50                 } else {
51                         nextProtosLength += 1 + l
52                 }
53         }
54         if nextProtosLength > 0xffff {
55                 return errors.New("tls: NextProtos values too large")
56         }
57
58         hello := &clientHelloMsg{
59                 isDTLS:              c.isDTLS,
60                 vers:                c.config.maxVersion(),
61                 compressionMethods:  []uint8{compressionNone},
62                 random:              make([]byte, 32),
63                 ocspStapling:        true,
64                 serverName:          c.config.ServerName,
65                 supportedCurves:     c.config.curvePreferences(),
66                 supportedPoints:     []uint8{pointFormatUncompressed},
67                 nextProtoNeg:        len(c.config.NextProtos) > 0,
68                 secureRenegotiation: true,
69                 alpnProtocols:       c.config.NextProtos,
70                 duplicateExtension:  c.config.Bugs.DuplicateExtension,
71                 channelIDSupported:  c.config.ChannelID != nil,
72                 npnLast:             c.config.Bugs.SwapNPNAndALPN,
73         }
74
75         if c.config.Bugs.SendClientVersion != 0 {
76                 hello.vers = c.config.Bugs.SendClientVersion
77         }
78
79         possibleCipherSuites := c.config.cipherSuites()
80         hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
81
82 NextCipherSuite:
83         for _, suiteId := range possibleCipherSuites {
84                 for _, suite := range cipherSuites {
85                         if suite.id != suiteId {
86                                 continue
87                         }
88                         // Don't advertise TLS 1.2-only cipher suites unless
89                         // we're attempting TLS 1.2.
90                         if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
91                                 continue
92                         }
93                         // Don't advertise non-DTLS cipher suites on DTLS.
94                         if c.isDTLS && suite.flags&suiteNoDTLS != 0 {
95                                 continue
96                         }
97                         hello.cipherSuites = append(hello.cipherSuites, suiteId)
98                         continue NextCipherSuite
99                 }
100         }
101
102         if c.config.Bugs.SendFallbackSCSV {
103                 hello.cipherSuites = append(hello.cipherSuites, fallbackSCSV)
104         }
105
106         _, err := io.ReadFull(c.config.rand(), hello.random)
107         if err != nil {
108                 c.sendAlert(alertInternalError)
109                 return errors.New("tls: short read from Rand: " + err.Error())
110         }
111
112         if hello.vers >= VersionTLS12 {
113                 hello.signatureAndHashes = supportedSKXSignatureAlgorithms
114         }
115
116         var session *ClientSessionState
117         var cacheKey string
118         sessionCache := c.config.ClientSessionCache
119         if c.config.SessionTicketsDisabled {
120                 sessionCache = nil
121         }
122
123         if sessionCache != nil {
124                 hello.ticketSupported = true
125
126                 // Try to resume a previously negotiated TLS session, if
127                 // available.
128                 cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
129                 candidateSession, ok := sessionCache.Get(cacheKey)
130                 if ok {
131                         // Check that the ciphersuite/version used for the
132                         // previous session are still valid.
133                         cipherSuiteOk := false
134                         for _, id := range hello.cipherSuites {
135                                 if id == candidateSession.cipherSuite {
136                                         cipherSuiteOk = true
137                                         break
138                                 }
139                         }
140
141                         versOk := candidateSession.vers >= c.config.minVersion() &&
142                                 candidateSession.vers <= c.config.maxVersion()
143                         if versOk && cipherSuiteOk {
144                                 session = candidateSession
145                         }
146                 }
147         }
148
149         if session != nil {
150                 hello.sessionTicket = session.sessionTicket
151                 // A random session ID is used to detect when the
152                 // server accepted the ticket and is resuming a session
153                 // (see RFC 5077).
154                 hello.sessionId = make([]byte, 16)
155                 if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
156                         c.sendAlert(alertInternalError)
157                         return errors.New("tls: short read from Rand: " + err.Error())
158                 }
159         }
160
161         var helloBytes []byte
162         if c.config.Bugs.SendV2ClientHello {
163                 v2Hello := &v2ClientHelloMsg{
164                         vers:         hello.vers,
165                         cipherSuites: hello.cipherSuites,
166                         // No session resumption for V2ClientHello.
167                         sessionId: nil,
168                         challenge: hello.random,
169                 }
170                 helloBytes = v2Hello.marshal()
171                 c.writeV2Record(helloBytes)
172         } else {
173                 helloBytes = hello.marshal()
174                 c.writeRecord(recordTypeHandshake, helloBytes)
175         }
176
177         msg, err := c.readHandshake()
178         if err != nil {
179                 return err
180         }
181
182         if c.isDTLS {
183                 helloVerifyRequest, ok := msg.(*helloVerifyRequestMsg)
184                 if ok {
185                         if helloVerifyRequest.vers != VersionTLS10 {
186                                 // Per RFC 6347, the version field in
187                                 // HelloVerifyRequest SHOULD be always DTLS
188                                 // 1.0. Enforce this for testing purposes.
189                                 return errors.New("dtls: bad HelloVerifyRequest version")
190                         }
191
192                         hello.raw = nil
193                         hello.cookie = helloVerifyRequest.cookie
194                         helloBytes = hello.marshal()
195                         c.writeRecord(recordTypeHandshake, helloBytes)
196
197                         msg, err = c.readHandshake()
198                         if err != nil {
199                                 return err
200                         }
201                 }
202         }
203
204         serverHello, ok := msg.(*serverHelloMsg)
205         if !ok {
206                 c.sendAlert(alertUnexpectedMessage)
207                 return unexpectedMessageError(serverHello, msg)
208         }
209
210         c.vers, ok = c.config.mutualVersion(serverHello.vers)
211         if !ok {
212                 c.sendAlert(alertProtocolVersion)
213                 return fmt.Errorf("tls: server selected unsupported protocol version %x", serverHello.vers)
214         }
215         c.haveVers = true
216
217         suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
218         if suite == nil {
219                 c.sendAlert(alertHandshakeFailure)
220                 return fmt.Errorf("tls: server selected an unsupported cipher suite")
221         }
222
223         hs := &clientHandshakeState{
224                 c:            c,
225                 serverHello:  serverHello,
226                 hello:        hello,
227                 suite:        suite,
228                 finishedHash: newFinishedHash(c.vers, suite),
229                 session:      session,
230         }
231
232         hs.writeHash(helloBytes, hs.c.sendHandshakeSeq-1)
233         hs.writeServerHash(hs.serverHello.marshal())
234
235         if c.config.Bugs.EarlyChangeCipherSpec > 0 {
236                 hs.establishKeys()
237                 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
238         }
239
240         isResume, err := hs.processServerHello()
241         if err != nil {
242                 return err
243         }
244
245         if isResume {
246                 if c.config.Bugs.EarlyChangeCipherSpec == 0 {
247                         if err := hs.establishKeys(); err != nil {
248                                 return err
249                         }
250                 }
251                 if err := hs.readSessionTicket(); err != nil {
252                         return err
253                 }
254                 if err := hs.readFinished(); err != nil {
255                         return err
256                 }
257                 if err := hs.sendFinished(isResume); err != nil {
258                         return err
259                 }
260         } else {
261                 if err := hs.doFullHandshake(); err != nil {
262                         return err
263                 }
264                 if err := hs.establishKeys(); err != nil {
265                         return err
266                 }
267                 if err := hs.sendFinished(isResume); err != nil {
268                         return err
269                 }
270                 if err := hs.readSessionTicket(); err != nil {
271                         return err
272                 }
273                 if err := hs.readFinished(); err != nil {
274                         return err
275                 }
276         }
277
278         if sessionCache != nil && hs.session != nil && session != hs.session {
279                 sessionCache.Put(cacheKey, hs.session)
280         }
281
282         c.didResume = isResume
283         c.handshakeComplete = true
284         c.cipherSuite = suite.id
285         return nil
286 }
287
288 func (hs *clientHandshakeState) doFullHandshake() error {
289         c := hs.c
290
291         msg, err := c.readHandshake()
292         if err != nil {
293                 return err
294         }
295         certMsg, ok := msg.(*certificateMsg)
296         if !ok || len(certMsg.certificates) == 0 {
297                 c.sendAlert(alertUnexpectedMessage)
298                 return unexpectedMessageError(certMsg, msg)
299         }
300         hs.writeServerHash(certMsg.marshal())
301
302         certs := make([]*x509.Certificate, len(certMsg.certificates))
303         for i, asn1Data := range certMsg.certificates {
304                 cert, err := x509.ParseCertificate(asn1Data)
305                 if err != nil {
306                         c.sendAlert(alertBadCertificate)
307                         return errors.New("tls: failed to parse certificate from server: " + err.Error())
308                 }
309                 certs[i] = cert
310         }
311
312         if !c.config.InsecureSkipVerify {
313                 opts := x509.VerifyOptions{
314                         Roots:         c.config.RootCAs,
315                         CurrentTime:   c.config.time(),
316                         DNSName:       c.config.ServerName,
317                         Intermediates: x509.NewCertPool(),
318                 }
319
320                 for i, cert := range certs {
321                         if i == 0 {
322                                 continue
323                         }
324                         opts.Intermediates.AddCert(cert)
325                 }
326                 c.verifiedChains, err = certs[0].Verify(opts)
327                 if err != nil {
328                         c.sendAlert(alertBadCertificate)
329                         return err
330                 }
331         }
332
333         switch certs[0].PublicKey.(type) {
334         case *rsa.PublicKey, *ecdsa.PublicKey:
335                 break
336         default:
337                 c.sendAlert(alertUnsupportedCertificate)
338                 return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
339         }
340
341         c.peerCertificates = certs
342
343         if hs.serverHello.ocspStapling {
344                 msg, err = c.readHandshake()
345                 if err != nil {
346                         return err
347                 }
348                 cs, ok := msg.(*certificateStatusMsg)
349                 if !ok {
350                         c.sendAlert(alertUnexpectedMessage)
351                         return unexpectedMessageError(cs, msg)
352                 }
353                 hs.writeServerHash(cs.marshal())
354
355                 if cs.statusType == statusTypeOCSP {
356                         c.ocspResponse = cs.response
357                 }
358         }
359
360         msg, err = c.readHandshake()
361         if err != nil {
362                 return err
363         }
364
365         keyAgreement := hs.suite.ka(c.vers)
366
367         skx, ok := msg.(*serverKeyExchangeMsg)
368         if ok {
369                 hs.writeServerHash(skx.marshal())
370                 err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, certs[0], skx)
371                 if err != nil {
372                         c.sendAlert(alertUnexpectedMessage)
373                         return err
374                 }
375
376                 msg, err = c.readHandshake()
377                 if err != nil {
378                         return err
379                 }
380         }
381
382         var chainToSend *Certificate
383         var certRequested bool
384         certReq, ok := msg.(*certificateRequestMsg)
385         if ok {
386                 certRequested = true
387
388                 // RFC 4346 on the certificateAuthorities field:
389                 // A list of the distinguished names of acceptable certificate
390                 // authorities. These distinguished names may specify a desired
391                 // distinguished name for a root CA or for a subordinate CA;
392                 // thus, this message can be used to describe both known roots
393                 // and a desired authorization space. If the
394                 // certificate_authorities list is empty then the client MAY
395                 // send any certificate of the appropriate
396                 // ClientCertificateType, unless there is some external
397                 // arrangement to the contrary.
398
399                 hs.writeServerHash(certReq.marshal())
400
401                 var rsaAvail, ecdsaAvail bool
402                 for _, certType := range certReq.certificateTypes {
403                         switch certType {
404                         case CertTypeRSASign:
405                                 rsaAvail = true
406                         case CertTypeECDSASign:
407                                 ecdsaAvail = true
408                         }
409                 }
410
411                 // We need to search our list of client certs for one
412                 // where SignatureAlgorithm is RSA and the Issuer is in
413                 // certReq.certificateAuthorities
414         findCert:
415                 for i, chain := range c.config.Certificates {
416                         if !rsaAvail && !ecdsaAvail {
417                                 continue
418                         }
419
420                         for j, cert := range chain.Certificate {
421                                 x509Cert := chain.Leaf
422                                 // parse the certificate if this isn't the leaf
423                                 // node, or if chain.Leaf was nil
424                                 if j != 0 || x509Cert == nil {
425                                         if x509Cert, err = x509.ParseCertificate(cert); err != nil {
426                                                 c.sendAlert(alertInternalError)
427                                                 return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
428                                         }
429                                 }
430
431                                 switch {
432                                 case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
433                                 case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
434                                 default:
435                                         continue findCert
436                                 }
437
438                                 if len(certReq.certificateAuthorities) == 0 {
439                                         // they gave us an empty list, so just take the
440                                         // first RSA cert from c.config.Certificates
441                                         chainToSend = &chain
442                                         break findCert
443                                 }
444
445                                 for _, ca := range certReq.certificateAuthorities {
446                                         if bytes.Equal(x509Cert.RawIssuer, ca) {
447                                                 chainToSend = &chain
448                                                 break findCert
449                                         }
450                                 }
451                         }
452                 }
453
454                 msg, err = c.readHandshake()
455                 if err != nil {
456                         return err
457                 }
458         }
459
460         shd, ok := msg.(*serverHelloDoneMsg)
461         if !ok {
462                 c.sendAlert(alertUnexpectedMessage)
463                 return unexpectedMessageError(shd, msg)
464         }
465         hs.writeServerHash(shd.marshal())
466
467         // If the server requested a certificate then we have to send a
468         // Certificate message, even if it's empty because we don't have a
469         // certificate to send.
470         if certRequested {
471                 certMsg = new(certificateMsg)
472                 if chainToSend != nil {
473                         certMsg.certificates = chainToSend.Certificate
474                 }
475                 hs.writeClientHash(certMsg.marshal())
476                 c.writeRecord(recordTypeHandshake, certMsg.marshal())
477         }
478
479         preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, certs[0])
480         if err != nil {
481                 c.sendAlert(alertInternalError)
482                 return err
483         }
484         if ckx != nil {
485                 if c.config.Bugs.EarlyChangeCipherSpec < 2 {
486                         hs.writeClientHash(ckx.marshal())
487                 }
488                 c.writeRecord(recordTypeHandshake, ckx.marshal())
489         }
490
491         hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
492
493         if chainToSend != nil {
494                 var signed []byte
495                 certVerify := &certificateVerifyMsg{
496                         hasSignatureAndHash: c.vers >= VersionTLS12,
497                 }
498
499                 switch key := c.config.Certificates[0].PrivateKey.(type) {
500                 case *ecdsa.PrivateKey:
501                         certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, signatureECDSA)
502                         if err != nil {
503                                 break
504                         }
505                         var digest []byte
506                         digest, _, err = hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret)
507                         if err != nil {
508                                 break
509                         }
510                         var r, s *big.Int
511                         r, s, err = ecdsa.Sign(c.config.rand(), key, digest)
512                         if err == nil {
513                                 signed, err = asn1.Marshal(ecdsaSignature{r, s})
514                         }
515                 case *rsa.PrivateKey:
516                         certVerify.signatureAndHash, err = hs.finishedHash.selectClientCertSignatureAlgorithm(certReq.signatureAndHashes, signatureRSA)
517                         if err != nil {
518                                 break
519                         }
520                         var digest []byte
521                         var hashFunc crypto.Hash
522                         digest, hashFunc, err = hs.finishedHash.hashForClientCertificate(certVerify.signatureAndHash, hs.masterSecret)
523                         if err != nil {
524                                 break
525                         }
526                         signed, err = rsa.SignPKCS1v15(c.config.rand(), key, hashFunc, digest)
527                 default:
528                         err = errors.New("unknown private key type")
529                 }
530                 if err != nil {
531                         c.sendAlert(alertInternalError)
532                         return errors.New("tls: failed to sign handshake with client certificate: " + err.Error())
533                 }
534                 certVerify.signature = signed
535
536                 hs.writeClientHash(certVerify.marshal())
537                 c.writeRecord(recordTypeHandshake, certVerify.marshal())
538         }
539
540         hs.finishedHash.discardHandshakeBuffer()
541
542         return nil
543 }
544
545 func (hs *clientHandshakeState) establishKeys() error {
546         c := hs.c
547
548         clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
549                 keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
550         var clientCipher, serverCipher interface{}
551         var clientHash, serverHash macFunction
552         if hs.suite.cipher != nil {
553                 clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
554                 clientHash = hs.suite.mac(c.vers, clientMAC)
555                 serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
556                 serverHash = hs.suite.mac(c.vers, serverMAC)
557         } else {
558                 clientCipher = hs.suite.aead(clientKey, clientIV)
559                 serverCipher = hs.suite.aead(serverKey, serverIV)
560         }
561
562         c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
563         c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
564         return nil
565 }
566
567 func (hs *clientHandshakeState) serverResumedSession() bool {
568         // If the server responded with the same sessionId then it means the
569         // sessionTicket is being used to resume a TLS session.
570         return hs.session != nil && hs.hello.sessionId != nil &&
571                 bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
572 }
573
574 func (hs *clientHandshakeState) processServerHello() (bool, error) {
575         c := hs.c
576
577         if hs.serverHello.compressionMethod != compressionNone {
578                 c.sendAlert(alertUnexpectedMessage)
579                 return false, errors.New("tls: server selected unsupported compression format")
580         }
581
582         clientDidNPN := hs.hello.nextProtoNeg
583         clientDidALPN := len(hs.hello.alpnProtocols) > 0
584         serverHasNPN := hs.serverHello.nextProtoNeg
585         serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
586
587         if !clientDidNPN && serverHasNPN {
588                 c.sendAlert(alertHandshakeFailure)
589                 return false, errors.New("server advertised unrequested NPN extension")
590         }
591
592         if !clientDidALPN && serverHasALPN {
593                 c.sendAlert(alertHandshakeFailure)
594                 return false, errors.New("server advertised unrequested ALPN extension")
595         }
596
597         if serverHasNPN && serverHasALPN {
598                 c.sendAlert(alertHandshakeFailure)
599                 return false, errors.New("server advertised both NPN and ALPN extensions")
600         }
601
602         if serverHasALPN {
603                 c.clientProtocol = hs.serverHello.alpnProtocol
604                 c.clientProtocolFallback = false
605                 c.usedALPN = true
606         }
607
608         if !hs.hello.channelIDSupported && hs.serverHello.channelIDRequested {
609                 c.sendAlert(alertHandshakeFailure)
610                 return false, errors.New("server advertised unrequested Channel ID extension")
611         }
612
613         if hs.serverResumedSession() {
614                 // Restore masterSecret and peerCerts from previous state
615                 hs.masterSecret = hs.session.masterSecret
616                 c.peerCertificates = hs.session.serverCertificates
617                 hs.finishedHash.discardHandshakeBuffer()
618                 return true, nil
619         }
620         return false, nil
621 }
622
623 func (hs *clientHandshakeState) readFinished() error {
624         c := hs.c
625
626         c.readRecord(recordTypeChangeCipherSpec)
627         if err := c.in.error(); err != nil {
628                 return err
629         }
630
631         msg, err := c.readHandshake()
632         if err != nil {
633                 return err
634         }
635         serverFinished, ok := msg.(*finishedMsg)
636         if !ok {
637                 c.sendAlert(alertUnexpectedMessage)
638                 return unexpectedMessageError(serverFinished, msg)
639         }
640
641         if c.config.Bugs.EarlyChangeCipherSpec == 0 {
642                 verify := hs.finishedHash.serverSum(hs.masterSecret)
643                 if len(verify) != len(serverFinished.verifyData) ||
644                         subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
645                         c.sendAlert(alertHandshakeFailure)
646                         return errors.New("tls: server's Finished message was incorrect")
647                 }
648         }
649         hs.writeServerHash(serverFinished.marshal())
650         return nil
651 }
652
653 func (hs *clientHandshakeState) readSessionTicket() error {
654         if !hs.serverHello.ticketSupported {
655                 return nil
656         }
657
658         c := hs.c
659         msg, err := c.readHandshake()
660         if err != nil {
661                 return err
662         }
663         sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
664         if !ok {
665                 c.sendAlert(alertUnexpectedMessage)
666                 return unexpectedMessageError(sessionTicketMsg, msg)
667         }
668
669         hs.session = &ClientSessionState{
670                 sessionTicket:      sessionTicketMsg.ticket,
671                 vers:               c.vers,
672                 cipherSuite:        hs.suite.id,
673                 masterSecret:       hs.masterSecret,
674                 handshakeHash:      hs.finishedHash.server.Sum(nil),
675                 serverCertificates: c.peerCertificates,
676         }
677
678         hs.writeServerHash(sessionTicketMsg.marshal())
679
680         return nil
681 }
682
683 func (hs *clientHandshakeState) sendFinished(isResume bool) error {
684         c := hs.c
685
686         var postCCSBytes []byte
687         seqno := hs.c.sendHandshakeSeq
688         if hs.serverHello.nextProtoNeg {
689                 nextProto := new(nextProtoMsg)
690                 proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
691                 nextProto.proto = proto
692                 c.clientProtocol = proto
693                 c.clientProtocolFallback = fallback
694
695                 nextProtoBytes := nextProto.marshal()
696                 hs.writeHash(nextProtoBytes, seqno)
697                 seqno++
698                 postCCSBytes = append(postCCSBytes, nextProtoBytes...)
699         }
700
701         if hs.serverHello.channelIDRequested {
702                 encryptedExtensions := new(encryptedExtensionsMsg)
703                 if c.config.ChannelID.Curve != elliptic.P256() {
704                         return fmt.Errorf("tls: Channel ID is not on P-256.")
705                 }
706                 var resumeHash []byte
707                 if isResume {
708                         resumeHash = hs.session.handshakeHash
709                 }
710                 r, s, err := ecdsa.Sign(c.config.rand(), c.config.ChannelID, hs.finishedHash.hashForChannelID(resumeHash))
711                 if err != nil {
712                         return err
713                 }
714                 channelID := make([]byte, 128)
715                 writeIntPadded(channelID[0:32], c.config.ChannelID.X)
716                 writeIntPadded(channelID[32:64], c.config.ChannelID.Y)
717                 writeIntPadded(channelID[64:96], r)
718                 writeIntPadded(channelID[96:128], s)
719                 encryptedExtensions.channelID = channelID
720
721                 c.channelID = &c.config.ChannelID.PublicKey
722
723                 encryptedExtensionsBytes := encryptedExtensions.marshal()
724                 hs.writeHash(encryptedExtensionsBytes, seqno)
725                 seqno++
726                 postCCSBytes = append(postCCSBytes, encryptedExtensionsBytes...)
727         }
728
729         finished := new(finishedMsg)
730         if c.config.Bugs.EarlyChangeCipherSpec == 2 {
731                 finished.verifyData = hs.finishedHash.clientSum(nil)
732         } else {
733                 finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
734         }
735         finishedBytes := finished.marshal()
736         hs.writeHash(finishedBytes, seqno)
737         postCCSBytes = append(postCCSBytes, finishedBytes...)
738
739         if c.config.Bugs.FragmentAcrossChangeCipherSpec {
740                 c.writeRecord(recordTypeHandshake, postCCSBytes[:5])
741                 postCCSBytes = postCCSBytes[5:]
742         }
743
744         if !c.config.Bugs.SkipChangeCipherSpec &&
745                 c.config.Bugs.EarlyChangeCipherSpec == 0 {
746                 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
747         }
748
749         c.writeRecord(recordTypeHandshake, postCCSBytes)
750         return nil
751 }
752
753 func (hs *clientHandshakeState) writeClientHash(msg []byte) {
754         // writeClientHash is called before writeRecord.
755         hs.writeHash(msg, hs.c.sendHandshakeSeq)
756 }
757
758 func (hs *clientHandshakeState) writeServerHash(msg []byte) {
759         // writeServerHash is called after readHandshake.
760         hs.writeHash(msg, hs.c.recvHandshakeSeq-1)
761 }
762
763 func (hs *clientHandshakeState) writeHash(msg []byte, seqno uint16) {
764         if hs.c.isDTLS {
765                 // This is somewhat hacky. DTLS hashes a slightly different format.
766                 // First, the TLS header.
767                 hs.finishedHash.Write(msg[:4])
768                 // Then the sequence number and reassembled fragment offset (always 0).
769                 hs.finishedHash.Write([]byte{byte(seqno >> 8), byte(seqno), 0, 0, 0})
770                 // Then the reassembled fragment (always equal to the message length).
771                 hs.finishedHash.Write(msg[1:4])
772                 // And then the message body.
773                 hs.finishedHash.Write(msg[4:])
774         } else {
775                 hs.finishedHash.Write(msg)
776         }
777 }
778
779 // clientSessionCacheKey returns a key used to cache sessionTickets that could
780 // be used to resume previously negotiated TLS sessions with a server.
781 func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
782         if len(config.ServerName) > 0 {
783                 return config.ServerName
784         }
785         return serverAddr.String()
786 }
787
788 // mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol
789 // given list of possible protocols and a list of the preference order. The
790 // first list must not be empty. It returns the resulting protocol and flag
791 // indicating if the fallback case was reached.
792 func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
793         for _, s := range preferenceProtos {
794                 for _, c := range protos {
795                         if s == c {
796                                 return s, false
797                         }
798                 }
799         }
800
801         return protos[0], true
802 }
803
804 // writeIntPadded writes x into b, padded up with leading zeros as
805 // needed.
806 func writeIntPadded(b []byte, x *big.Int) {
807         for i := range b {
808                 b[i] = 0
809         }
810         xb := x.Bytes()
811         copy(b[len(b)-len(xb):], xb)
812 }