blob: 30105a5b3966c7f55d7a8016b017775658672c34 [file] [log] [blame]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001// 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
Kenny Roote99801b2015-11-06 15:31:15 -08005package runner
Adam Langleyd9e397b2015-01-22 14:27:53 -08006
7import (
8 "bytes"
David Benjaminc895d6b2016-08-11 13:26:41 -04009 "crypto"
Adam Langleyd9e397b2015-01-22 14:27:53 -080010 "crypto/ecdsa"
11 "crypto/elliptic"
12 "crypto/rsa"
13 "crypto/subtle"
14 "crypto/x509"
Adam Langleyd9e397b2015-01-22 14:27:53 -080015 "errors"
16 "fmt"
17 "io"
18 "math/big"
19 "net"
David Benjaminc895d6b2016-08-11 13:26:41 -040020 "time"
Robert Sloan572a4e22017-04-17 10:52:19 -070021
22 "./ed25519"
Adam Langleyd9e397b2015-01-22 14:27:53 -080023)
24
25type clientHandshakeState struct {
Adam Langleye9ada862015-05-11 17:20:37 -070026 c *Conn
27 serverHello *serverHelloMsg
28 hello *clientHelloMsg
29 suite *cipherSuite
30 finishedHash finishedHash
David Benjaminc895d6b2016-08-11 13:26:41 -040031 keyShares map[CurveID]ecdhCurve
Adam Langleye9ada862015-05-11 17:20:37 -070032 masterSecret []byte
33 session *ClientSessionState
34 finishedBytes []byte
Adam Langleyd9e397b2015-01-22 14:27:53 -080035}
36
Robert Sloanf6200e72017-07-10 08:09:18 -070037func mapClientHelloVersion(vers uint16, isDTLS bool) uint16 {
38 if !isDTLS {
39 return vers
40 }
41
42 switch vers {
43 case VersionTLS12:
44 return VersionDTLS12
45 case VersionTLS10:
46 return VersionDTLS10
47 }
48
49 panic("Unknown ClientHello version.")
50}
51
Adam Langleyd9e397b2015-01-22 14:27:53 -080052func (c *Conn) clientHandshake() error {
53 if c.config == nil {
54 c.config = defaultConfig()
55 }
56
57 if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
58 return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
59 }
60
61 c.sendHandshakeSeq = 0
62 c.recvHandshakeSeq = 0
63
64 nextProtosLength := 0
65 for _, proto := range c.config.NextProtos {
Kenny Rootb8494592015-09-25 02:29:14 +000066 if l := len(proto); l > 255 {
Adam Langleyd9e397b2015-01-22 14:27:53 -080067 return errors.New("tls: invalid NextProtos value")
68 } else {
69 nextProtosLength += 1 + l
70 }
71 }
72 if nextProtosLength > 0xffff {
73 return errors.New("tls: NextProtos values too large")
74 }
75
Steven Valdezbb1ceac2016-10-07 10:34:51 -040076 minVersion := c.config.minVersion(c.isDTLS)
77 maxVersion := c.config.maxVersion(c.isDTLS)
Adam Langleyd9e397b2015-01-22 14:27:53 -080078 hello := &clientHelloMsg{
79 isDTLS: c.isDTLS,
Adam Langleyd9e397b2015-01-22 14:27:53 -080080 compressionMethods: []uint8{compressionNone},
81 random: make([]byte, 32),
Steven Valdez909b19f2016-11-21 15:35:44 -050082 ocspStapling: !c.config.Bugs.NoOCSPStapling,
83 sctListSupported: !c.config.Bugs.NoSignedCertificateTimestamps,
Adam Langleyd9e397b2015-01-22 14:27:53 -080084 serverName: c.config.ServerName,
85 supportedCurves: c.config.curvePreferences(),
86 supportedPoints: []uint8{pointFormatUncompressed},
87 nextProtoNeg: len(c.config.NextProtos) > 0,
88 secureRenegotiation: []byte{},
89 alpnProtocols: c.config.NextProtos,
90 duplicateExtension: c.config.Bugs.DuplicateExtension,
91 channelIDSupported: c.config.ChannelID != nil,
Steven Valdez909b19f2016-11-21 15:35:44 -050092 npnAfterAlpn: c.config.Bugs.SwapNPNAndALPN,
Steven Valdezbb1ceac2016-10-07 10:34:51 -040093 extendedMasterSecret: maxVersion >= VersionTLS10,
Adam Langleyd9e397b2015-01-22 14:27:53 -080094 srtpProtectionProfiles: c.config.SRTPProtectionProfiles,
95 srtpMasterKeyIdentifier: c.config.Bugs.SRTPMasterKeyIdentifer,
Kenny Rootb8494592015-09-25 02:29:14 +000096 customExtension: c.config.Bugs.CustomExtension,
Steven Valdez909b19f2016-11-21 15:35:44 -050097 pskBinderFirst: c.config.Bugs.PSKBinderFirst,
Robert Sloana12bf462017-07-17 07:08:26 -070098 omitExtensions: c.config.Bugs.OmitExtensions,
99 emptyExtensions: c.config.Bugs.EmptyExtensions,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800100 }
101
Robert Sloanf6200e72017-07-10 08:09:18 -0700102 if maxVersion >= VersionTLS13 {
103 hello.vers = mapClientHelloVersion(VersionTLS12, c.isDTLS)
104 if !c.config.Bugs.OmitSupportedVersions {
105 hello.supportedVersions = c.config.supportedVersions(c.isDTLS)
106 }
Robert Sloana12bf462017-07-17 07:08:26 -0700107 hello.pskKEModes = []byte{pskDHEKEMode}
Robert Sloanf6200e72017-07-10 08:09:18 -0700108 } else {
109 hello.vers = mapClientHelloVersion(maxVersion, c.isDTLS)
110 }
111
112 if c.config.Bugs.SendClientVersion != 0 {
113 hello.vers = c.config.Bugs.SendClientVersion
114 }
115
116 if len(c.config.Bugs.SendSupportedVersions) > 0 {
117 hello.supportedVersions = c.config.Bugs.SendSupportedVersions
118 }
119
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400120 disableEMS := c.config.Bugs.NoExtendedMasterSecret
121 if c.cipherSuite != nil {
122 disableEMS = c.config.Bugs.NoExtendedMasterSecretOnRenegotiation
Adam Langleyd9e397b2015-01-22 14:27:53 -0800123 }
124
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400125 if disableEMS {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800126 hello.extendedMasterSecret = false
127 }
128
Adam Langleye9ada862015-05-11 17:20:37 -0700129 if c.config.Bugs.NoSupportedCurves {
130 hello.supportedCurves = nil
131 }
132
Steven Valdez909b19f2016-11-21 15:35:44 -0500133 if len(c.config.Bugs.SendPSKKeyExchangeModes) != 0 {
134 hello.pskKEModes = c.config.Bugs.SendPSKKeyExchangeModes
135 }
136
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400137 if c.config.Bugs.SendCompressionMethods != nil {
138 hello.compressionMethods = c.config.Bugs.SendCompressionMethods
139 }
140
Robert Sloan69939df2017-01-09 10:53:07 -0800141 if c.config.Bugs.SendSupportedPointFormats != nil {
142 hello.supportedPoints = c.config.Bugs.SendSupportedPointFormats
143 }
144
Adam Langleyd9e397b2015-01-22 14:27:53 -0800145 if len(c.clientVerify) > 0 && !c.config.Bugs.EmptyRenegotiationInfo {
146 if c.config.Bugs.BadRenegotiationInfo {
147 hello.secureRenegotiation = append(hello.secureRenegotiation, c.clientVerify...)
148 hello.secureRenegotiation[0] ^= 0x80
149 } else {
150 hello.secureRenegotiation = c.clientVerify
151 }
152 }
153
Adam Langley4139edb2016-01-13 15:00:54 -0800154 if c.noRenegotiationInfo() {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800155 hello.secureRenegotiation = nil
156 }
157
David Benjaminc895d6b2016-08-11 13:26:41 -0400158 var keyShares map[CurveID]ecdhCurve
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400159 if maxVersion >= VersionTLS13 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400160 keyShares = make(map[CurveID]ecdhCurve)
161 hello.hasKeyShares = true
David Benjamin7c0d06c2016-08-11 13:26:41 -0400162 hello.trailingKeyShareData = c.config.Bugs.TrailingKeyShareData
David Benjaminc895d6b2016-08-11 13:26:41 -0400163 curvesToSend := c.config.defaultCurves()
164 for _, curveID := range hello.supportedCurves {
165 if !curvesToSend[curveID] {
166 continue
167 }
168 curve, ok := curveForCurveID(curveID)
169 if !ok {
170 continue
171 }
172 publicKey, err := curve.offer(c.config.rand())
173 if err != nil {
174 return err
175 }
176
177 if c.config.Bugs.SendCurve != 0 {
178 curveID = c.config.Bugs.SendCurve
179 }
180 if c.config.Bugs.InvalidECDHPoint {
181 publicKey[0] ^= 0xff
182 }
183
184 hello.keyShares = append(hello.keyShares, keyShareEntry{
185 group: curveID,
186 keyExchange: publicKey,
187 })
188 keyShares[curveID] = curve
189
190 if c.config.Bugs.DuplicateKeyShares {
191 hello.keyShares = append(hello.keyShares, hello.keyShares[len(hello.keyShares)-1])
192 }
193 }
194
195 if c.config.Bugs.MissingKeyShare {
196 hello.hasKeyShares = false
197 }
198 }
199
Adam Langleyd9e397b2015-01-22 14:27:53 -0800200 possibleCipherSuites := c.config.cipherSuites()
201 hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
202
203NextCipherSuite:
204 for _, suiteId := range possibleCipherSuites {
205 for _, suite := range cipherSuites {
206 if suite.id != suiteId {
207 continue
208 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400209 // Don't advertise TLS 1.2-only cipher suites unless
210 // we're attempting TLS 1.2.
211 if maxVersion < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
212 continue
213 }
214 // Don't advertise non-DTLS cipher suites in DTLS.
215 if c.isDTLS && suite.flags&suiteNoDTLS != 0 {
216 continue
Adam Langleyd9e397b2015-01-22 14:27:53 -0800217 }
218 hello.cipherSuites = append(hello.cipherSuites, suiteId)
219 continue NextCipherSuite
220 }
221 }
222
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400223 if c.config.Bugs.AdvertiseAllConfiguredCiphers {
224 hello.cipherSuites = possibleCipherSuites
225 }
226
Kenny Rootb8494592015-09-25 02:29:14 +0000227 if c.config.Bugs.SendRenegotiationSCSV {
228 hello.cipherSuites = append(hello.cipherSuites, renegotiationSCSV)
229 }
230
Adam Langleyd9e397b2015-01-22 14:27:53 -0800231 if c.config.Bugs.SendFallbackSCSV {
232 hello.cipherSuites = append(hello.cipherSuites, fallbackSCSV)
233 }
234
235 _, err := io.ReadFull(c.config.rand(), hello.random)
236 if err != nil {
237 c.sendAlert(alertInternalError)
238 return errors.New("tls: short read from Rand: " + err.Error())
239 }
240
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400241 if maxVersion >= VersionTLS12 && !c.config.Bugs.NoSignatureAlgorithms {
David Benjaminc895d6b2016-08-11 13:26:41 -0400242 hello.signatureAlgorithms = c.config.verifySignatureAlgorithms()
Adam Langleyd9e397b2015-01-22 14:27:53 -0800243 }
244
245 var session *ClientSessionState
246 var cacheKey string
247 sessionCache := c.config.ClientSessionCache
248
249 if sessionCache != nil {
250 hello.ticketSupported = !c.config.SessionTicketsDisabled
251
252 // Try to resume a previously negotiated TLS session, if
253 // available.
254 cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
David Benjaminc895d6b2016-08-11 13:26:41 -0400255 // TODO(nharper): Support storing more than one session
256 // ticket for TLS 1.3.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800257 candidateSession, ok := sessionCache.Get(cacheKey)
258 if ok {
259 ticketOk := !c.config.SessionTicketsDisabled || candidateSession.sessionTicket == nil
260
261 // Check that the ciphersuite/version used for the
262 // previous session are still valid.
263 cipherSuiteOk := false
Steven Valdez909b19f2016-11-21 15:35:44 -0500264 if candidateSession.vers <= VersionTLS12 {
265 for _, id := range hello.cipherSuites {
266 if id == candidateSession.cipherSuite {
267 cipherSuiteOk = true
268 break
269 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800270 }
Steven Valdez909b19f2016-11-21 15:35:44 -0500271 } else {
272 // TLS 1.3 allows the cipher to change on
273 // resumption.
274 cipherSuiteOk = true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800275 }
276
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400277 versOk := candidateSession.vers >= minVersion &&
278 candidateSession.vers <= maxVersion
Adam Langleyd9e397b2015-01-22 14:27:53 -0800279 if ticketOk && versOk && cipherSuiteOk {
280 session = candidateSession
281 }
282 }
283 }
284
Steven Valdez909b19f2016-11-21 15:35:44 -0500285 var pskCipherSuite *cipherSuite
David Benjaminc895d6b2016-08-11 13:26:41 -0400286 if session != nil && c.config.time().Before(session.ticketExpiration) {
287 ticket := session.sessionTicket
Steven Valdez909b19f2016-11-21 15:35:44 -0500288 if c.config.Bugs.FilterTicket != nil && len(ticket) > 0 {
289 // Copy the ticket so FilterTicket may act in-place.
David Benjaminc895d6b2016-08-11 13:26:41 -0400290 ticket = make([]byte, len(session.sessionTicket))
291 copy(ticket, session.sessionTicket)
Steven Valdez909b19f2016-11-21 15:35:44 -0500292
293 ticket, err = c.config.Bugs.FilterTicket(ticket)
294 if err != nil {
295 return err
David Benjaminc895d6b2016-08-11 13:26:41 -0400296 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400297 }
298
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400299 if session.vers >= VersionTLS13 || c.config.Bugs.SendBothTickets {
Steven Valdez909b19f2016-11-21 15:35:44 -0500300 pskCipherSuite = cipherSuiteFromID(session.cipherSuite)
301 if pskCipherSuite == nil {
302 return errors.New("tls: client session cache has invalid cipher suite")
303 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400304 // TODO(nharper): Support sending more
305 // than one PSK identity.
Steven Valdez909b19f2016-11-21 15:35:44 -0500306 ticketAge := uint32(c.config.time().Sub(session.ticketCreationTime) / time.Millisecond)
Robert Sloan1c9db532017-03-13 08:03:59 -0700307 if c.config.Bugs.SendTicketAge != 0 {
308 ticketAge = uint32(c.config.Bugs.SendTicketAge / time.Millisecond)
309 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400310 psk := pskIdentity{
Steven Valdez909b19f2016-11-21 15:35:44 -0500311 ticket: ticket,
312 obfuscatedTicketAge: session.ticketAgeAdd + ticketAge,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800313 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400314 hello.pskIdentities = []pskIdentity{psk}
Steven Valdez909b19f2016-11-21 15:35:44 -0500315
316 if c.config.Bugs.ExtraPSKIdentity {
317 hello.pskIdentities = append(hello.pskIdentities, psk)
318 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800319 }
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400320
321 if session.vers < VersionTLS13 || c.config.Bugs.SendBothTickets {
322 if ticket != nil {
323 hello.sessionTicket = ticket
324 // A random session ID is used to detect when the
325 // server accepted the ticket and is resuming a session
326 // (see RFC 5077).
327 sessionIdLen := 16
Robert Sloan5d625782017-02-13 09:55:39 -0800328 if c.config.Bugs.TicketSessionIDLength != 0 {
329 sessionIdLen = c.config.Bugs.TicketSessionIDLength
330 }
331 if c.config.Bugs.EmptyTicketSessionID {
332 sessionIdLen = 0
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400333 }
334 hello.sessionId = make([]byte, sessionIdLen)
335 if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
336 c.sendAlert(alertInternalError)
337 return errors.New("tls: short read from Rand: " + err.Error())
338 }
339 } else {
340 hello.sessionId = session.sessionId
341 }
342 }
343 }
344
Steven Valdez909b19f2016-11-21 15:35:44 -0500345 if c.config.Bugs.SendCipherSuites != nil {
346 hello.cipherSuites = c.config.Bugs.SendCipherSuites
347 }
348
Robert Sloan47f43ed2017-02-06 14:55:15 -0800349 var sendEarlyData bool
Robert Sloan6d0d00e2017-03-27 07:13:07 -0700350 if len(hello.pskIdentities) > 0 && c.config.Bugs.SendEarlyData != nil {
David Benjamin1b249672016-12-06 18:25:50 -0500351 hello.hasEarlyData = true
Robert Sloan47f43ed2017-02-06 14:55:15 -0800352 sendEarlyData = true
353 }
354 if c.config.Bugs.SendFakeEarlyDataLength > 0 {
355 hello.hasEarlyData = true
356 }
357 if c.config.Bugs.OmitEarlyDataExtension {
358 hello.hasEarlyData = false
David Benjamin1b249672016-12-06 18:25:50 -0500359 }
Robert Sloanb6d070c2017-07-24 08:40:01 -0700360 if c.config.Bugs.SendClientHelloSessionID != nil {
361 hello.sessionId = c.config.Bugs.SendClientHelloSessionID
362 }
David Benjamin1b249672016-12-06 18:25:50 -0500363
Adam Langleyd9e397b2015-01-22 14:27:53 -0800364 var helloBytes []byte
365 if c.config.Bugs.SendV2ClientHello {
366 // Test that the peer left-pads random.
367 hello.random[0] = 0
368 v2Hello := &v2ClientHelloMsg{
369 vers: hello.vers,
370 cipherSuites: hello.cipherSuites,
371 // No session resumption for V2ClientHello.
372 sessionId: nil,
373 challenge: hello.random[1:],
374 }
375 helloBytes = v2Hello.marshal()
376 c.writeV2Record(helloBytes)
377 } else {
Steven Valdez909b19f2016-11-21 15:35:44 -0500378 if len(hello.pskIdentities) > 0 {
379 generatePSKBinders(hello, pskCipherSuite, session.masterSecret, []byte{}, c.config)
380 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800381 helloBytes = hello.marshal()
Steven Valdez909b19f2016-11-21 15:35:44 -0500382
David Benjaminc895d6b2016-08-11 13:26:41 -0400383 if c.config.Bugs.PartialClientFinishedWithClientHello {
384 // Include one byte of Finished. We can compute it
385 // without completing the handshake. This assumes we
386 // negotiate TLS 1.3 with no HelloRetryRequest or
387 // CertificateRequest.
388 toWrite := make([]byte, 0, len(helloBytes)+1)
389 toWrite = append(toWrite, helloBytes...)
390 toWrite = append(toWrite, typeFinished)
391 c.writeRecord(recordTypeHandshake, toWrite)
392 } else {
393 c.writeRecord(recordTypeHandshake, helloBytes)
394 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800395 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400396 c.flushHandshake()
Adam Langleyd9e397b2015-01-22 14:27:53 -0800397
Adam Langleye9ada862015-05-11 17:20:37 -0700398 if err := c.simulatePacketLoss(nil); err != nil {
399 return err
400 }
David Benjamin1b249672016-12-06 18:25:50 -0500401 if c.config.Bugs.SendEarlyAlert {
402 c.sendAlert(alertHandshakeFailure)
403 }
Robert Sloan47f43ed2017-02-06 14:55:15 -0800404 if c.config.Bugs.SendFakeEarlyDataLength > 0 {
405 c.sendFakeEarlyData(c.config.Bugs.SendFakeEarlyDataLength)
David Benjamin1b249672016-12-06 18:25:50 -0500406 }
Robert Sloan47f43ed2017-02-06 14:55:15 -0800407
408 // Derive early write keys and set Conn state to allow early writes.
409 if sendEarlyData {
410 finishedHash := newFinishedHash(session.vers, pskCipherSuite)
411 finishedHash.addEntropy(session.masterSecret)
412 finishedHash.Write(helloBytes)
413 earlyTrafficSecret := finishedHash.deriveSecret(earlyTrafficLabel)
Robert Sloan29c1d2c2017-10-30 14:10:28 -0700414 c.useOutTrafficSecret(session.wireVersion, pskCipherSuite, earlyTrafficSecret)
Robert Sloan47f43ed2017-02-06 14:55:15 -0800415 for _, earlyData := range c.config.Bugs.SendEarlyData {
416 if _, err := c.writeRecord(recordTypeApplicationData, earlyData); err != nil {
417 return err
418 }
419 }
420 }
421
Adam Langleyd9e397b2015-01-22 14:27:53 -0800422 msg, err := c.readHandshake()
423 if err != nil {
424 return err
425 }
426
427 if c.isDTLS {
428 helloVerifyRequest, ok := msg.(*helloVerifyRequestMsg)
429 if ok {
Robert Sloanf6200e72017-07-10 08:09:18 -0700430 if helloVerifyRequest.vers != VersionDTLS10 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800431 // Per RFC 6347, the version field in
432 // HelloVerifyRequest SHOULD be always DTLS
433 // 1.0. Enforce this for testing purposes.
434 return errors.New("dtls: bad HelloVerifyRequest version")
435 }
436
437 hello.raw = nil
438 hello.cookie = helloVerifyRequest.cookie
439 helloBytes = hello.marshal()
440 c.writeRecord(recordTypeHandshake, helloBytes)
David Benjaminc895d6b2016-08-11 13:26:41 -0400441 c.flushHandshake()
Adam Langleyd9e397b2015-01-22 14:27:53 -0800442
Adam Langleye9ada862015-05-11 17:20:37 -0700443 if err := c.simulatePacketLoss(nil); err != nil {
444 return err
445 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800446 msg, err = c.readHandshake()
447 if err != nil {
448 return err
449 }
450 }
451 }
452
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400453 var serverWireVersion uint16
David Benjaminc895d6b2016-08-11 13:26:41 -0400454 switch m := msg.(type) {
455 case *helloRetryRequestMsg:
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400456 serverWireVersion = m.vers
David Benjaminc895d6b2016-08-11 13:26:41 -0400457 case *serverHelloMsg:
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400458 serverWireVersion = m.vers
David Benjaminc895d6b2016-08-11 13:26:41 -0400459 default:
460 c.sendAlert(alertUnexpectedMessage)
461 return fmt.Errorf("tls: received unexpected message of type %T when waiting for HelloRetryRequest or ServerHello", msg)
462 }
463
Robert Sloanf6200e72017-07-10 08:09:18 -0700464 serverVersion, ok := c.config.isSupportedVersion(serverWireVersion, c.isDTLS)
David Benjaminc895d6b2016-08-11 13:26:41 -0400465 if !ok {
466 c.sendAlert(alertProtocolVersion)
467 return fmt.Errorf("tls: server selected unsupported protocol version %x", c.vers)
468 }
Robert Sloanf6200e72017-07-10 08:09:18 -0700469 c.wireVersion = serverWireVersion
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400470 c.vers = serverVersion
David Benjaminc895d6b2016-08-11 13:26:41 -0400471 c.haveVers = true
472
473 helloRetryRequest, haveHelloRetryRequest := msg.(*helloRetryRequestMsg)
474 var secondHelloBytes []byte
475 if haveHelloRetryRequest {
Robert Sloan47f43ed2017-02-06 14:55:15 -0800476 c.out.resetCipher()
David Benjamin95add822016-10-19 01:09:12 -0400477 if len(helloRetryRequest.cookie) > 0 {
478 hello.tls13Cookie = helloRetryRequest.cookie
479 }
480
David Benjaminc895d6b2016-08-11 13:26:41 -0400481 if c.config.Bugs.MisinterpretHelloRetryRequestCurve != 0 {
David Benjamin95add822016-10-19 01:09:12 -0400482 helloRetryRequest.hasSelectedGroup = true
David Benjaminc895d6b2016-08-11 13:26:41 -0400483 helloRetryRequest.selectedGroup = c.config.Bugs.MisinterpretHelloRetryRequestCurve
484 }
David Benjamin95add822016-10-19 01:09:12 -0400485 if helloRetryRequest.hasSelectedGroup {
486 var hrrCurveFound bool
487 group := helloRetryRequest.selectedGroup
488 for _, curveID := range hello.supportedCurves {
489 if group == curveID {
490 hrrCurveFound = true
491 break
492 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400493 }
David Benjamin95add822016-10-19 01:09:12 -0400494 if !hrrCurveFound || keyShares[group] != nil {
495 c.sendAlert(alertHandshakeFailure)
496 return errors.New("tls: received invalid HelloRetryRequest")
497 }
498 curve, ok := curveForCurveID(group)
499 if !ok {
500 return errors.New("tls: Unable to get curve requested in HelloRetryRequest")
501 }
502 publicKey, err := curve.offer(c.config.rand())
503 if err != nil {
504 return err
505 }
506 keyShares[group] = curve
Steven Valdez909b19f2016-11-21 15:35:44 -0500507 hello.keyShares = []keyShareEntry{{
David Benjamin95add822016-10-19 01:09:12 -0400508 group: group,
509 keyExchange: publicKey,
Steven Valdez909b19f2016-11-21 15:35:44 -0500510 }}
David Benjaminc895d6b2016-08-11 13:26:41 -0400511 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400512
513 if c.config.Bugs.SecondClientHelloMissingKeyShare {
514 hello.hasKeyShares = false
515 }
516
David Benjamin1b249672016-12-06 18:25:50 -0500517 hello.hasEarlyData = c.config.Bugs.SendEarlyDataOnSecondClientHello
David Benjaminc895d6b2016-08-11 13:26:41 -0400518 hello.raw = nil
519
Steven Valdez909b19f2016-11-21 15:35:44 -0500520 if len(hello.pskIdentities) > 0 {
521 generatePSKBinders(hello, pskCipherSuite, session.masterSecret, append(helloBytes, helloRetryRequest.marshal()...), c.config)
522 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400523 secondHelloBytes = hello.marshal()
David Benjamin1b249672016-12-06 18:25:50 -0500524
525 if c.config.Bugs.InterleaveEarlyData {
526 c.sendFakeEarlyData(4)
527 c.writeRecord(recordTypeHandshake, secondHelloBytes[:16])
528 c.sendFakeEarlyData(4)
529 c.writeRecord(recordTypeHandshake, secondHelloBytes[16:])
530 } else {
531 c.writeRecord(recordTypeHandshake, secondHelloBytes)
532 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400533 c.flushHandshake()
534
David Benjamin1b249672016-12-06 18:25:50 -0500535 if c.config.Bugs.SendEarlyDataOnSecondClientHello {
536 c.sendFakeEarlyData(4)
537 }
538
David Benjaminc895d6b2016-08-11 13:26:41 -0400539 msg, err = c.readHandshake()
540 if err != nil {
541 return err
542 }
543 }
544
Adam Langleyd9e397b2015-01-22 14:27:53 -0800545 serverHello, ok := msg.(*serverHelloMsg)
546 if !ok {
547 c.sendAlert(alertUnexpectedMessage)
548 return unexpectedMessageError(serverHello, msg)
549 }
550
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400551 if serverWireVersion != serverHello.vers {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800552 c.sendAlert(alertProtocolVersion)
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400553 return fmt.Errorf("tls: server sent non-matching version %x vs %x", serverWireVersion, serverHello.vers)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800554 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800555
David Benjaminc895d6b2016-08-11 13:26:41 -0400556 // Check for downgrade signals in the server random, per
David Benjamin95add822016-10-19 01:09:12 -0400557 // draft-ietf-tls-tls13-16, section 4.1.3.
David Benjaminc895d6b2016-08-11 13:26:41 -0400558 if c.vers <= VersionTLS12 && c.config.maxVersion(c.isDTLS) >= VersionTLS13 {
559 if bytes.Equal(serverHello.random[len(serverHello.random)-8:], downgradeTLS13) {
560 c.sendAlert(alertProtocolVersion)
561 return errors.New("tls: downgrade from TLS 1.3 detected")
562 }
563 }
564 if c.vers <= VersionTLS11 && c.config.maxVersion(c.isDTLS) >= VersionTLS12 {
565 if bytes.Equal(serverHello.random[len(serverHello.random)-8:], downgradeTLS12) {
566 c.sendAlert(alertProtocolVersion)
567 return errors.New("tls: downgrade from TLS 1.2 detected")
568 }
569 }
570
571 suite := mutualCipherSuite(hello.cipherSuites, serverHello.cipherSuite)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800572 if suite == nil {
573 c.sendAlert(alertHandshakeFailure)
574 return fmt.Errorf("tls: server selected an unsupported cipher suite")
575 }
576
David Benjamin95add822016-10-19 01:09:12 -0400577 if haveHelloRetryRequest && helloRetryRequest.hasSelectedGroup && helloRetryRequest.selectedGroup != serverHello.keyShare.group {
David Benjaminc895d6b2016-08-11 13:26:41 -0400578 c.sendAlert(alertHandshakeFailure)
579 return errors.New("tls: ServerHello parameters did not match HelloRetryRequest")
Kenny Rootb8494592015-09-25 02:29:14 +0000580 }
581
Robert Sloana27a6a42017-09-05 08:39:28 -0700582 if c.config.Bugs.ExpectOmitExtensions && !serverHello.omitExtensions {
583 return errors.New("tls: ServerHello did not omit extensions")
584 }
585
Adam Langleyd9e397b2015-01-22 14:27:53 -0800586 hs := &clientHandshakeState{
587 c: c,
588 serverHello: serverHello,
589 hello: hello,
590 suite: suite,
591 finishedHash: newFinishedHash(c.vers, suite),
David Benjaminc895d6b2016-08-11 13:26:41 -0400592 keyShares: keyShares,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800593 session: session,
594 }
595
596 hs.writeHash(helloBytes, hs.c.sendHandshakeSeq-1)
David Benjaminc895d6b2016-08-11 13:26:41 -0400597 if haveHelloRetryRequest {
598 hs.writeServerHash(helloRetryRequest.marshal())
599 hs.writeClientHash(secondHelloBytes)
600 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800601 hs.writeServerHash(hs.serverHello.marshal())
602
David Benjaminc895d6b2016-08-11 13:26:41 -0400603 if c.vers >= VersionTLS13 {
604 if err := hs.doTLS13Handshake(); err != nil {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800605 return err
606 }
607 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -0400608 if c.config.Bugs.EarlyChangeCipherSpec > 0 {
609 hs.establishKeys()
610 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
611 }
612
613 if hs.serverHello.compressionMethod != compressionNone {
614 c.sendAlert(alertUnexpectedMessage)
615 return errors.New("tls: server selected unsupported compression format")
616 }
617
618 err = hs.processServerExtensions(&serverHello.extensions)
619 if err != nil {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800620 return err
621 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400622
623 isResume, err := hs.processServerHello()
624 if err != nil {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800625 return err
626 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400627
628 if isResume {
629 if c.config.Bugs.EarlyChangeCipherSpec == 0 {
630 if err := hs.establishKeys(); err != nil {
631 return err
632 }
633 }
634 if err := hs.readSessionTicket(); err != nil {
635 return err
636 }
637 if err := hs.readFinished(c.firstFinished[:]); err != nil {
638 return err
639 }
640 if err := hs.sendFinished(nil, isResume); err != nil {
641 return err
642 }
643 } else {
644 if err := hs.doFullHandshake(); err != nil {
645 return err
646 }
647 if err := hs.establishKeys(); err != nil {
648 return err
649 }
650 if err := hs.sendFinished(c.firstFinished[:], isResume); err != nil {
651 return err
652 }
653 // Most retransmits are triggered by a timeout, but the final
654 // leg of the handshake is retransmited upon re-receiving a
655 // Finished.
656 if err := c.simulatePacketLoss(func() {
657 c.sendHandshakeSeq--
658 c.writeRecord(recordTypeHandshake, hs.finishedBytes)
659 c.flushHandshake()
660 }); err != nil {
661 return err
662 }
663 if err := hs.readSessionTicket(); err != nil {
664 return err
665 }
666 if err := hs.readFinished(nil); err != nil {
667 return err
668 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800669 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400670
671 if sessionCache != nil && hs.session != nil && session != hs.session {
672 if c.config.Bugs.RequireSessionTickets && len(hs.session.sessionTicket) == 0 {
673 return errors.New("tls: new session used session IDs instead of tickets")
674 }
675 sessionCache.Put(cacheKey, hs.session)
Adam Langleye9ada862015-05-11 17:20:37 -0700676 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400677
678 c.didResume = isResume
679 c.exporterSecret = hs.masterSecret
Adam Langleyd9e397b2015-01-22 14:27:53 -0800680 }
681
Adam Langleyd9e397b2015-01-22 14:27:53 -0800682 c.handshakeComplete = true
Adam Langleye9ada862015-05-11 17:20:37 -0700683 c.cipherSuite = suite
684 copy(c.clientRandom[:], hs.hello.random)
685 copy(c.serverRandom[:], hs.serverHello.random)
Kenny Rootb8494592015-09-25 02:29:14 +0000686
Adam Langleyd9e397b2015-01-22 14:27:53 -0800687 return nil
688}
689
David Benjaminc895d6b2016-08-11 13:26:41 -0400690func (hs *clientHandshakeState) doTLS13Handshake() error {
691 c := hs.c
692
Robert Sloandb4251a2017-09-18 09:38:15 -0700693 if isResumptionExperiment(c.wireVersion) && !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
Robert Sloanb6d070c2017-07-24 08:40:01 -0700694 return errors.New("tls: session IDs did not match.")
695 }
696
David Benjaminc895d6b2016-08-11 13:26:41 -0400697 // Once the PRF hash is known, TLS 1.3 does not require a handshake
698 // buffer.
699 hs.finishedHash.discardHandshakeBuffer()
700
701 zeroSecret := hs.finishedHash.zeroSecret()
702
703 // Resolve PSK and compute the early secret.
704 //
705 // TODO(davidben): This will need to be handled slightly earlier once
706 // 0-RTT is implemented.
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400707 if hs.serverHello.hasPSKIdentity {
David Benjaminc895d6b2016-08-11 13:26:41 -0400708 // We send at most one PSK identity.
709 if hs.session == nil || hs.serverHello.pskIdentity != 0 {
710 c.sendAlert(alertUnknownPSKIdentity)
711 return errors.New("tls: server sent unknown PSK identity")
712 }
Steven Valdez909b19f2016-11-21 15:35:44 -0500713 sessionCipher := cipherSuiteFromID(hs.session.cipherSuite)
714 if sessionCipher == nil || sessionCipher.hash() != hs.suite.hash() {
David Benjaminc895d6b2016-08-11 13:26:41 -0400715 c.sendAlert(alertHandshakeFailure)
Steven Valdez909b19f2016-11-21 15:35:44 -0500716 return errors.New("tls: server resumed an invalid session for the cipher suite")
David Benjaminc895d6b2016-08-11 13:26:41 -0400717 }
David Benjamin1b249672016-12-06 18:25:50 -0500718 hs.finishedHash.addEntropy(hs.session.masterSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -0400719 c.didResume = true
720 } else {
David Benjamin1b249672016-12-06 18:25:50 -0500721 hs.finishedHash.addEntropy(zeroSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -0400722 }
723
Steven Valdez909b19f2016-11-21 15:35:44 -0500724 if !hs.serverHello.hasKeyShare {
725 c.sendAlert(alertUnsupportedExtension)
726 return errors.New("tls: server omitted KeyShare on resumption.")
727 }
728
David Benjaminc895d6b2016-08-11 13:26:41 -0400729 // Resolve ECDHE and compute the handshake secret.
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400730 if !c.config.Bugs.MissingKeyShare && !c.config.Bugs.SecondClientHelloMissingKeyShare {
David Benjaminc895d6b2016-08-11 13:26:41 -0400731 curve, ok := hs.keyShares[hs.serverHello.keyShare.group]
732 if !ok {
733 c.sendAlert(alertHandshakeFailure)
734 return errors.New("tls: server selected an unsupported group")
735 }
736 c.curveID = hs.serverHello.keyShare.group
737
David Benjamin1b249672016-12-06 18:25:50 -0500738 ecdheSecret, err := curve.finish(hs.serverHello.keyShare.keyExchange)
David Benjaminc895d6b2016-08-11 13:26:41 -0400739 if err != nil {
740 return err
741 }
David Benjamin1b249672016-12-06 18:25:50 -0500742 hs.finishedHash.addEntropy(ecdheSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -0400743 } else {
David Benjamin1b249672016-12-06 18:25:50 -0500744 hs.finishedHash.addEntropy(zeroSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -0400745 }
746
Robert Sloandb4251a2017-09-18 09:38:15 -0700747 if isResumptionExperiment(c.wireVersion) {
Robert Sloana12bf462017-07-17 07:08:26 -0700748 if err := c.readRecord(recordTypeChangeCipherSpec); err != nil {
749 return err
750 }
751 }
752
Robert Sloan47f43ed2017-02-06 14:55:15 -0800753 // Derive handshake traffic keys and switch read key to handshake
754 // traffic key.
David Benjamin1b249672016-12-06 18:25:50 -0500755 clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientHandshakeTrafficLabel)
David Benjamin1b249672016-12-06 18:25:50 -0500756 serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverHandshakeTrafficLabel)
Robert Sloan29c1d2c2017-10-30 14:10:28 -0700757 if err := c.useInTrafficSecret(c.wireVersion, hs.suite, serverHandshakeTrafficSecret); err != nil {
758 return err
759 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400760
761 msg, err := c.readHandshake()
762 if err != nil {
763 return err
764 }
765
766 encryptedExtensions, ok := msg.(*encryptedExtensionsMsg)
767 if !ok {
768 c.sendAlert(alertUnexpectedMessage)
769 return unexpectedMessageError(encryptedExtensions, msg)
770 }
771 hs.writeServerHash(encryptedExtensions.marshal())
772
773 err = hs.processServerExtensions(&encryptedExtensions.extensions)
774 if err != nil {
775 return err
776 }
777
778 var chainToSend *Certificate
779 var certReq *certificateRequestMsg
Steven Valdez909b19f2016-11-21 15:35:44 -0500780 if c.didResume {
David Benjaminc895d6b2016-08-11 13:26:41 -0400781 // Copy over authentication from the session.
782 c.peerCertificates = hs.session.serverCertificates
783 c.sctList = hs.session.sctList
784 c.ocspResponse = hs.session.ocspResponse
785 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -0400786 msg, err := c.readHandshake()
787 if err != nil {
788 return err
789 }
790
791 var ok bool
792 certReq, ok = msg.(*certificateRequestMsg)
793 if ok {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400794 if len(certReq.requestContext) != 0 {
795 return errors.New("tls: non-empty certificate request context sent in handshake")
796 }
797
David Benjaminc895d6b2016-08-11 13:26:41 -0400798 if c.config.Bugs.IgnorePeerSignatureAlgorithmPreferences {
799 certReq.signatureAlgorithms = c.config.signSignatureAlgorithms()
800 }
801
802 hs.writeServerHash(certReq.marshal())
803
804 chainToSend, err = selectClientCertificate(c, certReq)
805 if err != nil {
806 return err
807 }
808
809 msg, err = c.readHandshake()
810 if err != nil {
811 return err
812 }
813 }
814
815 certMsg, ok := msg.(*certificateMsg)
816 if !ok {
817 c.sendAlert(alertUnexpectedMessage)
818 return unexpectedMessageError(certMsg, msg)
819 }
820 hs.writeServerHash(certMsg.marshal())
821
Steven Valdez909b19f2016-11-21 15:35:44 -0500822 // Check for unsolicited extensions.
823 for i, cert := range certMsg.certificates {
824 if c.config.Bugs.NoOCSPStapling && cert.ocspResponse != nil {
825 c.sendAlert(alertUnsupportedExtension)
826 return errors.New("tls: unexpected OCSP response in the server certificate")
827 }
828 if c.config.Bugs.NoSignedCertificateTimestamps && cert.sctList != nil {
829 c.sendAlert(alertUnsupportedExtension)
830 return errors.New("tls: unexpected SCT list in the server certificate")
831 }
832 if i > 0 && c.config.Bugs.ExpectNoExtensionsOnIntermediate && (cert.ocspResponse != nil || cert.sctList != nil) {
833 c.sendAlert(alertUnsupportedExtension)
834 return errors.New("tls: unexpected extensions in the server certificate")
835 }
836 }
837
David Benjaminc895d6b2016-08-11 13:26:41 -0400838 if err := hs.verifyCertificates(certMsg); err != nil {
839 return err
840 }
841 leaf := c.peerCertificates[0]
Steven Valdez909b19f2016-11-21 15:35:44 -0500842 c.ocspResponse = certMsg.certificates[0].ocspResponse
843 c.sctList = certMsg.certificates[0].sctList
David Benjaminc895d6b2016-08-11 13:26:41 -0400844
845 msg, err = c.readHandshake()
846 if err != nil {
847 return err
848 }
849 certVerifyMsg, ok := msg.(*certificateVerifyMsg)
850 if !ok {
851 c.sendAlert(alertUnexpectedMessage)
852 return unexpectedMessageError(certVerifyMsg, msg)
853 }
854
855 c.peerSignatureAlgorithm = certVerifyMsg.signatureAlgorithm
856 input := hs.finishedHash.certificateVerifyInput(serverCertificateVerifyContextTLS13)
Robert Sloan572a4e22017-04-17 10:52:19 -0700857 err = verifyMessage(c.vers, getCertificatePublicKey(leaf), c.config, certVerifyMsg.signatureAlgorithm, input, certVerifyMsg.signature)
David Benjaminc895d6b2016-08-11 13:26:41 -0400858 if err != nil {
859 return err
860 }
861
862 hs.writeServerHash(certVerifyMsg.marshal())
863 }
864
865 msg, err = c.readHandshake()
866 if err != nil {
867 return err
868 }
869 serverFinished, ok := msg.(*finishedMsg)
870 if !ok {
871 c.sendAlert(alertUnexpectedMessage)
872 return unexpectedMessageError(serverFinished, msg)
873 }
874
David Benjamin95add822016-10-19 01:09:12 -0400875 verify := hs.finishedHash.serverSum(serverHandshakeTrafficSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -0400876 if len(verify) != len(serverFinished.verifyData) ||
877 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
878 c.sendAlert(alertHandshakeFailure)
879 return errors.New("tls: server's Finished message was incorrect")
880 }
881
882 hs.writeServerHash(serverFinished.marshal())
883
884 // The various secrets do not incorporate the client's final leg, so
885 // derive them now before updating the handshake context.
David Benjamin1b249672016-12-06 18:25:50 -0500886 hs.finishedHash.addEntropy(zeroSecret)
887 clientTrafficSecret := hs.finishedHash.deriveSecret(clientApplicationTrafficLabel)
888 serverTrafficSecret := hs.finishedHash.deriveSecret(serverApplicationTrafficLabel)
Robert Sloan5d625782017-02-13 09:55:39 -0800889 c.exporterSecret = hs.finishedHash.deriveSecret(exporterLabel)
890
891 // Switch to application data keys on read. In particular, any alerts
892 // from the client certificate are read over these keys.
Robert Sloan29c1d2c2017-10-30 14:10:28 -0700893 if err := c.useInTrafficSecret(c.wireVersion, hs.suite, serverTrafficSecret); err != nil {
894 return err
895 }
Robert Sloan4d1ac502017-02-06 08:36:14 -0800896
897 // If we're expecting 0.5-RTT messages from the server, read them
898 // now.
Robert Sloan6d0d00e2017-03-27 07:13:07 -0700899 if encryptedExtensions.extensions.hasEarlyData {
900 // BoringSSL will always send two tickets half-RTT when
901 // negotiating 0-RTT.
902 for i := 0; i < shimConfig.HalfRTTTickets; i++ {
903 msg, err := c.readHandshake()
904 if err != nil {
905 return fmt.Errorf("tls: error reading half-RTT ticket: %s", err)
906 }
907 newSessionTicket, ok := msg.(*newSessionTicketMsg)
908 if !ok {
909 return errors.New("tls: expected half-RTT ticket")
910 }
911 if err := c.processTLS13NewSessionTicket(newSessionTicket, hs.suite); err != nil {
912 return err
913 }
Robert Sloan4d1ac502017-02-06 08:36:14 -0800914 }
Robert Sloan6d0d00e2017-03-27 07:13:07 -0700915 for _, expectedMsg := range c.config.Bugs.ExpectHalfRTTData {
916 if err := c.readRecord(recordTypeApplicationData); err != nil {
917 return err
918 }
919 if !bytes.Equal(c.input.data[c.input.off:], expectedMsg) {
920 return errors.New("ExpectHalfRTTData: did not get expected message")
921 }
922 c.in.freeBlock(c.input)
923 c.input = nil
Robert Sloan4d1ac502017-02-06 08:36:14 -0800924 }
Robert Sloan4d1ac502017-02-06 08:36:14 -0800925 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400926
Robert Sloan47f43ed2017-02-06 14:55:15 -0800927 // Send EndOfEarlyData and then switch write key to handshake
928 // traffic key.
Robert Sloan6d0d00e2017-03-27 07:13:07 -0700929 if c.out.cipher != nil && !c.config.Bugs.SkipEndOfEarlyData {
930 if c.config.Bugs.SendStrayEarlyHandshake {
931 helloRequest := new(helloRequestMsg)
932 c.writeRecord(recordTypeHandshake, helloRequest.marshal())
933 }
Robert Sloan47f43ed2017-02-06 14:55:15 -0800934 c.sendAlert(alertEndOfEarlyData)
935 }
Robert Sloana12bf462017-07-17 07:08:26 -0700936
Robert Sloandb4251a2017-09-18 09:38:15 -0700937 if isResumptionClientCCSExperiment(c.wireVersion) {
Robert Sloana12bf462017-07-17 07:08:26 -0700938 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
939 }
940
Robert Sloan29c1d2c2017-10-30 14:10:28 -0700941 c.useOutTrafficSecret(c.wireVersion, hs.suite, clientHandshakeTrafficSecret)
Robert Sloan47f43ed2017-02-06 14:55:15 -0800942
David Benjaminc895d6b2016-08-11 13:26:41 -0400943 if certReq != nil && !c.config.Bugs.SkipClientCertificate {
944 certMsg := &certificateMsg{
945 hasRequestContext: true,
946 requestContext: certReq.requestContext,
947 }
948 if chainToSend != nil {
Steven Valdez909b19f2016-11-21 15:35:44 -0500949 for _, certData := range chainToSend.Certificate {
950 certMsg.certificates = append(certMsg.certificates, certificateEntry{
951 data: certData,
952 extraExtension: c.config.Bugs.SendExtensionOnCertificate,
953 })
954 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400955 }
956 hs.writeClientHash(certMsg.marshal())
957 c.writeRecord(recordTypeHandshake, certMsg.marshal())
958
959 if chainToSend != nil {
960 certVerify := &certificateVerifyMsg{
961 hasSignatureAlgorithm: true,
962 }
963
964 // Determine the hash to sign.
965 privKey := chainToSend.PrivateKey
966
967 var err error
968 certVerify.signatureAlgorithm, err = selectSignatureAlgorithm(c.vers, privKey, c.config, certReq.signatureAlgorithms)
969 if err != nil {
970 c.sendAlert(alertInternalError)
971 return err
972 }
973
974 input := hs.finishedHash.certificateVerifyInput(clientCertificateVerifyContextTLS13)
975 certVerify.signature, err = signMessage(c.vers, privKey, c.config, certVerify.signatureAlgorithm, input)
976 if err != nil {
977 c.sendAlert(alertInternalError)
978 return err
979 }
980 if c.config.Bugs.SendSignatureAlgorithm != 0 {
981 certVerify.signatureAlgorithm = c.config.Bugs.SendSignatureAlgorithm
982 }
983
Robert Sloan84377092017-08-14 09:33:19 -0700984 if !c.config.Bugs.SkipCertificateVerify {
985 hs.writeClientHash(certVerify.marshal())
986 c.writeRecord(recordTypeHandshake, certVerify.marshal())
987 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400988 }
989 }
990
Steven Valdez909b19f2016-11-21 15:35:44 -0500991 if encryptedExtensions.extensions.channelIDRequested {
992 channelIDHash := crypto.SHA256.New()
993 channelIDHash.Write(hs.finishedHash.certificateVerifyInput(channelIDContextTLS13))
994 channelIDMsgBytes, err := hs.writeChannelIDMessage(channelIDHash.Sum(nil))
995 if err != nil {
996 return err
997 }
998 hs.writeClientHash(channelIDMsgBytes)
999 c.writeRecord(recordTypeHandshake, channelIDMsgBytes)
1000 }
1001
David Benjaminc895d6b2016-08-11 13:26:41 -04001002 // Send a client Finished message.
1003 finished := new(finishedMsg)
David Benjamin95add822016-10-19 01:09:12 -04001004 finished.verifyData = hs.finishedHash.clientSum(clientHandshakeTrafficSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -04001005 if c.config.Bugs.BadFinished {
1006 finished.verifyData[0]++
1007 }
1008 hs.writeClientHash(finished.marshal())
1009 if c.config.Bugs.PartialClientFinishedWithClientHello {
1010 // The first byte has already been sent.
1011 c.writeRecord(recordTypeHandshake, finished.marshal()[1:])
David Benjamin1b249672016-12-06 18:25:50 -05001012 } else if c.config.Bugs.InterleaveEarlyData {
1013 finishedBytes := finished.marshal()
1014 c.sendFakeEarlyData(4)
1015 c.writeRecord(recordTypeHandshake, finishedBytes[:1])
1016 c.sendFakeEarlyData(4)
1017 c.writeRecord(recordTypeHandshake, finishedBytes[1:])
David Benjaminc895d6b2016-08-11 13:26:41 -04001018 } else {
1019 c.writeRecord(recordTypeHandshake, finished.marshal())
1020 }
1021 if c.config.Bugs.SendExtraFinished {
1022 c.writeRecord(recordTypeHandshake, finished.marshal())
1023 }
1024 c.flushHandshake()
1025
1026 // Switch to application data keys.
Robert Sloan29c1d2c2017-10-30 14:10:28 -07001027 c.useOutTrafficSecret(c.wireVersion, hs.suite, clientTrafficSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -04001028
David Benjamin1b249672016-12-06 18:25:50 -05001029 c.resumptionSecret = hs.finishedHash.deriveSecret(resumptionLabel)
David Benjaminc895d6b2016-08-11 13:26:41 -04001030 return nil
1031}
1032
Adam Langleyd9e397b2015-01-22 14:27:53 -08001033func (hs *clientHandshakeState) doFullHandshake() error {
1034 c := hs.c
1035
1036 var leaf *x509.Certificate
1037 if hs.suite.flags&suitePSK == 0 {
1038 msg, err := c.readHandshake()
1039 if err != nil {
1040 return err
1041 }
1042
1043 certMsg, ok := msg.(*certificateMsg)
David Benjaminc895d6b2016-08-11 13:26:41 -04001044 if !ok {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001045 c.sendAlert(alertUnexpectedMessage)
1046 return unexpectedMessageError(certMsg, msg)
1047 }
1048 hs.writeServerHash(certMsg.marshal())
1049
David Benjaminc895d6b2016-08-11 13:26:41 -04001050 if err := hs.verifyCertificates(certMsg); err != nil {
1051 return err
Adam Langleyd9e397b2015-01-22 14:27:53 -08001052 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001053 leaf = c.peerCertificates[0]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001054 }
1055
David Benjaminc895d6b2016-08-11 13:26:41 -04001056 if hs.serverHello.extensions.ocspStapling {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001057 msg, err := c.readHandshake()
1058 if err != nil {
1059 return err
1060 }
1061 cs, ok := msg.(*certificateStatusMsg)
1062 if !ok {
1063 c.sendAlert(alertUnexpectedMessage)
1064 return unexpectedMessageError(cs, msg)
1065 }
1066 hs.writeServerHash(cs.marshal())
1067
1068 if cs.statusType == statusTypeOCSP {
1069 c.ocspResponse = cs.response
1070 }
1071 }
1072
1073 msg, err := c.readHandshake()
1074 if err != nil {
1075 return err
1076 }
1077
1078 keyAgreement := hs.suite.ka(c.vers)
1079
1080 skx, ok := msg.(*serverKeyExchangeMsg)
1081 if ok {
1082 hs.writeServerHash(skx.marshal())
1083 err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, leaf, skx)
1084 if err != nil {
1085 c.sendAlert(alertUnexpectedMessage)
1086 return err
1087 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001088 if ecdhe, ok := keyAgreement.(*ecdheKeyAgreement); ok {
1089 c.curveID = ecdhe.curveID
1090 }
1091
1092 c.peerSignatureAlgorithm = keyAgreement.peerSignatureAlgorithm()
Adam Langleyd9e397b2015-01-22 14:27:53 -08001093
1094 msg, err = c.readHandshake()
1095 if err != nil {
1096 return err
1097 }
1098 }
1099
1100 var chainToSend *Certificate
1101 var certRequested bool
1102 certReq, ok := msg.(*certificateRequestMsg)
1103 if ok {
1104 certRequested = true
David Benjaminc895d6b2016-08-11 13:26:41 -04001105 if c.config.Bugs.IgnorePeerSignatureAlgorithmPreferences {
1106 certReq.signatureAlgorithms = c.config.signSignatureAlgorithms()
1107 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001108
1109 hs.writeServerHash(certReq.marshal())
1110
David Benjaminc895d6b2016-08-11 13:26:41 -04001111 chainToSend, err = selectClientCertificate(c, certReq)
1112 if err != nil {
1113 return err
Adam Langleyd9e397b2015-01-22 14:27:53 -08001114 }
1115
1116 msg, err = c.readHandshake()
1117 if err != nil {
1118 return err
1119 }
1120 }
1121
1122 shd, ok := msg.(*serverHelloDoneMsg)
1123 if !ok {
1124 c.sendAlert(alertUnexpectedMessage)
1125 return unexpectedMessageError(shd, msg)
1126 }
1127 hs.writeServerHash(shd.marshal())
1128
1129 // If the server requested a certificate then we have to send a
David Benjamin4969cc92016-04-22 15:02:23 -04001130 // Certificate message in TLS, even if it's empty because we don't have
1131 // a certificate to send. In SSL 3.0, skip the message and send a
1132 // no_certificate warning alert.
Adam Langleyd9e397b2015-01-22 14:27:53 -08001133 if certRequested {
David Benjamin4969cc92016-04-22 15:02:23 -04001134 if c.vers == VersionSSL30 && chainToSend == nil {
Robert Sloan69939df2017-01-09 10:53:07 -08001135 c.sendAlert(alertNoCertificate)
David Benjamin4969cc92016-04-22 15:02:23 -04001136 } else if !c.config.Bugs.SkipClientCertificate {
1137 certMsg := new(certificateMsg)
1138 if chainToSend != nil {
Steven Valdez909b19f2016-11-21 15:35:44 -05001139 for _, certData := range chainToSend.Certificate {
1140 certMsg.certificates = append(certMsg.certificates, certificateEntry{
1141 data: certData,
1142 })
1143 }
David Benjamin4969cc92016-04-22 15:02:23 -04001144 }
1145 hs.writeClientHash(certMsg.marshal())
1146 c.writeRecord(recordTypeHandshake, certMsg.marshal())
Adam Langleyd9e397b2015-01-22 14:27:53 -08001147 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001148 }
1149
1150 preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, leaf)
1151 if err != nil {
1152 c.sendAlert(alertInternalError)
1153 return err
1154 }
1155 if ckx != nil {
1156 if c.config.Bugs.EarlyChangeCipherSpec < 2 {
1157 hs.writeClientHash(ckx.marshal())
1158 }
1159 c.writeRecord(recordTypeHandshake, ckx.marshal())
1160 }
1161
David Benjaminc895d6b2016-08-11 13:26:41 -04001162 if hs.serverHello.extensions.extendedMasterSecret && c.vers >= VersionTLS10 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001163 hs.masterSecret = extendedMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.finishedHash)
1164 c.extendedMasterSecret = true
1165 } else {
1166 if c.config.Bugs.RequireExtendedMasterSecret {
1167 return errors.New("tls: extended master secret required but not supported by peer")
1168 }
1169 hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
1170 }
1171
1172 if chainToSend != nil {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001173 certVerify := &certificateVerifyMsg{
David Benjaminc895d6b2016-08-11 13:26:41 -04001174 hasSignatureAlgorithm: c.vers >= VersionTLS12,
Adam Langleyd9e397b2015-01-22 14:27:53 -08001175 }
1176
Adam Langleye9ada862015-05-11 17:20:37 -07001177 // Determine the hash to sign.
David Benjaminc895d6b2016-08-11 13:26:41 -04001178 privKey := c.config.Certificates[0].PrivateKey
1179
1180 if certVerify.hasSignatureAlgorithm {
1181 certVerify.signatureAlgorithm, err = selectSignatureAlgorithm(c.vers, privKey, c.config, certReq.signatureAlgorithms)
1182 if err != nil {
1183 c.sendAlert(alertInternalError)
1184 return err
1185 }
Kenny Rootb8494592015-09-25 02:29:14 +00001186 }
Adam Langleye9ada862015-05-11 17:20:37 -07001187
David Benjaminc895d6b2016-08-11 13:26:41 -04001188 if c.vers > VersionSSL30 {
1189 certVerify.signature, err = signMessage(c.vers, privKey, c.config, certVerify.signatureAlgorithm, hs.finishedHash.buffer)
1190 if err == nil && c.config.Bugs.SendSignatureAlgorithm != 0 {
1191 certVerify.signatureAlgorithm = c.config.Bugs.SendSignatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -08001192 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001193 } else {
1194 // SSL 3.0's client certificate construction is
1195 // incompatible with signatureAlgorithm.
1196 rsaKey, ok := privKey.(*rsa.PrivateKey)
1197 if !ok {
1198 err = errors.New("unsupported signature type for client certificate")
1199 } else {
1200 digest := hs.finishedHash.hashForClientCertificateSSL3(hs.masterSecret)
1201 if c.config.Bugs.InvalidSignature {
1202 digest[0] ^= 0x80
1203 }
1204 certVerify.signature, err = rsa.SignPKCS1v15(c.config.rand(), rsaKey, crypto.MD5SHA1, digest)
1205 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001206 }
1207 if err != nil {
1208 c.sendAlert(alertInternalError)
1209 return errors.New("tls: failed to sign handshake with client certificate: " + err.Error())
1210 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001211
Robert Sloan84377092017-08-14 09:33:19 -07001212 if !c.config.Bugs.SkipCertificateVerify {
1213 hs.writeClientHash(certVerify.marshal())
1214 c.writeRecord(recordTypeHandshake, certVerify.marshal())
1215 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001216 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001217 // flushHandshake will be called in sendFinished.
Adam Langleyd9e397b2015-01-22 14:27:53 -08001218
1219 hs.finishedHash.discardHandshakeBuffer()
1220
1221 return nil
1222}
1223
David Benjaminc895d6b2016-08-11 13:26:41 -04001224func (hs *clientHandshakeState) verifyCertificates(certMsg *certificateMsg) error {
1225 c := hs.c
1226
1227 if len(certMsg.certificates) == 0 {
1228 c.sendAlert(alertIllegalParameter)
1229 return errors.New("tls: no certificates sent")
1230 }
1231
1232 certs := make([]*x509.Certificate, len(certMsg.certificates))
Steven Valdez909b19f2016-11-21 15:35:44 -05001233 for i, certEntry := range certMsg.certificates {
1234 cert, err := x509.ParseCertificate(certEntry.data)
David Benjaminc895d6b2016-08-11 13:26:41 -04001235 if err != nil {
1236 c.sendAlert(alertBadCertificate)
1237 return errors.New("tls: failed to parse certificate from server: " + err.Error())
1238 }
1239 certs[i] = cert
1240 }
1241
1242 if !c.config.InsecureSkipVerify {
1243 opts := x509.VerifyOptions{
1244 Roots: c.config.RootCAs,
1245 CurrentTime: c.config.time(),
1246 DNSName: c.config.ServerName,
1247 Intermediates: x509.NewCertPool(),
1248 }
1249
1250 for i, cert := range certs {
1251 if i == 0 {
1252 continue
1253 }
1254 opts.Intermediates.AddCert(cert)
1255 }
1256 var err error
1257 c.verifiedChains, err = certs[0].Verify(opts)
1258 if err != nil {
1259 c.sendAlert(alertBadCertificate)
1260 return err
1261 }
1262 }
1263
Robert Sloan572a4e22017-04-17 10:52:19 -07001264 publicKey := getCertificatePublicKey(certs[0])
1265 switch publicKey.(type) {
1266 case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
David Benjaminc895d6b2016-08-11 13:26:41 -04001267 break
1268 default:
1269 c.sendAlert(alertUnsupportedCertificate)
Robert Sloan572a4e22017-04-17 10:52:19 -07001270 return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", publicKey)
David Benjaminc895d6b2016-08-11 13:26:41 -04001271 }
1272
1273 c.peerCertificates = certs
1274 return nil
1275}
1276
Adam Langleyd9e397b2015-01-22 14:27:53 -08001277func (hs *clientHandshakeState) establishKeys() error {
1278 c := hs.c
1279
1280 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
David Benjaminc895d6b2016-08-11 13:26:41 -04001281 keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen(c.vers))
Adam Langleyd9e397b2015-01-22 14:27:53 -08001282 var clientCipher, serverCipher interface{}
1283 var clientHash, serverHash macFunction
1284 if hs.suite.cipher != nil {
1285 clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
1286 clientHash = hs.suite.mac(c.vers, clientMAC)
1287 serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
1288 serverHash = hs.suite.mac(c.vers, serverMAC)
1289 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -04001290 clientCipher = hs.suite.aead(c.vers, clientKey, clientIV)
1291 serverCipher = hs.suite.aead(c.vers, serverKey, serverIV)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001292 }
1293
Robert Sloandb4251a2017-09-18 09:38:15 -07001294 c.in.prepareCipherSpec(c.wireVersion, serverCipher, serverHash)
1295 c.out.prepareCipherSpec(c.wireVersion, clientCipher, clientHash)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001296 return nil
1297}
1298
David Benjaminc895d6b2016-08-11 13:26:41 -04001299func (hs *clientHandshakeState) processServerExtensions(serverExtensions *serverExtensions) error {
1300 c := hs.c
1301
1302 if c.vers < VersionTLS13 {
1303 if c.config.Bugs.RequireRenegotiationInfo && serverExtensions.secureRenegotiation == nil {
1304 return errors.New("tls: renegotiation extension missing")
1305 }
1306
1307 if len(c.clientVerify) > 0 && !c.noRenegotiationInfo() {
1308 var expectedRenegInfo []byte
1309 expectedRenegInfo = append(expectedRenegInfo, c.clientVerify...)
1310 expectedRenegInfo = append(expectedRenegInfo, c.serverVerify...)
1311 if !bytes.Equal(serverExtensions.secureRenegotiation, expectedRenegInfo) {
1312 c.sendAlert(alertHandshakeFailure)
1313 return fmt.Errorf("tls: renegotiation mismatch")
1314 }
1315 }
1316 } else if serverExtensions.secureRenegotiation != nil {
1317 return errors.New("tls: renegotiation info sent in TLS 1.3")
1318 }
1319
1320 if expected := c.config.Bugs.ExpectedCustomExtension; expected != nil {
1321 if serverExtensions.customExtension != *expected {
1322 return fmt.Errorf("tls: bad custom extension contents %q", serverExtensions.customExtension)
1323 }
1324 }
1325
1326 clientDidNPN := hs.hello.nextProtoNeg
1327 clientDidALPN := len(hs.hello.alpnProtocols) > 0
1328 serverHasNPN := serverExtensions.nextProtoNeg
1329 serverHasALPN := len(serverExtensions.alpnProtocol) > 0
1330
1331 if !clientDidNPN && serverHasNPN {
1332 c.sendAlert(alertHandshakeFailure)
1333 return errors.New("server advertised unrequested NPN extension")
1334 }
1335
1336 if !clientDidALPN && serverHasALPN {
1337 c.sendAlert(alertHandshakeFailure)
1338 return errors.New("server advertised unrequested ALPN extension")
1339 }
1340
1341 if serverHasNPN && serverHasALPN {
1342 c.sendAlert(alertHandshakeFailure)
1343 return errors.New("server advertised both NPN and ALPN extensions")
1344 }
1345
1346 if serverHasALPN {
1347 c.clientProtocol = serverExtensions.alpnProtocol
1348 c.clientProtocolFallback = false
1349 c.usedALPN = true
1350 }
1351
1352 if serverHasNPN && c.vers >= VersionTLS13 {
1353 c.sendAlert(alertHandshakeFailure)
1354 return errors.New("server advertised NPN over TLS 1.3")
1355 }
1356
1357 if !hs.hello.channelIDSupported && serverExtensions.channelIDRequested {
1358 c.sendAlert(alertHandshakeFailure)
1359 return errors.New("server advertised unrequested Channel ID extension")
1360 }
1361
David Benjaminc895d6b2016-08-11 13:26:41 -04001362 if serverExtensions.extendedMasterSecret && c.vers >= VersionTLS13 {
1363 return errors.New("tls: server advertised extended master secret over TLS 1.3")
1364 }
1365
1366 if serverExtensions.ticketSupported && c.vers >= VersionTLS13 {
1367 return errors.New("tls: server advertised ticket extension over TLS 1.3")
1368 }
1369
Steven Valdez909b19f2016-11-21 15:35:44 -05001370 if serverExtensions.ocspStapling && c.vers >= VersionTLS13 {
1371 return errors.New("tls: server advertised OCSP in ServerHello over TLS 1.3")
1372 }
1373
1374 if serverExtensions.ocspStapling && c.config.Bugs.NoOCSPStapling {
1375 return errors.New("tls: server advertised unrequested OCSP extension")
1376 }
1377
1378 if len(serverExtensions.sctList) > 0 && c.vers >= VersionTLS13 {
1379 return errors.New("tls: server advertised SCTs in ServerHello over TLS 1.3")
1380 }
1381
1382 if len(serverExtensions.sctList) > 0 && c.config.Bugs.NoSignedCertificateTimestamps {
1383 return errors.New("tls: server advertised unrequested SCTs")
1384 }
1385
David Benjaminc895d6b2016-08-11 13:26:41 -04001386 if serverExtensions.srtpProtectionProfile != 0 {
1387 if serverExtensions.srtpMasterKeyIdentifier != "" {
1388 return errors.New("tls: server selected SRTP MKI value")
1389 }
1390
1391 found := false
1392 for _, p := range c.config.SRTPProtectionProfiles {
1393 if p == serverExtensions.srtpProtectionProfile {
1394 found = true
1395 break
1396 }
1397 }
1398 if !found {
1399 return errors.New("tls: server advertised unsupported SRTP profile")
1400 }
1401
1402 c.srtpProtectionProfile = serverExtensions.srtpProtectionProfile
1403 }
1404
Robert Sloan6d0d00e2017-03-27 07:13:07 -07001405 if c.vers >= VersionTLS13 && c.didResume {
1406 if c.config.Bugs.ExpectEarlyDataAccepted && !serverExtensions.hasEarlyData {
1407 c.sendAlert(alertHandshakeFailure)
1408 return errors.New("tls: server did not accept early data when expected")
1409 }
1410
1411 if !c.config.Bugs.ExpectEarlyDataAccepted && serverExtensions.hasEarlyData {
1412 c.sendAlert(alertHandshakeFailure)
1413 return errors.New("tls: server accepted early data when not expected")
1414 }
1415 }
1416
David Benjaminc895d6b2016-08-11 13:26:41 -04001417 return nil
1418}
1419
Adam Langleyd9e397b2015-01-22 14:27:53 -08001420func (hs *clientHandshakeState) serverResumedSession() bool {
1421 // If the server responded with the same sessionId then it means the
1422 // sessionTicket is being used to resume a TLS session.
Robert Sloan5d625782017-02-13 09:55:39 -08001423 //
1424 // Note that, if hs.hello.sessionId is a non-nil empty array, this will
1425 // accept an empty session ID from the server as resumption. See
1426 // EmptyTicketSessionID.
Adam Langleyd9e397b2015-01-22 14:27:53 -08001427 return hs.session != nil && hs.hello.sessionId != nil &&
1428 bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
1429}
1430
1431func (hs *clientHandshakeState) processServerHello() (bool, error) {
1432 c := hs.c
1433
Adam Langleyd9e397b2015-01-22 14:27:53 -08001434 if hs.serverResumedSession() {
Adam Langleyf4e42722015-06-04 17:45:09 -07001435 // For test purposes, assert that the server never accepts the
1436 // resumption offer on renegotiation.
1437 if c.cipherSuite != nil && c.config.Bugs.FailIfResumeOnRenego {
1438 return false, errors.New("tls: server resumed session on renegotiation")
1439 }
1440
David Benjaminc895d6b2016-08-11 13:26:41 -04001441 if hs.serverHello.extensions.sctList != nil {
Kenny Rootb8494592015-09-25 02:29:14 +00001442 return false, errors.New("tls: server sent SCT extension on session resumption")
1443 }
1444
David Benjaminc895d6b2016-08-11 13:26:41 -04001445 if hs.serverHello.extensions.ocspStapling {
Kenny Rootb8494592015-09-25 02:29:14 +00001446 return false, errors.New("tls: server sent OCSP extension on session resumption")
1447 }
1448
Adam Langleyd9e397b2015-01-22 14:27:53 -08001449 // Restore masterSecret and peerCerts from previous state
1450 hs.masterSecret = hs.session.masterSecret
1451 c.peerCertificates = hs.session.serverCertificates
1452 c.extendedMasterSecret = hs.session.extendedMasterSecret
Kenny Rootb8494592015-09-25 02:29:14 +00001453 c.sctList = hs.session.sctList
1454 c.ocspResponse = hs.session.ocspResponse
Adam Langleyd9e397b2015-01-22 14:27:53 -08001455 hs.finishedHash.discardHandshakeBuffer()
1456 return true, nil
1457 }
Kenny Rootb8494592015-09-25 02:29:14 +00001458
David Benjaminc895d6b2016-08-11 13:26:41 -04001459 if hs.serverHello.extensions.sctList != nil {
1460 c.sctList = hs.serverHello.extensions.sctList
Kenny Rootb8494592015-09-25 02:29:14 +00001461 }
1462
Adam Langleyd9e397b2015-01-22 14:27:53 -08001463 return false, nil
1464}
1465
Adam Langleyf4e42722015-06-04 17:45:09 -07001466func (hs *clientHandshakeState) readFinished(out []byte) error {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001467 c := hs.c
1468
1469 c.readRecord(recordTypeChangeCipherSpec)
1470 if err := c.in.error(); err != nil {
1471 return err
1472 }
1473
1474 msg, err := c.readHandshake()
1475 if err != nil {
1476 return err
1477 }
1478 serverFinished, ok := msg.(*finishedMsg)
1479 if !ok {
1480 c.sendAlert(alertUnexpectedMessage)
1481 return unexpectedMessageError(serverFinished, msg)
1482 }
1483
1484 if c.config.Bugs.EarlyChangeCipherSpec == 0 {
1485 verify := hs.finishedHash.serverSum(hs.masterSecret)
1486 if len(verify) != len(serverFinished.verifyData) ||
1487 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
1488 c.sendAlert(alertHandshakeFailure)
1489 return errors.New("tls: server's Finished message was incorrect")
1490 }
1491 }
1492 c.serverVerify = append(c.serverVerify[:0], serverFinished.verifyData...)
Adam Langleyf4e42722015-06-04 17:45:09 -07001493 copy(out, serverFinished.verifyData)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001494 hs.writeServerHash(serverFinished.marshal())
1495 return nil
1496}
1497
1498func (hs *clientHandshakeState) readSessionTicket() error {
1499 c := hs.c
1500
1501 // Create a session with no server identifier. Either a
1502 // session ID or session ticket will be attached.
1503 session := &ClientSessionState{
1504 vers: c.vers,
1505 cipherSuite: hs.suite.id,
1506 masterSecret: hs.masterSecret,
Steven Valdez909b19f2016-11-21 15:35:44 -05001507 handshakeHash: hs.finishedHash.Sum(),
Adam Langleyd9e397b2015-01-22 14:27:53 -08001508 serverCertificates: c.peerCertificates,
Kenny Rootb8494592015-09-25 02:29:14 +00001509 sctList: c.sctList,
1510 ocspResponse: c.ocspResponse,
David Benjaminc895d6b2016-08-11 13:26:41 -04001511 ticketExpiration: c.config.time().Add(time.Duration(7 * 24 * time.Hour)),
Adam Langleyd9e397b2015-01-22 14:27:53 -08001512 }
1513
David Benjaminc895d6b2016-08-11 13:26:41 -04001514 if !hs.serverHello.extensions.ticketSupported {
Kenny Rootb8494592015-09-25 02:29:14 +00001515 if c.config.Bugs.ExpectNewTicket {
1516 return errors.New("tls: expected new ticket")
1517 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001518 if hs.session == nil && len(hs.serverHello.sessionId) > 0 {
1519 session.sessionId = hs.serverHello.sessionId
1520 hs.session = session
1521 }
1522 return nil
1523 }
1524
Kenny Roote99801b2015-11-06 15:31:15 -08001525 if c.vers == VersionSSL30 {
1526 return errors.New("tls: negotiated session tickets in SSL 3.0")
1527 }
1528
Adam Langleyd9e397b2015-01-22 14:27:53 -08001529 msg, err := c.readHandshake()
1530 if err != nil {
1531 return err
1532 }
1533 sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
1534 if !ok {
1535 c.sendAlert(alertUnexpectedMessage)
1536 return unexpectedMessageError(sessionTicketMsg, msg)
1537 }
1538
1539 session.sessionTicket = sessionTicketMsg.ticket
1540 hs.session = session
1541
1542 hs.writeServerHash(sessionTicketMsg.marshal())
1543
1544 return nil
1545}
1546
Adam Langleyf4e42722015-06-04 17:45:09 -07001547func (hs *clientHandshakeState) sendFinished(out []byte, isResume bool) error {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001548 c := hs.c
1549
David Benjaminc895d6b2016-08-11 13:26:41 -04001550 var postCCSMsgs [][]byte
Adam Langleyd9e397b2015-01-22 14:27:53 -08001551 seqno := hs.c.sendHandshakeSeq
David Benjaminc895d6b2016-08-11 13:26:41 -04001552 if hs.serverHello.extensions.nextProtoNeg {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001553 nextProto := new(nextProtoMsg)
David Benjaminc895d6b2016-08-11 13:26:41 -04001554 proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.extensions.nextProtos)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001555 nextProto.proto = proto
1556 c.clientProtocol = proto
1557 c.clientProtocolFallback = fallback
1558
1559 nextProtoBytes := nextProto.marshal()
1560 hs.writeHash(nextProtoBytes, seqno)
1561 seqno++
David Benjaminc895d6b2016-08-11 13:26:41 -04001562 postCCSMsgs = append(postCCSMsgs, nextProtoBytes)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001563 }
1564
David Benjaminc895d6b2016-08-11 13:26:41 -04001565 if hs.serverHello.extensions.channelIDRequested {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001566 var resumeHash []byte
1567 if isResume {
1568 resumeHash = hs.session.handshakeHash
1569 }
Steven Valdez909b19f2016-11-21 15:35:44 -05001570 channelIDMsgBytes, err := hs.writeChannelIDMessage(hs.finishedHash.hashForChannelID(resumeHash))
Adam Langleyd9e397b2015-01-22 14:27:53 -08001571 if err != nil {
1572 return err
1573 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001574 hs.writeHash(channelIDMsgBytes, seqno)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001575 seqno++
David Benjaminc895d6b2016-08-11 13:26:41 -04001576 postCCSMsgs = append(postCCSMsgs, channelIDMsgBytes)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001577 }
1578
1579 finished := new(finishedMsg)
1580 if c.config.Bugs.EarlyChangeCipherSpec == 2 {
1581 finished.verifyData = hs.finishedHash.clientSum(nil)
1582 } else {
1583 finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
1584 }
Adam Langleyf4e42722015-06-04 17:45:09 -07001585 copy(out, finished.verifyData)
Adam Langleye9ada862015-05-11 17:20:37 -07001586 if c.config.Bugs.BadFinished {
1587 finished.verifyData[0]++
1588 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001589 c.clientVerify = append(c.clientVerify[:0], finished.verifyData...)
Adam Langleye9ada862015-05-11 17:20:37 -07001590 hs.finishedBytes = finished.marshal()
1591 hs.writeHash(hs.finishedBytes, seqno)
David Benjaminc895d6b2016-08-11 13:26:41 -04001592 postCCSMsgs = append(postCCSMsgs, hs.finishedBytes)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001593
1594 if c.config.Bugs.FragmentAcrossChangeCipherSpec {
David Benjaminc895d6b2016-08-11 13:26:41 -04001595 c.writeRecord(recordTypeHandshake, postCCSMsgs[0][:5])
1596 postCCSMsgs[0] = postCCSMsgs[0][5:]
1597 } else if c.config.Bugs.SendUnencryptedFinished {
1598 c.writeRecord(recordTypeHandshake, postCCSMsgs[0])
1599 postCCSMsgs = postCCSMsgs[1:]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001600 }
1601
1602 if !c.config.Bugs.SkipChangeCipherSpec &&
1603 c.config.Bugs.EarlyChangeCipherSpec == 0 {
Adam Langley4139edb2016-01-13 15:00:54 -08001604 ccs := []byte{1}
1605 if c.config.Bugs.BadChangeCipherSpec != nil {
1606 ccs = c.config.Bugs.BadChangeCipherSpec
1607 }
1608 c.writeRecord(recordTypeChangeCipherSpec, ccs)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001609 }
1610
1611 if c.config.Bugs.AppDataAfterChangeCipherSpec != nil {
1612 c.writeRecord(recordTypeApplicationData, c.config.Bugs.AppDataAfterChangeCipherSpec)
1613 }
Adam Langleye9ada862015-05-11 17:20:37 -07001614 if c.config.Bugs.AlertAfterChangeCipherSpec != 0 {
1615 c.sendAlert(c.config.Bugs.AlertAfterChangeCipherSpec)
1616 return errors.New("tls: simulating post-CCS alert")
1617 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001618
Adam Langleye9ada862015-05-11 17:20:37 -07001619 if !c.config.Bugs.SkipFinished {
David Benjaminc895d6b2016-08-11 13:26:41 -04001620 for _, msg := range postCCSMsgs {
1621 c.writeRecord(recordTypeHandshake, msg)
1622 }
1623
1624 if c.config.Bugs.SendExtraFinished {
1625 c.writeRecord(recordTypeHandshake, finished.marshal())
1626 }
Adam Langleye9ada862015-05-11 17:20:37 -07001627 }
Robert Sloanfe7cd212017-08-07 09:03:39 -07001628
Robert Sloan921ef2c2017-10-17 09:02:20 -07001629 if !isResume || !c.config.Bugs.PackAppDataWithHandshake {
1630 c.flushHandshake()
1631 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001632 return nil
1633}
1634
Steven Valdez909b19f2016-11-21 15:35:44 -05001635func (hs *clientHandshakeState) writeChannelIDMessage(channelIDHash []byte) ([]byte, error) {
1636 c := hs.c
1637 channelIDMsg := new(channelIDMsg)
1638 if c.config.ChannelID.Curve != elliptic.P256() {
1639 return nil, fmt.Errorf("tls: Channel ID is not on P-256.")
1640 }
1641 r, s, err := ecdsa.Sign(c.config.rand(), c.config.ChannelID, channelIDHash)
1642 if err != nil {
1643 return nil, err
1644 }
1645 channelID := make([]byte, 128)
1646 writeIntPadded(channelID[0:32], c.config.ChannelID.X)
1647 writeIntPadded(channelID[32:64], c.config.ChannelID.Y)
1648 writeIntPadded(channelID[64:96], r)
1649 writeIntPadded(channelID[96:128], s)
1650 if c.config.Bugs.InvalidChannelIDSignature {
1651 channelID[64] ^= 1
1652 }
1653 channelIDMsg.channelID = channelID
1654
1655 c.channelID = &c.config.ChannelID.PublicKey
1656
1657 return channelIDMsg.marshal(), nil
1658}
1659
Adam Langleyd9e397b2015-01-22 14:27:53 -08001660func (hs *clientHandshakeState) writeClientHash(msg []byte) {
1661 // writeClientHash is called before writeRecord.
1662 hs.writeHash(msg, hs.c.sendHandshakeSeq)
1663}
1664
1665func (hs *clientHandshakeState) writeServerHash(msg []byte) {
1666 // writeServerHash is called after readHandshake.
1667 hs.writeHash(msg, hs.c.recvHandshakeSeq-1)
1668}
1669
1670func (hs *clientHandshakeState) writeHash(msg []byte, seqno uint16) {
1671 if hs.c.isDTLS {
1672 // This is somewhat hacky. DTLS hashes a slightly different format.
1673 // First, the TLS header.
1674 hs.finishedHash.Write(msg[:4])
1675 // Then the sequence number and reassembled fragment offset (always 0).
1676 hs.finishedHash.Write([]byte{byte(seqno >> 8), byte(seqno), 0, 0, 0})
1677 // Then the reassembled fragment (always equal to the message length).
1678 hs.finishedHash.Write(msg[1:4])
1679 // And then the message body.
1680 hs.finishedHash.Write(msg[4:])
1681 } else {
1682 hs.finishedHash.Write(msg)
1683 }
1684}
1685
David Benjaminc895d6b2016-08-11 13:26:41 -04001686// selectClientCertificate selects a certificate for use with the given
1687// certificate, or none if none match. It may return a particular certificate or
1688// nil on success, or an error on internal error.
1689func selectClientCertificate(c *Conn, certReq *certificateRequestMsg) (*Certificate, error) {
Robert Sloana27a6a42017-09-05 08:39:28 -07001690 if len(c.config.Certificates) == 0 {
1691 return nil, nil
David Benjaminc895d6b2016-08-11 13:26:41 -04001692 }
1693
Robert Sloana27a6a42017-09-05 08:39:28 -07001694 // The test is assumed to have configured the certificate it meant to
1695 // send.
1696 if len(c.config.Certificates) > 1 {
1697 return nil, errors.New("tls: multiple certificates configured")
David Benjaminc895d6b2016-08-11 13:26:41 -04001698 }
1699
Robert Sloana27a6a42017-09-05 08:39:28 -07001700 return &c.config.Certificates[0], nil
David Benjaminc895d6b2016-08-11 13:26:41 -04001701}
1702
Adam Langleyd9e397b2015-01-22 14:27:53 -08001703// clientSessionCacheKey returns a key used to cache sessionTickets that could
1704// be used to resume previously negotiated TLS sessions with a server.
1705func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
1706 if len(config.ServerName) > 0 {
1707 return config.ServerName
1708 }
1709 return serverAddr.String()
1710}
1711
1712// mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol
1713// given list of possible protocols and a list of the preference order. The
1714// first list must not be empty. It returns the resulting protocol and flag
1715// indicating if the fallback case was reached.
1716func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
1717 for _, s := range preferenceProtos {
1718 for _, c := range protos {
1719 if s == c {
1720 return s, false
1721 }
1722 }
1723 }
1724
1725 return protos[0], true
1726}
1727
1728// writeIntPadded writes x into b, padded up with leading zeros as
1729// needed.
1730func writeIntPadded(b []byte, x *big.Int) {
1731 for i := range b {
1732 b[i] = 0
1733 }
1734 xb := x.Bytes()
1735 copy(b[len(b)-len(xb):], xb)
1736}
Steven Valdez909b19f2016-11-21 15:35:44 -05001737
1738func generatePSKBinders(hello *clientHelloMsg, pskCipherSuite *cipherSuite, psk, transcript []byte, config *Config) {
1739 if config.Bugs.SendNoPSKBinder {
1740 return
1741 }
1742
1743 binderLen := pskCipherSuite.hash().Size()
1744 if config.Bugs.SendShortPSKBinder {
1745 binderLen--
1746 }
1747
David Benjamin1b249672016-12-06 18:25:50 -05001748 numBinders := 1
1749 if config.Bugs.SendExtraPSKBinder {
1750 numBinders++
1751 }
1752
Steven Valdez909b19f2016-11-21 15:35:44 -05001753 // Fill hello.pskBinders with appropriate length arrays of zeros so the
1754 // length prefixes are correct when computing the binder over the truncated
1755 // ClientHello message.
David Benjamin1b249672016-12-06 18:25:50 -05001756 hello.pskBinders = make([][]byte, numBinders)
1757 for i := range hello.pskBinders {
Steven Valdez909b19f2016-11-21 15:35:44 -05001758 hello.pskBinders[i] = make([]byte, binderLen)
1759 }
1760
1761 helloBytes := hello.marshal()
1762 binderSize := len(hello.pskBinders)*(binderLen+1) + 2
1763 truncatedHello := helloBytes[:len(helloBytes)-binderSize]
1764 binder := computePSKBinder(psk, resumptionPSKBinderLabel, pskCipherSuite, transcript, truncatedHello)
1765 if config.Bugs.SendShortPSKBinder {
1766 binder = binder[:binderLen]
1767 }
1768 if config.Bugs.SendInvalidPSKBinder {
1769 binder[0] ^= 1
1770 }
1771
1772 for i := range hello.pskBinders {
1773 hello.pskBinders[i] = binder
1774 }
1775
1776 hello.raw = nil
1777}