blob: 2e6d2865b44bfce5b9473710827d03adc8a1fbdd [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
Nick Harper0b3625b2016-07-25 16:16:28 -07007import (
8 "bytes"
9 "encoding/binary"
David Benjaminb853f312017-07-14 18:40:34 -040010 "fmt"
Nick Harper0b3625b2016-07-25 16:16:28 -070011)
Adam Langley95c29f32014-06-20 12:00:00 -070012
Nick Harper8dda5cc2016-06-30 18:51:11 -040013func writeLen(buf []byte, v, size int) {
14 for i := 0; i < size; i++ {
15 buf[size-i-1] = byte(v)
16 v >>= 8
17 }
18 if v != 0 {
19 panic("length is too long")
20 }
21}
22
23type byteBuilder struct {
24 buf *[]byte
25 start int
26 prefixLen int
27 child *byteBuilder
28}
29
30func newByteBuilder() *byteBuilder {
31 buf := make([]byte, 0, 32)
32 return &byteBuilder{buf: &buf}
33}
34
35func (bb *byteBuilder) len() int {
36 return len(*bb.buf) - bb.start - bb.prefixLen
37}
38
David Benjaminb853f312017-07-14 18:40:34 -040039func (bb *byteBuilder) data() []byte {
40 bb.flush()
41 return (*bb.buf)[bb.start+bb.prefixLen:]
42}
43
Nick Harper8dda5cc2016-06-30 18:51:11 -040044func (bb *byteBuilder) flush() {
45 if bb.child == nil {
46 return
47 }
48 bb.child.flush()
49 writeLen((*bb.buf)[bb.child.start:], bb.child.len(), bb.child.prefixLen)
50 bb.child = nil
51 return
52}
53
54func (bb *byteBuilder) finish() []byte {
55 bb.flush()
56 return *bb.buf
57}
58
59func (bb *byteBuilder) addU8(u uint8) {
60 bb.flush()
61 *bb.buf = append(*bb.buf, u)
62}
63
64func (bb *byteBuilder) addU16(u uint16) {
65 bb.flush()
66 *bb.buf = append(*bb.buf, byte(u>>8), byte(u))
67}
68
69func (bb *byteBuilder) addU24(u int) {
70 bb.flush()
71 *bb.buf = append(*bb.buf, byte(u>>16), byte(u>>8), byte(u))
72}
73
74func (bb *byteBuilder) addU32(u uint32) {
75 bb.flush()
76 *bb.buf = append(*bb.buf, byte(u>>24), byte(u>>16), byte(u>>8), byte(u))
77}
78
Nick Harper0b3625b2016-07-25 16:16:28 -070079func (bb *byteBuilder) addU64(u uint64) {
80 bb.flush()
81 var b [8]byte
82 binary.BigEndian.PutUint64(b[:], u)
83 *bb.buf = append(*bb.buf, b[:]...)
84}
85
Nick Harper8dda5cc2016-06-30 18:51:11 -040086func (bb *byteBuilder) addU8LengthPrefixed() *byteBuilder {
87 return bb.createChild(1)
88}
89
90func (bb *byteBuilder) addU16LengthPrefixed() *byteBuilder {
91 return bb.createChild(2)
92}
93
94func (bb *byteBuilder) addU24LengthPrefixed() *byteBuilder {
95 return bb.createChild(3)
96}
97
Nick Harper0b3625b2016-07-25 16:16:28 -070098func (bb *byteBuilder) addU32LengthPrefixed() *byteBuilder {
99 return bb.createChild(4)
100}
101
Nick Harper8dda5cc2016-06-30 18:51:11 -0400102func (bb *byteBuilder) addBytes(b []byte) {
103 bb.flush()
104 *bb.buf = append(*bb.buf, b...)
105}
106
107func (bb *byteBuilder) createChild(lengthPrefixSize int) *byteBuilder {
108 bb.flush()
109 bb.child = &byteBuilder{
110 buf: bb.buf,
111 start: len(*bb.buf),
112 prefixLen: lengthPrefixSize,
113 }
114 for i := 0; i < lengthPrefixSize; i++ {
115 *bb.buf = append(*bb.buf, 0)
116 }
117 return bb.child
118}
119
120func (bb *byteBuilder) discardChild() {
David Benjaminb853f312017-07-14 18:40:34 -0400121 if bb.child == nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400122 return
123 }
David Benjaminb853f312017-07-14 18:40:34 -0400124 *bb.buf = (*bb.buf)[:bb.child.start]
Nick Harper8dda5cc2016-06-30 18:51:11 -0400125 bb.child = nil
Nick Harper8dda5cc2016-06-30 18:51:11 -0400126}
127
Nick Harperf8b0e702016-06-30 19:59:01 -0400128type keyShareEntry struct {
129 group CurveID
130 keyExchange []byte
131}
132
Steven Valdez5b986082016-09-01 12:29:49 -0400133type pskIdentity struct {
Steven Valdeza833c352016-11-01 13:39:36 -0400134 ticket []uint8
135 obfuscatedTicketAge uint32
Steven Valdez5b986082016-09-01 12:29:49 -0400136}
137
Adam Langley95c29f32014-06-20 12:00:00 -0700138type clientHelloMsg struct {
David Benjamin3baa6e12016-10-07 21:10:38 -0400139 raw []byte
140 isDTLS bool
141 vers uint16
142 random []byte
143 sessionId []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500144 cookie []byte
145 cipherSuites []uint16
146 compressionMethods []uint8
147 nextProtoNeg bool
148 serverName string
149 ocspStapling bool
150 supportedCurves []CurveID
151 supportedPoints []uint8
Nick Harperdcfbc672016-07-16 17:47:31 +0200152 hasKeyShares bool
Nick Harperf8b0e702016-06-30 19:59:01 -0400153 keyShares []keyShareEntry
David Benjamin7e1f9842016-09-20 19:24:40 -0400154 trailingKeyShareData bool
Steven Valdez5b986082016-09-01 12:29:49 -0400155 pskIdentities []pskIdentity
Steven Valdeza833c352016-11-01 13:39:36 -0400156 pskKEModes []byte
157 pskBinders [][]uint8
Nick Harperf8b0e702016-06-30 19:59:01 -0400158 hasEarlyData bool
David Benjamin3baa6e12016-10-07 21:10:38 -0400159 tls13Cookie []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500160 ticketSupported bool
161 sessionTicket []uint8
Nick Harper60edffd2016-06-21 15:19:24 -0700162 signatureAlgorithms []signatureAlgorithm
Steven Valdezfdd10992016-09-15 16:27:05 -0400163 supportedVersions []uint16
David Benjaminca6c8262014-11-15 19:06:08 -0500164 secureRenegotiation []byte
165 alpnProtocols []string
166 duplicateExtension bool
167 channelIDSupported bool
Steven Valdeza833c352016-11-01 13:39:36 -0400168 npnAfterAlpn bool
David Benjaminca6c8262014-11-15 19:06:08 -0500169 extendedMasterSecret bool
170 srtpProtectionProfiles []uint16
171 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -0500172 sctListSupported bool
Adam Langley09505632015-07-30 18:10:13 -0700173 customExtension string
David Benjamin65ac9972016-09-02 21:35:25 -0400174 hasGREASEExtension bool
Steven Valdeza833c352016-11-01 13:39:36 -0400175 pskBinderFirst bool
David Benjaminb853f312017-07-14 18:40:34 -0400176 omitExtensions bool
177 emptyExtensions bool
David Benjamine51fb0f2017-09-07 11:51:46 -0400178 pad int
David Benjaminaba057a2017-09-11 15:21:43 -0400179 sendOnlyECExtensions bool
Adam Langley95c29f32014-06-20 12:00:00 -0700180}
181
182func (m *clientHelloMsg) equal(i interface{}) bool {
183 m1, ok := i.(*clientHelloMsg)
184 if !ok {
185 return false
186 }
187
188 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400189 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700190 m.vers == m1.vers &&
191 bytes.Equal(m.random, m1.random) &&
192 bytes.Equal(m.sessionId, m1.sessionId) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400193 bytes.Equal(m.cookie, m1.cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700194 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
195 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
196 m.nextProtoNeg == m1.nextProtoNeg &&
197 m.serverName == m1.serverName &&
198 m.ocspStapling == m1.ocspStapling &&
199 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
200 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
Nick Harperdcfbc672016-07-16 17:47:31 +0200201 m.hasKeyShares == m1.hasKeyShares &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400202 eqKeyShareEntryLists(m.keyShares, m1.keyShares) &&
David Benjamin7e1f9842016-09-20 19:24:40 -0400203 m.trailingKeyShareData == m1.trailingKeyShareData &&
Steven Valdez5b986082016-09-01 12:29:49 -0400204 eqPSKIdentityLists(m.pskIdentities, m1.pskIdentities) &&
Steven Valdeza833c352016-11-01 13:39:36 -0400205 bytes.Equal(m.pskKEModes, m1.pskKEModes) &&
206 eqByteSlices(m.pskBinders, m1.pskBinders) &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400207 m.hasEarlyData == m1.hasEarlyData &&
David Benjamin3baa6e12016-10-07 21:10:38 -0400208 bytes.Equal(m.tls13Cookie, m1.tls13Cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700209 m.ticketSupported == m1.ticketSupported &&
210 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
Nick Harper60edffd2016-06-21 15:19:24 -0700211 eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
Steven Valdezfdd10992016-09-15 16:27:05 -0400212 eqUint16s(m.supportedVersions, m1.supportedVersions) &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700213 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
214 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400215 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -0400216 m.duplicateExtension == m1.duplicateExtension &&
David Benjaminfc7b0862014-09-06 13:21:53 -0400217 m.channelIDSupported == m1.channelIDSupported &&
Steven Valdeza833c352016-11-01 13:39:36 -0400218 m.npnAfterAlpn == m1.npnAfterAlpn &&
David Benjaminca6c8262014-11-15 19:06:08 -0500219 m.extendedMasterSecret == m1.extendedMasterSecret &&
220 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
David Benjamin61f95272014-11-25 01:55:35 -0500221 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
Adam Langley09505632015-07-30 18:10:13 -0700222 m.sctListSupported == m1.sctListSupported &&
David Benjamin65ac9972016-09-02 21:35:25 -0400223 m.customExtension == m1.customExtension &&
Steven Valdeza833c352016-11-01 13:39:36 -0400224 m.hasGREASEExtension == m1.hasGREASEExtension &&
David Benjaminb853f312017-07-14 18:40:34 -0400225 m.pskBinderFirst == m1.pskBinderFirst &&
226 m.omitExtensions == m1.omitExtensions &&
David Benjamine51fb0f2017-09-07 11:51:46 -0400227 m.emptyExtensions == m1.emptyExtensions &&
David Benjaminaba057a2017-09-11 15:21:43 -0400228 m.pad == m1.pad &&
229 m.sendOnlyECExtensions == m1.sendOnlyECExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700230}
231
232func (m *clientHelloMsg) marshal() []byte {
233 if m.raw != nil {
234 return m.raw
235 }
236
Nick Harper8dda5cc2016-06-30 18:51:11 -0400237 handshakeMsg := newByteBuilder()
238 handshakeMsg.addU8(typeClientHello)
239 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400240 hello.addU16(m.vers)
Nick Harper8dda5cc2016-06-30 18:51:11 -0400241 hello.addBytes(m.random)
242 sessionId := hello.addU8LengthPrefixed()
243 sessionId.addBytes(m.sessionId)
David Benjamin83c0bc92014-08-04 01:23:53 -0400244 if m.isDTLS {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400245 cookie := hello.addU8LengthPrefixed()
246 cookie.addBytes(m.cookie)
David Benjamin83c0bc92014-08-04 01:23:53 -0400247 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400248 cipherSuites := hello.addU16LengthPrefixed()
249 for _, suite := range m.cipherSuites {
250 cipherSuites.addU16(suite)
Adam Langley95c29f32014-06-20 12:00:00 -0700251 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400252 compressionMethods := hello.addU8LengthPrefixed()
253 compressionMethods.addBytes(m.compressionMethods)
Adam Langley95c29f32014-06-20 12:00:00 -0700254
Nick Harper8dda5cc2016-06-30 18:51:11 -0400255 extensions := hello.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -0400256 if len(m.pskIdentities) > 0 && m.pskBinderFirst {
257 extensions.addU16(extensionPreSharedKey)
258 pskExtension := extensions.addU16LengthPrefixed()
259
260 pskIdentities := pskExtension.addU16LengthPrefixed()
261 for _, psk := range m.pskIdentities {
262 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
263 pskIdentities.addU32(psk.obfuscatedTicketAge)
264 }
265 pskBinders := pskExtension.addU16LengthPrefixed()
266 for _, binder := range m.pskBinders {
267 pskBinders.addU8LengthPrefixed().addBytes(binder)
268 }
269 }
David Benjamin35a7a442014-07-05 00:23:20 -0400270 if m.duplicateExtension {
271 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400272 extensions.addU16(0xffff)
273 extensions.addU16(0) // 0-length for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400274 }
Steven Valdeza833c352016-11-01 13:39:36 -0400275 if m.nextProtoNeg && !m.npnAfterAlpn {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400276 extensions.addU16(extensionNextProtoNeg)
277 extensions.addU16(0) // The length is always 0
Adam Langley95c29f32014-06-20 12:00:00 -0700278 }
279 if len(m.serverName) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400280 extensions.addU16(extensionServerName)
281 serverNameList := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700282
283 // RFC 3546, section 3.1
284 //
285 // struct {
286 // NameType name_type;
287 // select (name_type) {
288 // case host_name: HostName;
289 // } name;
290 // } ServerName;
291 //
292 // enum {
293 // host_name(0), (255)
294 // } NameType;
295 //
296 // opaque HostName<1..2^16-1>;
297 //
298 // struct {
299 // ServerName server_name_list<1..2^16-1>
300 // } ServerNameList;
301
Nick Harper8dda5cc2016-06-30 18:51:11 -0400302 serverName := serverNameList.addU16LengthPrefixed()
303 serverName.addU8(0) // NameType host_name(0)
304 hostName := serverName.addU16LengthPrefixed()
305 hostName.addBytes([]byte(m.serverName))
Adam Langley95c29f32014-06-20 12:00:00 -0700306 }
307 if m.ocspStapling {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400308 extensions.addU16(extensionStatusRequest)
309 certificateStatusRequest := extensions.addU16LengthPrefixed()
310
Adam Langley95c29f32014-06-20 12:00:00 -0700311 // RFC 4366, section 3.6
Nick Harper8dda5cc2016-06-30 18:51:11 -0400312 certificateStatusRequest.addU8(1) // OCSP type
Adam Langley95c29f32014-06-20 12:00:00 -0700313 // Two zero valued uint16s for the two lengths.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400314 certificateStatusRequest.addU16(0) // ResponderID length
315 certificateStatusRequest.addU16(0) // Extensions length
Adam Langley95c29f32014-06-20 12:00:00 -0700316 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200317 if m.hasKeyShares {
Nick Harperf8b0e702016-06-30 19:59:01 -0400318 extensions.addU16(extensionKeyShare)
319 keyShareList := extensions.addU16LengthPrefixed()
320
321 keyShares := keyShareList.addU16LengthPrefixed()
322 for _, keyShare := range m.keyShares {
323 keyShares.addU16(uint16(keyShare.group))
324 keyExchange := keyShares.addU16LengthPrefixed()
325 keyExchange.addBytes(keyShare.keyExchange)
326 }
David Benjamin7e1f9842016-09-20 19:24:40 -0400327
328 if m.trailingKeyShareData {
329 keyShares.addU8(0)
330 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400331 }
Steven Valdeza833c352016-11-01 13:39:36 -0400332 if len(m.pskKEModes) > 0 {
333 extensions.addU16(extensionPSKKeyExchangeModes)
334 pskModesExtension := extensions.addU16LengthPrefixed()
335 pskModesExtension.addU8LengthPrefixed().addBytes(m.pskKEModes)
Nick Harperf8b0e702016-06-30 19:59:01 -0400336 }
337 if m.hasEarlyData {
338 extensions.addU16(extensionEarlyData)
David Benjaminc5665c92016-11-15 18:12:58 +0900339 extensions.addU16(0) // The length is zero.
Nick Harperf8b0e702016-06-30 19:59:01 -0400340 }
David Benjamin3baa6e12016-10-07 21:10:38 -0400341 if len(m.tls13Cookie) > 0 {
342 extensions.addU16(extensionCookie)
343 body := extensions.addU16LengthPrefixed()
344 body.addU16LengthPrefixed().addBytes(m.tls13Cookie)
345 }
Adam Langley95c29f32014-06-20 12:00:00 -0700346 if m.ticketSupported {
347 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400348 extensions.addU16(extensionSessionTicket)
349 sessionTicketExtension := extensions.addU16LengthPrefixed()
350 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700351 }
Nick Harper60edffd2016-06-21 15:19:24 -0700352 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700353 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400354 extensions.addU16(extensionSignatureAlgorithms)
355 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
356 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700357 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400358 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700359 }
360 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400361 if len(m.supportedVersions) > 0 {
362 extensions.addU16(extensionSupportedVersions)
363 supportedVersionsExtension := extensions.addU16LengthPrefixed()
364 supportedVersions := supportedVersionsExtension.addU8LengthPrefixed()
365 for _, version := range m.supportedVersions {
366 supportedVersions.addU16(uint16(version))
367 }
368 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700369 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400370 extensions.addU16(extensionRenegotiationInfo)
371 secureRenegoExt := extensions.addU16LengthPrefixed()
372 secureRenego := secureRenegoExt.addU8LengthPrefixed()
373 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700374 }
David Benjaminfa055a22014-09-15 16:51:51 -0400375 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400376 // https://tools.ietf.org/html/rfc7301#section-3.1
377 extensions.addU16(extensionALPN)
378 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400379
Nick Harper8dda5cc2016-06-30 18:51:11 -0400380 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400381 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400382 protocolName := protocolNameList.addU8LengthPrefixed()
383 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400384 }
David Benjaminfa055a22014-09-15 16:51:51 -0400385 }
David Benjamind30a9902014-08-24 01:44:23 -0400386 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400387 extensions.addU16(extensionChannelID)
388 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400389 }
Steven Valdeza833c352016-11-01 13:39:36 -0400390 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400391 extensions.addU16(extensionNextProtoNeg)
392 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400393 }
David Benjamin35a7a442014-07-05 00:23:20 -0400394 if m.duplicateExtension {
395 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400396 extensions.addU16(0xffff)
397 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400398 }
Adam Langley75712922014-10-10 16:23:43 -0700399 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500400 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400401 extensions.addU16(extensionExtendedMasterSecret)
402 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700403 }
David Benjaminca6c8262014-11-15 19:06:08 -0500404 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400405 // https://tools.ietf.org/html/rfc5764#section-4.1.1
406 extensions.addU16(extensionUseSRTP)
407 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500408
Nick Harper8dda5cc2016-06-30 18:51:11 -0400409 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500410 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400411 // An SRTPProtectionProfile is defined as uint8[2],
412 // not uint16. For some reason, we're storing it
413 // as a uint16.
414 srtpProtectionProfiles.addU8(byte(p >> 8))
415 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500416 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400417 srtpMki := useSrtpExt.addU8LengthPrefixed()
418 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500419 }
David Benjamin61f95272014-11-25 01:55:35 -0500420 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400421 extensions.addU16(extensionSignedCertificateTimestamp)
422 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500423 }
Adam Langley09505632015-07-30 18:10:13 -0700424 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400425 extensions.addU16(extensionCustom)
426 customExt := extensions.addU16LengthPrefixed()
427 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700428 }
David Benjaminaba057a2017-09-11 15:21:43 -0400429
430 // Discard all extensions but the curve-related ones to trigger the Java
431 // fingerprinter.
432 if m.sendOnlyECExtensions {
433 hello.discardChild()
434 extensions = hello.addU16LengthPrefixed()
435 }
436 if len(m.supportedCurves) > 0 {
437 // http://tools.ietf.org/html/rfc4492#section-5.1.1
438 extensions.addU16(extensionSupportedCurves)
439 supportedCurvesList := extensions.addU16LengthPrefixed()
440 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
441 for _, curve := range m.supportedCurves {
442 supportedCurves.addU16(uint16(curve))
443 }
444 }
445 if len(m.supportedPoints) > 0 {
446 // http://tools.ietf.org/html/rfc4492#section-5.1.2
447 extensions.addU16(extensionSupportedPoints)
448 supportedPointsList := extensions.addU16LengthPrefixed()
449 supportedPoints := supportedPointsList.addU8LengthPrefixed()
450 supportedPoints.addBytes(m.supportedPoints)
451 }
452
Steven Valdeza833c352016-11-01 13:39:36 -0400453 // The PSK extension must be last (draft-ietf-tls-tls13-18 section 4.2.6).
454 if len(m.pskIdentities) > 0 && !m.pskBinderFirst {
455 extensions.addU16(extensionPreSharedKey)
456 pskExtension := extensions.addU16LengthPrefixed()
457
458 pskIdentities := pskExtension.addU16LengthPrefixed()
459 for _, psk := range m.pskIdentities {
460 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
461 pskIdentities.addU32(psk.obfuscatedTicketAge)
462 }
463 pskBinders := pskExtension.addU16LengthPrefixed()
464 for _, binder := range m.pskBinders {
465 pskBinders.addU8LengthPrefixed().addBytes(binder)
466 }
467 }
Adam Langley95c29f32014-06-20 12:00:00 -0700468
David Benjaminaba057a2017-09-11 15:21:43 -0400469 // This must be swapped with PSK (with some length computation) if we
470 // ever need to support PadClientHello and TLS 1.3.
David Benjamine51fb0f2017-09-07 11:51:46 -0400471 if m.pad != 0 && hello.len()%m.pad != 0 {
472 extensions.addU16(extensionPadding)
473 padding := extensions.addU16LengthPrefixed()
474 // Note hello.len() has changed at this point from the length
475 // prefix.
476 if l := hello.len() % m.pad; l != 0 {
477 padding.addBytes(make([]byte, m.pad-l))
478 }
479 }
480
David Benjaminb853f312017-07-14 18:40:34 -0400481 if m.omitExtensions || m.emptyExtensions {
482 // Silently erase any extensions which were sent.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400483 hello.discardChild()
David Benjaminb853f312017-07-14 18:40:34 -0400484 if m.emptyExtensions {
485 hello.addU16(0)
486 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400487 }
Adam Langley95c29f32014-06-20 12:00:00 -0700488
Nick Harper8dda5cc2016-06-30 18:51:11 -0400489 m.raw = handshakeMsg.finish()
David Benjamine51fb0f2017-09-07 11:51:46 -0400490 // Sanity-check padding.
491 if m.pad != 0 && (len(m.raw)-4)%m.pad != 0 {
492 panic(fmt.Sprintf("%d is not a multiple of %d", len(m.raw)-4, m.pad))
493 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400494 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700495}
496
497func (m *clientHelloMsg) unmarshal(data []byte) bool {
498 if len(data) < 42 {
499 return false
500 }
501 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400502 m.vers = uint16(data[4])<<8 | uint16(data[5])
Adam Langley95c29f32014-06-20 12:00:00 -0700503 m.random = data[6:38]
504 sessionIdLen := int(data[38])
505 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
506 return false
507 }
508 m.sessionId = data[39 : 39+sessionIdLen]
509 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400510 if m.isDTLS {
511 if len(data) < 1 {
512 return false
513 }
514 cookieLen := int(data[0])
515 if cookieLen > 32 || len(data) < 1+cookieLen {
516 return false
517 }
518 m.cookie = data[1 : 1+cookieLen]
519 data = data[1+cookieLen:]
520 }
Adam Langley95c29f32014-06-20 12:00:00 -0700521 if len(data) < 2 {
522 return false
523 }
524 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
525 // they are uint16s, the number must be even.
526 cipherSuiteLen := int(data[0])<<8 | int(data[1])
527 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
528 return false
529 }
530 numCipherSuites := cipherSuiteLen / 2
531 m.cipherSuites = make([]uint16, numCipherSuites)
532 for i := 0; i < numCipherSuites; i++ {
533 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
534 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700535 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700536 }
537 }
538 data = data[2+cipherSuiteLen:]
539 if len(data) < 1 {
540 return false
541 }
542 compressionMethodsLen := int(data[0])
543 if len(data) < 1+compressionMethodsLen {
544 return false
545 }
546 m.compressionMethods = data[1 : 1+compressionMethodsLen]
547
548 data = data[1+compressionMethodsLen:]
549
550 m.nextProtoNeg = false
551 m.serverName = ""
552 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400553 m.keyShares = nil
554 m.pskIdentities = nil
555 m.hasEarlyData = false
Adam Langley95c29f32014-06-20 12:00:00 -0700556 m.ticketSupported = false
557 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700558 m.signatureAlgorithms = nil
Steven Valdezfdd10992016-09-15 16:27:05 -0400559 m.supportedVersions = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400560 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700561 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700562 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700563
564 if len(data) == 0 {
565 // ClientHello is optionally followed by extension data
566 return true
567 }
568 if len(data) < 2 {
569 return false
570 }
571
572 extensionsLength := int(data[0])<<8 | int(data[1])
573 data = data[2:]
574 if extensionsLength != len(data) {
575 return false
576 }
577
578 for len(data) != 0 {
579 if len(data) < 4 {
580 return false
581 }
582 extension := uint16(data[0])<<8 | uint16(data[1])
583 length := int(data[2])<<8 | int(data[3])
584 data = data[4:]
585 if len(data) < length {
586 return false
587 }
588
589 switch extension {
590 case extensionServerName:
591 if length < 2 {
592 return false
593 }
594 numNames := int(data[0])<<8 | int(data[1])
595 d := data[2:]
596 for i := 0; i < numNames; i++ {
597 if len(d) < 3 {
598 return false
599 }
600 nameType := d[0]
601 nameLen := int(d[1])<<8 | int(d[2])
602 d = d[3:]
603 if len(d) < nameLen {
604 return false
605 }
606 if nameType == 0 {
607 m.serverName = string(d[0:nameLen])
608 break
609 }
610 d = d[nameLen:]
611 }
612 case extensionNextProtoNeg:
613 if length > 0 {
614 return false
615 }
616 m.nextProtoNeg = true
617 case extensionStatusRequest:
618 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
619 case extensionSupportedCurves:
620 // http://tools.ietf.org/html/rfc4492#section-5.5.1
621 if length < 2 {
622 return false
623 }
624 l := int(data[0])<<8 | int(data[1])
625 if l%2 == 1 || length != l+2 {
626 return false
627 }
628 numCurves := l / 2
629 m.supportedCurves = make([]CurveID, numCurves)
630 d := data[2:]
631 for i := 0; i < numCurves; i++ {
632 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
633 d = d[2:]
634 }
635 case extensionSupportedPoints:
636 // http://tools.ietf.org/html/rfc4492#section-5.5.2
637 if length < 1 {
638 return false
639 }
640 l := int(data[0])
641 if length != l+1 {
642 return false
643 }
David Benjamina81967b2016-12-22 09:16:57 -0500644 m.supportedPoints = data[1 : 1+l]
Adam Langley95c29f32014-06-20 12:00:00 -0700645 case extensionSessionTicket:
646 // http://tools.ietf.org/html/rfc5077#section-3.2
647 m.ticketSupported = true
648 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400649 case extensionKeyShare:
650 // draft-ietf-tls-tls13 section 6.3.2.3
651 if length < 2 {
652 return false
653 }
654 l := int(data[0])<<8 | int(data[1])
655 if l != length-2 {
656 return false
657 }
658 d := data[2:length]
Nick Harperdcfbc672016-07-16 17:47:31 +0200659 m.hasKeyShares = true
Nick Harperf8b0e702016-06-30 19:59:01 -0400660 for len(d) > 0 {
661 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
662 // key_exchange (2-byte length prefix with at least 1 byte of content).
663 if len(d) < 5 {
664 return false
665 }
666 entry := keyShareEntry{}
667 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
668 keyExchLen := int(d[2])<<8 | int(d[3])
669 d = d[4:]
670 if len(d) < keyExchLen {
671 return false
672 }
673 entry.keyExchange = d[:keyExchLen]
674 d = d[keyExchLen:]
675 m.keyShares = append(m.keyShares, entry)
676 }
677 case extensionPreSharedKey:
Steven Valdeza833c352016-11-01 13:39:36 -0400678 // draft-ietf-tls-tls13-18 section 4.2.6
Nick Harperf8b0e702016-06-30 19:59:01 -0400679 if length < 2 {
680 return false
681 }
682 l := int(data[0])<<8 | int(data[1])
Steven Valdeza833c352016-11-01 13:39:36 -0400683 d := data[2 : l+2]
684 // Parse PSK identities.
Nick Harperf8b0e702016-06-30 19:59:01 -0400685 for len(d) > 0 {
686 if len(d) < 2 {
687 return false
688 }
689 pskLen := int(d[0])<<8 | int(d[1])
690 d = d[2:]
Steven Valdez5b986082016-09-01 12:29:49 -0400691
Steven Valdeza833c352016-11-01 13:39:36 -0400692 if len(d) < pskLen+4 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400693 return false
694 }
Steven Valdeza833c352016-11-01 13:39:36 -0400695 ticket := d[:pskLen]
696 obfuscatedTicketAge := uint32(d[pskLen])<<24 | uint32(d[pskLen+1])<<16 | uint32(d[pskLen+2])<<8 | uint32(d[pskLen+3])
697 psk := pskIdentity{
698 ticket: ticket,
699 obfuscatedTicketAge: obfuscatedTicketAge,
700 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400701 m.pskIdentities = append(m.pskIdentities, psk)
Steven Valdeza833c352016-11-01 13:39:36 -0400702 d = d[pskLen+4:]
Nick Harperf8b0e702016-06-30 19:59:01 -0400703 }
Steven Valdeza833c352016-11-01 13:39:36 -0400704 d = data[l+2:]
705 if len(d) < 2 {
706 return false
707 }
708 l = int(d[0])<<8 | int(d[1])
709 d = d[2:]
710 if l != len(d) {
711 return false
712 }
713 // Parse PSK binders.
714 for len(d) > 0 {
715 if len(d) < 1 {
716 return false
717 }
718 binderLen := int(d[0])
719 d = d[1:]
720 if binderLen > len(d) {
721 return false
722 }
723 m.pskBinders = append(m.pskBinders, d[:binderLen])
724 d = d[binderLen:]
725 }
726
727 // There must be the same number of identities as binders.
728 if len(m.pskIdentities) != len(m.pskBinders) {
729 return false
730 }
731 case extensionPSKKeyExchangeModes:
732 // draft-ietf-tls-tls13-18 section 4.2.7
733 if length < 1 {
734 return false
735 }
736 l := int(data[0])
737 if l != length-1 {
738 return false
739 }
740 m.pskKEModes = data[1:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400741 case extensionEarlyData:
742 // draft-ietf-tls-tls13 section 6.3.2.5
David Benjaminc5665c92016-11-15 18:12:58 +0900743 if length != 0 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400744 return false
745 }
746 m.hasEarlyData = true
David Benjamin3baa6e12016-10-07 21:10:38 -0400747 case extensionCookie:
748 if length < 2 {
749 return false
750 }
751 l := int(data[0])<<8 | int(data[1])
752 if l != length-2 || l == 0 {
753 return false
754 }
755 m.tls13Cookie = data[2 : 2+l]
Adam Langley95c29f32014-06-20 12:00:00 -0700756 case extensionSignatureAlgorithms:
757 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
758 if length < 2 || length&1 != 0 {
759 return false
760 }
761 l := int(data[0])<<8 | int(data[1])
762 if l != length-2 {
763 return false
764 }
765 n := l / 2
766 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700767 m.signatureAlgorithms = make([]signatureAlgorithm, n)
768 for i := range m.signatureAlgorithms {
769 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700770 d = d[2:]
771 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400772 case extensionSupportedVersions:
773 if length < 1+2 {
774 return false
775 }
776 l := int(data[0])
777 if l != length-1 || l%2 == 1 || l < 2 {
778 return false
779 }
780 n := l / 2
781 d := data[1:]
782 m.supportedVersions = make([]uint16, n)
783 for i := range m.supportedVersions {
784 m.supportedVersions[i] = uint16(d[0])<<8 | uint16(d[1])
785 d = d[2:]
786 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700787 case extensionRenegotiationInfo:
788 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700789 return false
790 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700791 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400792 case extensionALPN:
793 if length < 2 {
794 return false
795 }
796 l := int(data[0])<<8 | int(data[1])
797 if l != length-2 {
798 return false
799 }
800 d := data[2:length]
801 for len(d) != 0 {
802 stringLen := int(d[0])
803 d = d[1:]
804 if stringLen == 0 || stringLen > len(d) {
805 return false
806 }
807 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
808 d = d[stringLen:]
809 }
David Benjamind30a9902014-08-24 01:44:23 -0400810 case extensionChannelID:
811 if length > 0 {
812 return false
813 }
814 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700815 case extensionExtendedMasterSecret:
816 if length != 0 {
817 return false
818 }
819 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500820 case extensionUseSRTP:
821 if length < 2 {
822 return false
823 }
824 l := int(data[0])<<8 | int(data[1])
825 if l > length-2 || l%2 != 0 {
826 return false
827 }
828 n := l / 2
829 m.srtpProtectionProfiles = make([]uint16, n)
830 d := data[2:length]
831 for i := 0; i < n; i++ {
832 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
833 d = d[2:]
834 }
835 if len(d) < 1 || int(d[0]) != len(d)-1 {
836 return false
837 }
838 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500839 case extensionSignedCertificateTimestamp:
840 if length != 0 {
841 return false
842 }
843 m.sctListSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700844 case extensionCustom:
845 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700846 }
847 data = data[length:]
David Benjamin65ac9972016-09-02 21:35:25 -0400848
849 if isGREASEValue(extension) {
850 m.hasGREASEExtension = true
851 }
Adam Langley95c29f32014-06-20 12:00:00 -0700852 }
853
854 return true
855}
856
857type serverHelloMsg struct {
Steven Valdez038da9b2017-07-10 12:57:25 -0400858 raw []byte
859 isDTLS bool
860 vers uint16
861 versOverride uint16
862 supportedVersOverride uint16
863 random []byte
864 sessionId []byte
865 cipherSuite uint16
866 hasKeyShare bool
867 keyShare keyShareEntry
868 hasPSKIdentity bool
869 pskIdentity uint16
870 compressionMethod uint8
871 customExtension string
872 unencryptedALPN string
David Benjaminb853f312017-07-14 18:40:34 -0400873 omitExtensions bool
874 emptyExtensions bool
Steven Valdez038da9b2017-07-10 12:57:25 -0400875 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700876}
877
Adam Langley95c29f32014-06-20 12:00:00 -0700878func (m *serverHelloMsg) marshal() []byte {
879 if m.raw != nil {
880 return m.raw
881 }
882
Nick Harper5212ef82016-06-30 19:26:07 -0400883 handshakeMsg := newByteBuilder()
884 handshakeMsg.addU8(typeServerHello)
885 hello := handshakeMsg.addU24LengthPrefixed()
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400886
887 // m.vers is used both to determine the format of the rest of the
888 // ServerHello and to override the value, so include a second version
889 // field.
890 vers, ok := wireToVersion(m.vers, m.isDTLS)
891 if !ok {
892 panic("unknown version")
893 }
894 if m.versOverride != 0 {
895 hello.addU16(m.versOverride)
Steven Valdez16821262017-09-08 17:03:42 -0400896 } else if isResumptionExperiment(m.vers) {
Steven Valdez038da9b2017-07-10 12:57:25 -0400897 hello.addU16(VersionTLS12)
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400898 } else {
899 hello.addU16(m.vers)
900 }
901
Nick Harper5212ef82016-06-30 19:26:07 -0400902 hello.addBytes(m.random)
Steven Valdez16821262017-09-08 17:03:42 -0400903 if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
Nick Harperb41d2e42016-07-01 17:50:32 -0400904 sessionId := hello.addU8LengthPrefixed()
905 sessionId.addBytes(m.sessionId)
906 }
Nick Harper5212ef82016-06-30 19:26:07 -0400907 hello.addU16(m.cipherSuite)
Steven Valdez16821262017-09-08 17:03:42 -0400908 if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
Nick Harperb41d2e42016-07-01 17:50:32 -0400909 hello.addU8(m.compressionMethod)
910 }
Adam Langley95c29f32014-06-20 12:00:00 -0700911
Nick Harper5212ef82016-06-30 19:26:07 -0400912 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400913
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400914 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400915 if m.hasKeyShare {
916 extensions.addU16(extensionKeyShare)
917 keyShare := extensions.addU16LengthPrefixed()
918 keyShare.addU16(uint16(m.keyShare.group))
919 keyExchange := keyShare.addU16LengthPrefixed()
920 keyExchange.addBytes(m.keyShare.keyExchange)
921 }
922 if m.hasPSKIdentity {
923 extensions.addU16(extensionPreSharedKey)
924 extensions.addU16(2) // Length
925 extensions.addU16(m.pskIdentity)
926 }
Steven Valdez16821262017-09-08 17:03:42 -0400927 if isResumptionExperiment(m.vers) || m.supportedVersOverride != 0 {
Steven Valdez038da9b2017-07-10 12:57:25 -0400928 extensions.addU16(extensionSupportedVersions)
929 extensions.addU16(2) // Length
930 if m.supportedVersOverride != 0 {
931 extensions.addU16(m.supportedVersOverride)
932 } else {
933 extensions.addU16(m.vers)
934 }
935 }
David Benjamin490469f2016-10-05 22:44:38 -0400936 if len(m.customExtension) > 0 {
937 extensions.addU16(extensionCustom)
938 customExt := extensions.addU16LengthPrefixed()
939 customExt.addBytes([]byte(m.customExtension))
940 }
941 if len(m.unencryptedALPN) > 0 {
942 extensions.addU16(extensionALPN)
943 extension := extensions.addU16LengthPrefixed()
944
945 protocolNameList := extension.addU16LengthPrefixed()
946 protocolName := protocolNameList.addU8LengthPrefixed()
947 protocolName.addBytes([]byte(m.unencryptedALPN))
948 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400949 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400950 m.extensions.marshal(extensions)
David Benjaminb853f312017-07-14 18:40:34 -0400951 if m.omitExtensions || m.emptyExtensions {
952 // Silently erasing server extensions will break the handshake. Instead,
953 // assert that tests which use this field also disable all features which
954 // would write an extension.
955 if extensions.len() != 0 {
956 panic(fmt.Sprintf("ServerHello unexpectedly contained extensions: %x, %+v", extensions.data(), m))
957 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400958 hello.discardChild()
David Benjaminb853f312017-07-14 18:40:34 -0400959 if m.emptyExtensions {
960 hello.addU16(0)
961 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400962 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400963 }
964
965 m.raw = handshakeMsg.finish()
966 return m.raw
967}
968
969func (m *serverHelloMsg) unmarshal(data []byte) bool {
970 if len(data) < 42 {
971 return false
972 }
973 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400974 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400975 vers, ok := wireToVersion(m.vers, m.isDTLS)
976 if !ok {
977 return false
978 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400979 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400980 data = data[38:]
Steven Valdez16821262017-09-08 17:03:42 -0400981 if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
Nick Harperb41d2e42016-07-01 17:50:32 -0400982 sessionIdLen := int(data[0])
983 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
984 return false
985 }
986 m.sessionId = data[1 : 1+sessionIdLen]
987 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400988 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400989 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400990 return false
991 }
992 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400993 data = data[2:]
Steven Valdez16821262017-09-08 17:03:42 -0400994 if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
Nick Harperb41d2e42016-07-01 17:50:32 -0400995 if len(data) < 1 {
996 return false
997 }
998 m.compressionMethod = data[0]
999 data = data[1:]
1000 }
Nick Harperb3d51be2016-07-01 11:43:18 -04001001
David Benjamin8d315d72016-07-18 01:03:18 +02001002 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -04001003 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -04001004 m.extensions = serverExtensions{}
David Benjamin0a471912017-08-31 00:19:57 -04001005 m.omitExtensions = true
Nick Harperb3d51be2016-07-01 11:43:18 -04001006 return true
1007 }
1008 if len(data) < 2 {
1009 return false
1010 }
1011
1012 extensionsLength := int(data[0])<<8 | int(data[1])
1013 data = data[2:]
1014 if len(data) != extensionsLength {
1015 return false
1016 }
1017
Steven Valdez038da9b2017-07-10 12:57:25 -04001018 // Parse out the version from supported_versions if available.
1019 if m.vers == VersionTLS12 {
1020 vdata := data
1021 for len(vdata) != 0 {
1022 if len(vdata) < 4 {
1023 return false
1024 }
1025 extension := uint16(vdata[0])<<8 | uint16(vdata[1])
1026 length := int(vdata[2])<<8 | int(vdata[3])
1027 vdata = vdata[4:]
1028
1029 if len(vdata) < length {
1030 return false
1031 }
1032 d := vdata[:length]
1033 vdata = vdata[length:]
1034
1035 if extension == extensionSupportedVersions {
1036 if len(d) < 2 {
1037 return false
1038 }
1039 m.vers = uint16(d[0])<<8 | uint16(d[1])
1040 vers, ok = wireToVersion(m.vers, m.isDTLS)
1041 if !ok {
1042 return false
1043 }
1044 }
1045 }
1046 }
1047
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001048 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -04001049 for len(data) != 0 {
1050 if len(data) < 4 {
1051 return false
1052 }
1053 extension := uint16(data[0])<<8 | uint16(data[1])
1054 length := int(data[2])<<8 | int(data[3])
1055 data = data[4:]
1056
1057 if len(data) < length {
1058 return false
1059 }
1060 d := data[:length]
1061 data = data[length:]
1062
1063 switch extension {
1064 case extensionKeyShare:
1065 m.hasKeyShare = true
1066 if len(d) < 4 {
1067 return false
1068 }
1069 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
1070 keyExchLen := int(d[2])<<8 | int(d[3])
1071 if keyExchLen != len(d)-4 {
1072 return false
1073 }
1074 m.keyShare.keyExchange = make([]byte, keyExchLen)
1075 copy(m.keyShare.keyExchange, d[4:])
1076 case extensionPreSharedKey:
1077 if len(d) != 2 {
1078 return false
1079 }
1080 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
1081 m.hasPSKIdentity = true
Steven Valdez038da9b2017-07-10 12:57:25 -04001082 case extensionSupportedVersions:
Steven Valdez16821262017-09-08 17:03:42 -04001083 if !isResumptionExperiment(m.vers) {
Steven Valdez038da9b2017-07-10 12:57:25 -04001084 return false
1085 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001086 default:
1087 // Only allow the 3 extensions that are sent in
1088 // the clear in TLS 1.3.
1089 return false
1090 }
1091 }
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001092 } else if !m.extensions.unmarshal(data, vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -04001093 return false
1094 }
1095
1096 return true
1097}
1098
Nick Harperb41d2e42016-07-01 17:50:32 -04001099type encryptedExtensionsMsg struct {
1100 raw []byte
1101 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -04001102 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001103}
1104
1105func (m *encryptedExtensionsMsg) marshal() []byte {
1106 if m.raw != nil {
1107 return m.raw
1108 }
1109
1110 encryptedExtensionsMsg := newByteBuilder()
1111 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
1112 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -04001113 if !m.empty {
1114 extensions := encryptedExtensions.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001115 m.extensions.marshal(extensions)
Steven Valdez143e8b32016-07-11 13:19:03 -04001116 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001117
1118 m.raw = encryptedExtensionsMsg.finish()
1119 return m.raw
1120}
1121
1122func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -04001123 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001124 if len(data) < 6 {
1125 return false
1126 }
1127 if data[0] != typeEncryptedExtensions {
1128 return false
1129 }
1130 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1131 data = data[4:]
1132 if len(data) != msgLen {
1133 return false
1134 }
1135 extLen := int(data[0])<<8 | int(data[1])
1136 data = data[2:]
1137 if extLen != len(data) {
1138 return false
1139 }
David Benjamin44b33bc2016-07-01 22:40:23 -04001140 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -04001141}
1142
Nick Harperb3d51be2016-07-01 11:43:18 -04001143type serverExtensions struct {
1144 nextProtoNeg bool
1145 nextProtos []string
1146 ocspStapling bool
1147 ticketSupported bool
1148 secureRenegotiation []byte
1149 alpnProtocol string
1150 alpnProtocolEmpty bool
1151 duplicateExtension bool
1152 channelIDRequested bool
1153 extendedMasterSecret bool
1154 srtpProtectionProfile uint16
1155 srtpMasterKeyIdentifier string
1156 sctList []byte
1157 customExtension string
Steven Valdeza833c352016-11-01 13:39:36 -04001158 npnAfterAlpn bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001159 hasKeyShare bool
Nick Harperf2511f12016-12-06 16:02:31 -08001160 hasEarlyData bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001161 keyShare keyShareEntry
Steven Valdez038da9b2017-07-10 12:57:25 -04001162 supportedVersion uint16
David Benjamina81967b2016-12-22 09:16:57 -05001163 supportedPoints []uint8
David Benjamin023d4192017-02-06 13:49:07 -05001164 serverNameAck bool
Nick Harperb3d51be2016-07-01 11:43:18 -04001165}
1166
Steven Valdeza833c352016-11-01 13:39:36 -04001167func (m *serverExtensions) marshal(extensions *byteBuilder) {
David Benjamin35a7a442014-07-05 00:23:20 -04001168 if m.duplicateExtension {
1169 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001170 extensions.addU16(0xffff)
1171 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -04001172 }
Steven Valdeza833c352016-11-01 13:39:36 -04001173 if m.nextProtoNeg && !m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001174 extensions.addU16(extensionNextProtoNeg)
1175 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001176
1177 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001178 if len(v) > 255 {
1179 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -07001180 }
Nick Harper5212ef82016-06-30 19:26:07 -04001181 npn := extension.addU8LengthPrefixed()
1182 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -07001183 }
1184 }
Steven Valdeza833c352016-11-01 13:39:36 -04001185 if m.ocspStapling {
1186 extensions.addU16(extensionStatusRequest)
1187 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001188 }
1189 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -04001190 extensions.addU16(extensionSessionTicket)
1191 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001192 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001193 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001194 extensions.addU16(extensionRenegotiationInfo)
1195 extension := extensions.addU16LengthPrefixed()
1196 secureRenego := extension.addU8LengthPrefixed()
1197 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -07001198 }
Nick Harper5212ef82016-06-30 19:26:07 -04001199 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
1200 extensions.addU16(extensionALPN)
1201 extension := extensions.addU16LengthPrefixed()
1202
1203 protocolNameList := extension.addU16LengthPrefixed()
1204 protocolName := protocolNameList.addU8LengthPrefixed()
1205 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -04001206 }
David Benjamind30a9902014-08-24 01:44:23 -04001207 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -04001208 extensions.addU16(extensionChannelID)
1209 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -04001210 }
David Benjamin35a7a442014-07-05 00:23:20 -04001211 if m.duplicateExtension {
1212 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001213 extensions.addU16(0xffff)
1214 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -04001215 }
Adam Langley75712922014-10-10 16:23:43 -07001216 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -04001217 extensions.addU16(extensionExtendedMasterSecret)
1218 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -07001219 }
David Benjaminca6c8262014-11-15 19:06:08 -05001220 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001221 extensions.addU16(extensionUseSRTP)
1222 extension := extensions.addU16LengthPrefixed()
1223
1224 srtpProtectionProfiles := extension.addU16LengthPrefixed()
1225 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
1226 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
1227 srtpMki := extension.addU8LengthPrefixed()
1228 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -05001229 }
David Benjamin61f95272014-11-25 01:55:35 -05001230 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001231 extensions.addU16(extensionSignedCertificateTimestamp)
1232 extension := extensions.addU16LengthPrefixed()
1233 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -05001234 }
Adam Langley09505632015-07-30 18:10:13 -07001235 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001236 extensions.addU16(extensionCustom)
1237 customExt := extensions.addU16LengthPrefixed()
1238 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -07001239 }
Steven Valdeza833c352016-11-01 13:39:36 -04001240 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001241 extensions.addU16(extensionNextProtoNeg)
1242 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -04001243
1244 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001245 if len(v) > 255 {
1246 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -04001247 }
Nick Harper5212ef82016-06-30 19:26:07 -04001248 npn := extension.addU8LengthPrefixed()
1249 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001250 }
1251 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001252 if m.hasKeyShare {
1253 extensions.addU16(extensionKeyShare)
1254 keyShare := extensions.addU16LengthPrefixed()
1255 keyShare.addU16(uint16(m.keyShare.group))
1256 keyExchange := keyShare.addU16LengthPrefixed()
1257 keyExchange.addBytes(m.keyShare.keyExchange)
1258 }
Steven Valdez038da9b2017-07-10 12:57:25 -04001259 if m.supportedVersion != 0 {
1260 extensions.addU16(extensionSupportedVersions)
1261 extensions.addU16(2) // Length
1262 extensions.addU16(m.supportedVersion)
1263 }
David Benjamina81967b2016-12-22 09:16:57 -05001264 if len(m.supportedPoints) > 0 {
1265 // http://tools.ietf.org/html/rfc4492#section-5.1.2
1266 extensions.addU16(extensionSupportedPoints)
1267 supportedPointsList := extensions.addU16LengthPrefixed()
1268 supportedPoints := supportedPointsList.addU8LengthPrefixed()
1269 supportedPoints.addBytes(m.supportedPoints)
1270 }
Nick Harperf2511f12016-12-06 16:02:31 -08001271 if m.hasEarlyData {
1272 extensions.addU16(extensionEarlyData)
1273 extensions.addBytes([]byte{0, 0})
1274 }
David Benjamin023d4192017-02-06 13:49:07 -05001275 if m.serverNameAck {
1276 extensions.addU16(extensionServerName)
1277 extensions.addU16(0) // zero length
1278 }
Adam Langley95c29f32014-06-20 12:00:00 -07001279}
1280
David Benjamin44b33bc2016-07-01 22:40:23 -04001281func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001282 // Reset all fields.
1283 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001284
1285 for len(data) != 0 {
1286 if len(data) < 4 {
1287 return false
1288 }
1289 extension := uint16(data[0])<<8 | uint16(data[1])
1290 length := int(data[2])<<8 | int(data[3])
1291 data = data[4:]
1292 if len(data) < length {
1293 return false
1294 }
1295
1296 switch extension {
1297 case extensionNextProtoNeg:
1298 m.nextProtoNeg = true
1299 d := data[:length]
1300 for len(d) > 0 {
1301 l := int(d[0])
1302 d = d[1:]
1303 if l == 0 || l > len(d) {
1304 return false
1305 }
1306 m.nextProtos = append(m.nextProtos, string(d[:l]))
1307 d = d[l:]
1308 }
1309 case extensionStatusRequest:
Steven Valdeza833c352016-11-01 13:39:36 -04001310 if length > 0 {
1311 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001312 }
Steven Valdeza833c352016-11-01 13:39:36 -04001313 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001314 case extensionSessionTicket:
1315 if length > 0 {
1316 return false
1317 }
1318 m.ticketSupported = true
1319 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001320 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001321 return false
1322 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001323 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001324 case extensionALPN:
1325 d := data[:length]
1326 if len(d) < 3 {
1327 return false
1328 }
1329 l := int(d[0])<<8 | int(d[1])
1330 if l != len(d)-2 {
1331 return false
1332 }
1333 d = d[2:]
1334 l = int(d[0])
1335 if l != len(d)-1 {
1336 return false
1337 }
1338 d = d[1:]
1339 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001340 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001341 case extensionChannelID:
1342 if length > 0 {
1343 return false
1344 }
1345 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001346 case extensionExtendedMasterSecret:
1347 if length != 0 {
1348 return false
1349 }
1350 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001351 case extensionUseSRTP:
1352 if length < 2+2+1 {
1353 return false
1354 }
1355 if data[0] != 0 || data[1] != 2 {
1356 return false
1357 }
1358 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1359 d := data[4:length]
1360 l := int(d[0])
1361 if l != len(d)-1 {
1362 return false
1363 }
1364 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001365 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001366 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001367 case extensionCustom:
1368 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001369 case extensionServerName:
1370 if length != 0 {
1371 return false
1372 }
David Benjamin023d4192017-02-06 13:49:07 -05001373 m.serverNameAck = true
David Benjamin46f94bd2016-07-14 16:43:37 -04001374 case extensionSupportedPoints:
1375 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001376 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001377 return false
1378 }
David Benjamina81967b2016-12-22 09:16:57 -05001379 // http://tools.ietf.org/html/rfc4492#section-5.5.2
1380 if length < 1 {
1381 return false
1382 }
1383 l := int(data[0])
1384 if length != l+1 {
1385 return false
1386 }
1387 m.supportedPoints = data[1 : 1+l]
David Benjamin4ee027f2016-07-17 12:34:41 +02001388 case extensionSupportedCurves:
1389 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001390 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001391 return false
1392 }
Nick Harperf2511f12016-12-06 16:02:31 -08001393 case extensionEarlyData:
1394 if version < VersionTLS13 || length != 0 {
1395 return false
1396 }
1397 m.hasEarlyData = true
David Benjamin46f94bd2016-07-14 16:43:37 -04001398 default:
1399 // Unknown extensions are illegal from the server.
1400 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001401 }
1402 data = data[length:]
1403 }
1404
1405 return true
1406}
1407
Nick Harperdcfbc672016-07-16 17:47:31 +02001408type helloRetryRequestMsg struct {
David Benjamin3baa6e12016-10-07 21:10:38 -04001409 raw []byte
1410 vers uint16
1411 hasSelectedGroup bool
1412 selectedGroup CurveID
1413 cookie []byte
1414 customExtension string
1415 duplicateExtensions bool
Nick Harperdcfbc672016-07-16 17:47:31 +02001416}
1417
1418func (m *helloRetryRequestMsg) marshal() []byte {
1419 if m.raw != nil {
1420 return m.raw
1421 }
1422
1423 retryRequestMsg := newByteBuilder()
1424 retryRequestMsg.addU8(typeHelloRetryRequest)
1425 retryRequest := retryRequestMsg.addU24LengthPrefixed()
1426 retryRequest.addU16(m.vers)
David Benjamin3baa6e12016-10-07 21:10:38 -04001427 extensions := retryRequest.addU16LengthPrefixed()
1428
1429 count := 1
1430 if m.duplicateExtensions {
1431 count = 2
1432 }
1433
1434 for i := 0; i < count; i++ {
1435 if m.hasSelectedGroup {
1436 extensions.addU16(extensionKeyShare)
1437 extensions.addU16(2) // length
1438 extensions.addU16(uint16(m.selectedGroup))
1439 }
1440 if len(m.cookie) > 0 {
1441 extensions.addU16(extensionCookie)
1442 body := extensions.addU16LengthPrefixed()
1443 body.addU16LengthPrefixed().addBytes(m.cookie)
1444 }
1445 if len(m.customExtension) > 0 {
1446 extensions.addU16(extensionCustom)
1447 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
1448 }
1449 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001450
1451 m.raw = retryRequestMsg.finish()
1452 return m.raw
1453}
1454
1455func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1456 m.raw = data
David Benjamin3baa6e12016-10-07 21:10:38 -04001457 if len(data) < 8 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001458 return false
1459 }
1460 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin3baa6e12016-10-07 21:10:38 -04001461 extLen := int(data[6])<<8 | int(data[7])
1462 data = data[8:]
1463 if len(data) != extLen || len(data) == 0 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001464 return false
1465 }
David Benjamin3baa6e12016-10-07 21:10:38 -04001466 for len(data) > 0 {
1467 if len(data) < 4 {
1468 return false
1469 }
1470 extension := uint16(data[0])<<8 | uint16(data[1])
1471 length := int(data[2])<<8 | int(data[3])
1472 data = data[4:]
1473 if len(data) < length {
1474 return false
1475 }
1476
1477 switch extension {
1478 case extensionKeyShare:
1479 if length != 2 {
1480 return false
1481 }
1482 m.hasSelectedGroup = true
1483 m.selectedGroup = CurveID(data[0])<<8 | CurveID(data[1])
1484 case extensionCookie:
1485 if length < 2 {
1486 return false
1487 }
1488 cookieLen := int(data[0])<<8 | int(data[1])
1489 if 2+cookieLen != length {
1490 return false
1491 }
1492 m.cookie = data[2 : 2+cookieLen]
1493 default:
1494 // Unknown extensions are illegal from the server.
1495 return false
1496 }
1497 data = data[length:]
1498 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001499 return true
1500}
1501
Steven Valdeza833c352016-11-01 13:39:36 -04001502type certificateEntry struct {
1503 data []byte
1504 ocspResponse []byte
1505 sctList []byte
1506 duplicateExtensions bool
1507 extraExtension []byte
1508}
1509
Adam Langley95c29f32014-06-20 12:00:00 -07001510type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001511 raw []byte
1512 hasRequestContext bool
1513 requestContext []byte
Steven Valdeza833c352016-11-01 13:39:36 -04001514 certificates []certificateEntry
Adam Langley95c29f32014-06-20 12:00:00 -07001515}
1516
Adam Langley95c29f32014-06-20 12:00:00 -07001517func (m *certificateMsg) marshal() (x []byte) {
1518 if m.raw != nil {
1519 return m.raw
1520 }
1521
Nick Harper7e0442a2016-07-01 17:40:09 -04001522 certMsg := newByteBuilder()
1523 certMsg.addU8(typeCertificate)
1524 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001525 if m.hasRequestContext {
1526 context := certificate.addU8LengthPrefixed()
1527 context.addBytes(m.requestContext)
1528 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001529 certificateList := certificate.addU24LengthPrefixed()
1530 for _, cert := range m.certificates {
1531 certEntry := certificateList.addU24LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001532 certEntry.addBytes(cert.data)
1533 if m.hasRequestContext {
1534 extensions := certificateList.addU16LengthPrefixed()
1535 count := 1
1536 if cert.duplicateExtensions {
1537 count = 2
1538 }
1539
1540 for i := 0; i < count; i++ {
1541 if cert.ocspResponse != nil {
1542 extensions.addU16(extensionStatusRequest)
1543 body := extensions.addU16LengthPrefixed()
1544 body.addU8(statusTypeOCSP)
1545 response := body.addU24LengthPrefixed()
1546 response.addBytes(cert.ocspResponse)
1547 }
1548
1549 if cert.sctList != nil {
1550 extensions.addU16(extensionSignedCertificateTimestamp)
1551 extension := extensions.addU16LengthPrefixed()
1552 extension.addBytes(cert.sctList)
1553 }
1554 }
1555 if cert.extraExtension != nil {
1556 extensions.addBytes(cert.extraExtension)
1557 }
1558 }
Adam Langley95c29f32014-06-20 12:00:00 -07001559 }
1560
Nick Harper7e0442a2016-07-01 17:40:09 -04001561 m.raw = certMsg.finish()
1562 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001563}
1564
1565func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001566 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001567 return false
1568 }
1569
1570 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001571 data = data[4:]
1572
1573 if m.hasRequestContext {
1574 if len(data) == 0 {
1575 return false
1576 }
1577 contextLen := int(data[0])
1578 if len(data) < 1+contextLen {
1579 return false
1580 }
1581 m.requestContext = make([]byte, contextLen)
1582 copy(m.requestContext, data[1:])
1583 data = data[1+contextLen:]
1584 }
1585
1586 if len(data) < 3 {
1587 return false
1588 }
1589 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1590 data = data[3:]
1591 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001592 return false
1593 }
1594
Steven Valdeza833c352016-11-01 13:39:36 -04001595 m.certificates = nil
1596 for len(data) != 0 {
1597 if len(data) < 3 {
Adam Langley95c29f32014-06-20 12:00:00 -07001598 return false
1599 }
Steven Valdeza833c352016-11-01 13:39:36 -04001600 certLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1601 if len(data) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001602 return false
1603 }
Steven Valdeza833c352016-11-01 13:39:36 -04001604 cert := certificateEntry{
1605 data: data[3 : 3+certLen],
1606 }
1607 data = data[3+certLen:]
1608 if m.hasRequestContext {
1609 if len(data) < 2 {
1610 return false
1611 }
1612 extensionsLen := int(data[0])<<8 | int(data[1])
1613 if len(data) < 2+extensionsLen {
1614 return false
1615 }
1616 extensions := data[2 : 2+extensionsLen]
1617 data = data[2+extensionsLen:]
1618 for len(extensions) != 0 {
1619 if len(extensions) < 4 {
1620 return false
1621 }
1622 extension := uint16(extensions[0])<<8 | uint16(extensions[1])
1623 length := int(extensions[2])<<8 | int(extensions[3])
1624 if len(extensions) < 4+length {
1625 return false
1626 }
1627 contents := extensions[4 : 4+length]
1628 extensions = extensions[4+length:]
Adam Langley95c29f32014-06-20 12:00:00 -07001629
Steven Valdeza833c352016-11-01 13:39:36 -04001630 switch extension {
1631 case extensionStatusRequest:
1632 if length < 4 {
1633 return false
1634 }
1635 if contents[0] != statusTypeOCSP {
1636 return false
1637 }
1638 respLen := int(contents[1])<<16 | int(contents[2])<<8 | int(contents[3])
1639 if respLen+4 != len(contents) || respLen == 0 {
1640 return false
1641 }
1642 cert.ocspResponse = contents[4:]
1643 case extensionSignedCertificateTimestamp:
1644 cert.sctList = contents
1645 default:
1646 return false
1647 }
1648 }
1649 }
1650 m.certificates = append(m.certificates, cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001651 }
1652
1653 return true
1654}
1655
1656type serverKeyExchangeMsg struct {
1657 raw []byte
1658 key []byte
1659}
1660
Adam Langley95c29f32014-06-20 12:00:00 -07001661func (m *serverKeyExchangeMsg) marshal() []byte {
1662 if m.raw != nil {
1663 return m.raw
1664 }
1665 length := len(m.key)
1666 x := make([]byte, length+4)
1667 x[0] = typeServerKeyExchange
1668 x[1] = uint8(length >> 16)
1669 x[2] = uint8(length >> 8)
1670 x[3] = uint8(length)
1671 copy(x[4:], m.key)
1672
1673 m.raw = x
1674 return x
1675}
1676
1677func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1678 m.raw = data
1679 if len(data) < 4 {
1680 return false
1681 }
1682 m.key = data[4:]
1683 return true
1684}
1685
1686type certificateStatusMsg struct {
1687 raw []byte
1688 statusType uint8
1689 response []byte
1690}
1691
Adam Langley95c29f32014-06-20 12:00:00 -07001692func (m *certificateStatusMsg) marshal() []byte {
1693 if m.raw != nil {
1694 return m.raw
1695 }
1696
1697 var x []byte
1698 if m.statusType == statusTypeOCSP {
1699 x = make([]byte, 4+4+len(m.response))
1700 x[0] = typeCertificateStatus
1701 l := len(m.response) + 4
1702 x[1] = byte(l >> 16)
1703 x[2] = byte(l >> 8)
1704 x[3] = byte(l)
1705 x[4] = statusTypeOCSP
1706
1707 l -= 4
1708 x[5] = byte(l >> 16)
1709 x[6] = byte(l >> 8)
1710 x[7] = byte(l)
1711 copy(x[8:], m.response)
1712 } else {
1713 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1714 }
1715
1716 m.raw = x
1717 return x
1718}
1719
1720func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1721 m.raw = data
1722 if len(data) < 5 {
1723 return false
1724 }
1725 m.statusType = data[4]
1726
1727 m.response = nil
1728 if m.statusType == statusTypeOCSP {
1729 if len(data) < 8 {
1730 return false
1731 }
1732 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1733 if uint32(len(data)) != 4+4+respLen {
1734 return false
1735 }
1736 m.response = data[8:]
1737 }
1738 return true
1739}
1740
1741type serverHelloDoneMsg struct{}
1742
Adam Langley95c29f32014-06-20 12:00:00 -07001743func (m *serverHelloDoneMsg) marshal() []byte {
1744 x := make([]byte, 4)
1745 x[0] = typeServerHelloDone
1746 return x
1747}
1748
1749func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1750 return len(data) == 4
1751}
1752
1753type clientKeyExchangeMsg struct {
1754 raw []byte
1755 ciphertext []byte
1756}
1757
Adam Langley95c29f32014-06-20 12:00:00 -07001758func (m *clientKeyExchangeMsg) marshal() []byte {
1759 if m.raw != nil {
1760 return m.raw
1761 }
1762 length := len(m.ciphertext)
1763 x := make([]byte, length+4)
1764 x[0] = typeClientKeyExchange
1765 x[1] = uint8(length >> 16)
1766 x[2] = uint8(length >> 8)
1767 x[3] = uint8(length)
1768 copy(x[4:], m.ciphertext)
1769
1770 m.raw = x
1771 return x
1772}
1773
1774func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1775 m.raw = data
1776 if len(data) < 4 {
1777 return false
1778 }
1779 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1780 if l != len(data)-4 {
1781 return false
1782 }
1783 m.ciphertext = data[4:]
1784 return true
1785}
1786
1787type finishedMsg struct {
1788 raw []byte
1789 verifyData []byte
1790}
1791
Adam Langley95c29f32014-06-20 12:00:00 -07001792func (m *finishedMsg) marshal() (x []byte) {
1793 if m.raw != nil {
1794 return m.raw
1795 }
1796
1797 x = make([]byte, 4+len(m.verifyData))
1798 x[0] = typeFinished
1799 x[3] = byte(len(m.verifyData))
1800 copy(x[4:], m.verifyData)
1801 m.raw = x
1802 return
1803}
1804
1805func (m *finishedMsg) unmarshal(data []byte) bool {
1806 m.raw = data
1807 if len(data) < 4 {
1808 return false
1809 }
1810 m.verifyData = data[4:]
1811 return true
1812}
1813
1814type nextProtoMsg struct {
1815 raw []byte
1816 proto string
1817}
1818
Adam Langley95c29f32014-06-20 12:00:00 -07001819func (m *nextProtoMsg) marshal() []byte {
1820 if m.raw != nil {
1821 return m.raw
1822 }
1823 l := len(m.proto)
1824 if l > 255 {
1825 l = 255
1826 }
1827
1828 padding := 32 - (l+2)%32
1829 length := l + padding + 2
1830 x := make([]byte, length+4)
1831 x[0] = typeNextProtocol
1832 x[1] = uint8(length >> 16)
1833 x[2] = uint8(length >> 8)
1834 x[3] = uint8(length)
1835
1836 y := x[4:]
1837 y[0] = byte(l)
1838 copy(y[1:], []byte(m.proto[0:l]))
1839 y = y[1+l:]
1840 y[0] = byte(padding)
1841
1842 m.raw = x
1843
1844 return x
1845}
1846
1847func (m *nextProtoMsg) unmarshal(data []byte) bool {
1848 m.raw = data
1849
1850 if len(data) < 5 {
1851 return false
1852 }
1853 data = data[4:]
1854 protoLen := int(data[0])
1855 data = data[1:]
1856 if len(data) < protoLen {
1857 return false
1858 }
1859 m.proto = string(data[0:protoLen])
1860 data = data[protoLen:]
1861
1862 if len(data) < 1 {
1863 return false
1864 }
1865 paddingLen := int(data[0])
1866 data = data[1:]
1867 if len(data) != paddingLen {
1868 return false
1869 }
1870
1871 return true
1872}
1873
1874type certificateRequestMsg struct {
1875 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001876 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001877 // of signature and hash functions. This change was introduced with TLS
1878 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001879 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001880 // hasRequestContext indicates whether this message includes a context
1881 // field instead of certificateTypes. This change was introduced with
1882 // TLS 1.3.
1883 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001884
1885 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001886 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001887 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001888 certificateAuthorities [][]byte
1889}
1890
Nick Harper7e0442a2016-07-01 17:40:09 -04001891func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001892 if m.raw != nil {
1893 return m.raw
1894 }
1895
1896 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001897 builder := newByteBuilder()
1898 builder.addU8(typeCertificateRequest)
1899 body := builder.addU24LengthPrefixed()
1900
Nick Harperb41d2e42016-07-01 17:50:32 -04001901 if m.hasRequestContext {
1902 requestContext := body.addU8LengthPrefixed()
1903 requestContext.addBytes(m.requestContext)
1904 } else {
1905 certificateTypes := body.addU8LengthPrefixed()
1906 certificateTypes.addBytes(m.certificateTypes)
1907 }
Adam Langley95c29f32014-06-20 12:00:00 -07001908
Nick Harper60edffd2016-06-21 15:19:24 -07001909 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001910 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001911 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001912 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001913 }
1914 }
1915
Nick Harper7e0442a2016-07-01 17:40:09 -04001916 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001917 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001918 caEntry := certificateAuthorities.addU16LengthPrefixed()
1919 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001920 }
1921
David Benjamin8d343b42016-07-09 14:26:01 -07001922 if m.hasRequestContext {
1923 // Emit no certificate extensions.
1924 body.addU16(0)
1925 }
1926
Nick Harper7e0442a2016-07-01 17:40:09 -04001927 m.raw = builder.finish()
1928 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001929}
1930
1931func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1932 m.raw = data
1933
1934 if len(data) < 5 {
1935 return false
1936 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001937 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001938
Nick Harperb41d2e42016-07-01 17:50:32 -04001939 if m.hasRequestContext {
1940 contextLen := int(data[0])
1941 if len(data) < 1+contextLen {
1942 return false
1943 }
1944 m.requestContext = make([]byte, contextLen)
1945 copy(m.requestContext, data[1:])
1946 data = data[1+contextLen:]
1947 } else {
1948 numCertTypes := int(data[0])
1949 if len(data) < 1+numCertTypes {
1950 return false
1951 }
1952 m.certificateTypes = make([]byte, numCertTypes)
1953 copy(m.certificateTypes, data[1:])
1954 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001955 }
1956
Nick Harper60edffd2016-06-21 15:19:24 -07001957 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001958 if len(data) < 2 {
1959 return false
1960 }
Nick Harper60edffd2016-06-21 15:19:24 -07001961 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001962 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001963 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001964 return false
1965 }
Nick Harper60edffd2016-06-21 15:19:24 -07001966 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001967 return false
1968 }
Nick Harper60edffd2016-06-21 15:19:24 -07001969 numSigAlgs := sigAlgsLen / 2
1970 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1971 for i := range m.signatureAlgorithms {
1972 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001973 data = data[2:]
1974 }
1975 }
1976
1977 if len(data) < 2 {
1978 return false
1979 }
1980 casLength := uint16(data[0])<<8 | uint16(data[1])
1981 data = data[2:]
1982 if len(data) < int(casLength) {
1983 return false
1984 }
1985 cas := make([]byte, casLength)
1986 copy(cas, data)
1987 data = data[casLength:]
1988
1989 m.certificateAuthorities = nil
1990 for len(cas) > 0 {
1991 if len(cas) < 2 {
1992 return false
1993 }
1994 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1995 cas = cas[2:]
1996
1997 if len(cas) < int(caLen) {
1998 return false
1999 }
2000
2001 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
2002 cas = cas[caLen:]
2003 }
David Benjamin8d343b42016-07-09 14:26:01 -07002004
2005 if m.hasRequestContext {
2006 // Ignore certificate extensions.
2007 if len(data) < 2 {
2008 return false
2009 }
2010 extsLength := int(data[0])<<8 | int(data[1])
2011 if len(data) < 2+extsLength {
2012 return false
2013 }
2014 data = data[2+extsLength:]
2015 }
2016
Adam Langley95c29f32014-06-20 12:00:00 -07002017 if len(data) > 0 {
2018 return false
2019 }
2020
2021 return true
2022}
2023
2024type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07002025 raw []byte
2026 hasSignatureAlgorithm bool
2027 signatureAlgorithm signatureAlgorithm
2028 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07002029}
2030
Adam Langley95c29f32014-06-20 12:00:00 -07002031func (m *certificateVerifyMsg) marshal() (x []byte) {
2032 if m.raw != nil {
2033 return m.raw
2034 }
2035
2036 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
2037 siglength := len(m.signature)
2038 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07002039 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07002040 length += 2
2041 }
2042 x = make([]byte, 4+length)
2043 x[0] = typeCertificateVerify
2044 x[1] = uint8(length >> 16)
2045 x[2] = uint8(length >> 8)
2046 x[3] = uint8(length)
2047 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07002048 if m.hasSignatureAlgorithm {
2049 y[0] = byte(m.signatureAlgorithm >> 8)
2050 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07002051 y = y[2:]
2052 }
2053 y[0] = uint8(siglength >> 8)
2054 y[1] = uint8(siglength)
2055 copy(y[2:], m.signature)
2056
2057 m.raw = x
2058
2059 return
2060}
2061
2062func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
2063 m.raw = data
2064
2065 if len(data) < 6 {
2066 return false
2067 }
2068
2069 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2070 if uint32(len(data))-4 != length {
2071 return false
2072 }
2073
2074 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07002075 if m.hasSignatureAlgorithm {
2076 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07002077 data = data[2:]
2078 }
2079
2080 if len(data) < 2 {
2081 return false
2082 }
2083 siglength := int(data[0])<<8 + int(data[1])
2084 data = data[2:]
2085 if len(data) != siglength {
2086 return false
2087 }
2088
2089 m.signature = data
2090
2091 return true
2092}
2093
2094type newSessionTicketMsg struct {
David Benjamin9c33ae82017-01-08 06:04:43 -05002095 raw []byte
2096 version uint16
2097 ticketLifetime uint32
2098 ticketAgeAdd uint32
2099 ticket []byte
Nick Harperf2511f12016-12-06 16:02:31 -08002100 maxEarlyDataSize uint32
David Benjamin9c33ae82017-01-08 06:04:43 -05002101 customExtension string
2102 duplicateEarlyDataInfo bool
2103 hasGREASEExtension bool
Adam Langley95c29f32014-06-20 12:00:00 -07002104}
2105
David Benjamin58104882016-07-18 01:25:41 +02002106func (m *newSessionTicketMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07002107 if m.raw != nil {
2108 return m.raw
2109 }
2110
2111 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjamin58104882016-07-18 01:25:41 +02002112 ticketMsg := newByteBuilder()
2113 ticketMsg.addU8(typeNewSessionTicket)
2114 body := ticketMsg.addU24LengthPrefixed()
2115 body.addU32(m.ticketLifetime)
2116 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002117 body.addU32(m.ticketAgeAdd)
Steven Valdez5b986082016-09-01 12:29:49 -04002118 }
2119
2120 ticket := body.addU16LengthPrefixed()
2121 ticket.addBytes(m.ticket)
2122
2123 if m.version >= VersionTLS13 {
David Benjamin1286bee2016-10-07 15:25:06 -04002124 extensions := body.addU16LengthPrefixed()
Nick Harperf2511f12016-12-06 16:02:31 -08002125 if m.maxEarlyDataSize > 0 {
Steven Valdez08b65f42016-12-07 15:29:45 -05002126 extensions.addU16(extensionTicketEarlyDataInfo)
Nick Harperf2511f12016-12-06 16:02:31 -08002127 extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
David Benjamin9c33ae82017-01-08 06:04:43 -05002128 if m.duplicateEarlyDataInfo {
2129 extensions.addU16(extensionTicketEarlyDataInfo)
Nick Harperf2511f12016-12-06 16:02:31 -08002130 extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
David Benjamin9c33ae82017-01-08 06:04:43 -05002131 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002132 }
David Benjamin1286bee2016-10-07 15:25:06 -04002133 if len(m.customExtension) > 0 {
Steven Valdez08b65f42016-12-07 15:29:45 -05002134 extensions.addU16(extensionCustom)
David Benjamin1286bee2016-10-07 15:25:06 -04002135 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
2136 }
David Benjamin58104882016-07-18 01:25:41 +02002137 }
Adam Langley95c29f32014-06-20 12:00:00 -07002138
David Benjamin58104882016-07-18 01:25:41 +02002139 m.raw = ticketMsg.finish()
2140 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07002141}
2142
2143func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
2144 m.raw = data
2145
David Benjamin58104882016-07-18 01:25:41 +02002146 if len(data) < 8 {
2147 return false
2148 }
2149 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
2150 data = data[8:]
2151
2152 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002153 if len(data) < 4 {
David Benjamin58104882016-07-18 01:25:41 +02002154 return false
2155 }
Steven Valdeza833c352016-11-01 13:39:36 -04002156 m.ticketAgeAdd = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2157 data = data[4:]
David Benjamin58104882016-07-18 01:25:41 +02002158 }
2159
2160 if len(data) < 2 {
2161 return false
2162 }
2163 ticketLen := int(data[0])<<8 + int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002164 data = data[2:]
2165 if len(data) < ticketLen {
David Benjamin58104882016-07-18 01:25:41 +02002166 return false
2167 }
Steven Valdez5b986082016-09-01 12:29:49 -04002168
David Benjamin58104882016-07-18 01:25:41 +02002169 if m.version >= VersionTLS13 && ticketLen == 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07002170 return false
2171 }
2172
Steven Valdez5b986082016-09-01 12:29:49 -04002173 m.ticket = data[:ticketLen]
2174 data = data[ticketLen:]
2175
2176 if m.version >= VersionTLS13 {
2177 if len(data) < 2 {
2178 return false
2179 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002180
2181 extensionsLength := int(data[0])<<8 | int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002182 data = data[2:]
Steven Valdez08b65f42016-12-07 15:29:45 -05002183 if extensionsLength != len(data) {
Steven Valdez5b986082016-09-01 12:29:49 -04002184 return false
2185 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002186
Steven Valdez08b65f42016-12-07 15:29:45 -05002187 for len(data) != 0 {
2188 if len(data) < 4 {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002189 return false
2190 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002191 extension := uint16(data[0])<<8 | uint16(data[1])
2192 length := int(data[2])<<8 | int(data[3])
2193 data = data[4:]
2194 if len(data) < length {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002195 return false
2196 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002197
Steven Valdez08b65f42016-12-07 15:29:45 -05002198 switch extension {
2199 case extensionTicketEarlyDataInfo:
2200 if length != 4 {
2201 return false
2202 }
Nick Harperf2511f12016-12-06 16:02:31 -08002203 m.maxEarlyDataSize = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
Steven Valdez08b65f42016-12-07 15:29:45 -05002204 default:
2205 if isGREASEValue(extension) {
2206 m.hasGREASEExtension = true
2207 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002208 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002209
2210 data = data[length:]
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002211 }
Steven Valdez5b986082016-09-01 12:29:49 -04002212 }
2213
2214 if len(data) > 0 {
2215 return false
2216 }
Adam Langley95c29f32014-06-20 12:00:00 -07002217
2218 return true
2219}
2220
David Benjamind86c7672014-08-02 04:07:12 -04002221type v2ClientHelloMsg struct {
2222 raw []byte
2223 vers uint16
2224 cipherSuites []uint16
2225 sessionId []byte
2226 challenge []byte
2227}
2228
David Benjamind86c7672014-08-02 04:07:12 -04002229func (m *v2ClientHelloMsg) marshal() []byte {
2230 if m.raw != nil {
2231 return m.raw
2232 }
2233
2234 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
2235
2236 x := make([]byte, length)
2237 x[0] = 1
2238 x[1] = uint8(m.vers >> 8)
2239 x[2] = uint8(m.vers)
2240 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
2241 x[4] = uint8(len(m.cipherSuites) * 3)
2242 x[5] = uint8(len(m.sessionId) >> 8)
2243 x[6] = uint8(len(m.sessionId))
2244 x[7] = uint8(len(m.challenge) >> 8)
2245 x[8] = uint8(len(m.challenge))
2246 y := x[9:]
2247 for i, spec := range m.cipherSuites {
2248 y[i*3] = 0
2249 y[i*3+1] = uint8(spec >> 8)
2250 y[i*3+2] = uint8(spec)
2251 }
2252 y = y[len(m.cipherSuites)*3:]
2253 copy(y, m.sessionId)
2254 y = y[len(m.sessionId):]
2255 copy(y, m.challenge)
2256
2257 m.raw = x
2258
2259 return x
2260}
2261
David Benjamin83c0bc92014-08-04 01:23:53 -04002262type helloVerifyRequestMsg struct {
2263 raw []byte
2264 vers uint16
2265 cookie []byte
2266}
2267
David Benjamin83c0bc92014-08-04 01:23:53 -04002268func (m *helloVerifyRequestMsg) marshal() []byte {
2269 if m.raw != nil {
2270 return m.raw
2271 }
2272
2273 length := 2 + 1 + len(m.cookie)
2274
2275 x := make([]byte, 4+length)
2276 x[0] = typeHelloVerifyRequest
2277 x[1] = uint8(length >> 16)
2278 x[2] = uint8(length >> 8)
2279 x[3] = uint8(length)
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002280 vers := m.vers
David Benjamin83c0bc92014-08-04 01:23:53 -04002281 x[4] = uint8(vers >> 8)
2282 x[5] = uint8(vers)
2283 x[6] = uint8(len(m.cookie))
2284 copy(x[7:7+len(m.cookie)], m.cookie)
2285
2286 return x
2287}
2288
2289func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
2290 if len(data) < 4+2+1 {
2291 return false
2292 }
2293 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002294 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin83c0bc92014-08-04 01:23:53 -04002295 cookieLen := int(data[6])
2296 if cookieLen > 32 || len(data) != 7+cookieLen {
2297 return false
2298 }
2299 m.cookie = data[7 : 7+cookieLen]
2300
2301 return true
2302}
2303
David Benjamin24599a82016-06-30 18:56:53 -04002304type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04002305 raw []byte
2306 channelID []byte
2307}
2308
David Benjamin24599a82016-06-30 18:56:53 -04002309func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04002310 if m.raw != nil {
2311 return m.raw
2312 }
2313
2314 length := 2 + 2 + len(m.channelID)
2315
2316 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04002317 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04002318 x[1] = uint8(length >> 16)
2319 x[2] = uint8(length >> 8)
2320 x[3] = uint8(length)
2321 x[4] = uint8(extensionChannelID >> 8)
2322 x[5] = uint8(extensionChannelID & 0xff)
2323 x[6] = uint8(len(m.channelID) >> 8)
2324 x[7] = uint8(len(m.channelID) & 0xff)
2325 copy(x[8:], m.channelID)
2326
2327 return x
2328}
2329
David Benjamin24599a82016-06-30 18:56:53 -04002330func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04002331 if len(data) != 4+2+2+128 {
2332 return false
2333 }
2334 m.raw = data
2335 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
2336 return false
2337 }
2338 if int(data[6])<<8|int(data[7]) != 128 {
2339 return false
2340 }
2341 m.channelID = data[4+2+2:]
2342
2343 return true
2344}
2345
Adam Langley2ae77d22014-10-28 17:29:33 -07002346type helloRequestMsg struct {
2347}
2348
2349func (*helloRequestMsg) marshal() []byte {
2350 return []byte{typeHelloRequest, 0, 0, 0}
2351}
2352
2353func (*helloRequestMsg) unmarshal(data []byte) bool {
2354 return len(data) == 4
2355}
2356
David Benjamin21c00282016-07-18 21:56:23 +02002357type keyUpdateMsg struct {
Steven Valdezc4aa7272016-10-03 12:25:56 -04002358 raw []byte
2359 keyUpdateRequest byte
David Benjamin21c00282016-07-18 21:56:23 +02002360}
2361
Steven Valdezc4aa7272016-10-03 12:25:56 -04002362func (m *keyUpdateMsg) marshal() []byte {
2363 if m.raw != nil {
2364 return m.raw
2365 }
2366
2367 return []byte{typeKeyUpdate, 0, 0, 1, m.keyUpdateRequest}
David Benjamin21c00282016-07-18 21:56:23 +02002368}
2369
Steven Valdezc4aa7272016-10-03 12:25:56 -04002370func (m *keyUpdateMsg) unmarshal(data []byte) bool {
2371 m.raw = data
2372
2373 if len(data) != 5 {
2374 return false
2375 }
2376
2377 length := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
2378 if len(data)-4 != length {
2379 return false
2380 }
2381
2382 m.keyUpdateRequest = data[4]
2383 return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
David Benjamin21c00282016-07-18 21:56:23 +02002384}
2385
David Benjamin053fee92017-01-02 08:30:36 -05002386// ssl3NoCertificateMsg is a dummy message to handle SSL 3.0 using a warning
2387// alert in the handshake.
2388type ssl3NoCertificateMsg struct{}
2389
Adam Langley95c29f32014-06-20 12:00:00 -07002390func eqUint16s(x, y []uint16) bool {
2391 if len(x) != len(y) {
2392 return false
2393 }
2394 for i, v := range x {
2395 if y[i] != v {
2396 return false
2397 }
2398 }
2399 return true
2400}
2401
2402func eqCurveIDs(x, y []CurveID) bool {
2403 if len(x) != len(y) {
2404 return false
2405 }
2406 for i, v := range x {
2407 if y[i] != v {
2408 return false
2409 }
2410 }
2411 return true
2412}
2413
2414func eqStrings(x, y []string) bool {
2415 if len(x) != len(y) {
2416 return false
2417 }
2418 for i, v := range x {
2419 if y[i] != v {
2420 return false
2421 }
2422 }
2423 return true
2424}
2425
2426func eqByteSlices(x, y [][]byte) bool {
2427 if len(x) != len(y) {
2428 return false
2429 }
2430 for i, v := range x {
2431 if !bytes.Equal(v, y[i]) {
2432 return false
2433 }
2434 }
2435 return true
2436}
2437
Nick Harper60edffd2016-06-21 15:19:24 -07002438func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07002439 if len(x) != len(y) {
2440 return false
2441 }
2442 for i, v := range x {
2443 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07002444 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07002445 return false
2446 }
2447 }
2448 return true
2449}
Nick Harperf8b0e702016-06-30 19:59:01 -04002450
2451func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2452 if len(x) != len(y) {
2453 return false
2454 }
2455 for i, v := range x {
2456 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2457 return false
2458 }
2459 }
2460 return true
2461
2462}
Steven Valdez5b986082016-09-01 12:29:49 -04002463
2464func eqPSKIdentityLists(x, y []pskIdentity) bool {
2465 if len(x) != len(y) {
2466 return false
2467 }
2468 for i, v := range x {
Steven Valdeza833c352016-11-01 13:39:36 -04002469 if !bytes.Equal(y[i].ticket, v.ticket) || y[i].obfuscatedTicketAge != v.obfuscatedTicketAge {
Steven Valdez5b986082016-09-01 12:29:49 -04002470 return false
2471 }
2472 }
2473 return true
2474
2475}