blob: cac1ebf52e2efc4e9ad04ed9b135d33c5ee58812 [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001// 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
Adam Langleydc7e9c42015-09-29 15:21:04 -07005package runner
Adam Langley95c29f32014-06-20 12:00:00 -07006
7import (
8 "bytes"
Nick Harper60edffd2016-06-21 15:19:24 -07009 "crypto"
Adam Langley95c29f32014-06-20 12:00:00 -070010 "crypto/ecdsa"
David Benjamind30a9902014-08-24 01:44:23 -040011 "crypto/elliptic"
Adam Langley95c29f32014-06-20 12:00:00 -070012 "crypto/rsa"
13 "crypto/subtle"
14 "crypto/x509"
Adam Langley95c29f32014-06-20 12:00:00 -070015 "errors"
16 "fmt"
17 "io"
David Benjaminde620d92014-07-18 15:03:41 -040018 "math/big"
Adam Langley95c29f32014-06-20 12:00:00 -070019 "net"
20 "strconv"
Nick Harper0b3625b2016-07-25 16:16:28 -070021 "time"
David Benjamind768c5d2017-03-28 18:28:44 -050022
23 "./ed25519"
Adam Langley95c29f32014-06-20 12:00:00 -070024)
25
26type clientHandshakeState struct {
David Benjamin83f90402015-01-27 01:09:43 -050027 c *Conn
28 serverHello *serverHelloMsg
29 hello *clientHelloMsg
30 suite *cipherSuite
31 finishedHash finishedHash
Nick Harperb41d2e42016-07-01 17:50:32 -040032 keyShares map[CurveID]ecdhCurve
David Benjamin83f90402015-01-27 01:09:43 -050033 masterSecret []byte
34 session *ClientSessionState
35 finishedBytes []byte
Adam Langley95c29f32014-06-20 12:00:00 -070036}
37
Steven Valdezc94998a2017-06-20 10:55:02 -040038func mapClientHelloVersion(vers uint16, isDTLS bool) uint16 {
39 if !isDTLS {
40 return vers
41 }
42
43 switch vers {
44 case VersionTLS12:
45 return VersionDTLS12
46 case VersionTLS10:
47 return VersionDTLS10
48 }
49
50 panic("Unknown ClientHello version.")
51}
52
Adam Langley95c29f32014-06-20 12:00:00 -070053func (c *Conn) clientHandshake() error {
54 if c.config == nil {
55 c.config = defaultConfig()
56 }
57
58 if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
59 return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
60 }
61
David Benjamin83c0bc92014-08-04 01:23:53 -040062 c.sendHandshakeSeq = 0
63 c.recvHandshakeSeq = 0
64
David Benjaminfa055a22014-09-15 16:51:51 -040065 nextProtosLength := 0
66 for _, proto := range c.config.NextProtos {
Adam Langleyefb0e162015-07-09 11:35:04 -070067 if l := len(proto); l > 255 {
David Benjaminfa055a22014-09-15 16:51:51 -040068 return errors.New("tls: invalid NextProtos value")
69 } else {
70 nextProtosLength += 1 + l
71 }
72 }
73 if nextProtosLength > 0xffff {
74 return errors.New("tls: NextProtos values too large")
75 }
76
Steven Valdezfdd10992016-09-15 16:27:05 -040077 minVersion := c.config.minVersion(c.isDTLS)
David Benjamin3c6a1ea2016-09-26 18:30:05 -040078 maxVersion := c.config.maxVersion(c.isDTLS)
Adam Langley95c29f32014-06-20 12:00:00 -070079 hello := &clientHelloMsg{
David Benjaminca6c8262014-11-15 19:06:08 -050080 isDTLS: c.isDTLS,
David Benjaminca6c8262014-11-15 19:06:08 -050081 compressionMethods: []uint8{compressionNone},
82 random: make([]byte, 32),
David Benjamin53210cb2016-11-16 09:01:48 +090083 ocspStapling: !c.config.Bugs.NoOCSPStapling,
84 sctListSupported: !c.config.Bugs.NoSignedCertificateTimestamps,
David Benjaminca6c8262014-11-15 19:06:08 -050085 serverName: c.config.ServerName,
86 supportedCurves: c.config.curvePreferences(),
Steven Valdeza833c352016-11-01 13:39:36 -040087 pskKEModes: []byte{pskDHEKEMode},
David Benjaminca6c8262014-11-15 19:06:08 -050088 supportedPoints: []uint8{pointFormatUncompressed},
89 nextProtoNeg: len(c.config.NextProtos) > 0,
90 secureRenegotiation: []byte{},
91 alpnProtocols: c.config.NextProtos,
92 duplicateExtension: c.config.Bugs.DuplicateExtension,
93 channelIDSupported: c.config.ChannelID != nil,
Steven Valdeza833c352016-11-01 13:39:36 -040094 npnAfterAlpn: c.config.Bugs.SwapNPNAndALPN,
Steven Valdezfdd10992016-09-15 16:27:05 -040095 extendedMasterSecret: maxVersion >= VersionTLS10,
David Benjaminca6c8262014-11-15 19:06:08 -050096 srtpProtectionProfiles: c.config.SRTPProtectionProfiles,
97 srtpMasterKeyIdentifier: c.config.Bugs.SRTPMasterKeyIdentifer,
Adam Langley09505632015-07-30 18:10:13 -070098 customExtension: c.config.Bugs.CustomExtension,
Steven Valdeza833c352016-11-01 13:39:36 -040099 pskBinderFirst: c.config.Bugs.PSKBinderFirst,
Adam Langley95c29f32014-06-20 12:00:00 -0700100 }
101
Steven Valdezc94998a2017-06-20 10:55:02 -0400102 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 }
107 } else {
108 hello.vers = mapClientHelloVersion(maxVersion, c.isDTLS)
109 }
110
111 if c.config.Bugs.SendClientVersion != 0 {
112 hello.vers = c.config.Bugs.SendClientVersion
113 }
114
115 if len(c.config.Bugs.SendSupportedVersions) > 0 {
116 hello.supportedVersions = c.config.Bugs.SendSupportedVersions
117 }
118
David Benjamin163c9562016-08-29 23:14:17 -0400119 disableEMS := c.config.Bugs.NoExtendedMasterSecret
120 if c.cipherSuite != nil {
121 disableEMS = c.config.Bugs.NoExtendedMasterSecretOnRenegotiation
122 }
123
124 if disableEMS {
Adam Langley75712922014-10-10 16:23:43 -0700125 hello.extendedMasterSecret = false
126 }
127
David Benjamin55a43642015-04-20 14:45:55 -0400128 if c.config.Bugs.NoSupportedCurves {
129 hello.supportedCurves = nil
130 }
131
Steven Valdeza833c352016-11-01 13:39:36 -0400132 if len(c.config.Bugs.SendPSKKeyExchangeModes) != 0 {
133 hello.pskKEModes = c.config.Bugs.SendPSKKeyExchangeModes
134 }
135
David Benjaminc241d792016-09-09 10:34:20 -0400136 if c.config.Bugs.SendCompressionMethods != nil {
137 hello.compressionMethods = c.config.Bugs.SendCompressionMethods
138 }
139
David Benjamina81967b2016-12-22 09:16:57 -0500140 if c.config.Bugs.SendSupportedPointFormats != nil {
141 hello.supportedPoints = c.config.Bugs.SendSupportedPointFormats
142 }
143
Adam Langley2ae77d22014-10-28 17:29:33 -0700144 if len(c.clientVerify) > 0 && !c.config.Bugs.EmptyRenegotiationInfo {
145 if c.config.Bugs.BadRenegotiationInfo {
146 hello.secureRenegotiation = append(hello.secureRenegotiation, c.clientVerify...)
147 hello.secureRenegotiation[0] ^= 0x80
148 } else {
149 hello.secureRenegotiation = c.clientVerify
150 }
151 }
152
David Benjamin3e052de2015-11-25 20:10:31 -0500153 if c.noRenegotiationInfo() {
David Benjaminca6554b2014-11-08 12:31:52 -0500154 hello.secureRenegotiation = nil
155 }
156
Nick Harperb41d2e42016-07-01 17:50:32 -0400157 var keyShares map[CurveID]ecdhCurve
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400158 if maxVersion >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400159 keyShares = make(map[CurveID]ecdhCurve)
Nick Harperdcfbc672016-07-16 17:47:31 +0200160 hello.hasKeyShares = true
David Benjamin7e1f9842016-09-20 19:24:40 -0400161 hello.trailingKeyShareData = c.config.Bugs.TrailingKeyShareData
Nick Harperdcfbc672016-07-16 17:47:31 +0200162 curvesToSend := c.config.defaultCurves()
Nick Harperb41d2e42016-07-01 17:50:32 -0400163 for _, curveID := range hello.supportedCurves {
Nick Harperdcfbc672016-07-16 17:47:31 +0200164 if !curvesToSend[curveID] {
165 continue
166 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400167 curve, ok := curveForCurveID(curveID)
168 if !ok {
169 continue
170 }
171 publicKey, err := curve.offer(c.config.rand())
172 if err != nil {
173 return err
174 }
Steven Valdez0ee2e112016-07-15 06:51:15 -0400175
176 if c.config.Bugs.SendCurve != 0 {
177 curveID = c.config.Bugs.SendCurve
178 }
179 if c.config.Bugs.InvalidECDHPoint {
180 publicKey[0] ^= 0xff
181 }
182
Nick Harperb41d2e42016-07-01 17:50:32 -0400183 hello.keyShares = append(hello.keyShares, keyShareEntry{
184 group: curveID,
185 keyExchange: publicKey,
186 })
187 keyShares[curveID] = curve
Steven Valdez143e8b32016-07-11 13:19:03 -0400188
189 if c.config.Bugs.DuplicateKeyShares {
190 hello.keyShares = append(hello.keyShares, hello.keyShares[len(hello.keyShares)-1])
191 }
192 }
193
194 if c.config.Bugs.MissingKeyShare {
Steven Valdez5440fe02016-07-18 12:40:30 -0400195 hello.hasKeyShares = false
Nick Harperb41d2e42016-07-01 17:50:32 -0400196 }
197 }
198
Adam Langley95c29f32014-06-20 12:00:00 -0700199 possibleCipherSuites := c.config.cipherSuites()
200 hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
201
202NextCipherSuite:
203 for _, suiteId := range possibleCipherSuites {
204 for _, suite := range cipherSuites {
205 if suite.id != suiteId {
206 continue
207 }
David Benjamin5ecb88b2016-10-04 17:51:35 -0400208 // Don't advertise TLS 1.2-only cipher suites unless
209 // we're attempting TLS 1.2.
210 if maxVersion < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
211 continue
212 }
213 // Don't advertise non-DTLS cipher suites in DTLS.
214 if c.isDTLS && suite.flags&suiteNoDTLS != 0 {
215 continue
David Benjamin83c0bc92014-08-04 01:23:53 -0400216 }
Adam Langley95c29f32014-06-20 12:00:00 -0700217 hello.cipherSuites = append(hello.cipherSuites, suiteId)
218 continue NextCipherSuite
219 }
220 }
221
David Benjamin5ecb88b2016-10-04 17:51:35 -0400222 if c.config.Bugs.AdvertiseAllConfiguredCiphers {
223 hello.cipherSuites = possibleCipherSuites
224 }
225
Adam Langley5021b222015-06-12 18:27:58 -0700226 if c.config.Bugs.SendRenegotiationSCSV {
227 hello.cipherSuites = append(hello.cipherSuites, renegotiationSCSV)
228 }
229
David Benjaminbef270a2014-08-02 04:22:02 -0400230 if c.config.Bugs.SendFallbackSCSV {
231 hello.cipherSuites = append(hello.cipherSuites, fallbackSCSV)
232 }
233
Adam Langley95c29f32014-06-20 12:00:00 -0700234 _, err := io.ReadFull(c.config.rand(), hello.random)
235 if err != nil {
236 c.sendAlert(alertInternalError)
237 return errors.New("tls: short read from Rand: " + err.Error())
238 }
239
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400240 if maxVersion >= VersionTLS12 && !c.config.Bugs.NoSignatureAlgorithms {
David Benjamin7a41d372016-07-09 11:21:54 -0700241 hello.signatureAlgorithms = c.config.verifySignatureAlgorithms()
Adam Langley95c29f32014-06-20 12:00:00 -0700242 }
243
244 var session *ClientSessionState
245 var cacheKey string
246 sessionCache := c.config.ClientSessionCache
Adam Langley95c29f32014-06-20 12:00:00 -0700247
248 if sessionCache != nil {
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500249 hello.ticketSupported = !c.config.SessionTicketsDisabled
Adam Langley95c29f32014-06-20 12:00:00 -0700250
251 // Try to resume a previously negotiated TLS session, if
252 // available.
253 cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
Nick Harper0b3625b2016-07-25 16:16:28 -0700254 // TODO(nharper): Support storing more than one session
255 // ticket for TLS 1.3.
Adam Langley95c29f32014-06-20 12:00:00 -0700256 candidateSession, ok := sessionCache.Get(cacheKey)
257 if ok {
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500258 ticketOk := !c.config.SessionTicketsDisabled || candidateSession.sessionTicket == nil
259
Adam Langley95c29f32014-06-20 12:00:00 -0700260 // Check that the ciphersuite/version used for the
261 // previous session are still valid.
262 cipherSuiteOk := false
David Benjamin2b02f4b2016-11-16 16:11:47 +0900263 if candidateSession.vers <= VersionTLS12 {
264 for _, id := range hello.cipherSuites {
265 if id == candidateSession.cipherSuite {
266 cipherSuiteOk = true
267 break
268 }
Adam Langley95c29f32014-06-20 12:00:00 -0700269 }
David Benjamin2b02f4b2016-11-16 16:11:47 +0900270 } else {
271 // TLS 1.3 allows the cipher to change on
272 // resumption.
273 cipherSuiteOk = true
Adam Langley95c29f32014-06-20 12:00:00 -0700274 }
275
Steven Valdezfdd10992016-09-15 16:27:05 -0400276 versOk := candidateSession.vers >= minVersion &&
277 candidateSession.vers <= maxVersion
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500278 if ticketOk && versOk && cipherSuiteOk {
Adam Langley95c29f32014-06-20 12:00:00 -0700279 session = candidateSession
280 }
281 }
282 }
283
Steven Valdeza833c352016-11-01 13:39:36 -0400284 var pskCipherSuite *cipherSuite
Nick Harper0b3625b2016-07-25 16:16:28 -0700285 if session != nil && c.config.time().Before(session.ticketExpiration) {
David Benjamind5a4ecb2016-07-18 01:17:13 +0200286 ticket := session.sessionTicket
David Benjamin4199b0d2016-11-01 13:58:25 -0400287 if c.config.Bugs.FilterTicket != nil && len(ticket) > 0 {
288 // Copy the ticket so FilterTicket may act in-place.
David Benjamind5a4ecb2016-07-18 01:17:13 +0200289 ticket = make([]byte, len(session.sessionTicket))
290 copy(ticket, session.sessionTicket)
David Benjamin4199b0d2016-11-01 13:58:25 -0400291
292 ticket, err = c.config.Bugs.FilterTicket(ticket)
293 if err != nil {
294 return err
Adam Langley38311732014-10-16 19:04:35 -0700295 }
David Benjamind5a4ecb2016-07-18 01:17:13 +0200296 }
297
David Benjamin405da482016-08-08 17:25:07 -0400298 if session.vers >= VersionTLS13 || c.config.Bugs.SendBothTickets {
Steven Valdeza833c352016-11-01 13:39:36 -0400299 pskCipherSuite = cipherSuiteFromID(session.cipherSuite)
300 if pskCipherSuite == nil {
301 return errors.New("tls: client session cache has invalid cipher suite")
302 }
Nick Harper0b3625b2016-07-25 16:16:28 -0700303 // TODO(nharper): Support sending more
304 // than one PSK identity.
Steven Valdeza833c352016-11-01 13:39:36 -0400305 ticketAge := uint32(c.config.time().Sub(session.ticketCreationTime) / time.Millisecond)
David Benjamin35ac5b72017-03-03 15:05:56 -0500306 if c.config.Bugs.SendTicketAge != 0 {
307 ticketAge = uint32(c.config.Bugs.SendTicketAge / time.Millisecond)
308 }
Steven Valdez5b986082016-09-01 12:29:49 -0400309 psk := pskIdentity{
Steven Valdeza833c352016-11-01 13:39:36 -0400310 ticket: ticket,
311 obfuscatedTicketAge: session.ticketAgeAdd + ticketAge,
Nick Harper0b3625b2016-07-25 16:16:28 -0700312 }
Steven Valdez5b986082016-09-01 12:29:49 -0400313 hello.pskIdentities = []pskIdentity{psk}
Steven Valdezaf3b8a92016-11-01 12:49:22 -0400314
315 if c.config.Bugs.ExtraPSKIdentity {
316 hello.pskIdentities = append(hello.pskIdentities, psk)
317 }
David Benjamin405da482016-08-08 17:25:07 -0400318 }
319
320 if session.vers < VersionTLS13 || c.config.Bugs.SendBothTickets {
321 if ticket != nil {
322 hello.sessionTicket = ticket
323 // A random session ID is used to detect when the
324 // server accepted the ticket and is resuming a session
325 // (see RFC 5077).
326 sessionIdLen := 16
David Benjamind4c349b2017-02-09 14:07:17 -0500327 if c.config.Bugs.TicketSessionIDLength != 0 {
328 sessionIdLen = c.config.Bugs.TicketSessionIDLength
329 }
330 if c.config.Bugs.EmptyTicketSessionID {
331 sessionIdLen = 0
David Benjamin405da482016-08-08 17:25:07 -0400332 }
333 hello.sessionId = make([]byte, sessionIdLen)
334 if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
335 c.sendAlert(alertInternalError)
336 return errors.New("tls: short read from Rand: " + err.Error())
337 }
338 } else {
339 hello.sessionId = session.sessionId
David Benjaminfe8eb9a2014-11-17 03:19:02 -0500340 }
Adam Langley95c29f32014-06-20 12:00:00 -0700341 }
342 }
343
David Benjamin75f99142016-11-12 12:36:06 +0900344 if c.config.Bugs.SendCipherSuites != nil {
345 hello.cipherSuites = c.config.Bugs.SendCipherSuites
346 }
347
Nick Harperf2511f12016-12-06 16:02:31 -0800348 var sendEarlyData bool
Steven Valdez2d850622017-01-11 11:34:52 -0500349 if len(hello.pskIdentities) > 0 && c.config.Bugs.SendEarlyData != nil {
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500350 hello.hasEarlyData = true
Nick Harperf2511f12016-12-06 16:02:31 -0800351 sendEarlyData = true
352 }
353 if c.config.Bugs.SendFakeEarlyDataLength > 0 {
354 hello.hasEarlyData = true
355 }
356 if c.config.Bugs.OmitEarlyDataExtension {
357 hello.hasEarlyData = false
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500358 }
359
David Benjamind86c7672014-08-02 04:07:12 -0400360 var helloBytes []byte
361 if c.config.Bugs.SendV2ClientHello {
David Benjamin94d701b2014-11-30 13:54:41 -0500362 // Test that the peer left-pads random.
363 hello.random[0] = 0
David Benjamind86c7672014-08-02 04:07:12 -0400364 v2Hello := &v2ClientHelloMsg{
365 vers: hello.vers,
366 cipherSuites: hello.cipherSuites,
367 // No session resumption for V2ClientHello.
368 sessionId: nil,
David Benjamin94d701b2014-11-30 13:54:41 -0500369 challenge: hello.random[1:],
David Benjamind86c7672014-08-02 04:07:12 -0400370 }
371 helloBytes = v2Hello.marshal()
372 c.writeV2Record(helloBytes)
373 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400374 if len(hello.pskIdentities) > 0 {
375 generatePSKBinders(hello, pskCipherSuite, session.masterSecret, []byte{}, c.config)
376 }
David Benjamind86c7672014-08-02 04:07:12 -0400377 helloBytes = hello.marshal()
Steven Valdeza833c352016-11-01 13:39:36 -0400378
David Benjamin7964b182016-07-14 23:36:30 -0400379 if c.config.Bugs.PartialClientFinishedWithClientHello {
380 // Include one byte of Finished. We can compute it
381 // without completing the handshake. This assumes we
382 // negotiate TLS 1.3 with no HelloRetryRequest or
383 // CertificateRequest.
384 toWrite := make([]byte, 0, len(helloBytes)+1)
385 toWrite = append(toWrite, helloBytes...)
386 toWrite = append(toWrite, typeFinished)
387 c.writeRecord(recordTypeHandshake, toWrite)
388 } else {
389 c.writeRecord(recordTypeHandshake, helloBytes)
390 }
David Benjamind86c7672014-08-02 04:07:12 -0400391 }
David Benjamin582ba042016-07-07 12:33:25 -0700392 c.flushHandshake()
Adam Langley95c29f32014-06-20 12:00:00 -0700393
David Benjamin83f90402015-01-27 01:09:43 -0500394 if err := c.simulatePacketLoss(nil); err != nil {
395 return err
396 }
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500397 if c.config.Bugs.SendEarlyAlert {
398 c.sendAlert(alertHandshakeFailure)
399 }
Nick Harperf2511f12016-12-06 16:02:31 -0800400 if c.config.Bugs.SendFakeEarlyDataLength > 0 {
401 c.sendFakeEarlyData(c.config.Bugs.SendFakeEarlyDataLength)
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500402 }
Nick Harperf2511f12016-12-06 16:02:31 -0800403
404 // Derive early write keys and set Conn state to allow early writes.
405 if sendEarlyData {
406 finishedHash := newFinishedHash(session.vers, pskCipherSuite)
407 finishedHash.addEntropy(session.masterSecret)
408 finishedHash.Write(helloBytes)
409 earlyTrafficSecret := finishedHash.deriveSecret(earlyTrafficLabel)
410 c.out.useTrafficSecret(session.vers, pskCipherSuite, earlyTrafficSecret, clientWrite)
Nick Harperf2511f12016-12-06 16:02:31 -0800411 for _, earlyData := range c.config.Bugs.SendEarlyData {
412 if _, err := c.writeRecord(recordTypeApplicationData, earlyData); err != nil {
413 return err
414 }
415 }
416 }
417
Adam Langley95c29f32014-06-20 12:00:00 -0700418 msg, err := c.readHandshake()
419 if err != nil {
420 return err
421 }
David Benjamin83c0bc92014-08-04 01:23:53 -0400422
423 if c.isDTLS {
424 helloVerifyRequest, ok := msg.(*helloVerifyRequestMsg)
425 if ok {
Steven Valdezc94998a2017-06-20 10:55:02 -0400426 if helloVerifyRequest.vers != VersionDTLS10 {
David Benjamin8bc38f52014-08-16 12:07:27 -0400427 // Per RFC 6347, the version field in
428 // HelloVerifyRequest SHOULD be always DTLS
429 // 1.0. Enforce this for testing purposes.
430 return errors.New("dtls: bad HelloVerifyRequest version")
431 }
432
David Benjamin83c0bc92014-08-04 01:23:53 -0400433 hello.raw = nil
434 hello.cookie = helloVerifyRequest.cookie
435 helloBytes = hello.marshal()
436 c.writeRecord(recordTypeHandshake, helloBytes)
David Benjamin582ba042016-07-07 12:33:25 -0700437 c.flushHandshake()
David Benjamin83c0bc92014-08-04 01:23:53 -0400438
David Benjamin83f90402015-01-27 01:09:43 -0500439 if err := c.simulatePacketLoss(nil); err != nil {
440 return err
441 }
David Benjamin83c0bc92014-08-04 01:23:53 -0400442 msg, err = c.readHandshake()
443 if err != nil {
444 return err
445 }
446 }
447 }
448
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400449 var serverWireVersion uint16
Nick Harperdcfbc672016-07-16 17:47:31 +0200450 switch m := msg.(type) {
451 case *helloRetryRequestMsg:
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400452 serverWireVersion = m.vers
Nick Harperdcfbc672016-07-16 17:47:31 +0200453 case *serverHelloMsg:
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400454 serverWireVersion = m.vers
Nick Harperdcfbc672016-07-16 17:47:31 +0200455 default:
456 c.sendAlert(alertUnexpectedMessage)
457 return fmt.Errorf("tls: received unexpected message of type %T when waiting for HelloRetryRequest or ServerHello", msg)
458 }
459
Steven Valdezc94998a2017-06-20 10:55:02 -0400460 serverVersion, ok := c.config.isSupportedVersion(serverWireVersion, c.isDTLS)
Nick Harperdcfbc672016-07-16 17:47:31 +0200461 if !ok {
462 c.sendAlert(alertProtocolVersion)
463 return fmt.Errorf("tls: server selected unsupported protocol version %x", c.vers)
464 }
Steven Valdezc94998a2017-06-20 10:55:02 -0400465 c.wireVersion = serverWireVersion
Steven Valdezfdd10992016-09-15 16:27:05 -0400466 c.vers = serverVersion
Nick Harperdcfbc672016-07-16 17:47:31 +0200467 c.haveVers = true
468
469 helloRetryRequest, haveHelloRetryRequest := msg.(*helloRetryRequestMsg)
470 var secondHelloBytes []byte
471 if haveHelloRetryRequest {
Nick Harperf2511f12016-12-06 16:02:31 -0800472 c.out.resetCipher()
David Benjamin3baa6e12016-10-07 21:10:38 -0400473 if len(helloRetryRequest.cookie) > 0 {
474 hello.tls13Cookie = helloRetryRequest.cookie
475 }
476
Steven Valdez5440fe02016-07-18 12:40:30 -0400477 if c.config.Bugs.MisinterpretHelloRetryRequestCurve != 0 {
David Benjamin3baa6e12016-10-07 21:10:38 -0400478 helloRetryRequest.hasSelectedGroup = true
Steven Valdez5440fe02016-07-18 12:40:30 -0400479 helloRetryRequest.selectedGroup = c.config.Bugs.MisinterpretHelloRetryRequestCurve
480 }
David Benjamin3baa6e12016-10-07 21:10:38 -0400481 if helloRetryRequest.hasSelectedGroup {
482 var hrrCurveFound bool
483 group := helloRetryRequest.selectedGroup
484 for _, curveID := range hello.supportedCurves {
485 if group == curveID {
486 hrrCurveFound = true
487 break
488 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200489 }
David Benjamin3baa6e12016-10-07 21:10:38 -0400490 if !hrrCurveFound || keyShares[group] != nil {
491 c.sendAlert(alertHandshakeFailure)
492 return errors.New("tls: received invalid HelloRetryRequest")
493 }
494 curve, ok := curveForCurveID(group)
495 if !ok {
496 return errors.New("tls: Unable to get curve requested in HelloRetryRequest")
497 }
498 publicKey, err := curve.offer(c.config.rand())
499 if err != nil {
500 return err
501 }
502 keyShares[group] = curve
Steven Valdeza833c352016-11-01 13:39:36 -0400503 hello.keyShares = []keyShareEntry{{
David Benjamin3baa6e12016-10-07 21:10:38 -0400504 group: group,
505 keyExchange: publicKey,
Steven Valdeza833c352016-11-01 13:39:36 -0400506 }}
Nick Harperdcfbc672016-07-16 17:47:31 +0200507 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200508
Steven Valdez5440fe02016-07-18 12:40:30 -0400509 if c.config.Bugs.SecondClientHelloMissingKeyShare {
510 hello.hasKeyShares = false
511 }
512
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500513 hello.hasEarlyData = c.config.Bugs.SendEarlyDataOnSecondClientHello
Nick Harperdcfbc672016-07-16 17:47:31 +0200514 hello.raw = nil
515
Steven Valdeza833c352016-11-01 13:39:36 -0400516 if len(hello.pskIdentities) > 0 {
517 generatePSKBinders(hello, pskCipherSuite, session.masterSecret, append(helloBytes, helloRetryRequest.marshal()...), c.config)
518 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200519 secondHelloBytes = hello.marshal()
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500520
521 if c.config.Bugs.InterleaveEarlyData {
522 c.sendFakeEarlyData(4)
523 c.writeRecord(recordTypeHandshake, secondHelloBytes[:16])
524 c.sendFakeEarlyData(4)
525 c.writeRecord(recordTypeHandshake, secondHelloBytes[16:])
526 } else {
527 c.writeRecord(recordTypeHandshake, secondHelloBytes)
528 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200529 c.flushHandshake()
530
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500531 if c.config.Bugs.SendEarlyDataOnSecondClientHello {
532 c.sendFakeEarlyData(4)
533 }
534
Nick Harperdcfbc672016-07-16 17:47:31 +0200535 msg, err = c.readHandshake()
536 if err != nil {
537 return err
538 }
539 }
540
Adam Langley95c29f32014-06-20 12:00:00 -0700541 serverHello, ok := msg.(*serverHelloMsg)
542 if !ok {
543 c.sendAlert(alertUnexpectedMessage)
544 return unexpectedMessageError(serverHello, msg)
545 }
546
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400547 if serverWireVersion != serverHello.vers {
Adam Langley95c29f32014-06-20 12:00:00 -0700548 c.sendAlert(alertProtocolVersion)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400549 return fmt.Errorf("tls: server sent non-matching version %x vs %x", serverWireVersion, serverHello.vers)
Adam Langley95c29f32014-06-20 12:00:00 -0700550 }
Adam Langley95c29f32014-06-20 12:00:00 -0700551
Nick Harper85f20c22016-07-04 10:11:59 -0700552 // Check for downgrade signals in the server random, per
David Benjamina128a552016-10-13 14:26:33 -0400553 // draft-ietf-tls-tls13-16, section 4.1.3.
Nick Harper85f20c22016-07-04 10:11:59 -0700554 if c.vers <= VersionTLS12 && c.config.maxVersion(c.isDTLS) >= VersionTLS13 {
David Benjamin1f61f0d2016-07-10 12:20:35 -0400555 if bytes.Equal(serverHello.random[len(serverHello.random)-8:], downgradeTLS13) {
Nick Harper85f20c22016-07-04 10:11:59 -0700556 c.sendAlert(alertProtocolVersion)
557 return errors.New("tls: downgrade from TLS 1.3 detected")
558 }
559 }
560 if c.vers <= VersionTLS11 && c.config.maxVersion(c.isDTLS) >= VersionTLS12 {
David Benjamin1f61f0d2016-07-10 12:20:35 -0400561 if bytes.Equal(serverHello.random[len(serverHello.random)-8:], downgradeTLS12) {
Nick Harper85f20c22016-07-04 10:11:59 -0700562 c.sendAlert(alertProtocolVersion)
563 return errors.New("tls: downgrade from TLS 1.2 detected")
564 }
565 }
566
Nick Harper0b3625b2016-07-25 16:16:28 -0700567 suite := mutualCipherSuite(hello.cipherSuites, serverHello.cipherSuite)
Adam Langley95c29f32014-06-20 12:00:00 -0700568 if suite == nil {
569 c.sendAlert(alertHandshakeFailure)
570 return fmt.Errorf("tls: server selected an unsupported cipher suite")
571 }
572
David Benjamin3baa6e12016-10-07 21:10:38 -0400573 if haveHelloRetryRequest && helloRetryRequest.hasSelectedGroup && helloRetryRequest.selectedGroup != serverHello.keyShare.group {
Nick Harperdcfbc672016-07-16 17:47:31 +0200574 c.sendAlert(alertHandshakeFailure)
575 return errors.New("tls: ServerHello parameters did not match HelloRetryRequest")
576 }
577
Adam Langley95c29f32014-06-20 12:00:00 -0700578 hs := &clientHandshakeState{
579 c: c,
580 serverHello: serverHello,
581 hello: hello,
582 suite: suite,
583 finishedHash: newFinishedHash(c.vers, suite),
Nick Harperb41d2e42016-07-01 17:50:32 -0400584 keyShares: keyShares,
Adam Langley95c29f32014-06-20 12:00:00 -0700585 session: session,
586 }
587
David Benjamin83c0bc92014-08-04 01:23:53 -0400588 hs.writeHash(helloBytes, hs.c.sendHandshakeSeq-1)
Nick Harperdcfbc672016-07-16 17:47:31 +0200589 if haveHelloRetryRequest {
590 hs.writeServerHash(helloRetryRequest.marshal())
591 hs.writeClientHash(secondHelloBytes)
592 }
David Benjamin83c0bc92014-08-04 01:23:53 -0400593 hs.writeServerHash(hs.serverHello.marshal())
Adam Langley95c29f32014-06-20 12:00:00 -0700594
David Benjamin8d315d72016-07-18 01:03:18 +0200595 if c.vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400596 if err := hs.doTLS13Handshake(); err != nil {
Adam Langley95c29f32014-06-20 12:00:00 -0700597 return err
598 }
599 } else {
Nick Harperb41d2e42016-07-01 17:50:32 -0400600 if c.config.Bugs.EarlyChangeCipherSpec > 0 {
601 hs.establishKeys()
602 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
603 }
604
605 if hs.serverHello.compressionMethod != compressionNone {
606 c.sendAlert(alertUnexpectedMessage)
607 return errors.New("tls: server selected unsupported compression format")
608 }
609
610 err = hs.processServerExtensions(&serverHello.extensions)
611 if err != nil {
Adam Langley95c29f32014-06-20 12:00:00 -0700612 return err
613 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400614
615 isResume, err := hs.processServerHello()
616 if err != nil {
Adam Langley95c29f32014-06-20 12:00:00 -0700617 return err
618 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400619
620 if isResume {
621 if c.config.Bugs.EarlyChangeCipherSpec == 0 {
622 if err := hs.establishKeys(); err != nil {
623 return err
624 }
625 }
626 if err := hs.readSessionTicket(); err != nil {
627 return err
628 }
629 if err := hs.readFinished(c.firstFinished[:]); err != nil {
630 return err
631 }
632 if err := hs.sendFinished(nil, isResume); err != nil {
633 return err
634 }
635 } else {
636 if err := hs.doFullHandshake(); err != nil {
637 return err
638 }
639 if err := hs.establishKeys(); err != nil {
640 return err
641 }
642 if err := hs.sendFinished(c.firstFinished[:], isResume); err != nil {
643 return err
644 }
645 // Most retransmits are triggered by a timeout, but the final
646 // leg of the handshake is retransmited upon re-receiving a
647 // Finished.
648 if err := c.simulatePacketLoss(func() {
David Benjamin02edcd02016-07-27 17:40:37 -0400649 c.sendHandshakeSeq--
Nick Harperb41d2e42016-07-01 17:50:32 -0400650 c.writeRecord(recordTypeHandshake, hs.finishedBytes)
651 c.flushHandshake()
652 }); err != nil {
653 return err
654 }
655 if err := hs.readSessionTicket(); err != nil {
656 return err
657 }
658 if err := hs.readFinished(nil); err != nil {
659 return err
660 }
Adam Langley95c29f32014-06-20 12:00:00 -0700661 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400662
663 if sessionCache != nil && hs.session != nil && session != hs.session {
664 if c.config.Bugs.RequireSessionTickets && len(hs.session.sessionTicket) == 0 {
665 return errors.New("tls: new session used session IDs instead of tickets")
666 }
667 sessionCache.Put(cacheKey, hs.session)
David Benjamin83f90402015-01-27 01:09:43 -0500668 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400669
670 c.didResume = isResume
David Benjamin97a0a082016-07-13 17:57:35 -0400671 c.exporterSecret = hs.masterSecret
Adam Langley95c29f32014-06-20 12:00:00 -0700672 }
673
Adam Langley95c29f32014-06-20 12:00:00 -0700674 c.handshakeComplete = true
David Benjaminc565ebb2015-04-03 04:06:36 -0400675 c.cipherSuite = suite
676 copy(c.clientRandom[:], hs.hello.random)
677 copy(c.serverRandom[:], hs.serverHello.random)
Paul Lietar4fac72e2015-09-09 13:44:55 +0100678
Adam Langley95c29f32014-06-20 12:00:00 -0700679 return nil
680}
681
Nick Harperb41d2e42016-07-01 17:50:32 -0400682func (hs *clientHandshakeState) doTLS13Handshake() error {
683 c := hs.c
684
685 // Once the PRF hash is known, TLS 1.3 does not require a handshake
686 // buffer.
687 hs.finishedHash.discardHandshakeBuffer()
688
689 zeroSecret := hs.finishedHash.zeroSecret()
690
691 // Resolve PSK and compute the early secret.
692 //
693 // TODO(davidben): This will need to be handled slightly earlier once
694 // 0-RTT is implemented.
Steven Valdez803c77a2016-09-06 14:13:43 -0400695 if hs.serverHello.hasPSKIdentity {
Nick Harper0b3625b2016-07-25 16:16:28 -0700696 // We send at most one PSK identity.
697 if hs.session == nil || hs.serverHello.pskIdentity != 0 {
698 c.sendAlert(alertUnknownPSKIdentity)
699 return errors.New("tls: server sent unknown PSK identity")
700 }
David Benjamin2b02f4b2016-11-16 16:11:47 +0900701 sessionCipher := cipherSuiteFromID(hs.session.cipherSuite)
702 if sessionCipher == nil || sessionCipher.hash() != hs.suite.hash() {
Nick Harper0b3625b2016-07-25 16:16:28 -0700703 c.sendAlert(alertHandshakeFailure)
David Benjamin2b02f4b2016-11-16 16:11:47 +0900704 return errors.New("tls: server resumed an invalid session for the cipher suite")
Nick Harper0b3625b2016-07-25 16:16:28 -0700705 }
David Benjamin48891ad2016-12-04 00:02:43 -0500706 hs.finishedHash.addEntropy(hs.session.masterSecret)
Nick Harper0b3625b2016-07-25 16:16:28 -0700707 c.didResume = true
Nick Harperb41d2e42016-07-01 17:50:32 -0400708 } else {
David Benjamin48891ad2016-12-04 00:02:43 -0500709 hs.finishedHash.addEntropy(zeroSecret)
Nick Harperb41d2e42016-07-01 17:50:32 -0400710 }
711
Steven Valdeza833c352016-11-01 13:39:36 -0400712 if !hs.serverHello.hasKeyShare {
713 c.sendAlert(alertUnsupportedExtension)
714 return errors.New("tls: server omitted KeyShare on resumption.")
715 }
716
Nick Harperb41d2e42016-07-01 17:50:32 -0400717 // Resolve ECDHE and compute the handshake secret.
Steven Valdez803c77a2016-09-06 14:13:43 -0400718 if !c.config.Bugs.MissingKeyShare && !c.config.Bugs.SecondClientHelloMissingKeyShare {
Nick Harperb41d2e42016-07-01 17:50:32 -0400719 curve, ok := hs.keyShares[hs.serverHello.keyShare.group]
720 if !ok {
721 c.sendAlert(alertHandshakeFailure)
722 return errors.New("tls: server selected an unsupported group")
723 }
Steven Valdez5440fe02016-07-18 12:40:30 -0400724 c.curveID = hs.serverHello.keyShare.group
Nick Harperb41d2e42016-07-01 17:50:32 -0400725
David Benjamin48891ad2016-12-04 00:02:43 -0500726 ecdheSecret, err := curve.finish(hs.serverHello.keyShare.keyExchange)
Nick Harperb41d2e42016-07-01 17:50:32 -0400727 if err != nil {
728 return err
729 }
David Benjamin48891ad2016-12-04 00:02:43 -0500730 hs.finishedHash.addEntropy(ecdheSecret)
Nick Harperb41d2e42016-07-01 17:50:32 -0400731 } else {
David Benjamin48891ad2016-12-04 00:02:43 -0500732 hs.finishedHash.addEntropy(zeroSecret)
Nick Harperb41d2e42016-07-01 17:50:32 -0400733 }
734
Steven Valdez520e1222017-06-13 12:45:25 -0400735 if c.wireVersion == tls13ExperimentVersion {
736 if err := c.readRecord(recordTypeChangeCipherSpec); err != nil {
737 return err
738 }
739 }
740
Nick Harperf2511f12016-12-06 16:02:31 -0800741 // Derive handshake traffic keys and switch read key to handshake
742 // traffic key.
David Benjamin48891ad2016-12-04 00:02:43 -0500743 clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientHandshakeTrafficLabel)
David Benjamin48891ad2016-12-04 00:02:43 -0500744 serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverHandshakeTrafficLabel)
Steven Valdeza833c352016-11-01 13:39:36 -0400745 c.in.useTrafficSecret(c.vers, hs.suite, serverHandshakeTrafficSecret, serverWrite)
Nick Harperb41d2e42016-07-01 17:50:32 -0400746
747 msg, err := c.readHandshake()
748 if err != nil {
749 return err
750 }
751
752 encryptedExtensions, ok := msg.(*encryptedExtensionsMsg)
753 if !ok {
754 c.sendAlert(alertUnexpectedMessage)
755 return unexpectedMessageError(encryptedExtensions, msg)
756 }
757 hs.writeServerHash(encryptedExtensions.marshal())
758
759 err = hs.processServerExtensions(&encryptedExtensions.extensions)
760 if err != nil {
761 return err
762 }
763
764 var chainToSend *Certificate
David Benjamin8d343b42016-07-09 14:26:01 -0700765 var certReq *certificateRequestMsg
Steven Valdeza833c352016-11-01 13:39:36 -0400766 if c.didResume {
Nick Harper0b3625b2016-07-25 16:16:28 -0700767 // Copy over authentication from the session.
768 c.peerCertificates = hs.session.serverCertificates
769 c.sctList = hs.session.sctList
770 c.ocspResponse = hs.session.ocspResponse
David Benjamin44b33bc2016-07-01 22:40:23 -0400771 } else {
Nick Harperb41d2e42016-07-01 17:50:32 -0400772 msg, err := c.readHandshake()
773 if err != nil {
774 return err
775 }
776
David Benjamin8d343b42016-07-09 14:26:01 -0700777 var ok bool
778 certReq, ok = msg.(*certificateRequestMsg)
Nick Harperb41d2e42016-07-01 17:50:32 -0400779 if ok {
David Benjamin8a8349b2016-08-18 02:32:23 -0400780 if len(certReq.requestContext) != 0 {
781 return errors.New("tls: non-empty certificate request context sent in handshake")
782 }
783
David Benjaminb62d2872016-07-18 14:55:02 +0200784 if c.config.Bugs.IgnorePeerSignatureAlgorithmPreferences {
785 certReq.signatureAlgorithms = c.config.signSignatureAlgorithms()
786 }
787
Nick Harperb41d2e42016-07-01 17:50:32 -0400788 hs.writeServerHash(certReq.marshal())
Nick Harperb41d2e42016-07-01 17:50:32 -0400789
790 chainToSend, err = selectClientCertificate(c, certReq)
791 if err != nil {
792 return err
793 }
794
795 msg, err = c.readHandshake()
796 if err != nil {
797 return err
798 }
799 }
800
801 certMsg, ok := msg.(*certificateMsg)
802 if !ok {
803 c.sendAlert(alertUnexpectedMessage)
804 return unexpectedMessageError(certMsg, msg)
805 }
806 hs.writeServerHash(certMsg.marshal())
807
David Benjamin53210cb2016-11-16 09:01:48 +0900808 // Check for unsolicited extensions.
809 for i, cert := range certMsg.certificates {
810 if c.config.Bugs.NoOCSPStapling && cert.ocspResponse != nil {
811 c.sendAlert(alertUnsupportedExtension)
812 return errors.New("tls: unexpected OCSP response in the server certificate")
813 }
814 if c.config.Bugs.NoSignedCertificateTimestamps && cert.sctList != nil {
815 c.sendAlert(alertUnsupportedExtension)
816 return errors.New("tls: unexpected SCT list in the server certificate")
817 }
818 if i > 0 && c.config.Bugs.ExpectNoExtensionsOnIntermediate && (cert.ocspResponse != nil || cert.sctList != nil) {
819 c.sendAlert(alertUnsupportedExtension)
820 return errors.New("tls: unexpected extensions in the server certificate")
821 }
822 }
823
Nick Harperb41d2e42016-07-01 17:50:32 -0400824 if err := hs.verifyCertificates(certMsg); err != nil {
825 return err
826 }
827 leaf := c.peerCertificates[0]
Steven Valdeza833c352016-11-01 13:39:36 -0400828 c.ocspResponse = certMsg.certificates[0].ocspResponse
829 c.sctList = certMsg.certificates[0].sctList
830
Nick Harperb41d2e42016-07-01 17:50:32 -0400831 msg, err = c.readHandshake()
832 if err != nil {
833 return err
834 }
835 certVerifyMsg, ok := msg.(*certificateVerifyMsg)
836 if !ok {
837 c.sendAlert(alertUnexpectedMessage)
838 return unexpectedMessageError(certVerifyMsg, msg)
839 }
840
David Benjaminf74ec792016-07-13 21:18:49 -0400841 c.peerSignatureAlgorithm = certVerifyMsg.signatureAlgorithm
Nick Harperb41d2e42016-07-01 17:50:32 -0400842 input := hs.finishedHash.certificateVerifyInput(serverCertificateVerifyContextTLS13)
David Benjamind768c5d2017-03-28 18:28:44 -0500843 err = verifyMessage(c.vers, getCertificatePublicKey(leaf), c.config, certVerifyMsg.signatureAlgorithm, input, certVerifyMsg.signature)
Nick Harperb41d2e42016-07-01 17:50:32 -0400844 if err != nil {
845 return err
846 }
847
848 hs.writeServerHash(certVerifyMsg.marshal())
849 }
850
851 msg, err = c.readHandshake()
852 if err != nil {
853 return err
854 }
855 serverFinished, ok := msg.(*finishedMsg)
856 if !ok {
857 c.sendAlert(alertUnexpectedMessage)
858 return unexpectedMessageError(serverFinished, msg)
859 }
860
Steven Valdezc4aa7272016-10-03 12:25:56 -0400861 verify := hs.finishedHash.serverSum(serverHandshakeTrafficSecret)
Nick Harperb41d2e42016-07-01 17:50:32 -0400862 if len(verify) != len(serverFinished.verifyData) ||
863 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
864 c.sendAlert(alertHandshakeFailure)
865 return errors.New("tls: server's Finished message was incorrect")
866 }
867
868 hs.writeServerHash(serverFinished.marshal())
869
870 // The various secrets do not incorporate the client's final leg, so
871 // derive them now before updating the handshake context.
David Benjamin48891ad2016-12-04 00:02:43 -0500872 hs.finishedHash.addEntropy(zeroSecret)
873 clientTrafficSecret := hs.finishedHash.deriveSecret(clientApplicationTrafficLabel)
874 serverTrafficSecret := hs.finishedHash.deriveSecret(serverApplicationTrafficLabel)
David Benjamincdb6fe92017-02-07 16:06:48 -0500875 c.exporterSecret = hs.finishedHash.deriveSecret(exporterLabel)
876
877 // Switch to application data keys on read. In particular, any alerts
878 // from the client certificate are read over these keys.
Nick Harper7cd0a972016-12-02 11:08:40 -0800879 c.in.useTrafficSecret(c.vers, hs.suite, serverTrafficSecret, serverWrite)
880
881 // If we're expecting 0.5-RTT messages from the server, read them
882 // now.
David Benjamin794cc592017-03-25 22:24:23 -0500883 if encryptedExtensions.extensions.hasEarlyData {
884 // BoringSSL will always send two tickets half-RTT when
885 // negotiating 0-RTT.
886 for i := 0; i < shimConfig.HalfRTTTickets; i++ {
887 msg, err := c.readHandshake()
888 if err != nil {
889 return fmt.Errorf("tls: error reading half-RTT ticket: %s", err)
890 }
891 newSessionTicket, ok := msg.(*newSessionTicketMsg)
892 if !ok {
893 return errors.New("tls: expected half-RTT ticket")
894 }
895 if err := c.processTLS13NewSessionTicket(newSessionTicket, hs.suite); err != nil {
896 return err
897 }
Nick Harper7cd0a972016-12-02 11:08:40 -0800898 }
David Benjamin794cc592017-03-25 22:24:23 -0500899 for _, expectedMsg := range c.config.Bugs.ExpectHalfRTTData {
900 if err := c.readRecord(recordTypeApplicationData); err != nil {
901 return err
902 }
903 if !bytes.Equal(c.input.data[c.input.off:], expectedMsg) {
904 return errors.New("ExpectHalfRTTData: did not get expected message")
905 }
906 c.in.freeBlock(c.input)
907 c.input = nil
Nick Harper7cd0a972016-12-02 11:08:40 -0800908 }
Nick Harper7cd0a972016-12-02 11:08:40 -0800909 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400910
Nick Harperf2511f12016-12-06 16:02:31 -0800911 // Send EndOfEarlyData and then switch write key to handshake
912 // traffic key.
David Benjamin32c89272017-03-26 13:54:21 -0500913 if c.out.cipher != nil && !c.config.Bugs.SkipEndOfEarlyData {
Steven Valdez681eb6a2016-12-19 13:19:29 -0500914 if c.config.Bugs.SendStrayEarlyHandshake {
915 helloRequest := new(helloRequestMsg)
916 c.writeRecord(recordTypeHandshake, helloRequest.marshal())
917 }
Nick Harperf2511f12016-12-06 16:02:31 -0800918 c.sendAlert(alertEndOfEarlyData)
919 }
Steven Valdez520e1222017-06-13 12:45:25 -0400920
921 if c.wireVersion == tls13ExperimentVersion {
922 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
923 }
924
Nick Harperf2511f12016-12-06 16:02:31 -0800925 c.out.useTrafficSecret(c.vers, hs.suite, clientHandshakeTrafficSecret, clientWrite)
926
Steven Valdez0ee2e112016-07-15 06:51:15 -0400927 if certReq != nil && !c.config.Bugs.SkipClientCertificate {
David Benjamin8d343b42016-07-09 14:26:01 -0700928 certMsg := &certificateMsg{
929 hasRequestContext: true,
930 requestContext: certReq.requestContext,
931 }
932 if chainToSend != nil {
Steven Valdeza833c352016-11-01 13:39:36 -0400933 for _, certData := range chainToSend.Certificate {
934 certMsg.certificates = append(certMsg.certificates, certificateEntry{
935 data: certData,
936 extraExtension: c.config.Bugs.SendExtensionOnCertificate,
937 })
938 }
David Benjamin8d343b42016-07-09 14:26:01 -0700939 }
940 hs.writeClientHash(certMsg.marshal())
941 c.writeRecord(recordTypeHandshake, certMsg.marshal())
942
943 if chainToSend != nil {
944 certVerify := &certificateVerifyMsg{
945 hasSignatureAlgorithm: true,
946 }
947
948 // Determine the hash to sign.
949 privKey := chainToSend.PrivateKey
950
951 var err error
952 certVerify.signatureAlgorithm, err = selectSignatureAlgorithm(c.vers, privKey, c.config, certReq.signatureAlgorithms)
953 if err != nil {
954 c.sendAlert(alertInternalError)
955 return err
956 }
957
958 input := hs.finishedHash.certificateVerifyInput(clientCertificateVerifyContextTLS13)
959 certVerify.signature, err = signMessage(c.vers, privKey, c.config, certVerify.signatureAlgorithm, input)
960 if err != nil {
961 c.sendAlert(alertInternalError)
962 return err
963 }
Steven Valdez0ee2e112016-07-15 06:51:15 -0400964 if c.config.Bugs.SendSignatureAlgorithm != 0 {
965 certVerify.signatureAlgorithm = c.config.Bugs.SendSignatureAlgorithm
966 }
David Benjamin8d343b42016-07-09 14:26:01 -0700967
968 hs.writeClientHash(certVerify.marshal())
969 c.writeRecord(recordTypeHandshake, certVerify.marshal())
970 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400971 }
972
Nick Harper60a85cb2016-09-23 16:25:11 -0700973 if encryptedExtensions.extensions.channelIDRequested {
974 channelIDHash := crypto.SHA256.New()
975 channelIDHash.Write(hs.finishedHash.certificateVerifyInput(channelIDContextTLS13))
976 channelIDMsgBytes, err := hs.writeChannelIDMessage(channelIDHash.Sum(nil))
977 if err != nil {
978 return err
979 }
980 hs.writeClientHash(channelIDMsgBytes)
981 c.writeRecord(recordTypeHandshake, channelIDMsgBytes)
982 }
983
Nick Harperb41d2e42016-07-01 17:50:32 -0400984 // Send a client Finished message.
985 finished := new(finishedMsg)
Steven Valdezc4aa7272016-10-03 12:25:56 -0400986 finished.verifyData = hs.finishedHash.clientSum(clientHandshakeTrafficSecret)
Nick Harperb41d2e42016-07-01 17:50:32 -0400987 if c.config.Bugs.BadFinished {
988 finished.verifyData[0]++
989 }
David Benjamin97a0a082016-07-13 17:57:35 -0400990 hs.writeClientHash(finished.marshal())
David Benjamin7964b182016-07-14 23:36:30 -0400991 if c.config.Bugs.PartialClientFinishedWithClientHello {
992 // The first byte has already been sent.
993 c.writeRecord(recordTypeHandshake, finished.marshal()[1:])
Steven Valdeza4ee74d2016-11-29 13:36:45 -0500994 } else if c.config.Bugs.InterleaveEarlyData {
995 finishedBytes := finished.marshal()
996 c.sendFakeEarlyData(4)
997 c.writeRecord(recordTypeHandshake, finishedBytes[:1])
998 c.sendFakeEarlyData(4)
999 c.writeRecord(recordTypeHandshake, finishedBytes[1:])
David Benjamin7964b182016-07-14 23:36:30 -04001000 } else {
1001 c.writeRecord(recordTypeHandshake, finished.marshal())
1002 }
David Benjamin02edcd02016-07-27 17:40:37 -04001003 if c.config.Bugs.SendExtraFinished {
1004 c.writeRecord(recordTypeHandshake, finished.marshal())
1005 }
David Benjaminee51a222016-07-07 18:34:12 -07001006 c.flushHandshake()
Nick Harperb41d2e42016-07-01 17:50:32 -04001007
1008 // Switch to application data keys.
Steven Valdeza833c352016-11-01 13:39:36 -04001009 c.out.useTrafficSecret(c.vers, hs.suite, clientTrafficSecret, clientWrite)
Nick Harperb41d2e42016-07-01 17:50:32 -04001010
David Benjamin48891ad2016-12-04 00:02:43 -05001011 c.resumptionSecret = hs.finishedHash.deriveSecret(resumptionLabel)
Nick Harperb41d2e42016-07-01 17:50:32 -04001012 return nil
1013}
1014
Adam Langley95c29f32014-06-20 12:00:00 -07001015func (hs *clientHandshakeState) doFullHandshake() error {
1016 c := hs.c
1017
David Benjamin48cae082014-10-27 01:06:24 -04001018 var leaf *x509.Certificate
1019 if hs.suite.flags&suitePSK == 0 {
1020 msg, err := c.readHandshake()
Adam Langley95c29f32014-06-20 12:00:00 -07001021 if err != nil {
Adam Langley95c29f32014-06-20 12:00:00 -07001022 return err
1023 }
Adam Langley95c29f32014-06-20 12:00:00 -07001024
David Benjamin48cae082014-10-27 01:06:24 -04001025 certMsg, ok := msg.(*certificateMsg)
David Benjamin75051442016-07-01 18:58:51 -04001026 if !ok {
David Benjamin48cae082014-10-27 01:06:24 -04001027 c.sendAlert(alertUnexpectedMessage)
1028 return unexpectedMessageError(certMsg, msg)
1029 }
1030 hs.writeServerHash(certMsg.marshal())
Adam Langley95c29f32014-06-20 12:00:00 -07001031
David Benjamin75051442016-07-01 18:58:51 -04001032 if err := hs.verifyCertificates(certMsg); err != nil {
1033 return err
David Benjamin48cae082014-10-27 01:06:24 -04001034 }
David Benjamin75051442016-07-01 18:58:51 -04001035 leaf = c.peerCertificates[0]
David Benjamin48cae082014-10-27 01:06:24 -04001036 }
Adam Langley95c29f32014-06-20 12:00:00 -07001037
Nick Harperb3d51be2016-07-01 11:43:18 -04001038 if hs.serverHello.extensions.ocspStapling {
David Benjamin48cae082014-10-27 01:06:24 -04001039 msg, err := c.readHandshake()
Adam Langley95c29f32014-06-20 12:00:00 -07001040 if err != nil {
1041 return err
1042 }
1043 cs, ok := msg.(*certificateStatusMsg)
1044 if !ok {
1045 c.sendAlert(alertUnexpectedMessage)
1046 return unexpectedMessageError(cs, msg)
1047 }
David Benjamin83c0bc92014-08-04 01:23:53 -04001048 hs.writeServerHash(cs.marshal())
Adam Langley95c29f32014-06-20 12:00:00 -07001049
1050 if cs.statusType == statusTypeOCSP {
1051 c.ocspResponse = cs.response
1052 }
1053 }
1054
David Benjamin48cae082014-10-27 01:06:24 -04001055 msg, err := c.readHandshake()
Adam Langley95c29f32014-06-20 12:00:00 -07001056 if err != nil {
1057 return err
1058 }
1059
1060 keyAgreement := hs.suite.ka(c.vers)
1061
1062 skx, ok := msg.(*serverKeyExchangeMsg)
1063 if ok {
David Benjamin83c0bc92014-08-04 01:23:53 -04001064 hs.writeServerHash(skx.marshal())
David Benjamin48cae082014-10-27 01:06:24 -04001065 err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, leaf, skx)
Adam Langley95c29f32014-06-20 12:00:00 -07001066 if err != nil {
1067 c.sendAlert(alertUnexpectedMessage)
1068 return err
1069 }
Steven Valdez5440fe02016-07-18 12:40:30 -04001070 if ecdhe, ok := keyAgreement.(*ecdheKeyAgreement); ok {
1071 c.curveID = ecdhe.curveID
1072 }
Adam Langley95c29f32014-06-20 12:00:00 -07001073
Nick Harper60edffd2016-06-21 15:19:24 -07001074 c.peerSignatureAlgorithm = keyAgreement.peerSignatureAlgorithm()
1075
Adam Langley95c29f32014-06-20 12:00:00 -07001076 msg, err = c.readHandshake()
1077 if err != nil {
1078 return err
1079 }
1080 }
1081
1082 var chainToSend *Certificate
1083 var certRequested bool
1084 certReq, ok := msg.(*certificateRequestMsg)
1085 if ok {
1086 certRequested = true
David Benjamin7a41d372016-07-09 11:21:54 -07001087 if c.config.Bugs.IgnorePeerSignatureAlgorithmPreferences {
1088 certReq.signatureAlgorithms = c.config.signSignatureAlgorithms()
1089 }
Adam Langley95c29f32014-06-20 12:00:00 -07001090
David Benjamin83c0bc92014-08-04 01:23:53 -04001091 hs.writeServerHash(certReq.marshal())
Adam Langley95c29f32014-06-20 12:00:00 -07001092
David Benjamina6f82632016-07-01 18:44:02 -04001093 chainToSend, err = selectClientCertificate(c, certReq)
1094 if err != nil {
1095 return err
Adam Langley95c29f32014-06-20 12:00:00 -07001096 }
1097
1098 msg, err = c.readHandshake()
1099 if err != nil {
1100 return err
1101 }
1102 }
1103
1104 shd, ok := msg.(*serverHelloDoneMsg)
1105 if !ok {
1106 c.sendAlert(alertUnexpectedMessage)
1107 return unexpectedMessageError(shd, msg)
1108 }
David Benjamin83c0bc92014-08-04 01:23:53 -04001109 hs.writeServerHash(shd.marshal())
Adam Langley95c29f32014-06-20 12:00:00 -07001110
1111 // If the server requested a certificate then we have to send a
David Benjamin0b7ca7d2016-03-10 15:44:22 -05001112 // Certificate message in TLS, even if it's empty because we don't have
1113 // a certificate to send. In SSL 3.0, skip the message and send a
1114 // no_certificate warning alert.
Adam Langley95c29f32014-06-20 12:00:00 -07001115 if certRequested {
David Benjamin0b7ca7d2016-03-10 15:44:22 -05001116 if c.vers == VersionSSL30 && chainToSend == nil {
David Benjamin053fee92017-01-02 08:30:36 -05001117 c.sendAlert(alertNoCertificate)
David Benjamin0b7ca7d2016-03-10 15:44:22 -05001118 } else if !c.config.Bugs.SkipClientCertificate {
1119 certMsg := new(certificateMsg)
1120 if chainToSend != nil {
Steven Valdeza833c352016-11-01 13:39:36 -04001121 for _, certData := range chainToSend.Certificate {
1122 certMsg.certificates = append(certMsg.certificates, certificateEntry{
1123 data: certData,
1124 })
1125 }
David Benjamin0b7ca7d2016-03-10 15:44:22 -05001126 }
1127 hs.writeClientHash(certMsg.marshal())
1128 c.writeRecord(recordTypeHandshake, certMsg.marshal())
Adam Langley95c29f32014-06-20 12:00:00 -07001129 }
Adam Langley95c29f32014-06-20 12:00:00 -07001130 }
1131
David Benjamin48cae082014-10-27 01:06:24 -04001132 preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, leaf)
Adam Langley95c29f32014-06-20 12:00:00 -07001133 if err != nil {
1134 c.sendAlert(alertInternalError)
1135 return err
1136 }
1137 if ckx != nil {
David Benjaminf3ec83d2014-07-21 22:42:34 -04001138 if c.config.Bugs.EarlyChangeCipherSpec < 2 {
David Benjamin83c0bc92014-08-04 01:23:53 -04001139 hs.writeClientHash(ckx.marshal())
David Benjaminf3ec83d2014-07-21 22:42:34 -04001140 }
Adam Langley95c29f32014-06-20 12:00:00 -07001141 c.writeRecord(recordTypeHandshake, ckx.marshal())
1142 }
1143
Nick Harperb3d51be2016-07-01 11:43:18 -04001144 if hs.serverHello.extensions.extendedMasterSecret && c.vers >= VersionTLS10 {
Adam Langley75712922014-10-10 16:23:43 -07001145 hs.masterSecret = extendedMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.finishedHash)
1146 c.extendedMasterSecret = true
1147 } else {
1148 if c.config.Bugs.RequireExtendedMasterSecret {
1149 return errors.New("tls: extended master secret required but not supported by peer")
1150 }
1151 hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
1152 }
David Benjamine098ec22014-08-27 23:13:20 -04001153
Adam Langley95c29f32014-06-20 12:00:00 -07001154 if chainToSend != nil {
Adam Langley95c29f32014-06-20 12:00:00 -07001155 certVerify := &certificateVerifyMsg{
Nick Harper60edffd2016-06-21 15:19:24 -07001156 hasSignatureAlgorithm: c.vers >= VersionTLS12,
Adam Langley95c29f32014-06-20 12:00:00 -07001157 }
1158
David Benjamin72dc7832015-03-16 17:49:43 -04001159 // Determine the hash to sign.
Nick Harper60edffd2016-06-21 15:19:24 -07001160 privKey := c.config.Certificates[0].PrivateKey
David Benjamin72dc7832015-03-16 17:49:43 -04001161
Nick Harper60edffd2016-06-21 15:19:24 -07001162 if certVerify.hasSignatureAlgorithm {
David Benjamin0a8deb22016-07-09 21:02:01 -07001163 certVerify.signatureAlgorithm, err = selectSignatureAlgorithm(c.vers, privKey, c.config, certReq.signatureAlgorithms)
Nick Harper60edffd2016-06-21 15:19:24 -07001164 if err != nil {
1165 c.sendAlert(alertInternalError)
1166 return err
Adam Langley95c29f32014-06-20 12:00:00 -07001167 }
Nick Harper60edffd2016-06-21 15:19:24 -07001168 }
1169
1170 if c.vers > VersionSSL30 {
David Benjamin5208fd42016-07-13 21:43:25 -04001171 certVerify.signature, err = signMessage(c.vers, privKey, c.config, certVerify.signatureAlgorithm, hs.finishedHash.buffer)
David Benjamina95e9f32016-07-08 16:28:04 -07001172 if err == nil && c.config.Bugs.SendSignatureAlgorithm != 0 {
1173 certVerify.signatureAlgorithm = c.config.Bugs.SendSignatureAlgorithm
1174 }
Nick Harper60edffd2016-06-21 15:19:24 -07001175 } else {
1176 // SSL 3.0's client certificate construction is
1177 // incompatible with signatureAlgorithm.
1178 rsaKey, ok := privKey.(*rsa.PrivateKey)
1179 if !ok {
1180 err = errors.New("unsupported signature type for client certificate")
1181 } else {
1182 digest := hs.finishedHash.hashForClientCertificateSSL3(hs.masterSecret)
David Benjamin5208fd42016-07-13 21:43:25 -04001183 if c.config.Bugs.InvalidSignature {
Nick Harper60edffd2016-06-21 15:19:24 -07001184 digest[0] ^= 0x80
1185 }
1186 certVerify.signature, err = rsa.SignPKCS1v15(c.config.rand(), rsaKey, crypto.MD5SHA1, digest)
1187 }
Adam Langley95c29f32014-06-20 12:00:00 -07001188 }
1189 if err != nil {
1190 c.sendAlert(alertInternalError)
1191 return errors.New("tls: failed to sign handshake with client certificate: " + err.Error())
1192 }
Adam Langley95c29f32014-06-20 12:00:00 -07001193
David Benjamin83c0bc92014-08-04 01:23:53 -04001194 hs.writeClientHash(certVerify.marshal())
Adam Langley95c29f32014-06-20 12:00:00 -07001195 c.writeRecord(recordTypeHandshake, certVerify.marshal())
1196 }
David Benjamin82261be2016-07-07 14:32:50 -07001197 // flushHandshake will be called in sendFinished.
Adam Langley95c29f32014-06-20 12:00:00 -07001198
David Benjamine098ec22014-08-27 23:13:20 -04001199 hs.finishedHash.discardHandshakeBuffer()
1200
Adam Langley95c29f32014-06-20 12:00:00 -07001201 return nil
1202}
1203
David Benjamin75051442016-07-01 18:58:51 -04001204func (hs *clientHandshakeState) verifyCertificates(certMsg *certificateMsg) error {
1205 c := hs.c
1206
1207 if len(certMsg.certificates) == 0 {
1208 c.sendAlert(alertIllegalParameter)
1209 return errors.New("tls: no certificates sent")
1210 }
1211
1212 certs := make([]*x509.Certificate, len(certMsg.certificates))
Steven Valdeza833c352016-11-01 13:39:36 -04001213 for i, certEntry := range certMsg.certificates {
1214 cert, err := x509.ParseCertificate(certEntry.data)
David Benjamin75051442016-07-01 18:58:51 -04001215 if err != nil {
1216 c.sendAlert(alertBadCertificate)
1217 return errors.New("tls: failed to parse certificate from server: " + err.Error())
1218 }
1219 certs[i] = cert
1220 }
1221
1222 if !c.config.InsecureSkipVerify {
1223 opts := x509.VerifyOptions{
1224 Roots: c.config.RootCAs,
1225 CurrentTime: c.config.time(),
1226 DNSName: c.config.ServerName,
1227 Intermediates: x509.NewCertPool(),
1228 }
1229
1230 for i, cert := range certs {
1231 if i == 0 {
1232 continue
1233 }
1234 opts.Intermediates.AddCert(cert)
1235 }
1236 var err error
1237 c.verifiedChains, err = certs[0].Verify(opts)
1238 if err != nil {
1239 c.sendAlert(alertBadCertificate)
1240 return err
1241 }
1242 }
1243
David Benjamind768c5d2017-03-28 18:28:44 -05001244 publicKey := getCertificatePublicKey(certs[0])
1245 switch publicKey.(type) {
1246 case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
David Benjamin75051442016-07-01 18:58:51 -04001247 break
1248 default:
1249 c.sendAlert(alertUnsupportedCertificate)
David Benjamind768c5d2017-03-28 18:28:44 -05001250 return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", publicKey)
David Benjamin75051442016-07-01 18:58:51 -04001251 }
1252
1253 c.peerCertificates = certs
1254 return nil
1255}
1256
Adam Langley95c29f32014-06-20 12:00:00 -07001257func (hs *clientHandshakeState) establishKeys() error {
1258 c := hs.c
1259
1260 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
Nick Harper1fd39d82016-06-14 18:14:35 -07001261 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 Langley95c29f32014-06-20 12:00:00 -07001262 var clientCipher, serverCipher interface{}
1263 var clientHash, serverHash macFunction
1264 if hs.suite.cipher != nil {
1265 clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
1266 clientHash = hs.suite.mac(c.vers, clientMAC)
1267 serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
1268 serverHash = hs.suite.mac(c.vers, serverMAC)
1269 } else {
Nick Harper1fd39d82016-06-14 18:14:35 -07001270 clientCipher = hs.suite.aead(c.vers, clientKey, clientIV)
1271 serverCipher = hs.suite.aead(c.vers, serverKey, serverIV)
Adam Langley95c29f32014-06-20 12:00:00 -07001272 }
1273
1274 c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
1275 c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
1276 return nil
1277}
1278
David Benjamin75101402016-07-01 13:40:23 -04001279func (hs *clientHandshakeState) processServerExtensions(serverExtensions *serverExtensions) error {
1280 c := hs.c
1281
David Benjamin8d315d72016-07-18 01:03:18 +02001282 if c.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -04001283 if c.config.Bugs.RequireRenegotiationInfo && serverExtensions.secureRenegotiation == nil {
1284 return errors.New("tls: renegotiation extension missing")
1285 }
David Benjamin75101402016-07-01 13:40:23 -04001286
Nick Harperb41d2e42016-07-01 17:50:32 -04001287 if len(c.clientVerify) > 0 && !c.noRenegotiationInfo() {
1288 var expectedRenegInfo []byte
1289 expectedRenegInfo = append(expectedRenegInfo, c.clientVerify...)
1290 expectedRenegInfo = append(expectedRenegInfo, c.serverVerify...)
1291 if !bytes.Equal(serverExtensions.secureRenegotiation, expectedRenegInfo) {
1292 c.sendAlert(alertHandshakeFailure)
1293 return fmt.Errorf("tls: renegotiation mismatch")
1294 }
David Benjamin75101402016-07-01 13:40:23 -04001295 }
David Benjamincea0ab42016-07-14 12:33:14 -04001296 } else if serverExtensions.secureRenegotiation != nil {
1297 return errors.New("tls: renegotiation info sent in TLS 1.3")
David Benjamin75101402016-07-01 13:40:23 -04001298 }
1299
1300 if expected := c.config.Bugs.ExpectedCustomExtension; expected != nil {
1301 if serverExtensions.customExtension != *expected {
1302 return fmt.Errorf("tls: bad custom extension contents %q", serverExtensions.customExtension)
1303 }
1304 }
1305
1306 clientDidNPN := hs.hello.nextProtoNeg
1307 clientDidALPN := len(hs.hello.alpnProtocols) > 0
1308 serverHasNPN := serverExtensions.nextProtoNeg
1309 serverHasALPN := len(serverExtensions.alpnProtocol) > 0
1310
1311 if !clientDidNPN && serverHasNPN {
1312 c.sendAlert(alertHandshakeFailure)
1313 return errors.New("server advertised unrequested NPN extension")
1314 }
1315
1316 if !clientDidALPN && serverHasALPN {
1317 c.sendAlert(alertHandshakeFailure)
1318 return errors.New("server advertised unrequested ALPN extension")
1319 }
1320
1321 if serverHasNPN && serverHasALPN {
1322 c.sendAlert(alertHandshakeFailure)
1323 return errors.New("server advertised both NPN and ALPN extensions")
1324 }
1325
1326 if serverHasALPN {
1327 c.clientProtocol = serverExtensions.alpnProtocol
1328 c.clientProtocolFallback = false
1329 c.usedALPN = true
1330 }
1331
David Benjamin8d315d72016-07-18 01:03:18 +02001332 if serverHasNPN && c.vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -04001333 c.sendAlert(alertHandshakeFailure)
1334 return errors.New("server advertised NPN over TLS 1.3")
1335 }
1336
David Benjamin75101402016-07-01 13:40:23 -04001337 if !hs.hello.channelIDSupported && serverExtensions.channelIDRequested {
1338 c.sendAlert(alertHandshakeFailure)
1339 return errors.New("server advertised unrequested Channel ID extension")
1340 }
1341
David Benjamin8d315d72016-07-18 01:03:18 +02001342 if serverExtensions.extendedMasterSecret && c.vers >= VersionTLS13 {
David Benjamine9077652016-07-13 21:02:08 -04001343 return errors.New("tls: server advertised extended master secret over TLS 1.3")
1344 }
1345
David Benjamin8d315d72016-07-18 01:03:18 +02001346 if serverExtensions.ticketSupported && c.vers >= VersionTLS13 {
Steven Valdez143e8b32016-07-11 13:19:03 -04001347 return errors.New("tls: server advertised ticket extension over TLS 1.3")
1348 }
1349
Steven Valdeza833c352016-11-01 13:39:36 -04001350 if serverExtensions.ocspStapling && c.vers >= VersionTLS13 {
1351 return errors.New("tls: server advertised OCSP in ServerHello over TLS 1.3")
1352 }
1353
David Benjamin53210cb2016-11-16 09:01:48 +09001354 if serverExtensions.ocspStapling && c.config.Bugs.NoOCSPStapling {
1355 return errors.New("tls: server advertised unrequested OCSP extension")
1356 }
1357
Steven Valdeza833c352016-11-01 13:39:36 -04001358 if len(serverExtensions.sctList) > 0 && c.vers >= VersionTLS13 {
1359 return errors.New("tls: server advertised SCTs in ServerHello over TLS 1.3")
1360 }
1361
David Benjamin53210cb2016-11-16 09:01:48 +09001362 if len(serverExtensions.sctList) > 0 && c.config.Bugs.NoSignedCertificateTimestamps {
1363 return errors.New("tls: server advertised unrequested SCTs")
1364 }
1365
David Benjamin75101402016-07-01 13:40:23 -04001366 if serverExtensions.srtpProtectionProfile != 0 {
1367 if serverExtensions.srtpMasterKeyIdentifier != "" {
1368 return errors.New("tls: server selected SRTP MKI value")
1369 }
1370
1371 found := false
1372 for _, p := range c.config.SRTPProtectionProfiles {
1373 if p == serverExtensions.srtpProtectionProfile {
1374 found = true
1375 break
1376 }
1377 }
1378 if !found {
1379 return errors.New("tls: server advertised unsupported SRTP profile")
1380 }
1381
1382 c.srtpProtectionProfile = serverExtensions.srtpProtectionProfile
1383 }
1384
Steven Valdez2d850622017-01-11 11:34:52 -05001385 if c.vers >= VersionTLS13 && c.didResume {
1386 if c.config.Bugs.ExpectEarlyDataAccepted && !serverExtensions.hasEarlyData {
1387 c.sendAlert(alertHandshakeFailure)
1388 return errors.New("tls: server did not accept early data when expected")
1389 }
1390
1391 if !c.config.Bugs.ExpectEarlyDataAccepted && serverExtensions.hasEarlyData {
1392 c.sendAlert(alertHandshakeFailure)
1393 return errors.New("tls: server accepted early data when not expected")
1394 }
1395 }
1396
David Benjamin75101402016-07-01 13:40:23 -04001397 return nil
1398}
1399
Adam Langley95c29f32014-06-20 12:00:00 -07001400func (hs *clientHandshakeState) serverResumedSession() bool {
1401 // If the server responded with the same sessionId then it means the
1402 // sessionTicket is being used to resume a TLS session.
David Benjamind4c349b2017-02-09 14:07:17 -05001403 //
1404 // Note that, if hs.hello.sessionId is a non-nil empty array, this will
1405 // accept an empty session ID from the server as resumption. See
1406 // EmptyTicketSessionID.
Adam Langley95c29f32014-06-20 12:00:00 -07001407 return hs.session != nil && hs.hello.sessionId != nil &&
1408 bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
1409}
1410
1411func (hs *clientHandshakeState) processServerHello() (bool, error) {
1412 c := hs.c
1413
Adam Langley95c29f32014-06-20 12:00:00 -07001414 if hs.serverResumedSession() {
David Benjamin4b27d9f2015-05-12 22:42:52 -04001415 // For test purposes, assert that the server never accepts the
1416 // resumption offer on renegotiation.
1417 if c.cipherSuite != nil && c.config.Bugs.FailIfResumeOnRenego {
1418 return false, errors.New("tls: server resumed session on renegotiation")
1419 }
1420
Nick Harperb3d51be2016-07-01 11:43:18 -04001421 if hs.serverHello.extensions.sctList != nil {
Paul Lietar62be8ac2015-09-16 10:03:30 +01001422 return false, errors.New("tls: server sent SCT extension on session resumption")
1423 }
1424
Nick Harperb3d51be2016-07-01 11:43:18 -04001425 if hs.serverHello.extensions.ocspStapling {
Paul Lietar62be8ac2015-09-16 10:03:30 +01001426 return false, errors.New("tls: server sent OCSP extension on session resumption")
1427 }
1428
Adam Langley95c29f32014-06-20 12:00:00 -07001429 // Restore masterSecret and peerCerts from previous state
1430 hs.masterSecret = hs.session.masterSecret
1431 c.peerCertificates = hs.session.serverCertificates
Adam Langley75712922014-10-10 16:23:43 -07001432 c.extendedMasterSecret = hs.session.extendedMasterSecret
Paul Lietar62be8ac2015-09-16 10:03:30 +01001433 c.sctList = hs.session.sctList
1434 c.ocspResponse = hs.session.ocspResponse
David Benjamine098ec22014-08-27 23:13:20 -04001435 hs.finishedHash.discardHandshakeBuffer()
Adam Langley95c29f32014-06-20 12:00:00 -07001436 return true, nil
1437 }
Paul Lietar62be8ac2015-09-16 10:03:30 +01001438
Nick Harperb3d51be2016-07-01 11:43:18 -04001439 if hs.serverHello.extensions.sctList != nil {
1440 c.sctList = hs.serverHello.extensions.sctList
Paul Lietar62be8ac2015-09-16 10:03:30 +01001441 }
1442
Adam Langley95c29f32014-06-20 12:00:00 -07001443 return false, nil
1444}
1445
Adam Langleyaf0e32c2015-06-03 09:57:23 -07001446func (hs *clientHandshakeState) readFinished(out []byte) error {
Adam Langley95c29f32014-06-20 12:00:00 -07001447 c := hs.c
1448
1449 c.readRecord(recordTypeChangeCipherSpec)
1450 if err := c.in.error(); err != nil {
1451 return err
1452 }
1453
1454 msg, err := c.readHandshake()
1455 if err != nil {
1456 return err
1457 }
1458 serverFinished, ok := msg.(*finishedMsg)
1459 if !ok {
1460 c.sendAlert(alertUnexpectedMessage)
1461 return unexpectedMessageError(serverFinished, msg)
1462 }
1463
David Benjaminf3ec83d2014-07-21 22:42:34 -04001464 if c.config.Bugs.EarlyChangeCipherSpec == 0 {
1465 verify := hs.finishedHash.serverSum(hs.masterSecret)
1466 if len(verify) != len(serverFinished.verifyData) ||
1467 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
1468 c.sendAlert(alertHandshakeFailure)
1469 return errors.New("tls: server's Finished message was incorrect")
1470 }
Adam Langley95c29f32014-06-20 12:00:00 -07001471 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001472 c.serverVerify = append(c.serverVerify[:0], serverFinished.verifyData...)
Adam Langleyaf0e32c2015-06-03 09:57:23 -07001473 copy(out, serverFinished.verifyData)
David Benjamin83c0bc92014-08-04 01:23:53 -04001474 hs.writeServerHash(serverFinished.marshal())
Adam Langley95c29f32014-06-20 12:00:00 -07001475 return nil
1476}
1477
1478func (hs *clientHandshakeState) readSessionTicket() error {
David Benjaminfe8eb9a2014-11-17 03:19:02 -05001479 c := hs.c
1480
1481 // Create a session with no server identifier. Either a
1482 // session ID or session ticket will be attached.
1483 session := &ClientSessionState{
1484 vers: c.vers,
1485 cipherSuite: hs.suite.id,
1486 masterSecret: hs.masterSecret,
Nick Harperc9846112016-10-17 15:05:35 -07001487 handshakeHash: hs.finishedHash.Sum(),
David Benjaminfe8eb9a2014-11-17 03:19:02 -05001488 serverCertificates: c.peerCertificates,
Paul Lietar62be8ac2015-09-16 10:03:30 +01001489 sctList: c.sctList,
1490 ocspResponse: c.ocspResponse,
Nick Harper0b3625b2016-07-25 16:16:28 -07001491 ticketExpiration: c.config.time().Add(time.Duration(7 * 24 * time.Hour)),
David Benjaminfe8eb9a2014-11-17 03:19:02 -05001492 }
1493
Nick Harperb3d51be2016-07-01 11:43:18 -04001494 if !hs.serverHello.extensions.ticketSupported {
David Benjamind98452d2015-06-16 14:16:23 -04001495 if c.config.Bugs.ExpectNewTicket {
1496 return errors.New("tls: expected new ticket")
1497 }
David Benjaminfe8eb9a2014-11-17 03:19:02 -05001498 if hs.session == nil && len(hs.serverHello.sessionId) > 0 {
1499 session.sessionId = hs.serverHello.sessionId
1500 hs.session = session
1501 }
Adam Langley95c29f32014-06-20 12:00:00 -07001502 return nil
1503 }
1504
David Benjaminc7ce9772015-10-09 19:32:41 -04001505 if c.vers == VersionSSL30 {
1506 return errors.New("tls: negotiated session tickets in SSL 3.0")
1507 }
1508
Adam Langley95c29f32014-06-20 12:00:00 -07001509 msg, err := c.readHandshake()
1510 if err != nil {
1511 return err
1512 }
1513 sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
1514 if !ok {
1515 c.sendAlert(alertUnexpectedMessage)
1516 return unexpectedMessageError(sessionTicketMsg, msg)
1517 }
Adam Langley95c29f32014-06-20 12:00:00 -07001518
David Benjaminfe8eb9a2014-11-17 03:19:02 -05001519 session.sessionTicket = sessionTicketMsg.ticket
1520 hs.session = session
Adam Langley95c29f32014-06-20 12:00:00 -07001521
David Benjamind30a9902014-08-24 01:44:23 -04001522 hs.writeServerHash(sessionTicketMsg.marshal())
1523
Adam Langley95c29f32014-06-20 12:00:00 -07001524 return nil
1525}
1526
Adam Langleyaf0e32c2015-06-03 09:57:23 -07001527func (hs *clientHandshakeState) sendFinished(out []byte, isResume bool) error {
Adam Langley95c29f32014-06-20 12:00:00 -07001528 c := hs.c
1529
David Benjamin0b8d5da2016-07-15 00:39:56 -04001530 var postCCSMsgs [][]byte
David Benjamin83c0bc92014-08-04 01:23:53 -04001531 seqno := hs.c.sendHandshakeSeq
Nick Harperb3d51be2016-07-01 11:43:18 -04001532 if hs.serverHello.extensions.nextProtoNeg {
Adam Langley95c29f32014-06-20 12:00:00 -07001533 nextProto := new(nextProtoMsg)
Nick Harperb3d51be2016-07-01 11:43:18 -04001534 proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.extensions.nextProtos)
Adam Langley95c29f32014-06-20 12:00:00 -07001535 nextProto.proto = proto
1536 c.clientProtocol = proto
1537 c.clientProtocolFallback = fallback
1538
David Benjamin86271ee2014-07-21 16:14:03 -04001539 nextProtoBytes := nextProto.marshal()
David Benjamin83c0bc92014-08-04 01:23:53 -04001540 hs.writeHash(nextProtoBytes, seqno)
1541 seqno++
David Benjamin0b8d5da2016-07-15 00:39:56 -04001542 postCCSMsgs = append(postCCSMsgs, nextProtoBytes)
Adam Langley95c29f32014-06-20 12:00:00 -07001543 }
1544
Nick Harperb3d51be2016-07-01 11:43:18 -04001545 if hs.serverHello.extensions.channelIDRequested {
David Benjamind30a9902014-08-24 01:44:23 -04001546 var resumeHash []byte
1547 if isResume {
1548 resumeHash = hs.session.handshakeHash
1549 }
Nick Harper60a85cb2016-09-23 16:25:11 -07001550 channelIDMsgBytes, err := hs.writeChannelIDMessage(hs.finishedHash.hashForChannelID(resumeHash))
David Benjamind30a9902014-08-24 01:44:23 -04001551 if err != nil {
1552 return err
1553 }
David Benjamin24599a82016-06-30 18:56:53 -04001554 hs.writeHash(channelIDMsgBytes, seqno)
David Benjamind30a9902014-08-24 01:44:23 -04001555 seqno++
David Benjamin0b8d5da2016-07-15 00:39:56 -04001556 postCCSMsgs = append(postCCSMsgs, channelIDMsgBytes)
David Benjamind30a9902014-08-24 01:44:23 -04001557 }
1558
Adam Langley95c29f32014-06-20 12:00:00 -07001559 finished := new(finishedMsg)
David Benjaminf3ec83d2014-07-21 22:42:34 -04001560 if c.config.Bugs.EarlyChangeCipherSpec == 2 {
1561 finished.verifyData = hs.finishedHash.clientSum(nil)
1562 } else {
1563 finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
1564 }
Adam Langleyaf0e32c2015-06-03 09:57:23 -07001565 copy(out, finished.verifyData)
David Benjamin513f0ea2015-04-02 19:33:31 -04001566 if c.config.Bugs.BadFinished {
1567 finished.verifyData[0]++
1568 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001569 c.clientVerify = append(c.clientVerify[:0], finished.verifyData...)
David Benjamin83f90402015-01-27 01:09:43 -05001570 hs.finishedBytes = finished.marshal()
1571 hs.writeHash(hs.finishedBytes, seqno)
David Benjamin0b8d5da2016-07-15 00:39:56 -04001572 postCCSMsgs = append(postCCSMsgs, hs.finishedBytes)
David Benjamin86271ee2014-07-21 16:14:03 -04001573
1574 if c.config.Bugs.FragmentAcrossChangeCipherSpec {
David Benjamin0b8d5da2016-07-15 00:39:56 -04001575 c.writeRecord(recordTypeHandshake, postCCSMsgs[0][:5])
1576 postCCSMsgs[0] = postCCSMsgs[0][5:]
David Benjamin61672812016-07-14 23:10:43 -04001577 } else if c.config.Bugs.SendUnencryptedFinished {
David Benjamin0b8d5da2016-07-15 00:39:56 -04001578 c.writeRecord(recordTypeHandshake, postCCSMsgs[0])
1579 postCCSMsgs = postCCSMsgs[1:]
David Benjamin86271ee2014-07-21 16:14:03 -04001580 }
David Benjamin582ba042016-07-07 12:33:25 -07001581 c.flushHandshake()
David Benjamin86271ee2014-07-21 16:14:03 -04001582
1583 if !c.config.Bugs.SkipChangeCipherSpec &&
1584 c.config.Bugs.EarlyChangeCipherSpec == 0 {
David Benjamin8411b242015-11-26 12:07:28 -05001585 ccs := []byte{1}
1586 if c.config.Bugs.BadChangeCipherSpec != nil {
1587 ccs = c.config.Bugs.BadChangeCipherSpec
1588 }
1589 c.writeRecord(recordTypeChangeCipherSpec, ccs)
David Benjamin86271ee2014-07-21 16:14:03 -04001590 }
1591
David Benjamin4189bd92015-01-25 23:52:39 -05001592 if c.config.Bugs.AppDataAfterChangeCipherSpec != nil {
1593 c.writeRecord(recordTypeApplicationData, c.config.Bugs.AppDataAfterChangeCipherSpec)
1594 }
David Benjamindc3da932015-03-12 15:09:02 -04001595 if c.config.Bugs.AlertAfterChangeCipherSpec != 0 {
1596 c.sendAlert(c.config.Bugs.AlertAfterChangeCipherSpec)
1597 return errors.New("tls: simulating post-CCS alert")
1598 }
David Benjamin4189bd92015-01-25 23:52:39 -05001599
David Benjamin0b8d5da2016-07-15 00:39:56 -04001600 if !c.config.Bugs.SkipFinished {
1601 for _, msg := range postCCSMsgs {
1602 c.writeRecord(recordTypeHandshake, msg)
1603 }
David Benjamin02edcd02016-07-27 17:40:37 -04001604
1605 if c.config.Bugs.SendExtraFinished {
1606 c.writeRecord(recordTypeHandshake, finished.marshal())
1607 }
1608
David Benjamin582ba042016-07-07 12:33:25 -07001609 c.flushHandshake()
David Benjaminb3774b92015-01-31 17:16:01 -05001610 }
Adam Langley95c29f32014-06-20 12:00:00 -07001611 return nil
1612}
1613
Nick Harper60a85cb2016-09-23 16:25:11 -07001614func (hs *clientHandshakeState) writeChannelIDMessage(channelIDHash []byte) ([]byte, error) {
1615 c := hs.c
1616 channelIDMsg := new(channelIDMsg)
1617 if c.config.ChannelID.Curve != elliptic.P256() {
1618 return nil, fmt.Errorf("tls: Channel ID is not on P-256.")
1619 }
1620 r, s, err := ecdsa.Sign(c.config.rand(), c.config.ChannelID, channelIDHash)
1621 if err != nil {
1622 return nil, err
1623 }
1624 channelID := make([]byte, 128)
1625 writeIntPadded(channelID[0:32], c.config.ChannelID.X)
1626 writeIntPadded(channelID[32:64], c.config.ChannelID.Y)
1627 writeIntPadded(channelID[64:96], r)
1628 writeIntPadded(channelID[96:128], s)
1629 if c.config.Bugs.InvalidChannelIDSignature {
1630 channelID[64] ^= 1
1631 }
1632 channelIDMsg.channelID = channelID
1633
1634 c.channelID = &c.config.ChannelID.PublicKey
1635
1636 return channelIDMsg.marshal(), nil
1637}
1638
David Benjamin83c0bc92014-08-04 01:23:53 -04001639func (hs *clientHandshakeState) writeClientHash(msg []byte) {
1640 // writeClientHash is called before writeRecord.
1641 hs.writeHash(msg, hs.c.sendHandshakeSeq)
1642}
1643
1644func (hs *clientHandshakeState) writeServerHash(msg []byte) {
1645 // writeServerHash is called after readHandshake.
1646 hs.writeHash(msg, hs.c.recvHandshakeSeq-1)
1647}
1648
1649func (hs *clientHandshakeState) writeHash(msg []byte, seqno uint16) {
1650 if hs.c.isDTLS {
1651 // This is somewhat hacky. DTLS hashes a slightly different format.
1652 // First, the TLS header.
1653 hs.finishedHash.Write(msg[:4])
1654 // Then the sequence number and reassembled fragment offset (always 0).
1655 hs.finishedHash.Write([]byte{byte(seqno >> 8), byte(seqno), 0, 0, 0})
1656 // Then the reassembled fragment (always equal to the message length).
1657 hs.finishedHash.Write(msg[1:4])
1658 // And then the message body.
1659 hs.finishedHash.Write(msg[4:])
1660 } else {
1661 hs.finishedHash.Write(msg)
1662 }
1663}
1664
David Benjamina6f82632016-07-01 18:44:02 -04001665// selectClientCertificate selects a certificate for use with the given
1666// certificate, or none if none match. It may return a particular certificate or
1667// nil on success, or an error on internal error.
1668func selectClientCertificate(c *Conn, certReq *certificateRequestMsg) (*Certificate, error) {
1669 // RFC 4346 on the certificateAuthorities field:
1670 // A list of the distinguished names of acceptable certificate
1671 // authorities. These distinguished names may specify a desired
1672 // distinguished name for a root CA or for a subordinate CA; thus, this
1673 // message can be used to describe both known roots and a desired
1674 // authorization space. If the certificate_authorities list is empty
1675 // then the client MAY send any certificate of the appropriate
1676 // ClientCertificateType, unless there is some external arrangement to
1677 // the contrary.
1678
1679 var rsaAvail, ecdsaAvail bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001680 if !certReq.hasRequestContext {
1681 for _, certType := range certReq.certificateTypes {
1682 switch certType {
1683 case CertTypeRSASign:
1684 rsaAvail = true
1685 case CertTypeECDSASign:
1686 ecdsaAvail = true
1687 }
David Benjamina6f82632016-07-01 18:44:02 -04001688 }
1689 }
1690
1691 // We need to search our list of client certs for one
1692 // where SignatureAlgorithm is RSA and the Issuer is in
1693 // certReq.certificateAuthorities
1694findCert:
1695 for i, chain := range c.config.Certificates {
Nick Harperb41d2e42016-07-01 17:50:32 -04001696 if !certReq.hasRequestContext && !rsaAvail && !ecdsaAvail {
David Benjamina6f82632016-07-01 18:44:02 -04001697 continue
1698 }
1699
1700 // Ensure the private key supports one of the advertised
1701 // signature algorithms.
1702 if certReq.hasSignatureAlgorithm {
David Benjamin0a8deb22016-07-09 21:02:01 -07001703 if _, err := selectSignatureAlgorithm(c.vers, chain.PrivateKey, c.config, certReq.signatureAlgorithms); err != nil {
David Benjamina6f82632016-07-01 18:44:02 -04001704 continue
1705 }
1706 }
1707
1708 for j, cert := range chain.Certificate {
1709 x509Cert := chain.Leaf
1710 // parse the certificate if this isn't the leaf
1711 // node, or if chain.Leaf was nil
1712 if j != 0 || x509Cert == nil {
1713 var err error
1714 if x509Cert, err = x509.ParseCertificate(cert); err != nil {
1715 c.sendAlert(alertInternalError)
1716 return nil, errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
1717 }
1718 }
1719
Nick Harperb41d2e42016-07-01 17:50:32 -04001720 if !certReq.hasRequestContext {
1721 switch {
1722 case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
1723 case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
David Benjamind768c5d2017-03-28 18:28:44 -05001724 case ecdsaAvail && isEd25519Certificate(x509Cert):
Nick Harperb41d2e42016-07-01 17:50:32 -04001725 default:
1726 continue findCert
1727 }
David Benjamina6f82632016-07-01 18:44:02 -04001728 }
1729
Adam Langley2ff79332017-02-28 13:45:39 -08001730 if expected := c.config.Bugs.ExpectCertificateReqNames; expected != nil {
1731 if !eqByteSlices(expected, certReq.certificateAuthorities) {
1732 return nil, fmt.Errorf("tls: CertificateRequest names differed, got %#v but expected %#v", certReq.certificateAuthorities, expected)
David Benjamina6f82632016-07-01 18:44:02 -04001733 }
1734 }
Adam Langley2ff79332017-02-28 13:45:39 -08001735
1736 return &chain, nil
David Benjamina6f82632016-07-01 18:44:02 -04001737 }
1738 }
1739
1740 return nil, nil
1741}
1742
Adam Langley95c29f32014-06-20 12:00:00 -07001743// clientSessionCacheKey returns a key used to cache sessionTickets that could
1744// be used to resume previously negotiated TLS sessions with a server.
1745func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
1746 if len(config.ServerName) > 0 {
1747 return config.ServerName
1748 }
1749 return serverAddr.String()
1750}
1751
David Benjaminfa055a22014-09-15 16:51:51 -04001752// mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol
1753// given list of possible protocols and a list of the preference order. The
1754// first list must not be empty. It returns the resulting protocol and flag
Adam Langley95c29f32014-06-20 12:00:00 -07001755// indicating if the fallback case was reached.
David Benjaminfa055a22014-09-15 16:51:51 -04001756func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
1757 for _, s := range preferenceProtos {
1758 for _, c := range protos {
Adam Langley95c29f32014-06-20 12:00:00 -07001759 if s == c {
1760 return s, false
1761 }
1762 }
1763 }
1764
David Benjaminfa055a22014-09-15 16:51:51 -04001765 return protos[0], true
Adam Langley95c29f32014-06-20 12:00:00 -07001766}
David Benjamind30a9902014-08-24 01:44:23 -04001767
1768// writeIntPadded writes x into b, padded up with leading zeros as
1769// needed.
1770func writeIntPadded(b []byte, x *big.Int) {
1771 for i := range b {
1772 b[i] = 0
1773 }
1774 xb := x.Bytes()
1775 copy(b[len(b)-len(xb):], xb)
1776}
Steven Valdeza833c352016-11-01 13:39:36 -04001777
1778func generatePSKBinders(hello *clientHelloMsg, pskCipherSuite *cipherSuite, psk, transcript []byte, config *Config) {
1779 if config.Bugs.SendNoPSKBinder {
1780 return
1781 }
1782
1783 binderLen := pskCipherSuite.hash().Size()
1784 if config.Bugs.SendShortPSKBinder {
1785 binderLen--
1786 }
1787
David Benjaminaedf3032016-12-01 16:47:56 -05001788 numBinders := 1
1789 if config.Bugs.SendExtraPSKBinder {
1790 numBinders++
1791 }
1792
Steven Valdeza833c352016-11-01 13:39:36 -04001793 // Fill hello.pskBinders with appropriate length arrays of zeros so the
1794 // length prefixes are correct when computing the binder over the truncated
1795 // ClientHello message.
David Benjaminaedf3032016-12-01 16:47:56 -05001796 hello.pskBinders = make([][]byte, numBinders)
1797 for i := range hello.pskBinders {
Steven Valdeza833c352016-11-01 13:39:36 -04001798 hello.pskBinders[i] = make([]byte, binderLen)
1799 }
1800
1801 helloBytes := hello.marshal()
1802 binderSize := len(hello.pskBinders)*(binderLen+1) + 2
1803 truncatedHello := helloBytes[:len(helloBytes)-binderSize]
1804 binder := computePSKBinder(psk, resumptionPSKBinderLabel, pskCipherSuite, transcript, truncatedHello)
1805 if config.Bugs.SendShortPSKBinder {
1806 binder = binder[:binderLen]
1807 }
1808 if config.Bugs.SendInvalidPSKBinder {
1809 binder[0] ^= 1
1810 }
1811
1812 for i := range hello.pskBinders {
1813 hello.pskBinders[i] = binder
1814 }
1815
1816 hello.raw = nil
1817}