blob: 2574ec3f0361c31f011f774853dbda902e05b66d [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
Robert Sloanf573be72018-09-17 15:29:11 -070022 "boringssl.googlesource.com/boringssl/ssl/test/runner/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
Robert Sloan4c22c5f2019-03-01 15:53:37 -080035 peerPublicKey crypto.PublicKey
36 skxAlgo signatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -080037}
38
Robert Sloanf6200e72017-07-10 08:09:18 -070039func mapClientHelloVersion(vers uint16, isDTLS bool) uint16 {
40 if !isDTLS {
41 return vers
42 }
43
44 switch vers {
45 case VersionTLS12:
46 return VersionDTLS12
47 case VersionTLS10:
48 return VersionDTLS10
49 }
50
51 panic("Unknown ClientHello version.")
52}
53
Robert Sloanc9abfe42018-11-26 12:19:07 -080054func fixClientHellos(hello *clientHelloMsg, in []byte) ([]byte, error) {
55 ret := append([]byte{}, in...)
56 newHello := new(clientHelloMsg)
57 if !newHello.unmarshal(ret) {
58 return nil, errors.New("tls: invalid ClientHello")
59 }
60
61 hello.random = newHello.random
62 hello.sessionId = newHello.sessionId
63
64 // Replace |ret|'s key shares with those of |hello|. For simplicity, we
65 // require their lengths match, which is satisfied by matching the
66 // DefaultCurves setting to the selection in the replacement
67 // ClientHello.
68 bb := newByteBuilder()
69 hello.marshalKeyShares(bb)
70 keyShares := bb.finish()
71 if len(keyShares) != len(newHello.keySharesRaw) {
72 return nil, errors.New("tls: ClientHello key share length is inconsistent with DefaultCurves setting")
73 }
74 // |newHello.keySharesRaw| aliases |ret|.
75 copy(newHello.keySharesRaw, keyShares)
76
77 return ret, nil
78}
79
Adam Langleyd9e397b2015-01-22 14:27:53 -080080func (c *Conn) clientHandshake() error {
81 if c.config == nil {
82 c.config = defaultConfig()
83 }
84
85 if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
86 return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
87 }
88
89 c.sendHandshakeSeq = 0
90 c.recvHandshakeSeq = 0
91
92 nextProtosLength := 0
93 for _, proto := range c.config.NextProtos {
Kenny Rootb8494592015-09-25 02:29:14 +000094 if l := len(proto); l > 255 {
Adam Langleyd9e397b2015-01-22 14:27:53 -080095 return errors.New("tls: invalid NextProtos value")
96 } else {
97 nextProtosLength += 1 + l
98 }
99 }
100 if nextProtosLength > 0xffff {
101 return errors.New("tls: NextProtos values too large")
102 }
103
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400104 minVersion := c.config.minVersion(c.isDTLS)
105 maxVersion := c.config.maxVersion(c.isDTLS)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800106 hello := &clientHelloMsg{
107 isDTLS: c.isDTLS,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800108 compressionMethods: []uint8{compressionNone},
109 random: make([]byte, 32),
Steven Valdez909b19f2016-11-21 15:35:44 -0500110 ocspStapling: !c.config.Bugs.NoOCSPStapling,
111 sctListSupported: !c.config.Bugs.NoSignedCertificateTimestamps,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800112 serverName: c.config.ServerName,
113 supportedCurves: c.config.curvePreferences(),
114 supportedPoints: []uint8{pointFormatUncompressed},
115 nextProtoNeg: len(c.config.NextProtos) > 0,
116 secureRenegotiation: []byte{},
117 alpnProtocols: c.config.NextProtos,
Robert Sloan8542c082018-02-05 09:07:34 -0800118 quicTransportParams: c.config.QUICTransportParams,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800119 duplicateExtension: c.config.Bugs.DuplicateExtension,
120 channelIDSupported: c.config.ChannelID != nil,
Robert Sloan978112c2018-01-22 12:53:01 -0800121 tokenBindingParams: c.config.TokenBindingParams,
122 tokenBindingVersion: c.config.TokenBindingVersion,
Steven Valdez909b19f2016-11-21 15:35:44 -0500123 npnAfterAlpn: c.config.Bugs.SwapNPNAndALPN,
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400124 extendedMasterSecret: maxVersion >= VersionTLS10,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800125 srtpProtectionProfiles: c.config.SRTPProtectionProfiles,
126 srtpMasterKeyIdentifier: c.config.Bugs.SRTPMasterKeyIdentifer,
Kenny Rootb8494592015-09-25 02:29:14 +0000127 customExtension: c.config.Bugs.CustomExtension,
Steven Valdez909b19f2016-11-21 15:35:44 -0500128 pskBinderFirst: c.config.Bugs.PSKBinderFirst,
Robert Sloana12bf462017-07-17 07:08:26 -0700129 omitExtensions: c.config.Bugs.OmitExtensions,
130 emptyExtensions: c.config.Bugs.EmptyExtensions,
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800131 delegatedCredentials: !c.config.Bugs.DisableDelegatedCredentials,
Pete Bentley0c61efe2019-08-13 09:32:23 +0100132 pqExperimentSignal: c.config.PQExperimentSignal,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800133 }
134
Robert Sloanf6200e72017-07-10 08:09:18 -0700135 if maxVersion >= VersionTLS13 {
136 hello.vers = mapClientHelloVersion(VersionTLS12, c.isDTLS)
137 if !c.config.Bugs.OmitSupportedVersions {
138 hello.supportedVersions = c.config.supportedVersions(c.isDTLS)
139 }
Robert Sloana12bf462017-07-17 07:08:26 -0700140 hello.pskKEModes = []byte{pskDHEKEMode}
Robert Sloanf6200e72017-07-10 08:09:18 -0700141 } else {
142 hello.vers = mapClientHelloVersion(maxVersion, c.isDTLS)
143 }
144
145 if c.config.Bugs.SendClientVersion != 0 {
146 hello.vers = c.config.Bugs.SendClientVersion
147 }
148
149 if len(c.config.Bugs.SendSupportedVersions) > 0 {
150 hello.supportedVersions = c.config.Bugs.SendSupportedVersions
151 }
152
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400153 disableEMS := c.config.Bugs.NoExtendedMasterSecret
154 if c.cipherSuite != nil {
155 disableEMS = c.config.Bugs.NoExtendedMasterSecretOnRenegotiation
Adam Langleyd9e397b2015-01-22 14:27:53 -0800156 }
157
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400158 if disableEMS {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800159 hello.extendedMasterSecret = false
160 }
161
Adam Langleye9ada862015-05-11 17:20:37 -0700162 if c.config.Bugs.NoSupportedCurves {
163 hello.supportedCurves = nil
164 }
165
Steven Valdez909b19f2016-11-21 15:35:44 -0500166 if len(c.config.Bugs.SendPSKKeyExchangeModes) != 0 {
167 hello.pskKEModes = c.config.Bugs.SendPSKKeyExchangeModes
168 }
169
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400170 if c.config.Bugs.SendCompressionMethods != nil {
171 hello.compressionMethods = c.config.Bugs.SendCompressionMethods
172 }
173
Robert Sloan69939df2017-01-09 10:53:07 -0800174 if c.config.Bugs.SendSupportedPointFormats != nil {
175 hello.supportedPoints = c.config.Bugs.SendSupportedPointFormats
176 }
177
Adam Langleyd9e397b2015-01-22 14:27:53 -0800178 if len(c.clientVerify) > 0 && !c.config.Bugs.EmptyRenegotiationInfo {
179 if c.config.Bugs.BadRenegotiationInfo {
180 hello.secureRenegotiation = append(hello.secureRenegotiation, c.clientVerify...)
181 hello.secureRenegotiation[0] ^= 0x80
182 } else {
183 hello.secureRenegotiation = c.clientVerify
184 }
185 }
186
Adam Vartanianbfcf3a72018-08-10 14:55:24 +0100187 if c.config.Bugs.DuplicateCompressedCertAlgs {
188 hello.compressedCertAlgs = []uint16{1, 1}
189 } else if len(c.config.CertCompressionAlgs) > 0 {
190 hello.compressedCertAlgs = make([]uint16, 0, len(c.config.CertCompressionAlgs))
191 for id, _ := range c.config.CertCompressionAlgs {
192 hello.compressedCertAlgs = append(hello.compressedCertAlgs, uint16(id))
193 }
194 }
195
Adam Langley4139edb2016-01-13 15:00:54 -0800196 if c.noRenegotiationInfo() {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800197 hello.secureRenegotiation = nil
198 }
199
David Benjaminc895d6b2016-08-11 13:26:41 -0400200 var keyShares map[CurveID]ecdhCurve
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400201 if maxVersion >= VersionTLS13 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400202 keyShares = make(map[CurveID]ecdhCurve)
203 hello.hasKeyShares = true
David Benjamin7c0d06c2016-08-11 13:26:41 -0400204 hello.trailingKeyShareData = c.config.Bugs.TrailingKeyShareData
David Benjaminc895d6b2016-08-11 13:26:41 -0400205 curvesToSend := c.config.defaultCurves()
206 for _, curveID := range hello.supportedCurves {
207 if !curvesToSend[curveID] {
208 continue
209 }
Robert Sloanab8b8882018-03-26 11:39:51 -0700210 curve, ok := curveForCurveID(curveID, c.config)
David Benjaminc895d6b2016-08-11 13:26:41 -0400211 if !ok {
212 continue
213 }
214 publicKey, err := curve.offer(c.config.rand())
215 if err != nil {
216 return err
217 }
218
219 if c.config.Bugs.SendCurve != 0 {
220 curveID = c.config.Bugs.SendCurve
221 }
222 if c.config.Bugs.InvalidECDHPoint {
223 publicKey[0] ^= 0xff
224 }
225
226 hello.keyShares = append(hello.keyShares, keyShareEntry{
227 group: curveID,
228 keyExchange: publicKey,
229 })
230 keyShares[curveID] = curve
231
232 if c.config.Bugs.DuplicateKeyShares {
233 hello.keyShares = append(hello.keyShares, hello.keyShares[len(hello.keyShares)-1])
234 }
235 }
236
237 if c.config.Bugs.MissingKeyShare {
238 hello.hasKeyShares = false
239 }
240 }
241
Adam Langleyd9e397b2015-01-22 14:27:53 -0800242 possibleCipherSuites := c.config.cipherSuites()
243 hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
244
245NextCipherSuite:
246 for _, suiteId := range possibleCipherSuites {
247 for _, suite := range cipherSuites {
248 if suite.id != suiteId {
249 continue
250 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400251 // Don't advertise TLS 1.2-only cipher suites unless
252 // we're attempting TLS 1.2.
253 if maxVersion < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
254 continue
255 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800256 hello.cipherSuites = append(hello.cipherSuites, suiteId)
257 continue NextCipherSuite
258 }
259 }
260
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400261 if c.config.Bugs.AdvertiseAllConfiguredCiphers {
262 hello.cipherSuites = possibleCipherSuites
263 }
264
Kenny Rootb8494592015-09-25 02:29:14 +0000265 if c.config.Bugs.SendRenegotiationSCSV {
266 hello.cipherSuites = append(hello.cipherSuites, renegotiationSCSV)
267 }
268
Adam Langleyd9e397b2015-01-22 14:27:53 -0800269 if c.config.Bugs.SendFallbackSCSV {
270 hello.cipherSuites = append(hello.cipherSuites, fallbackSCSV)
271 }
272
273 _, err := io.ReadFull(c.config.rand(), hello.random)
274 if err != nil {
275 c.sendAlert(alertInternalError)
276 return errors.New("tls: short read from Rand: " + err.Error())
277 }
278
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400279 if maxVersion >= VersionTLS12 && !c.config.Bugs.NoSignatureAlgorithms {
David Benjaminc895d6b2016-08-11 13:26:41 -0400280 hello.signatureAlgorithms = c.config.verifySignatureAlgorithms()
Adam Langleyd9e397b2015-01-22 14:27:53 -0800281 }
282
283 var session *ClientSessionState
284 var cacheKey string
285 sessionCache := c.config.ClientSessionCache
286
287 if sessionCache != nil {
288 hello.ticketSupported = !c.config.SessionTicketsDisabled
289
290 // Try to resume a previously negotiated TLS session, if
291 // available.
292 cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
David Benjaminc895d6b2016-08-11 13:26:41 -0400293 // TODO(nharper): Support storing more than one session
294 // ticket for TLS 1.3.
Adam Langleyd9e397b2015-01-22 14:27:53 -0800295 candidateSession, ok := sessionCache.Get(cacheKey)
296 if ok {
297 ticketOk := !c.config.SessionTicketsDisabled || candidateSession.sessionTicket == nil
298
299 // Check that the ciphersuite/version used for the
300 // previous session are still valid.
301 cipherSuiteOk := false
Steven Valdez909b19f2016-11-21 15:35:44 -0500302 if candidateSession.vers <= VersionTLS12 {
303 for _, id := range hello.cipherSuites {
304 if id == candidateSession.cipherSuite {
305 cipherSuiteOk = true
306 break
307 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800308 }
Steven Valdez909b19f2016-11-21 15:35:44 -0500309 } else {
310 // TLS 1.3 allows the cipher to change on
311 // resumption.
312 cipherSuiteOk = true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800313 }
314
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400315 versOk := candidateSession.vers >= minVersion &&
316 candidateSession.vers <= maxVersion
Adam Langleyd9e397b2015-01-22 14:27:53 -0800317 if ticketOk && versOk && cipherSuiteOk {
318 session = candidateSession
319 }
320 }
321 }
322
Steven Valdez909b19f2016-11-21 15:35:44 -0500323 var pskCipherSuite *cipherSuite
David Benjaminc895d6b2016-08-11 13:26:41 -0400324 if session != nil && c.config.time().Before(session.ticketExpiration) {
325 ticket := session.sessionTicket
Steven Valdez909b19f2016-11-21 15:35:44 -0500326 if c.config.Bugs.FilterTicket != nil && len(ticket) > 0 {
327 // Copy the ticket so FilterTicket may act in-place.
David Benjaminc895d6b2016-08-11 13:26:41 -0400328 ticket = make([]byte, len(session.sessionTicket))
329 copy(ticket, session.sessionTicket)
Steven Valdez909b19f2016-11-21 15:35:44 -0500330
331 ticket, err = c.config.Bugs.FilterTicket(ticket)
332 if err != nil {
333 return err
David Benjaminc895d6b2016-08-11 13:26:41 -0400334 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400335 }
336
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400337 if session.vers >= VersionTLS13 || c.config.Bugs.SendBothTickets {
Steven Valdez909b19f2016-11-21 15:35:44 -0500338 pskCipherSuite = cipherSuiteFromID(session.cipherSuite)
339 if pskCipherSuite == nil {
340 return errors.New("tls: client session cache has invalid cipher suite")
341 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400342 // TODO(nharper): Support sending more
343 // than one PSK identity.
Steven Valdez909b19f2016-11-21 15:35:44 -0500344 ticketAge := uint32(c.config.time().Sub(session.ticketCreationTime) / time.Millisecond)
Robert Sloan1c9db532017-03-13 08:03:59 -0700345 if c.config.Bugs.SendTicketAge != 0 {
346 ticketAge = uint32(c.config.Bugs.SendTicketAge / time.Millisecond)
347 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400348 psk := pskIdentity{
Steven Valdez909b19f2016-11-21 15:35:44 -0500349 ticket: ticket,
350 obfuscatedTicketAge: session.ticketAgeAdd + ticketAge,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800351 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400352 hello.pskIdentities = []pskIdentity{psk}
Steven Valdez909b19f2016-11-21 15:35:44 -0500353
354 if c.config.Bugs.ExtraPSKIdentity {
355 hello.pskIdentities = append(hello.pskIdentities, psk)
356 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800357 }
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400358
359 if session.vers < VersionTLS13 || c.config.Bugs.SendBothTickets {
360 if ticket != nil {
361 hello.sessionTicket = ticket
362 // A random session ID is used to detect when the
363 // server accepted the ticket and is resuming a session
364 // (see RFC 5077).
365 sessionIdLen := 16
Robert Sloan5d625782017-02-13 09:55:39 -0800366 if c.config.Bugs.TicketSessionIDLength != 0 {
367 sessionIdLen = c.config.Bugs.TicketSessionIDLength
368 }
369 if c.config.Bugs.EmptyTicketSessionID {
370 sessionIdLen = 0
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400371 }
372 hello.sessionId = make([]byte, sessionIdLen)
373 if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
374 c.sendAlert(alertInternalError)
375 return errors.New("tls: short read from Rand: " + err.Error())
376 }
377 } else {
378 hello.sessionId = session.sessionId
379 }
380 }
381 }
382
Robert Sloanab8b8882018-03-26 11:39:51 -0700383 // Request compatibility mode from the client by sending a fake session
384 // ID. Although BoringSSL always enables compatibility mode, other
385 // implementations make it conditional on the ClientHello. We test
386 // BoringSSL's expected behavior with SendClientHelloSessionID.
387 if len(hello.sessionId) == 0 && maxVersion >= VersionTLS13 {
388 hello.sessionId = make([]byte, 32)
389 if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
390 c.sendAlert(alertInternalError)
391 return errors.New("tls: short read from Rand: " + err.Error())
392 }
393 }
394
Steven Valdez909b19f2016-11-21 15:35:44 -0500395 if c.config.Bugs.SendCipherSuites != nil {
396 hello.cipherSuites = c.config.Bugs.SendCipherSuites
397 }
398
Robert Sloan47f43ed2017-02-06 14:55:15 -0800399 var sendEarlyData bool
Robert Sloan6d0d00e2017-03-27 07:13:07 -0700400 if len(hello.pskIdentities) > 0 && c.config.Bugs.SendEarlyData != nil {
David Benjamin1b249672016-12-06 18:25:50 -0500401 hello.hasEarlyData = true
Robert Sloan47f43ed2017-02-06 14:55:15 -0800402 sendEarlyData = true
403 }
404 if c.config.Bugs.SendFakeEarlyDataLength > 0 {
405 hello.hasEarlyData = true
406 }
407 if c.config.Bugs.OmitEarlyDataExtension {
408 hello.hasEarlyData = false
David Benjamin1b249672016-12-06 18:25:50 -0500409 }
Robert Sloanb6d070c2017-07-24 08:40:01 -0700410 if c.config.Bugs.SendClientHelloSessionID != nil {
411 hello.sessionId = c.config.Bugs.SendClientHelloSessionID
412 }
David Benjamin1b249672016-12-06 18:25:50 -0500413
Adam Langleyd9e397b2015-01-22 14:27:53 -0800414 var helloBytes []byte
415 if c.config.Bugs.SendV2ClientHello {
416 // Test that the peer left-pads random.
417 hello.random[0] = 0
418 v2Hello := &v2ClientHelloMsg{
419 vers: hello.vers,
420 cipherSuites: hello.cipherSuites,
421 // No session resumption for V2ClientHello.
422 sessionId: nil,
423 challenge: hello.random[1:],
424 }
425 helloBytes = v2Hello.marshal()
426 c.writeV2Record(helloBytes)
427 } else {
Steven Valdez909b19f2016-11-21 15:35:44 -0500428 if len(hello.pskIdentities) > 0 {
Robert Sloanb1b54b82017-11-06 13:50:02 -0800429 version := session.wireVersion
430 // We may have a pre-1.3 session if SendBothTickets is
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800431 // set.
Robert Sloanb1b54b82017-11-06 13:50:02 -0800432 if session.vers < VersionTLS13 {
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800433 version = VersionTLS13
Robert Sloanb1b54b82017-11-06 13:50:02 -0800434 }
435 generatePSKBinders(version, hello, pskCipherSuite, session.masterSecret, []byte{}, []byte{}, c.config)
Steven Valdez909b19f2016-11-21 15:35:44 -0500436 }
Robert Sloanc9abfe42018-11-26 12:19:07 -0800437 if c.config.Bugs.SendClientHelloWithFixes != nil {
438 helloBytes, err = fixClientHellos(hello, c.config.Bugs.SendClientHelloWithFixes)
439 if err != nil {
440 return err
441 }
442 } else {
443 helloBytes = hello.marshal()
444 }
Steven Valdez909b19f2016-11-21 15:35:44 -0500445
David Benjaminc895d6b2016-08-11 13:26:41 -0400446 if c.config.Bugs.PartialClientFinishedWithClientHello {
447 // Include one byte of Finished. We can compute it
448 // without completing the handshake. This assumes we
449 // negotiate TLS 1.3 with no HelloRetryRequest or
450 // CertificateRequest.
451 toWrite := make([]byte, 0, len(helloBytes)+1)
452 toWrite = append(toWrite, helloBytes...)
453 toWrite = append(toWrite, typeFinished)
454 c.writeRecord(recordTypeHandshake, toWrite)
455 } else {
456 c.writeRecord(recordTypeHandshake, helloBytes)
457 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800458 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400459 c.flushHandshake()
Adam Langleyd9e397b2015-01-22 14:27:53 -0800460
Adam Langleye9ada862015-05-11 17:20:37 -0700461 if err := c.simulatePacketLoss(nil); err != nil {
462 return err
463 }
David Benjamin1b249672016-12-06 18:25:50 -0500464 if c.config.Bugs.SendEarlyAlert {
465 c.sendAlert(alertHandshakeFailure)
466 }
Robert Sloan47f43ed2017-02-06 14:55:15 -0800467 if c.config.Bugs.SendFakeEarlyDataLength > 0 {
468 c.sendFakeEarlyData(c.config.Bugs.SendFakeEarlyDataLength)
David Benjamin1b249672016-12-06 18:25:50 -0500469 }
Robert Sloan47f43ed2017-02-06 14:55:15 -0800470
471 // Derive early write keys and set Conn state to allow early writes.
472 if sendEarlyData {
Robert Sloanb1b54b82017-11-06 13:50:02 -0800473 finishedHash := newFinishedHash(session.wireVersion, c.isDTLS, pskCipherSuite)
Robert Sloan47f43ed2017-02-06 14:55:15 -0800474 finishedHash.addEntropy(session.masterSecret)
475 finishedHash.Write(helloBytes)
Robert Sloanb1b54b82017-11-06 13:50:02 -0800476
Robert Sloan8542c082018-02-05 09:07:34 -0800477 if !c.config.Bugs.SkipChangeCipherSpec {
Robert Sloand5c22152017-11-13 09:22:12 -0800478 c.wireVersion = session.wireVersion
Robert Sloan0da43952018-01-03 15:13:14 -0800479 c.vers = VersionTLS13
Robert Sloand5c22152017-11-13 09:22:12 -0800480 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
481 c.wireVersion = 0
Robert Sloan0da43952018-01-03 15:13:14 -0800482 c.vers = 0
Robert Sloand5c22152017-11-13 09:22:12 -0800483 }
484
Robert Sloan8542c082018-02-05 09:07:34 -0800485 earlyTrafficSecret := finishedHash.deriveSecret(earlyTrafficLabel)
486 c.earlyExporterSecret = finishedHash.deriveSecret(earlyExporterLabel)
Robert Sloan55818102017-12-18 11:26:17 -0800487
Robert Sloan29c1d2c2017-10-30 14:10:28 -0700488 c.useOutTrafficSecret(session.wireVersion, pskCipherSuite, earlyTrafficSecret)
Robert Sloan47f43ed2017-02-06 14:55:15 -0800489 for _, earlyData := range c.config.Bugs.SendEarlyData {
490 if _, err := c.writeRecord(recordTypeApplicationData, earlyData); err != nil {
491 return err
492 }
493 }
494 }
495
Adam Langleyd9e397b2015-01-22 14:27:53 -0800496 msg, err := c.readHandshake()
497 if err != nil {
498 return err
499 }
500
501 if c.isDTLS {
502 helloVerifyRequest, ok := msg.(*helloVerifyRequestMsg)
503 if ok {
Robert Sloanf6200e72017-07-10 08:09:18 -0700504 if helloVerifyRequest.vers != VersionDTLS10 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800505 // Per RFC 6347, the version field in
506 // HelloVerifyRequest SHOULD be always DTLS
507 // 1.0. Enforce this for testing purposes.
508 return errors.New("dtls: bad HelloVerifyRequest version")
509 }
510
511 hello.raw = nil
512 hello.cookie = helloVerifyRequest.cookie
513 helloBytes = hello.marshal()
514 c.writeRecord(recordTypeHandshake, helloBytes)
David Benjaminc895d6b2016-08-11 13:26:41 -0400515 c.flushHandshake()
Adam Langleyd9e397b2015-01-22 14:27:53 -0800516
Adam Langleye9ada862015-05-11 17:20:37 -0700517 if err := c.simulatePacketLoss(nil); err != nil {
518 return err
519 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800520 msg, err = c.readHandshake()
521 if err != nil {
522 return err
523 }
524 }
525 }
526
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400527 var serverWireVersion uint16
David Benjaminc895d6b2016-08-11 13:26:41 -0400528 switch m := msg.(type) {
529 case *helloRetryRequestMsg:
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400530 serverWireVersion = m.vers
David Benjaminc895d6b2016-08-11 13:26:41 -0400531 case *serverHelloMsg:
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400532 serverWireVersion = m.vers
David Benjaminc895d6b2016-08-11 13:26:41 -0400533 default:
534 c.sendAlert(alertUnexpectedMessage)
535 return fmt.Errorf("tls: received unexpected message of type %T when waiting for HelloRetryRequest or ServerHello", msg)
536 }
537
Robert Sloanf6200e72017-07-10 08:09:18 -0700538 serverVersion, ok := c.config.isSupportedVersion(serverWireVersion, c.isDTLS)
David Benjaminc895d6b2016-08-11 13:26:41 -0400539 if !ok {
540 c.sendAlert(alertProtocolVersion)
541 return fmt.Errorf("tls: server selected unsupported protocol version %x", c.vers)
542 }
Robert Sloanf6200e72017-07-10 08:09:18 -0700543 c.wireVersion = serverWireVersion
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400544 c.vers = serverVersion
David Benjaminc895d6b2016-08-11 13:26:41 -0400545 c.haveVers = true
546
Robert Sloan8542c082018-02-05 09:07:34 -0800547 if c.vers >= VersionTLS13 {
Robert Sloan99319a12017-11-27 10:32:46 -0800548 // The first server message must be followed by a ChangeCipherSpec.
549 c.expectTLS13ChangeCipherSpec = true
550 }
551
David Benjaminc895d6b2016-08-11 13:26:41 -0400552 helloRetryRequest, haveHelloRetryRequest := msg.(*helloRetryRequestMsg)
553 var secondHelloBytes []byte
554 if haveHelloRetryRequest {
Robert Sloan11c28bd2018-12-17 12:09:20 -0800555 if c.config.Bugs.FailIfHelloRetryRequested {
556 return errors.New("tls: unexpected HelloRetryRequest")
557 }
Robert Sloan8542c082018-02-05 09:07:34 -0800558 // Explicitly read the ChangeCipherSpec now; it should
559 // be attached to the first flight, not the second flight.
560 if err := c.readTLS13ChangeCipherSpec(); err != nil {
561 return err
Robert Sloand5c22152017-11-13 09:22:12 -0800562 }
563
Robert Sloan47f43ed2017-02-06 14:55:15 -0800564 c.out.resetCipher()
David Benjamin95add822016-10-19 01:09:12 -0400565 if len(helloRetryRequest.cookie) > 0 {
566 hello.tls13Cookie = helloRetryRequest.cookie
567 }
568
David Benjaminc895d6b2016-08-11 13:26:41 -0400569 if c.config.Bugs.MisinterpretHelloRetryRequestCurve != 0 {
David Benjamin95add822016-10-19 01:09:12 -0400570 helloRetryRequest.hasSelectedGroup = true
David Benjaminc895d6b2016-08-11 13:26:41 -0400571 helloRetryRequest.selectedGroup = c.config.Bugs.MisinterpretHelloRetryRequestCurve
572 }
David Benjamin95add822016-10-19 01:09:12 -0400573 if helloRetryRequest.hasSelectedGroup {
574 var hrrCurveFound bool
575 group := helloRetryRequest.selectedGroup
576 for _, curveID := range hello.supportedCurves {
577 if group == curveID {
578 hrrCurveFound = true
579 break
580 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400581 }
David Benjamin95add822016-10-19 01:09:12 -0400582 if !hrrCurveFound || keyShares[group] != nil {
583 c.sendAlert(alertHandshakeFailure)
584 return errors.New("tls: received invalid HelloRetryRequest")
585 }
Robert Sloanab8b8882018-03-26 11:39:51 -0700586 curve, ok := curveForCurveID(group, c.config)
David Benjamin95add822016-10-19 01:09:12 -0400587 if !ok {
588 return errors.New("tls: Unable to get curve requested in HelloRetryRequest")
589 }
590 publicKey, err := curve.offer(c.config.rand())
591 if err != nil {
592 return err
593 }
594 keyShares[group] = curve
Steven Valdez909b19f2016-11-21 15:35:44 -0500595 hello.keyShares = []keyShareEntry{{
David Benjamin95add822016-10-19 01:09:12 -0400596 group: group,
597 keyExchange: publicKey,
Steven Valdez909b19f2016-11-21 15:35:44 -0500598 }}
David Benjaminc895d6b2016-08-11 13:26:41 -0400599 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400600
601 if c.config.Bugs.SecondClientHelloMissingKeyShare {
602 hello.hasKeyShares = false
603 }
604
David Benjamin1b249672016-12-06 18:25:50 -0500605 hello.hasEarlyData = c.config.Bugs.SendEarlyDataOnSecondClientHello
David Benjaminc895d6b2016-08-11 13:26:41 -0400606 hello.raw = nil
607
Steven Valdez909b19f2016-11-21 15:35:44 -0500608 if len(hello.pskIdentities) > 0 {
Robert Sloanb1b54b82017-11-06 13:50:02 -0800609 generatePSKBinders(c.wireVersion, hello, pskCipherSuite, session.masterSecret, helloBytes, helloRetryRequest.marshal(), c.config)
Steven Valdez909b19f2016-11-21 15:35:44 -0500610 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400611 secondHelloBytes = hello.marshal()
David Benjamin1b249672016-12-06 18:25:50 -0500612
613 if c.config.Bugs.InterleaveEarlyData {
614 c.sendFakeEarlyData(4)
615 c.writeRecord(recordTypeHandshake, secondHelloBytes[:16])
616 c.sendFakeEarlyData(4)
617 c.writeRecord(recordTypeHandshake, secondHelloBytes[16:])
618 } else {
619 c.writeRecord(recordTypeHandshake, secondHelloBytes)
620 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400621 c.flushHandshake()
622
David Benjamin1b249672016-12-06 18:25:50 -0500623 if c.config.Bugs.SendEarlyDataOnSecondClientHello {
624 c.sendFakeEarlyData(4)
625 }
626
David Benjaminc895d6b2016-08-11 13:26:41 -0400627 msg, err = c.readHandshake()
628 if err != nil {
629 return err
630 }
631 }
632
Adam Langleyd9e397b2015-01-22 14:27:53 -0800633 serverHello, ok := msg.(*serverHelloMsg)
634 if !ok {
635 c.sendAlert(alertUnexpectedMessage)
636 return unexpectedMessageError(serverHello, msg)
637 }
638
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400639 if serverWireVersion != serverHello.vers {
Adam Vartanianbfcf3a72018-08-10 14:55:24 +0100640 c.sendAlert(alertIllegalParameter)
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400641 return fmt.Errorf("tls: server sent non-matching version %x vs %x", serverWireVersion, serverHello.vers)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800642 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800643
Robert Sloand9e572d2018-08-27 12:27:00 -0700644 _, supportsTLS13 := c.config.isSupportedVersion(VersionTLS13, false)
645 // Check for downgrade signals in the server random, per RFC 8446, section 4.1.3.
Robert Sloanc9abfe42018-11-26 12:19:07 -0800646 gotDowngrade := serverHello.random[len(serverHello.random)-8:]
Robert Sloand9e572d2018-08-27 12:27:00 -0700647 if (supportsTLS13 || c.config.Bugs.CheckTLS13DowngradeRandom) && !c.config.Bugs.IgnoreTLS13DowngradeRandom {
648 if c.vers <= VersionTLS12 && c.config.maxVersion(c.isDTLS) >= VersionTLS13 {
Robert Sloanc9abfe42018-11-26 12:19:07 -0800649 if bytes.Equal(gotDowngrade, downgradeTLS13) {
Robert Sloand9e572d2018-08-27 12:27:00 -0700650 c.sendAlert(alertProtocolVersion)
651 return errors.New("tls: downgrade from TLS 1.3 detected")
652 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400653 }
Robert Sloand9e572d2018-08-27 12:27:00 -0700654 if c.vers <= VersionTLS11 && c.config.maxVersion(c.isDTLS) >= VersionTLS12 {
Robert Sloanc9abfe42018-11-26 12:19:07 -0800655 if bytes.Equal(gotDowngrade, downgradeTLS12) {
Robert Sloand9e572d2018-08-27 12:27:00 -0700656 c.sendAlert(alertProtocolVersion)
657 return errors.New("tls: downgrade from TLS 1.2 detected")
658 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400659 }
660 }
661
Robert Sloanc9abfe42018-11-26 12:19:07 -0800662 if bytes.Equal(gotDowngrade, downgradeJDK11) != c.config.Bugs.ExpectJDK11DowngradeRandom {
663 c.sendAlert(alertProtocolVersion)
664 if c.config.Bugs.ExpectJDK11DowngradeRandom {
665 return errors.New("tls: server did not send a JDK 11 downgrade signal")
666 }
667 return errors.New("tls: server sent an unexpected JDK 11 downgrade signal")
668 }
669
David Benjaminc895d6b2016-08-11 13:26:41 -0400670 suite := mutualCipherSuite(hello.cipherSuites, serverHello.cipherSuite)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800671 if suite == nil {
672 c.sendAlert(alertHandshakeFailure)
673 return fmt.Errorf("tls: server selected an unsupported cipher suite")
674 }
675
David Benjamin95add822016-10-19 01:09:12 -0400676 if haveHelloRetryRequest && helloRetryRequest.hasSelectedGroup && helloRetryRequest.selectedGroup != serverHello.keyShare.group {
David Benjaminc895d6b2016-08-11 13:26:41 -0400677 c.sendAlert(alertHandshakeFailure)
678 return errors.New("tls: ServerHello parameters did not match HelloRetryRequest")
Kenny Rootb8494592015-09-25 02:29:14 +0000679 }
680
Robert Sloana27a6a42017-09-05 08:39:28 -0700681 if c.config.Bugs.ExpectOmitExtensions && !serverHello.omitExtensions {
682 return errors.New("tls: ServerHello did not omit extensions")
683 }
684
Adam Langleyd9e397b2015-01-22 14:27:53 -0800685 hs := &clientHandshakeState{
686 c: c,
687 serverHello: serverHello,
688 hello: hello,
689 suite: suite,
Robert Sloanb1b54b82017-11-06 13:50:02 -0800690 finishedHash: newFinishedHash(c.wireVersion, c.isDTLS, suite),
David Benjaminc895d6b2016-08-11 13:26:41 -0400691 keyShares: keyShares,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800692 session: session,
693 }
694
695 hs.writeHash(helloBytes, hs.c.sendHandshakeSeq-1)
David Benjaminc895d6b2016-08-11 13:26:41 -0400696 if haveHelloRetryRequest {
Robert Sloan8542c082018-02-05 09:07:34 -0800697 err = hs.finishedHash.UpdateForHelloRetryRequest()
698 if err != nil {
699 return err
Robert Sloanb1b54b82017-11-06 13:50:02 -0800700 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400701 hs.writeServerHash(helloRetryRequest.marshal())
702 hs.writeClientHash(secondHelloBytes)
703 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800704 hs.writeServerHash(hs.serverHello.marshal())
705
David Benjaminc895d6b2016-08-11 13:26:41 -0400706 if c.vers >= VersionTLS13 {
707 if err := hs.doTLS13Handshake(); err != nil {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800708 return err
709 }
710 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -0400711 if c.config.Bugs.EarlyChangeCipherSpec > 0 {
712 hs.establishKeys()
713 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
714 }
715
716 if hs.serverHello.compressionMethod != compressionNone {
717 c.sendAlert(alertUnexpectedMessage)
718 return errors.New("tls: server selected unsupported compression format")
719 }
720
721 err = hs.processServerExtensions(&serverHello.extensions)
722 if err != nil {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800723 return err
724 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400725
726 isResume, err := hs.processServerHello()
727 if err != nil {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800728 return err
729 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400730
731 if isResume {
732 if c.config.Bugs.EarlyChangeCipherSpec == 0 {
733 if err := hs.establishKeys(); err != nil {
734 return err
735 }
736 }
737 if err := hs.readSessionTicket(); err != nil {
738 return err
739 }
740 if err := hs.readFinished(c.firstFinished[:]); err != nil {
741 return err
742 }
743 if err := hs.sendFinished(nil, isResume); err != nil {
744 return err
745 }
746 } else {
747 if err := hs.doFullHandshake(); err != nil {
748 return err
749 }
750 if err := hs.establishKeys(); err != nil {
751 return err
752 }
753 if err := hs.sendFinished(c.firstFinished[:], isResume); err != nil {
754 return err
755 }
756 // Most retransmits are triggered by a timeout, but the final
757 // leg of the handshake is retransmited upon re-receiving a
758 // Finished.
759 if err := c.simulatePacketLoss(func() {
760 c.sendHandshakeSeq--
761 c.writeRecord(recordTypeHandshake, hs.finishedBytes)
762 c.flushHandshake()
763 }); err != nil {
764 return err
765 }
766 if err := hs.readSessionTicket(); err != nil {
767 return err
768 }
769 if err := hs.readFinished(nil); err != nil {
770 return err
771 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800772 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400773
774 if sessionCache != nil && hs.session != nil && session != hs.session {
775 if c.config.Bugs.RequireSessionTickets && len(hs.session.sessionTicket) == 0 {
776 return errors.New("tls: new session used session IDs instead of tickets")
777 }
Adam Vartanianbfcf3a72018-08-10 14:55:24 +0100778 if c.config.Bugs.RequireSessionIDs && len(hs.session.sessionId) == 0 {
779 return errors.New("tls: new session used session tickets instead of IDs")
780 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400781 sessionCache.Put(cacheKey, hs.session)
Adam Langleye9ada862015-05-11 17:20:37 -0700782 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400783
784 c.didResume = isResume
785 c.exporterSecret = hs.masterSecret
Adam Langleyd9e397b2015-01-22 14:27:53 -0800786 }
787
Adam Langleyd9e397b2015-01-22 14:27:53 -0800788 c.handshakeComplete = true
Adam Langleye9ada862015-05-11 17:20:37 -0700789 c.cipherSuite = suite
790 copy(c.clientRandom[:], hs.hello.random)
791 copy(c.serverRandom[:], hs.serverHello.random)
Kenny Rootb8494592015-09-25 02:29:14 +0000792
Adam Langleyd9e397b2015-01-22 14:27:53 -0800793 return nil
794}
795
David Benjaminc895d6b2016-08-11 13:26:41 -0400796func (hs *clientHandshakeState) doTLS13Handshake() error {
797 c := hs.c
798
Robert Sloan0da43952018-01-03 15:13:14 -0800799 if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
Robert Sloanb6d070c2017-07-24 08:40:01 -0700800 return errors.New("tls: session IDs did not match.")
801 }
802
David Benjaminc895d6b2016-08-11 13:26:41 -0400803 // Once the PRF hash is known, TLS 1.3 does not require a handshake
804 // buffer.
805 hs.finishedHash.discardHandshakeBuffer()
806
807 zeroSecret := hs.finishedHash.zeroSecret()
808
809 // Resolve PSK and compute the early secret.
810 //
811 // TODO(davidben): This will need to be handled slightly earlier once
812 // 0-RTT is implemented.
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400813 if hs.serverHello.hasPSKIdentity {
David Benjaminc895d6b2016-08-11 13:26:41 -0400814 // We send at most one PSK identity.
815 if hs.session == nil || hs.serverHello.pskIdentity != 0 {
816 c.sendAlert(alertUnknownPSKIdentity)
817 return errors.New("tls: server sent unknown PSK identity")
818 }
Steven Valdez909b19f2016-11-21 15:35:44 -0500819 sessionCipher := cipherSuiteFromID(hs.session.cipherSuite)
820 if sessionCipher == nil || sessionCipher.hash() != hs.suite.hash() {
David Benjaminc895d6b2016-08-11 13:26:41 -0400821 c.sendAlert(alertHandshakeFailure)
Steven Valdez909b19f2016-11-21 15:35:44 -0500822 return errors.New("tls: server resumed an invalid session for the cipher suite")
David Benjaminc895d6b2016-08-11 13:26:41 -0400823 }
David Benjamin1b249672016-12-06 18:25:50 -0500824 hs.finishedHash.addEntropy(hs.session.masterSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -0400825 c.didResume = true
826 } else {
David Benjamin1b249672016-12-06 18:25:50 -0500827 hs.finishedHash.addEntropy(zeroSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -0400828 }
829
Steven Valdez909b19f2016-11-21 15:35:44 -0500830 if !hs.serverHello.hasKeyShare {
831 c.sendAlert(alertUnsupportedExtension)
832 return errors.New("tls: server omitted KeyShare on resumption.")
833 }
834
David Benjaminc895d6b2016-08-11 13:26:41 -0400835 // Resolve ECDHE and compute the handshake secret.
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400836 if !c.config.Bugs.MissingKeyShare && !c.config.Bugs.SecondClientHelloMissingKeyShare {
David Benjaminc895d6b2016-08-11 13:26:41 -0400837 curve, ok := hs.keyShares[hs.serverHello.keyShare.group]
838 if !ok {
839 c.sendAlert(alertHandshakeFailure)
840 return errors.New("tls: server selected an unsupported group")
841 }
842 c.curveID = hs.serverHello.keyShare.group
843
David Benjamin1b249672016-12-06 18:25:50 -0500844 ecdheSecret, err := curve.finish(hs.serverHello.keyShare.keyExchange)
David Benjaminc895d6b2016-08-11 13:26:41 -0400845 if err != nil {
846 return err
847 }
Robert Sloanb1b54b82017-11-06 13:50:02 -0800848 hs.finishedHash.nextSecret()
David Benjamin1b249672016-12-06 18:25:50 -0500849 hs.finishedHash.addEntropy(ecdheSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -0400850 } else {
Robert Sloanb1b54b82017-11-06 13:50:02 -0800851 hs.finishedHash.nextSecret()
David Benjamin1b249672016-12-06 18:25:50 -0500852 hs.finishedHash.addEntropy(zeroSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -0400853 }
854
Robert Sloan47f43ed2017-02-06 14:55:15 -0800855 // Derive handshake traffic keys and switch read key to handshake
856 // traffic key.
Robert Sloan8542c082018-02-05 09:07:34 -0800857 clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(clientHandshakeTrafficLabel)
858 serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(serverHandshakeTrafficLabel)
Robert Sloan29c1d2c2017-10-30 14:10:28 -0700859 if err := c.useInTrafficSecret(c.wireVersion, hs.suite, serverHandshakeTrafficSecret); err != nil {
860 return err
861 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400862
863 msg, err := c.readHandshake()
864 if err != nil {
865 return err
866 }
867
868 encryptedExtensions, ok := msg.(*encryptedExtensionsMsg)
869 if !ok {
870 c.sendAlert(alertUnexpectedMessage)
871 return unexpectedMessageError(encryptedExtensions, msg)
872 }
873 hs.writeServerHash(encryptedExtensions.marshal())
874
875 err = hs.processServerExtensions(&encryptedExtensions.extensions)
876 if err != nil {
877 return err
878 }
879
880 var chainToSend *Certificate
881 var certReq *certificateRequestMsg
Steven Valdez909b19f2016-11-21 15:35:44 -0500882 if c.didResume {
David Benjaminc895d6b2016-08-11 13:26:41 -0400883 // Copy over authentication from the session.
884 c.peerCertificates = hs.session.serverCertificates
885 c.sctList = hs.session.sctList
886 c.ocspResponse = hs.session.ocspResponse
887 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -0400888 msg, err := c.readHandshake()
889 if err != nil {
890 return err
891 }
892
893 var ok bool
894 certReq, ok = msg.(*certificateRequestMsg)
895 if ok {
David Benjaminf0c4a6c2016-08-11 13:26:41 -0400896 if len(certReq.requestContext) != 0 {
897 return errors.New("tls: non-empty certificate request context sent in handshake")
898 }
899
Robert Sloanb1b54b82017-11-06 13:50:02 -0800900 if c.config.Bugs.ExpectNoCertificateAuthoritiesExtension && certReq.hasCAExtension {
901 return errors.New("tls: expected no certificate_authorities extension")
902 }
903
Robert Sloan5cbb5c82018-04-24 11:35:46 -0700904 if err := checkRSAPSSSupport(c.config.Bugs.ExpectRSAPSSSupport, certReq.signatureAlgorithms, certReq.signatureAlgorithmsCert); err != nil {
905 return err
906 }
907
David Benjaminc895d6b2016-08-11 13:26:41 -0400908 if c.config.Bugs.IgnorePeerSignatureAlgorithmPreferences {
909 certReq.signatureAlgorithms = c.config.signSignatureAlgorithms()
910 }
911
912 hs.writeServerHash(certReq.marshal())
913
914 chainToSend, err = selectClientCertificate(c, certReq)
915 if err != nil {
916 return err
917 }
918
919 msg, err = c.readHandshake()
920 if err != nil {
921 return err
922 }
923 }
924
Adam Vartanianbfcf3a72018-08-10 14:55:24 +0100925 var certMsg *certificateMsg
926
927 if compressedCertMsg, ok := msg.(*compressedCertificateMsg); ok {
928 hs.writeServerHash(compressedCertMsg.marshal())
929
930 alg, ok := c.config.CertCompressionAlgs[compressedCertMsg.algID]
931 if !ok {
932 c.sendAlert(alertBadCertificate)
933 return fmt.Errorf("tls: received certificate compressed with unknown algorithm %x", compressedCertMsg.algID)
934 }
935
936 decompressed := make([]byte, 4+int(compressedCertMsg.uncompressedLength))
937 if !alg.Decompress(decompressed[4:], compressedCertMsg.compressed) {
938 c.sendAlert(alertBadCertificate)
939 return fmt.Errorf("tls: failed to decompress certificate with algorithm %x", compressedCertMsg.algID)
940 }
941
942 certMsg = &certificateMsg{
943 hasRequestContext: true,
944 }
945
946 if !certMsg.unmarshal(decompressed) {
947 c.sendAlert(alertBadCertificate)
948 return errors.New("tls: failed to parse decompressed certificate")
949 }
950
951 if expected := c.config.Bugs.ExpectedCompressedCert; expected != 0 && expected != compressedCertMsg.algID {
952 return fmt.Errorf("tls: expected certificate compressed with algorithm %x, but message used %x", expected, compressedCertMsg.algID)
953 }
954 } else {
955 if certMsg, ok = msg.(*certificateMsg); !ok {
956 c.sendAlert(alertUnexpectedMessage)
957 return unexpectedMessageError(certMsg, msg)
958 }
959 hs.writeServerHash(certMsg.marshal())
960
961 if c.config.Bugs.ExpectedCompressedCert != 0 {
962 return errors.New("tls: uncompressed certificate received")
963 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400964 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400965
Steven Valdez909b19f2016-11-21 15:35:44 -0500966 // Check for unsolicited extensions.
967 for i, cert := range certMsg.certificates {
968 if c.config.Bugs.NoOCSPStapling && cert.ocspResponse != nil {
969 c.sendAlert(alertUnsupportedExtension)
970 return errors.New("tls: unexpected OCSP response in the server certificate")
971 }
972 if c.config.Bugs.NoSignedCertificateTimestamps && cert.sctList != nil {
973 c.sendAlert(alertUnsupportedExtension)
974 return errors.New("tls: unexpected SCT list in the server certificate")
975 }
976 if i > 0 && c.config.Bugs.ExpectNoExtensionsOnIntermediate && (cert.ocspResponse != nil || cert.sctList != nil) {
977 c.sendAlert(alertUnsupportedExtension)
978 return errors.New("tls: unexpected extensions in the server certificate")
979 }
980 }
981
David Benjaminc895d6b2016-08-11 13:26:41 -0400982 if err := hs.verifyCertificates(certMsg); err != nil {
983 return err
984 }
Steven Valdez909b19f2016-11-21 15:35:44 -0500985 c.ocspResponse = certMsg.certificates[0].ocspResponse
986 c.sctList = certMsg.certificates[0].sctList
David Benjaminc895d6b2016-08-11 13:26:41 -0400987
988 msg, err = c.readHandshake()
989 if err != nil {
990 return err
991 }
992 certVerifyMsg, ok := msg.(*certificateVerifyMsg)
993 if !ok {
994 c.sendAlert(alertUnexpectedMessage)
995 return unexpectedMessageError(certVerifyMsg, msg)
996 }
997
998 c.peerSignatureAlgorithm = certVerifyMsg.signatureAlgorithm
999 input := hs.finishedHash.certificateVerifyInput(serverCertificateVerifyContextTLS13)
Robert Sloan4c22c5f2019-03-01 15:53:37 -08001000 err = verifyMessage(c.vers, hs.peerPublicKey, c.config, certVerifyMsg.signatureAlgorithm, input, certVerifyMsg.signature)
David Benjaminc895d6b2016-08-11 13:26:41 -04001001 if err != nil {
1002 return err
1003 }
1004
1005 hs.writeServerHash(certVerifyMsg.marshal())
1006 }
1007
1008 msg, err = c.readHandshake()
1009 if err != nil {
1010 return err
1011 }
1012 serverFinished, ok := msg.(*finishedMsg)
1013 if !ok {
1014 c.sendAlert(alertUnexpectedMessage)
1015 return unexpectedMessageError(serverFinished, msg)
1016 }
1017
David Benjamin95add822016-10-19 01:09:12 -04001018 verify := hs.finishedHash.serverSum(serverHandshakeTrafficSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -04001019 if len(verify) != len(serverFinished.verifyData) ||
1020 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
1021 c.sendAlert(alertHandshakeFailure)
1022 return errors.New("tls: server's Finished message was incorrect")
1023 }
1024
1025 hs.writeServerHash(serverFinished.marshal())
1026
1027 // The various secrets do not incorporate the client's final leg, so
1028 // derive them now before updating the handshake context.
Robert Sloanb1b54b82017-11-06 13:50:02 -08001029 hs.finishedHash.nextSecret()
David Benjamin1b249672016-12-06 18:25:50 -05001030 hs.finishedHash.addEntropy(zeroSecret)
Robert Sloanb1b54b82017-11-06 13:50:02 -08001031
Robert Sloan8542c082018-02-05 09:07:34 -08001032 clientTrafficSecret := hs.finishedHash.deriveSecret(clientApplicationTrafficLabel)
1033 serverTrafficSecret := hs.finishedHash.deriveSecret(serverApplicationTrafficLabel)
1034 c.exporterSecret = hs.finishedHash.deriveSecret(exporterLabel)
Robert Sloan5d625782017-02-13 09:55:39 -08001035
1036 // Switch to application data keys on read. In particular, any alerts
1037 // from the client certificate are read over these keys.
Robert Sloan29c1d2c2017-10-30 14:10:28 -07001038 if err := c.useInTrafficSecret(c.wireVersion, hs.suite, serverTrafficSecret); err != nil {
1039 return err
1040 }
Robert Sloan4d1ac502017-02-06 08:36:14 -08001041
Robert Sloanb1b54b82017-11-06 13:50:02 -08001042 // If we're expecting 0.5-RTT messages from the server, read them now.
1043 var deferredTickets []*newSessionTicketMsg
Robert Sloan6d0d00e2017-03-27 07:13:07 -07001044 if encryptedExtensions.extensions.hasEarlyData {
1045 // BoringSSL will always send two tickets half-RTT when
1046 // negotiating 0-RTT.
1047 for i := 0; i < shimConfig.HalfRTTTickets; i++ {
1048 msg, err := c.readHandshake()
1049 if err != nil {
1050 return fmt.Errorf("tls: error reading half-RTT ticket: %s", err)
1051 }
1052 newSessionTicket, ok := msg.(*newSessionTicketMsg)
1053 if !ok {
1054 return errors.New("tls: expected half-RTT ticket")
1055 }
Robert Sloanb1b54b82017-11-06 13:50:02 -08001056 // Defer processing until the resumption secret is computed.
1057 deferredTickets = append(deferredTickets, newSessionTicket)
Robert Sloan4d1ac502017-02-06 08:36:14 -08001058 }
Robert Sloan6d0d00e2017-03-27 07:13:07 -07001059 for _, expectedMsg := range c.config.Bugs.ExpectHalfRTTData {
1060 if err := c.readRecord(recordTypeApplicationData); err != nil {
1061 return err
1062 }
1063 if !bytes.Equal(c.input.data[c.input.off:], expectedMsg) {
1064 return errors.New("ExpectHalfRTTData: did not get expected message")
1065 }
1066 c.in.freeBlock(c.input)
1067 c.input = nil
Robert Sloan4d1ac502017-02-06 08:36:14 -08001068 }
Robert Sloan4d1ac502017-02-06 08:36:14 -08001069 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001070
Robert Sloan47f43ed2017-02-06 14:55:15 -08001071 // Send EndOfEarlyData and then switch write key to handshake
1072 // traffic key.
Robert Sloanb1b54b82017-11-06 13:50:02 -08001073 if encryptedExtensions.extensions.hasEarlyData && c.out.cipher != nil && !c.config.Bugs.SkipEndOfEarlyData {
Robert Sloan6d0d00e2017-03-27 07:13:07 -07001074 if c.config.Bugs.SendStrayEarlyHandshake {
1075 helloRequest := new(helloRequestMsg)
1076 c.writeRecord(recordTypeHandshake, helloRequest.marshal())
1077 }
Robert Sloan8542c082018-02-05 09:07:34 -08001078 endOfEarlyData := new(endOfEarlyDataMsg)
1079 endOfEarlyData.nonEmpty = c.config.Bugs.NonEmptyEndOfEarlyData
1080 c.writeRecord(recordTypeHandshake, endOfEarlyData.marshal())
1081 hs.writeClientHash(endOfEarlyData.marshal())
Robert Sloan47f43ed2017-02-06 14:55:15 -08001082 }
Robert Sloana12bf462017-07-17 07:08:26 -07001083
Robert Sloan0da43952018-01-03 15:13:14 -08001084 if !c.config.Bugs.SkipChangeCipherSpec && !hs.hello.hasEarlyData {
Robert Sloand5c22152017-11-13 09:22:12 -08001085 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
1086 }
1087
1088 for i := 0; i < c.config.Bugs.SendExtraChangeCipherSpec; i++ {
Robert Sloana12bf462017-07-17 07:08:26 -07001089 c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
1090 }
1091
Robert Sloan29c1d2c2017-10-30 14:10:28 -07001092 c.useOutTrafficSecret(c.wireVersion, hs.suite, clientHandshakeTrafficSecret)
Robert Sloan47f43ed2017-02-06 14:55:15 -08001093
David Benjaminc895d6b2016-08-11 13:26:41 -04001094 if certReq != nil && !c.config.Bugs.SkipClientCertificate {
1095 certMsg := &certificateMsg{
1096 hasRequestContext: true,
1097 requestContext: certReq.requestContext,
1098 }
1099 if chainToSend != nil {
Steven Valdez909b19f2016-11-21 15:35:44 -05001100 for _, certData := range chainToSend.Certificate {
1101 certMsg.certificates = append(certMsg.certificates, certificateEntry{
1102 data: certData,
1103 extraExtension: c.config.Bugs.SendExtensionOnCertificate,
1104 })
1105 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001106 }
1107 hs.writeClientHash(certMsg.marshal())
1108 c.writeRecord(recordTypeHandshake, certMsg.marshal())
1109
1110 if chainToSend != nil {
1111 certVerify := &certificateVerifyMsg{
1112 hasSignatureAlgorithm: true,
1113 }
1114
1115 // Determine the hash to sign.
1116 privKey := chainToSend.PrivateKey
1117
1118 var err error
1119 certVerify.signatureAlgorithm, err = selectSignatureAlgorithm(c.vers, privKey, c.config, certReq.signatureAlgorithms)
1120 if err != nil {
1121 c.sendAlert(alertInternalError)
1122 return err
1123 }
1124
1125 input := hs.finishedHash.certificateVerifyInput(clientCertificateVerifyContextTLS13)
1126 certVerify.signature, err = signMessage(c.vers, privKey, c.config, certVerify.signatureAlgorithm, input)
1127 if err != nil {
1128 c.sendAlert(alertInternalError)
1129 return err
1130 }
1131 if c.config.Bugs.SendSignatureAlgorithm != 0 {
1132 certVerify.signatureAlgorithm = c.config.Bugs.SendSignatureAlgorithm
1133 }
1134
Robert Sloan84377092017-08-14 09:33:19 -07001135 if !c.config.Bugs.SkipCertificateVerify {
1136 hs.writeClientHash(certVerify.marshal())
1137 c.writeRecord(recordTypeHandshake, certVerify.marshal())
1138 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001139 }
1140 }
1141
Steven Valdez909b19f2016-11-21 15:35:44 -05001142 if encryptedExtensions.extensions.channelIDRequested {
1143 channelIDHash := crypto.SHA256.New()
1144 channelIDHash.Write(hs.finishedHash.certificateVerifyInput(channelIDContextTLS13))
1145 channelIDMsgBytes, err := hs.writeChannelIDMessage(channelIDHash.Sum(nil))
1146 if err != nil {
1147 return err
1148 }
1149 hs.writeClientHash(channelIDMsgBytes)
1150 c.writeRecord(recordTypeHandshake, channelIDMsgBytes)
1151 }
1152
David Benjaminc895d6b2016-08-11 13:26:41 -04001153 // Send a client Finished message.
1154 finished := new(finishedMsg)
David Benjamin95add822016-10-19 01:09:12 -04001155 finished.verifyData = hs.finishedHash.clientSum(clientHandshakeTrafficSecret)
David Benjaminc895d6b2016-08-11 13:26:41 -04001156 if c.config.Bugs.BadFinished {
1157 finished.verifyData[0]++
1158 }
1159 hs.writeClientHash(finished.marshal())
1160 if c.config.Bugs.PartialClientFinishedWithClientHello {
1161 // The first byte has already been sent.
1162 c.writeRecord(recordTypeHandshake, finished.marshal()[1:])
David Benjamin1b249672016-12-06 18:25:50 -05001163 } else if c.config.Bugs.InterleaveEarlyData {
1164 finishedBytes := finished.marshal()
1165 c.sendFakeEarlyData(4)
1166 c.writeRecord(recordTypeHandshake, finishedBytes[:1])
1167 c.sendFakeEarlyData(4)
1168 c.writeRecord(recordTypeHandshake, finishedBytes[1:])
David Benjaminc895d6b2016-08-11 13:26:41 -04001169 } else {
1170 c.writeRecord(recordTypeHandshake, finished.marshal())
1171 }
1172 if c.config.Bugs.SendExtraFinished {
1173 c.writeRecord(recordTypeHandshake, finished.marshal())
1174 }
1175 c.flushHandshake()
1176
1177 // Switch to application data keys.
Robert Sloan29c1d2c2017-10-30 14:10:28 -07001178 c.useOutTrafficSecret(c.wireVersion, hs.suite, clientTrafficSecret)
Robert Sloan8542c082018-02-05 09:07:34 -08001179 c.resumptionSecret = hs.finishedHash.deriveSecret(resumptionLabel)
Robert Sloanb1b54b82017-11-06 13:50:02 -08001180 for _, ticket := range deferredTickets {
1181 if err := c.processTLS13NewSessionTicket(ticket, hs.suite); err != nil {
1182 return err
1183 }
1184 }
1185
David Benjaminc895d6b2016-08-11 13:26:41 -04001186 return nil
1187}
1188
Adam Langleyd9e397b2015-01-22 14:27:53 -08001189func (hs *clientHandshakeState) doFullHandshake() error {
1190 c := hs.c
1191
1192 var leaf *x509.Certificate
1193 if hs.suite.flags&suitePSK == 0 {
1194 msg, err := c.readHandshake()
1195 if err != nil {
1196 return err
1197 }
1198
1199 certMsg, ok := msg.(*certificateMsg)
David Benjaminc895d6b2016-08-11 13:26:41 -04001200 if !ok {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001201 c.sendAlert(alertUnexpectedMessage)
1202 return unexpectedMessageError(certMsg, msg)
1203 }
1204 hs.writeServerHash(certMsg.marshal())
1205
David Benjaminc895d6b2016-08-11 13:26:41 -04001206 if err := hs.verifyCertificates(certMsg); err != nil {
1207 return err
Adam Langleyd9e397b2015-01-22 14:27:53 -08001208 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001209 leaf = c.peerCertificates[0]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001210 }
1211
David Benjaminc895d6b2016-08-11 13:26:41 -04001212 if hs.serverHello.extensions.ocspStapling {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001213 msg, err := c.readHandshake()
1214 if err != nil {
1215 return err
1216 }
1217 cs, ok := msg.(*certificateStatusMsg)
1218 if !ok {
1219 c.sendAlert(alertUnexpectedMessage)
1220 return unexpectedMessageError(cs, msg)
1221 }
1222 hs.writeServerHash(cs.marshal())
1223
1224 if cs.statusType == statusTypeOCSP {
1225 c.ocspResponse = cs.response
1226 }
1227 }
1228
1229 msg, err := c.readHandshake()
1230 if err != nil {
1231 return err
1232 }
1233
1234 keyAgreement := hs.suite.ka(c.vers)
1235
1236 skx, ok := msg.(*serverKeyExchangeMsg)
1237 if ok {
1238 hs.writeServerHash(skx.marshal())
Robert Sloan4c22c5f2019-03-01 15:53:37 -08001239 err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, hs.peerPublicKey, skx)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001240 if err != nil {
1241 c.sendAlert(alertUnexpectedMessage)
1242 return err
1243 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001244 if ecdhe, ok := keyAgreement.(*ecdheKeyAgreement); ok {
1245 c.curveID = ecdhe.curveID
1246 }
1247
1248 c.peerSignatureAlgorithm = keyAgreement.peerSignatureAlgorithm()
Adam Langleyd9e397b2015-01-22 14:27:53 -08001249
1250 msg, err = c.readHandshake()
1251 if err != nil {
1252 return err
1253 }
1254 }
1255
1256 var chainToSend *Certificate
1257 var certRequested bool
1258 certReq, ok := msg.(*certificateRequestMsg)
1259 if ok {
1260 certRequested = true
Robert Sloan5cbb5c82018-04-24 11:35:46 -07001261 if err := checkRSAPSSSupport(c.config.Bugs.ExpectRSAPSSSupport, certReq.signatureAlgorithms, certReq.signatureAlgorithmsCert); err != nil {
1262 return err
1263 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001264 if c.config.Bugs.IgnorePeerSignatureAlgorithmPreferences {
1265 certReq.signatureAlgorithms = c.config.signSignatureAlgorithms()
1266 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001267
1268 hs.writeServerHash(certReq.marshal())
1269
David Benjaminc895d6b2016-08-11 13:26:41 -04001270 chainToSend, err = selectClientCertificate(c, certReq)
1271 if err != nil {
1272 return err
Adam Langleyd9e397b2015-01-22 14:27:53 -08001273 }
1274
1275 msg, err = c.readHandshake()
1276 if err != nil {
1277 return err
1278 }
1279 }
1280
1281 shd, ok := msg.(*serverHelloDoneMsg)
1282 if !ok {
1283 c.sendAlert(alertUnexpectedMessage)
1284 return unexpectedMessageError(shd, msg)
1285 }
1286 hs.writeServerHash(shd.marshal())
1287
1288 // If the server requested a certificate then we have to send a
David Benjamin4969cc92016-04-22 15:02:23 -04001289 // Certificate message in TLS, even if it's empty because we don't have
1290 // a certificate to send. In SSL 3.0, skip the message and send a
1291 // no_certificate warning alert.
Adam Langleyd9e397b2015-01-22 14:27:53 -08001292 if certRequested {
David Benjamin4969cc92016-04-22 15:02:23 -04001293 if c.vers == VersionSSL30 && chainToSend == nil {
Robert Sloan69939df2017-01-09 10:53:07 -08001294 c.sendAlert(alertNoCertificate)
David Benjamin4969cc92016-04-22 15:02:23 -04001295 } else if !c.config.Bugs.SkipClientCertificate {
1296 certMsg := new(certificateMsg)
1297 if chainToSend != nil {
Steven Valdez909b19f2016-11-21 15:35:44 -05001298 for _, certData := range chainToSend.Certificate {
1299 certMsg.certificates = append(certMsg.certificates, certificateEntry{
1300 data: certData,
1301 })
1302 }
David Benjamin4969cc92016-04-22 15:02:23 -04001303 }
1304 hs.writeClientHash(certMsg.marshal())
1305 c.writeRecord(recordTypeHandshake, certMsg.marshal())
Adam Langleyd9e397b2015-01-22 14:27:53 -08001306 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001307 }
1308
1309 preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, leaf)
1310 if err != nil {
1311 c.sendAlert(alertInternalError)
1312 return err
1313 }
1314 if ckx != nil {
1315 if c.config.Bugs.EarlyChangeCipherSpec < 2 {
1316 hs.writeClientHash(ckx.marshal())
1317 }
1318 c.writeRecord(recordTypeHandshake, ckx.marshal())
1319 }
1320
David Benjaminc895d6b2016-08-11 13:26:41 -04001321 if hs.serverHello.extensions.extendedMasterSecret && c.vers >= VersionTLS10 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001322 hs.masterSecret = extendedMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.finishedHash)
1323 c.extendedMasterSecret = true
1324 } else {
1325 if c.config.Bugs.RequireExtendedMasterSecret {
1326 return errors.New("tls: extended master secret required but not supported by peer")
1327 }
1328 hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret, hs.hello.random, hs.serverHello.random)
1329 }
1330
1331 if chainToSend != nil {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001332 certVerify := &certificateVerifyMsg{
David Benjaminc895d6b2016-08-11 13:26:41 -04001333 hasSignatureAlgorithm: c.vers >= VersionTLS12,
Adam Langleyd9e397b2015-01-22 14:27:53 -08001334 }
1335
Adam Langleye9ada862015-05-11 17:20:37 -07001336 // Determine the hash to sign.
David Benjaminc895d6b2016-08-11 13:26:41 -04001337 privKey := c.config.Certificates[0].PrivateKey
1338
1339 if certVerify.hasSignatureAlgorithm {
1340 certVerify.signatureAlgorithm, err = selectSignatureAlgorithm(c.vers, privKey, c.config, certReq.signatureAlgorithms)
1341 if err != nil {
1342 c.sendAlert(alertInternalError)
1343 return err
1344 }
Kenny Rootb8494592015-09-25 02:29:14 +00001345 }
Adam Langleye9ada862015-05-11 17:20:37 -07001346
David Benjaminc895d6b2016-08-11 13:26:41 -04001347 if c.vers > VersionSSL30 {
1348 certVerify.signature, err = signMessage(c.vers, privKey, c.config, certVerify.signatureAlgorithm, hs.finishedHash.buffer)
1349 if err == nil && c.config.Bugs.SendSignatureAlgorithm != 0 {
1350 certVerify.signatureAlgorithm = c.config.Bugs.SendSignatureAlgorithm
Adam Langleyd9e397b2015-01-22 14:27:53 -08001351 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001352 } else {
1353 // SSL 3.0's client certificate construction is
1354 // incompatible with signatureAlgorithm.
1355 rsaKey, ok := privKey.(*rsa.PrivateKey)
1356 if !ok {
1357 err = errors.New("unsupported signature type for client certificate")
1358 } else {
1359 digest := hs.finishedHash.hashForClientCertificateSSL3(hs.masterSecret)
1360 if c.config.Bugs.InvalidSignature {
1361 digest[0] ^= 0x80
1362 }
1363 certVerify.signature, err = rsa.SignPKCS1v15(c.config.rand(), rsaKey, crypto.MD5SHA1, digest)
1364 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001365 }
1366 if err != nil {
1367 c.sendAlert(alertInternalError)
1368 return errors.New("tls: failed to sign handshake with client certificate: " + err.Error())
1369 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001370
Robert Sloan84377092017-08-14 09:33:19 -07001371 if !c.config.Bugs.SkipCertificateVerify {
1372 hs.writeClientHash(certVerify.marshal())
1373 c.writeRecord(recordTypeHandshake, certVerify.marshal())
1374 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001375 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001376 // flushHandshake will be called in sendFinished.
Adam Langleyd9e397b2015-01-22 14:27:53 -08001377
1378 hs.finishedHash.discardHandshakeBuffer()
1379
1380 return nil
1381}
1382
Robert Sloan4c22c5f2019-03-01 15:53:37 -08001383// delegatedCredentialSignedMessage returns the bytes that are signed in order
1384// to authenticate a delegated credential.
1385func delegatedCredentialSignedMessage(credBytes []byte, algorithm signatureAlgorithm, leafDER []byte) []byte {
1386 // https://tools.ietf.org/html/draft-ietf-tls-subcerts-03#section-3
1387 ret := make([]byte, 64, 128)
1388 for i := range ret {
1389 ret[i] = 0x20
1390 }
1391
1392 ret = append(ret, []byte("TLS, server delegated credentials\x00")...)
1393 ret = append(ret, leafDER...)
1394 ret = append(ret, byte(algorithm>>8), byte(algorithm))
1395 ret = append(ret, credBytes...)
1396
1397 return ret
1398}
1399
David Benjaminc895d6b2016-08-11 13:26:41 -04001400func (hs *clientHandshakeState) verifyCertificates(certMsg *certificateMsg) error {
1401 c := hs.c
1402
1403 if len(certMsg.certificates) == 0 {
1404 c.sendAlert(alertIllegalParameter)
1405 return errors.New("tls: no certificates sent")
1406 }
1407
Robert Sloan4c22c5f2019-03-01 15:53:37 -08001408 var dc *delegatedCredential
David Benjaminc895d6b2016-08-11 13:26:41 -04001409 certs := make([]*x509.Certificate, len(certMsg.certificates))
Steven Valdez909b19f2016-11-21 15:35:44 -05001410 for i, certEntry := range certMsg.certificates {
1411 cert, err := x509.ParseCertificate(certEntry.data)
David Benjaminc895d6b2016-08-11 13:26:41 -04001412 if err != nil {
1413 c.sendAlert(alertBadCertificate)
1414 return errors.New("tls: failed to parse certificate from server: " + err.Error())
1415 }
1416 certs[i] = cert
Robert Sloan4c22c5f2019-03-01 15:53:37 -08001417
1418 if certEntry.delegatedCredential != nil {
1419 if c.config.Bugs.FailIfDelegatedCredentials {
1420 c.sendAlert(alertIllegalParameter)
1421 return errors.New("tls: unexpected delegated credential")
1422 }
1423 if i != 0 {
1424 c.sendAlert(alertIllegalParameter)
1425 return errors.New("tls: non-leaf certificate has a delegated credential")
1426 }
1427 if c.config.Bugs.DisableDelegatedCredentials {
1428 c.sendAlert(alertIllegalParameter)
1429 return errors.New("tls: server sent delegated credential without it being requested")
1430 }
1431 dc = certEntry.delegatedCredential
1432 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001433 }
1434
1435 if !c.config.InsecureSkipVerify {
1436 opts := x509.VerifyOptions{
1437 Roots: c.config.RootCAs,
1438 CurrentTime: c.config.time(),
1439 DNSName: c.config.ServerName,
1440 Intermediates: x509.NewCertPool(),
1441 }
1442
1443 for i, cert := range certs {
1444 if i == 0 {
1445 continue
1446 }
1447 opts.Intermediates.AddCert(cert)
1448 }
1449 var err error
1450 c.verifiedChains, err = certs[0].Verify(opts)
1451 if err != nil {
1452 c.sendAlert(alertBadCertificate)
1453 return err
1454 }
1455 }
1456
Robert Sloan4c22c5f2019-03-01 15:53:37 -08001457 leafPublicKey := getCertificatePublicKey(certs[0])
1458 switch leafPublicKey.(type) {
Robert Sloan572a4e22017-04-17 10:52:19 -07001459 case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
David Benjaminc895d6b2016-08-11 13:26:41 -04001460 break
1461 default:
1462 c.sendAlert(alertUnsupportedCertificate)
Robert Sloan4c22c5f2019-03-01 15:53:37 -08001463 return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", leafPublicKey)
David Benjaminc895d6b2016-08-11 13:26:41 -04001464 }
1465
1466 c.peerCertificates = certs
Robert Sloan4c22c5f2019-03-01 15:53:37 -08001467
1468 if dc != nil {
1469 // Note that this doesn't check a) the delegated credential temporal
1470 // validity nor b) that the certificate has the special OID asserted.
1471 hs.skxAlgo = dc.expectedCertVerifyAlgo
1472
1473 var err error
1474 if hs.peerPublicKey, err = x509.ParsePKIXPublicKey(dc.pkixPublicKey); err != nil {
1475 c.sendAlert(alertBadCertificate)
1476 return errors.New("tls: failed to parse public key from delegated credential: " + err.Error())
1477 }
1478
1479 verifier, err := getSigner(c.vers, hs.peerPublicKey, c.config, dc.algorithm, true)
1480 if err != nil {
1481 c.sendAlert(alertBadCertificate)
1482 return errors.New("tls: failed to get verifier for delegated credential: " + err.Error())
1483 }
1484
1485 if err := verifier.verifyMessage(leafPublicKey, delegatedCredentialSignedMessage(dc.signedBytes, dc.algorithm, certs[0].Raw), dc.signature); err != nil {
1486 c.sendAlert(alertBadCertificate)
1487 return errors.New("tls: failed to verify delegated credential: " + err.Error())
1488 }
1489 } else if c.config.Bugs.ExpectDelegatedCredentials {
1490 c.sendAlert(alertInternalError)
1491 return errors.New("tls: delegated credentials missing")
1492 } else {
1493 hs.peerPublicKey = leafPublicKey
1494 }
1495
David Benjaminc895d6b2016-08-11 13:26:41 -04001496 return nil
1497}
1498
Adam Langleyd9e397b2015-01-22 14:27:53 -08001499func (hs *clientHandshakeState) establishKeys() error {
1500 c := hs.c
1501
1502 clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
David Benjaminc895d6b2016-08-11 13:26:41 -04001503 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 -08001504 var clientCipher, serverCipher interface{}
1505 var clientHash, serverHash macFunction
1506 if hs.suite.cipher != nil {
1507 clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
1508 clientHash = hs.suite.mac(c.vers, clientMAC)
1509 serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
1510 serverHash = hs.suite.mac(c.vers, serverMAC)
1511 } else {
David Benjaminc895d6b2016-08-11 13:26:41 -04001512 clientCipher = hs.suite.aead(c.vers, clientKey, clientIV)
1513 serverCipher = hs.suite.aead(c.vers, serverKey, serverIV)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001514 }
1515
Robert Sloandb4251a2017-09-18 09:38:15 -07001516 c.in.prepareCipherSpec(c.wireVersion, serverCipher, serverHash)
1517 c.out.prepareCipherSpec(c.wireVersion, clientCipher, clientHash)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001518 return nil
1519}
1520
David Benjaminc895d6b2016-08-11 13:26:41 -04001521func (hs *clientHandshakeState) processServerExtensions(serverExtensions *serverExtensions) error {
1522 c := hs.c
1523
1524 if c.vers < VersionTLS13 {
1525 if c.config.Bugs.RequireRenegotiationInfo && serverExtensions.secureRenegotiation == nil {
1526 return errors.New("tls: renegotiation extension missing")
1527 }
1528
1529 if len(c.clientVerify) > 0 && !c.noRenegotiationInfo() {
1530 var expectedRenegInfo []byte
1531 expectedRenegInfo = append(expectedRenegInfo, c.clientVerify...)
1532 expectedRenegInfo = append(expectedRenegInfo, c.serverVerify...)
1533 if !bytes.Equal(serverExtensions.secureRenegotiation, expectedRenegInfo) {
1534 c.sendAlert(alertHandshakeFailure)
1535 return fmt.Errorf("tls: renegotiation mismatch")
1536 }
1537 }
1538 } else if serverExtensions.secureRenegotiation != nil {
1539 return errors.New("tls: renegotiation info sent in TLS 1.3")
1540 }
1541
1542 if expected := c.config.Bugs.ExpectedCustomExtension; expected != nil {
1543 if serverExtensions.customExtension != *expected {
1544 return fmt.Errorf("tls: bad custom extension contents %q", serverExtensions.customExtension)
1545 }
1546 }
1547
1548 clientDidNPN := hs.hello.nextProtoNeg
1549 clientDidALPN := len(hs.hello.alpnProtocols) > 0
1550 serverHasNPN := serverExtensions.nextProtoNeg
1551 serverHasALPN := len(serverExtensions.alpnProtocol) > 0
1552
1553 if !clientDidNPN && serverHasNPN {
1554 c.sendAlert(alertHandshakeFailure)
1555 return errors.New("server advertised unrequested NPN extension")
1556 }
1557
1558 if !clientDidALPN && serverHasALPN {
1559 c.sendAlert(alertHandshakeFailure)
1560 return errors.New("server advertised unrequested ALPN extension")
1561 }
1562
1563 if serverHasNPN && serverHasALPN {
1564 c.sendAlert(alertHandshakeFailure)
1565 return errors.New("server advertised both NPN and ALPN extensions")
1566 }
1567
1568 if serverHasALPN {
1569 c.clientProtocol = serverExtensions.alpnProtocol
1570 c.clientProtocolFallback = false
1571 c.usedALPN = true
1572 }
1573
1574 if serverHasNPN && c.vers >= VersionTLS13 {
1575 c.sendAlert(alertHandshakeFailure)
1576 return errors.New("server advertised NPN over TLS 1.3")
1577 }
1578
1579 if !hs.hello.channelIDSupported && serverExtensions.channelIDRequested {
1580 c.sendAlert(alertHandshakeFailure)
1581 return errors.New("server advertised unrequested Channel ID extension")
1582 }
1583
Robert Sloan978112c2018-01-22 12:53:01 -08001584 if len(serverExtensions.tokenBindingParams) == 1 {
1585 found := false
1586 for _, p := range c.config.TokenBindingParams {
1587 if p == serverExtensions.tokenBindingParams[0] {
1588 c.tokenBindingParam = p
1589 found = true
1590 break
1591 }
1592 }
1593 if !found {
1594 return errors.New("tls: server advertised unsupported Token Binding key param")
1595 }
1596 if serverExtensions.tokenBindingVersion > c.config.TokenBindingVersion {
1597 return errors.New("tls: server's Token Binding version is too new")
1598 }
1599 if c.vers < VersionTLS13 {
1600 if !serverExtensions.extendedMasterSecret || serverExtensions.secureRenegotiation == nil {
1601 return errors.New("server sent Token Binding without EMS or RI")
1602 }
1603 }
1604 c.tokenBindingNegotiated = true
1605 }
1606
David Benjaminc895d6b2016-08-11 13:26:41 -04001607 if serverExtensions.extendedMasterSecret && c.vers >= VersionTLS13 {
1608 return errors.New("tls: server advertised extended master secret over TLS 1.3")
1609 }
1610
1611 if serverExtensions.ticketSupported && c.vers >= VersionTLS13 {
1612 return errors.New("tls: server advertised ticket extension over TLS 1.3")
1613 }
1614
Steven Valdez909b19f2016-11-21 15:35:44 -05001615 if serverExtensions.ocspStapling && c.vers >= VersionTLS13 {
1616 return errors.New("tls: server advertised OCSP in ServerHello over TLS 1.3")
1617 }
1618
1619 if serverExtensions.ocspStapling && c.config.Bugs.NoOCSPStapling {
1620 return errors.New("tls: server advertised unrequested OCSP extension")
1621 }
1622
1623 if len(serverExtensions.sctList) > 0 && c.vers >= VersionTLS13 {
1624 return errors.New("tls: server advertised SCTs in ServerHello over TLS 1.3")
1625 }
1626
1627 if len(serverExtensions.sctList) > 0 && c.config.Bugs.NoSignedCertificateTimestamps {
1628 return errors.New("tls: server advertised unrequested SCTs")
1629 }
1630
David Benjaminc895d6b2016-08-11 13:26:41 -04001631 if serverExtensions.srtpProtectionProfile != 0 {
1632 if serverExtensions.srtpMasterKeyIdentifier != "" {
1633 return errors.New("tls: server selected SRTP MKI value")
1634 }
1635
1636 found := false
1637 for _, p := range c.config.SRTPProtectionProfiles {
1638 if p == serverExtensions.srtpProtectionProfile {
1639 found = true
1640 break
1641 }
1642 }
1643 if !found {
1644 return errors.New("tls: server advertised unsupported SRTP profile")
1645 }
1646
1647 c.srtpProtectionProfile = serverExtensions.srtpProtectionProfile
1648 }
1649
Robert Sloan6d0d00e2017-03-27 07:13:07 -07001650 if c.vers >= VersionTLS13 && c.didResume {
1651 if c.config.Bugs.ExpectEarlyDataAccepted && !serverExtensions.hasEarlyData {
1652 c.sendAlert(alertHandshakeFailure)
1653 return errors.New("tls: server did not accept early data when expected")
1654 }
1655
1656 if !c.config.Bugs.ExpectEarlyDataAccepted && serverExtensions.hasEarlyData {
1657 c.sendAlert(alertHandshakeFailure)
1658 return errors.New("tls: server accepted early data when not expected")
1659 }
1660 }
1661
Robert Sloan8542c082018-02-05 09:07:34 -08001662 if len(serverExtensions.quicTransportParams) > 0 {
1663 if c.vers < VersionTLS13 {
1664 c.sendAlert(alertHandshakeFailure)
1665 return errors.New("tls: server sent QUIC transport params for TLS version less than 1.3")
1666 }
1667 c.quicTransportParams = serverExtensions.quicTransportParams
1668 }
Robert Sloanab8b8882018-03-26 11:39:51 -07001669
Pete Bentley0c61efe2019-08-13 09:32:23 +01001670 if c.config.Bugs.ExpectPQExperimentSignal != serverExtensions.pqExperimentSignal {
1671 return fmt.Errorf("tls: PQ experiment signal presence (%t) was not what was expected", serverExtensions.pqExperimentSignal)
1672 }
1673
David Benjaminc895d6b2016-08-11 13:26:41 -04001674 return nil
1675}
1676
Adam Langleyd9e397b2015-01-22 14:27:53 -08001677func (hs *clientHandshakeState) serverResumedSession() bool {
1678 // If the server responded with the same sessionId then it means the
1679 // sessionTicket is being used to resume a TLS session.
Robert Sloan5d625782017-02-13 09:55:39 -08001680 //
1681 // Note that, if hs.hello.sessionId is a non-nil empty array, this will
1682 // accept an empty session ID from the server as resumption. See
1683 // EmptyTicketSessionID.
Adam Langleyd9e397b2015-01-22 14:27:53 -08001684 return hs.session != nil && hs.hello.sessionId != nil &&
1685 bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
1686}
1687
1688func (hs *clientHandshakeState) processServerHello() (bool, error) {
1689 c := hs.c
1690
Adam Langleyd9e397b2015-01-22 14:27:53 -08001691 if hs.serverResumedSession() {
Adam Langleyf4e42722015-06-04 17:45:09 -07001692 // For test purposes, assert that the server never accepts the
1693 // resumption offer on renegotiation.
1694 if c.cipherSuite != nil && c.config.Bugs.FailIfResumeOnRenego {
1695 return false, errors.New("tls: server resumed session on renegotiation")
1696 }
1697
David Benjaminc895d6b2016-08-11 13:26:41 -04001698 if hs.serverHello.extensions.sctList != nil {
Kenny Rootb8494592015-09-25 02:29:14 +00001699 return false, errors.New("tls: server sent SCT extension on session resumption")
1700 }
1701
David Benjaminc895d6b2016-08-11 13:26:41 -04001702 if hs.serverHello.extensions.ocspStapling {
Kenny Rootb8494592015-09-25 02:29:14 +00001703 return false, errors.New("tls: server sent OCSP extension on session resumption")
1704 }
1705
Adam Langleyd9e397b2015-01-22 14:27:53 -08001706 // Restore masterSecret and peerCerts from previous state
1707 hs.masterSecret = hs.session.masterSecret
1708 c.peerCertificates = hs.session.serverCertificates
1709 c.extendedMasterSecret = hs.session.extendedMasterSecret
Kenny Rootb8494592015-09-25 02:29:14 +00001710 c.sctList = hs.session.sctList
1711 c.ocspResponse = hs.session.ocspResponse
Adam Langleyd9e397b2015-01-22 14:27:53 -08001712 hs.finishedHash.discardHandshakeBuffer()
1713 return true, nil
1714 }
Kenny Rootb8494592015-09-25 02:29:14 +00001715
David Benjaminc895d6b2016-08-11 13:26:41 -04001716 if hs.serverHello.extensions.sctList != nil {
1717 c.sctList = hs.serverHello.extensions.sctList
Kenny Rootb8494592015-09-25 02:29:14 +00001718 }
1719
Adam Langleyd9e397b2015-01-22 14:27:53 -08001720 return false, nil
1721}
1722
Adam Langleyf4e42722015-06-04 17:45:09 -07001723func (hs *clientHandshakeState) readFinished(out []byte) error {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001724 c := hs.c
1725
1726 c.readRecord(recordTypeChangeCipherSpec)
1727 if err := c.in.error(); err != nil {
1728 return err
1729 }
1730
1731 msg, err := c.readHandshake()
1732 if err != nil {
1733 return err
1734 }
1735 serverFinished, ok := msg.(*finishedMsg)
1736 if !ok {
1737 c.sendAlert(alertUnexpectedMessage)
1738 return unexpectedMessageError(serverFinished, msg)
1739 }
1740
1741 if c.config.Bugs.EarlyChangeCipherSpec == 0 {
1742 verify := hs.finishedHash.serverSum(hs.masterSecret)
1743 if len(verify) != len(serverFinished.verifyData) ||
1744 subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
1745 c.sendAlert(alertHandshakeFailure)
1746 return errors.New("tls: server's Finished message was incorrect")
1747 }
1748 }
1749 c.serverVerify = append(c.serverVerify[:0], serverFinished.verifyData...)
Adam Langleyf4e42722015-06-04 17:45:09 -07001750 copy(out, serverFinished.verifyData)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001751 hs.writeServerHash(serverFinished.marshal())
1752 return nil
1753}
1754
1755func (hs *clientHandshakeState) readSessionTicket() error {
1756 c := hs.c
1757
1758 // Create a session with no server identifier. Either a
1759 // session ID or session ticket will be attached.
1760 session := &ClientSessionState{
1761 vers: c.vers,
Robert Sloanb1b54b82017-11-06 13:50:02 -08001762 wireVersion: c.wireVersion,
Adam Langleyd9e397b2015-01-22 14:27:53 -08001763 cipherSuite: hs.suite.id,
1764 masterSecret: hs.masterSecret,
Steven Valdez909b19f2016-11-21 15:35:44 -05001765 handshakeHash: hs.finishedHash.Sum(),
Adam Langleyd9e397b2015-01-22 14:27:53 -08001766 serverCertificates: c.peerCertificates,
Kenny Rootb8494592015-09-25 02:29:14 +00001767 sctList: c.sctList,
1768 ocspResponse: c.ocspResponse,
David Benjaminc895d6b2016-08-11 13:26:41 -04001769 ticketExpiration: c.config.time().Add(time.Duration(7 * 24 * time.Hour)),
Adam Langleyd9e397b2015-01-22 14:27:53 -08001770 }
1771
David Benjaminc895d6b2016-08-11 13:26:41 -04001772 if !hs.serverHello.extensions.ticketSupported {
Kenny Rootb8494592015-09-25 02:29:14 +00001773 if c.config.Bugs.ExpectNewTicket {
1774 return errors.New("tls: expected new ticket")
1775 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001776 if hs.session == nil && len(hs.serverHello.sessionId) > 0 {
1777 session.sessionId = hs.serverHello.sessionId
1778 hs.session = session
1779 }
1780 return nil
1781 }
1782
Kenny Roote99801b2015-11-06 15:31:15 -08001783 if c.vers == VersionSSL30 {
1784 return errors.New("tls: negotiated session tickets in SSL 3.0")
1785 }
Adam Vartanianbfcf3a72018-08-10 14:55:24 +01001786 if c.config.Bugs.ExpectNoNewSessionTicket {
1787 return errors.New("tls: received unexpected NewSessionTicket")
1788 }
Kenny Roote99801b2015-11-06 15:31:15 -08001789
Adam Langleyd9e397b2015-01-22 14:27:53 -08001790 msg, err := c.readHandshake()
1791 if err != nil {
1792 return err
1793 }
1794 sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
1795 if !ok {
1796 c.sendAlert(alertUnexpectedMessage)
1797 return unexpectedMessageError(sessionTicketMsg, msg)
1798 }
1799
1800 session.sessionTicket = sessionTicketMsg.ticket
1801 hs.session = session
1802
1803 hs.writeServerHash(sessionTicketMsg.marshal())
1804
1805 return nil
1806}
1807
Adam Langleyf4e42722015-06-04 17:45:09 -07001808func (hs *clientHandshakeState) sendFinished(out []byte, isResume bool) error {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001809 c := hs.c
1810
David Benjaminc895d6b2016-08-11 13:26:41 -04001811 var postCCSMsgs [][]byte
Adam Langleyd9e397b2015-01-22 14:27:53 -08001812 seqno := hs.c.sendHandshakeSeq
David Benjaminc895d6b2016-08-11 13:26:41 -04001813 if hs.serverHello.extensions.nextProtoNeg {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001814 nextProto := new(nextProtoMsg)
David Benjaminc895d6b2016-08-11 13:26:41 -04001815 proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.extensions.nextProtos)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001816 nextProto.proto = proto
1817 c.clientProtocol = proto
1818 c.clientProtocolFallback = fallback
1819
1820 nextProtoBytes := nextProto.marshal()
1821 hs.writeHash(nextProtoBytes, seqno)
1822 seqno++
David Benjaminc895d6b2016-08-11 13:26:41 -04001823 postCCSMsgs = append(postCCSMsgs, nextProtoBytes)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001824 }
1825
David Benjaminc895d6b2016-08-11 13:26:41 -04001826 if hs.serverHello.extensions.channelIDRequested {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001827 var resumeHash []byte
1828 if isResume {
1829 resumeHash = hs.session.handshakeHash
1830 }
Steven Valdez909b19f2016-11-21 15:35:44 -05001831 channelIDMsgBytes, err := hs.writeChannelIDMessage(hs.finishedHash.hashForChannelID(resumeHash))
Adam Langleyd9e397b2015-01-22 14:27:53 -08001832 if err != nil {
1833 return err
1834 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001835 hs.writeHash(channelIDMsgBytes, seqno)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001836 seqno++
David Benjaminc895d6b2016-08-11 13:26:41 -04001837 postCCSMsgs = append(postCCSMsgs, channelIDMsgBytes)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001838 }
1839
1840 finished := new(finishedMsg)
1841 if c.config.Bugs.EarlyChangeCipherSpec == 2 {
1842 finished.verifyData = hs.finishedHash.clientSum(nil)
1843 } else {
1844 finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
1845 }
Adam Langleyf4e42722015-06-04 17:45:09 -07001846 copy(out, finished.verifyData)
Adam Langleye9ada862015-05-11 17:20:37 -07001847 if c.config.Bugs.BadFinished {
1848 finished.verifyData[0]++
1849 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001850 c.clientVerify = append(c.clientVerify[:0], finished.verifyData...)
Adam Langleye9ada862015-05-11 17:20:37 -07001851 hs.finishedBytes = finished.marshal()
1852 hs.writeHash(hs.finishedBytes, seqno)
David Benjaminc895d6b2016-08-11 13:26:41 -04001853 postCCSMsgs = append(postCCSMsgs, hs.finishedBytes)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001854
1855 if c.config.Bugs.FragmentAcrossChangeCipherSpec {
David Benjaminc895d6b2016-08-11 13:26:41 -04001856 c.writeRecord(recordTypeHandshake, postCCSMsgs[0][:5])
1857 postCCSMsgs[0] = postCCSMsgs[0][5:]
1858 } else if c.config.Bugs.SendUnencryptedFinished {
1859 c.writeRecord(recordTypeHandshake, postCCSMsgs[0])
1860 postCCSMsgs = postCCSMsgs[1:]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001861 }
1862
1863 if !c.config.Bugs.SkipChangeCipherSpec &&
1864 c.config.Bugs.EarlyChangeCipherSpec == 0 {
Adam Langley4139edb2016-01-13 15:00:54 -08001865 ccs := []byte{1}
1866 if c.config.Bugs.BadChangeCipherSpec != nil {
1867 ccs = c.config.Bugs.BadChangeCipherSpec
1868 }
1869 c.writeRecord(recordTypeChangeCipherSpec, ccs)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001870 }
1871
1872 if c.config.Bugs.AppDataAfterChangeCipherSpec != nil {
1873 c.writeRecord(recordTypeApplicationData, c.config.Bugs.AppDataAfterChangeCipherSpec)
1874 }
Adam Langleye9ada862015-05-11 17:20:37 -07001875 if c.config.Bugs.AlertAfterChangeCipherSpec != 0 {
1876 c.sendAlert(c.config.Bugs.AlertAfterChangeCipherSpec)
1877 return errors.New("tls: simulating post-CCS alert")
1878 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001879
Adam Langleye9ada862015-05-11 17:20:37 -07001880 if !c.config.Bugs.SkipFinished {
David Benjaminc895d6b2016-08-11 13:26:41 -04001881 for _, msg := range postCCSMsgs {
1882 c.writeRecord(recordTypeHandshake, msg)
1883 }
1884
1885 if c.config.Bugs.SendExtraFinished {
1886 c.writeRecord(recordTypeHandshake, finished.marshal())
1887 }
Adam Langleye9ada862015-05-11 17:20:37 -07001888 }
Robert Sloanfe7cd212017-08-07 09:03:39 -07001889
Robert Sloan921ef2c2017-10-17 09:02:20 -07001890 if !isResume || !c.config.Bugs.PackAppDataWithHandshake {
1891 c.flushHandshake()
1892 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001893 return nil
1894}
1895
Steven Valdez909b19f2016-11-21 15:35:44 -05001896func (hs *clientHandshakeState) writeChannelIDMessage(channelIDHash []byte) ([]byte, error) {
1897 c := hs.c
1898 channelIDMsg := new(channelIDMsg)
1899 if c.config.ChannelID.Curve != elliptic.P256() {
1900 return nil, fmt.Errorf("tls: Channel ID is not on P-256.")
1901 }
1902 r, s, err := ecdsa.Sign(c.config.rand(), c.config.ChannelID, channelIDHash)
1903 if err != nil {
1904 return nil, err
1905 }
1906 channelID := make([]byte, 128)
1907 writeIntPadded(channelID[0:32], c.config.ChannelID.X)
1908 writeIntPadded(channelID[32:64], c.config.ChannelID.Y)
1909 writeIntPadded(channelID[64:96], r)
1910 writeIntPadded(channelID[96:128], s)
1911 if c.config.Bugs.InvalidChannelIDSignature {
1912 channelID[64] ^= 1
1913 }
1914 channelIDMsg.channelID = channelID
1915
1916 c.channelID = &c.config.ChannelID.PublicKey
1917
1918 return channelIDMsg.marshal(), nil
1919}
1920
Adam Langleyd9e397b2015-01-22 14:27:53 -08001921func (hs *clientHandshakeState) writeClientHash(msg []byte) {
1922 // writeClientHash is called before writeRecord.
1923 hs.writeHash(msg, hs.c.sendHandshakeSeq)
1924}
1925
1926func (hs *clientHandshakeState) writeServerHash(msg []byte) {
1927 // writeServerHash is called after readHandshake.
1928 hs.writeHash(msg, hs.c.recvHandshakeSeq-1)
1929}
1930
1931func (hs *clientHandshakeState) writeHash(msg []byte, seqno uint16) {
1932 if hs.c.isDTLS {
1933 // This is somewhat hacky. DTLS hashes a slightly different format.
1934 // First, the TLS header.
1935 hs.finishedHash.Write(msg[:4])
1936 // Then the sequence number and reassembled fragment offset (always 0).
1937 hs.finishedHash.Write([]byte{byte(seqno >> 8), byte(seqno), 0, 0, 0})
1938 // Then the reassembled fragment (always equal to the message length).
1939 hs.finishedHash.Write(msg[1:4])
1940 // And then the message body.
1941 hs.finishedHash.Write(msg[4:])
1942 } else {
1943 hs.finishedHash.Write(msg)
1944 }
1945}
1946
David Benjaminc895d6b2016-08-11 13:26:41 -04001947// selectClientCertificate selects a certificate for use with the given
1948// certificate, or none if none match. It may return a particular certificate or
1949// nil on success, or an error on internal error.
1950func selectClientCertificate(c *Conn, certReq *certificateRequestMsg) (*Certificate, error) {
Robert Sloana27a6a42017-09-05 08:39:28 -07001951 if len(c.config.Certificates) == 0 {
1952 return nil, nil
David Benjaminc895d6b2016-08-11 13:26:41 -04001953 }
1954
Robert Sloana27a6a42017-09-05 08:39:28 -07001955 // The test is assumed to have configured the certificate it meant to
1956 // send.
1957 if len(c.config.Certificates) > 1 {
1958 return nil, errors.New("tls: multiple certificates configured")
David Benjaminc895d6b2016-08-11 13:26:41 -04001959 }
1960
Robert Sloana27a6a42017-09-05 08:39:28 -07001961 return &c.config.Certificates[0], nil
David Benjaminc895d6b2016-08-11 13:26:41 -04001962}
1963
Adam Langleyd9e397b2015-01-22 14:27:53 -08001964// clientSessionCacheKey returns a key used to cache sessionTickets that could
1965// be used to resume previously negotiated TLS sessions with a server.
1966func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
1967 if len(config.ServerName) > 0 {
1968 return config.ServerName
1969 }
1970 return serverAddr.String()
1971}
1972
1973// mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol
1974// given list of possible protocols and a list of the preference order. The
1975// first list must not be empty. It returns the resulting protocol and flag
1976// indicating if the fallback case was reached.
1977func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
1978 for _, s := range preferenceProtos {
1979 for _, c := range protos {
1980 if s == c {
1981 return s, false
1982 }
1983 }
1984 }
1985
1986 return protos[0], true
1987}
1988
1989// writeIntPadded writes x into b, padded up with leading zeros as
1990// needed.
1991func writeIntPadded(b []byte, x *big.Int) {
1992 for i := range b {
1993 b[i] = 0
1994 }
1995 xb := x.Bytes()
1996 copy(b[len(b)-len(xb):], xb)
1997}
Steven Valdez909b19f2016-11-21 15:35:44 -05001998
Robert Sloanb1b54b82017-11-06 13:50:02 -08001999func generatePSKBinders(version uint16, hello *clientHelloMsg, pskCipherSuite *cipherSuite, psk, firstClientHello, helloRetryRequest []byte, config *Config) {
Steven Valdez909b19f2016-11-21 15:35:44 -05002000 if config.Bugs.SendNoPSKBinder {
2001 return
2002 }
2003
2004 binderLen := pskCipherSuite.hash().Size()
2005 if config.Bugs.SendShortPSKBinder {
2006 binderLen--
2007 }
2008
David Benjamin1b249672016-12-06 18:25:50 -05002009 numBinders := 1
2010 if config.Bugs.SendExtraPSKBinder {
2011 numBinders++
2012 }
2013
Steven Valdez909b19f2016-11-21 15:35:44 -05002014 // Fill hello.pskBinders with appropriate length arrays of zeros so the
2015 // length prefixes are correct when computing the binder over the truncated
2016 // ClientHello message.
David Benjamin1b249672016-12-06 18:25:50 -05002017 hello.pskBinders = make([][]byte, numBinders)
2018 for i := range hello.pskBinders {
Steven Valdez909b19f2016-11-21 15:35:44 -05002019 hello.pskBinders[i] = make([]byte, binderLen)
2020 }
2021
2022 helloBytes := hello.marshal()
2023 binderSize := len(hello.pskBinders)*(binderLen+1) + 2
2024 truncatedHello := helloBytes[:len(helloBytes)-binderSize]
Robert Sloan8542c082018-02-05 09:07:34 -08002025 binder := computePSKBinder(psk, version, resumptionPSKBinderLabel, pskCipherSuite, firstClientHello, helloRetryRequest, truncatedHello)
Steven Valdez909b19f2016-11-21 15:35:44 -05002026 if config.Bugs.SendShortPSKBinder {
2027 binder = binder[:binderLen]
2028 }
2029 if config.Bugs.SendInvalidPSKBinder {
2030 binder[0] ^= 1
2031 }
2032
2033 for i := range hello.pskBinders {
2034 hello.pskBinders[i] = binder
2035 }
2036
2037 hello.raw = nil
2038}