blob: 1141797c5bb991b20d8bcc576b480a2aced05db4 [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"
10)
Adam Langley95c29f32014-06-20 12:00:00 -070011
Nick Harper8dda5cc2016-06-30 18:51:11 -040012func writeLen(buf []byte, v, size int) {
13 for i := 0; i < size; i++ {
14 buf[size-i-1] = byte(v)
15 v >>= 8
16 }
17 if v != 0 {
18 panic("length is too long")
19 }
20}
21
22type byteBuilder struct {
23 buf *[]byte
24 start int
25 prefixLen int
26 child *byteBuilder
27}
28
29func newByteBuilder() *byteBuilder {
30 buf := make([]byte, 0, 32)
31 return &byteBuilder{buf: &buf}
32}
33
34func (bb *byteBuilder) len() int {
35 return len(*bb.buf) - bb.start - bb.prefixLen
36}
37
38func (bb *byteBuilder) flush() {
39 if bb.child == nil {
40 return
41 }
42 bb.child.flush()
43 writeLen((*bb.buf)[bb.child.start:], bb.child.len(), bb.child.prefixLen)
44 bb.child = nil
45 return
46}
47
48func (bb *byteBuilder) finish() []byte {
49 bb.flush()
50 return *bb.buf
51}
52
53func (bb *byteBuilder) addU8(u uint8) {
54 bb.flush()
55 *bb.buf = append(*bb.buf, u)
56}
57
58func (bb *byteBuilder) addU16(u uint16) {
59 bb.flush()
60 *bb.buf = append(*bb.buf, byte(u>>8), byte(u))
61}
62
63func (bb *byteBuilder) addU24(u int) {
64 bb.flush()
65 *bb.buf = append(*bb.buf, byte(u>>16), byte(u>>8), byte(u))
66}
67
68func (bb *byteBuilder) addU32(u uint32) {
69 bb.flush()
70 *bb.buf = append(*bb.buf, byte(u>>24), byte(u>>16), byte(u>>8), byte(u))
71}
72
Nick Harper0b3625b2016-07-25 16:16:28 -070073func (bb *byteBuilder) addU64(u uint64) {
74 bb.flush()
75 var b [8]byte
76 binary.BigEndian.PutUint64(b[:], u)
77 *bb.buf = append(*bb.buf, b[:]...)
78}
79
Nick Harper8dda5cc2016-06-30 18:51:11 -040080func (bb *byteBuilder) addU8LengthPrefixed() *byteBuilder {
81 return bb.createChild(1)
82}
83
84func (bb *byteBuilder) addU16LengthPrefixed() *byteBuilder {
85 return bb.createChild(2)
86}
87
88func (bb *byteBuilder) addU24LengthPrefixed() *byteBuilder {
89 return bb.createChild(3)
90}
91
Nick Harper0b3625b2016-07-25 16:16:28 -070092func (bb *byteBuilder) addU32LengthPrefixed() *byteBuilder {
93 return bb.createChild(4)
94}
95
Nick Harper8dda5cc2016-06-30 18:51:11 -040096func (bb *byteBuilder) addBytes(b []byte) {
97 bb.flush()
98 *bb.buf = append(*bb.buf, b...)
99}
100
101func (bb *byteBuilder) createChild(lengthPrefixSize int) *byteBuilder {
102 bb.flush()
103 bb.child = &byteBuilder{
104 buf: bb.buf,
105 start: len(*bb.buf),
106 prefixLen: lengthPrefixSize,
107 }
108 for i := 0; i < lengthPrefixSize; i++ {
109 *bb.buf = append(*bb.buf, 0)
110 }
111 return bb.child
112}
113
114func (bb *byteBuilder) discardChild() {
115 if bb.child != nil {
116 return
117 }
118 bb.child = nil
119 *bb.buf = (*bb.buf)[:bb.start]
120}
121
Nick Harperf8b0e702016-06-30 19:59:01 -0400122type keyShareEntry struct {
123 group CurveID
124 keyExchange []byte
125}
126
Steven Valdez5b986082016-09-01 12:29:49 -0400127type pskIdentity struct {
Steven Valdeza833c352016-11-01 13:39:36 -0400128 ticket []uint8
129 obfuscatedTicketAge uint32
Steven Valdez5b986082016-09-01 12:29:49 -0400130}
131
Adam Langley95c29f32014-06-20 12:00:00 -0700132type clientHelloMsg struct {
David Benjamin3baa6e12016-10-07 21:10:38 -0400133 raw []byte
134 isDTLS bool
135 vers uint16
136 random []byte
137 sessionId []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500138 cookie []byte
139 cipherSuites []uint16
140 compressionMethods []uint8
141 nextProtoNeg bool
142 serverName string
143 ocspStapling bool
144 supportedCurves []CurveID
145 supportedPoints []uint8
Nick Harperdcfbc672016-07-16 17:47:31 +0200146 hasKeyShares bool
Nick Harperf8b0e702016-06-30 19:59:01 -0400147 keyShares []keyShareEntry
David Benjamin7e1f9842016-09-20 19:24:40 -0400148 trailingKeyShareData bool
Steven Valdez5b986082016-09-01 12:29:49 -0400149 pskIdentities []pskIdentity
Steven Valdeza833c352016-11-01 13:39:36 -0400150 pskKEModes []byte
151 pskBinders [][]uint8
Nick Harperf8b0e702016-06-30 19:59:01 -0400152 hasEarlyData bool
David Benjamin3baa6e12016-10-07 21:10:38 -0400153 tls13Cookie []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500154 ticketSupported bool
155 sessionTicket []uint8
Nick Harper60edffd2016-06-21 15:19:24 -0700156 signatureAlgorithms []signatureAlgorithm
Steven Valdezfdd10992016-09-15 16:27:05 -0400157 supportedVersions []uint16
David Benjaminca6c8262014-11-15 19:06:08 -0500158 secureRenegotiation []byte
159 alpnProtocols []string
160 duplicateExtension bool
161 channelIDSupported bool
Steven Valdeza833c352016-11-01 13:39:36 -0400162 npnAfterAlpn bool
David Benjaminca6c8262014-11-15 19:06:08 -0500163 extendedMasterSecret bool
164 srtpProtectionProfiles []uint16
165 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -0500166 sctListSupported bool
Adam Langley09505632015-07-30 18:10:13 -0700167 customExtension string
David Benjamin65ac9972016-09-02 21:35:25 -0400168 hasGREASEExtension bool
Steven Valdeza833c352016-11-01 13:39:36 -0400169 pskBinderFirst bool
David Benjamin6f600d62016-12-21 16:06:54 -0500170 shortHeaderSupported bool
Adam Langley95c29f32014-06-20 12:00:00 -0700171}
172
173func (m *clientHelloMsg) equal(i interface{}) bool {
174 m1, ok := i.(*clientHelloMsg)
175 if !ok {
176 return false
177 }
178
179 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400180 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700181 m.vers == m1.vers &&
182 bytes.Equal(m.random, m1.random) &&
183 bytes.Equal(m.sessionId, m1.sessionId) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400184 bytes.Equal(m.cookie, m1.cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700185 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
186 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
187 m.nextProtoNeg == m1.nextProtoNeg &&
188 m.serverName == m1.serverName &&
189 m.ocspStapling == m1.ocspStapling &&
190 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
191 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
Nick Harperdcfbc672016-07-16 17:47:31 +0200192 m.hasKeyShares == m1.hasKeyShares &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400193 eqKeyShareEntryLists(m.keyShares, m1.keyShares) &&
David Benjamin7e1f9842016-09-20 19:24:40 -0400194 m.trailingKeyShareData == m1.trailingKeyShareData &&
Steven Valdez5b986082016-09-01 12:29:49 -0400195 eqPSKIdentityLists(m.pskIdentities, m1.pskIdentities) &&
Steven Valdeza833c352016-11-01 13:39:36 -0400196 bytes.Equal(m.pskKEModes, m1.pskKEModes) &&
197 eqByteSlices(m.pskBinders, m1.pskBinders) &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400198 m.hasEarlyData == m1.hasEarlyData &&
David Benjamin3baa6e12016-10-07 21:10:38 -0400199 bytes.Equal(m.tls13Cookie, m1.tls13Cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700200 m.ticketSupported == m1.ticketSupported &&
201 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
Nick Harper60edffd2016-06-21 15:19:24 -0700202 eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
Steven Valdezfdd10992016-09-15 16:27:05 -0400203 eqUint16s(m.supportedVersions, m1.supportedVersions) &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700204 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
205 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400206 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -0400207 m.duplicateExtension == m1.duplicateExtension &&
David Benjaminfc7b0862014-09-06 13:21:53 -0400208 m.channelIDSupported == m1.channelIDSupported &&
Steven Valdeza833c352016-11-01 13:39:36 -0400209 m.npnAfterAlpn == m1.npnAfterAlpn &&
David Benjaminca6c8262014-11-15 19:06:08 -0500210 m.extendedMasterSecret == m1.extendedMasterSecret &&
211 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
David Benjamin61f95272014-11-25 01:55:35 -0500212 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
Adam Langley09505632015-07-30 18:10:13 -0700213 m.sctListSupported == m1.sctListSupported &&
David Benjamin65ac9972016-09-02 21:35:25 -0400214 m.customExtension == m1.customExtension &&
Steven Valdeza833c352016-11-01 13:39:36 -0400215 m.hasGREASEExtension == m1.hasGREASEExtension &&
David Benjamin6f600d62016-12-21 16:06:54 -0500216 m.pskBinderFirst == m1.pskBinderFirst &&
217 m.shortHeaderSupported == m1.shortHeaderSupported
Adam Langley95c29f32014-06-20 12:00:00 -0700218}
219
220func (m *clientHelloMsg) marshal() []byte {
221 if m.raw != nil {
222 return m.raw
223 }
224
Nick Harper8dda5cc2016-06-30 18:51:11 -0400225 handshakeMsg := newByteBuilder()
226 handshakeMsg.addU8(typeClientHello)
227 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400228 hello.addU16(m.vers)
Nick Harper8dda5cc2016-06-30 18:51:11 -0400229 hello.addBytes(m.random)
230 sessionId := hello.addU8LengthPrefixed()
231 sessionId.addBytes(m.sessionId)
David Benjamin83c0bc92014-08-04 01:23:53 -0400232 if m.isDTLS {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400233 cookie := hello.addU8LengthPrefixed()
234 cookie.addBytes(m.cookie)
David Benjamin83c0bc92014-08-04 01:23:53 -0400235 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400236 cipherSuites := hello.addU16LengthPrefixed()
237 for _, suite := range m.cipherSuites {
238 cipherSuites.addU16(suite)
Adam Langley95c29f32014-06-20 12:00:00 -0700239 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400240 compressionMethods := hello.addU8LengthPrefixed()
241 compressionMethods.addBytes(m.compressionMethods)
Adam Langley95c29f32014-06-20 12:00:00 -0700242
Nick Harper8dda5cc2016-06-30 18:51:11 -0400243 extensions := hello.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -0400244 if len(m.pskIdentities) > 0 && m.pskBinderFirst {
245 extensions.addU16(extensionPreSharedKey)
246 pskExtension := extensions.addU16LengthPrefixed()
247
248 pskIdentities := pskExtension.addU16LengthPrefixed()
249 for _, psk := range m.pskIdentities {
250 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
251 pskIdentities.addU32(psk.obfuscatedTicketAge)
252 }
253 pskBinders := pskExtension.addU16LengthPrefixed()
254 for _, binder := range m.pskBinders {
255 pskBinders.addU8LengthPrefixed().addBytes(binder)
256 }
257 }
David Benjamin35a7a442014-07-05 00:23:20 -0400258 if m.duplicateExtension {
259 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400260 extensions.addU16(0xffff)
261 extensions.addU16(0) // 0-length for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400262 }
Steven Valdeza833c352016-11-01 13:39:36 -0400263 if m.nextProtoNeg && !m.npnAfterAlpn {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400264 extensions.addU16(extensionNextProtoNeg)
265 extensions.addU16(0) // The length is always 0
Adam Langley95c29f32014-06-20 12:00:00 -0700266 }
267 if len(m.serverName) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400268 extensions.addU16(extensionServerName)
269 serverNameList := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700270
271 // RFC 3546, section 3.1
272 //
273 // struct {
274 // NameType name_type;
275 // select (name_type) {
276 // case host_name: HostName;
277 // } name;
278 // } ServerName;
279 //
280 // enum {
281 // host_name(0), (255)
282 // } NameType;
283 //
284 // opaque HostName<1..2^16-1>;
285 //
286 // struct {
287 // ServerName server_name_list<1..2^16-1>
288 // } ServerNameList;
289
Nick Harper8dda5cc2016-06-30 18:51:11 -0400290 serverName := serverNameList.addU16LengthPrefixed()
291 serverName.addU8(0) // NameType host_name(0)
292 hostName := serverName.addU16LengthPrefixed()
293 hostName.addBytes([]byte(m.serverName))
Adam Langley95c29f32014-06-20 12:00:00 -0700294 }
295 if m.ocspStapling {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400296 extensions.addU16(extensionStatusRequest)
297 certificateStatusRequest := extensions.addU16LengthPrefixed()
298
Adam Langley95c29f32014-06-20 12:00:00 -0700299 // RFC 4366, section 3.6
Nick Harper8dda5cc2016-06-30 18:51:11 -0400300 certificateStatusRequest.addU8(1) // OCSP type
Adam Langley95c29f32014-06-20 12:00:00 -0700301 // Two zero valued uint16s for the two lengths.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400302 certificateStatusRequest.addU16(0) // ResponderID length
303 certificateStatusRequest.addU16(0) // Extensions length
Adam Langley95c29f32014-06-20 12:00:00 -0700304 }
305 if len(m.supportedCurves) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400306 // http://tools.ietf.org/html/rfc4492#section-5.1.1
307 extensions.addU16(extensionSupportedCurves)
308 supportedCurvesList := extensions.addU16LengthPrefixed()
309 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700310 for _, curve := range m.supportedCurves {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400311 supportedCurves.addU16(uint16(curve))
Adam Langley95c29f32014-06-20 12:00:00 -0700312 }
313 }
314 if len(m.supportedPoints) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400315 // http://tools.ietf.org/html/rfc4492#section-5.1.2
316 extensions.addU16(extensionSupportedPoints)
317 supportedPointsList := extensions.addU16LengthPrefixed()
318 supportedPoints := supportedPointsList.addU8LengthPrefixed()
David Benjamina81967b2016-12-22 09:16:57 -0500319 supportedPoints.addBytes(m.supportedPoints)
Adam Langley95c29f32014-06-20 12:00:00 -0700320 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200321 if m.hasKeyShares {
Nick Harperf8b0e702016-06-30 19:59:01 -0400322 extensions.addU16(extensionKeyShare)
323 keyShareList := extensions.addU16LengthPrefixed()
324
325 keyShares := keyShareList.addU16LengthPrefixed()
326 for _, keyShare := range m.keyShares {
327 keyShares.addU16(uint16(keyShare.group))
328 keyExchange := keyShares.addU16LengthPrefixed()
329 keyExchange.addBytes(keyShare.keyExchange)
330 }
David Benjamin7e1f9842016-09-20 19:24:40 -0400331
332 if m.trailingKeyShareData {
333 keyShares.addU8(0)
334 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400335 }
Steven Valdeza833c352016-11-01 13:39:36 -0400336 if len(m.pskKEModes) > 0 {
337 extensions.addU16(extensionPSKKeyExchangeModes)
338 pskModesExtension := extensions.addU16LengthPrefixed()
339 pskModesExtension.addU8LengthPrefixed().addBytes(m.pskKEModes)
Nick Harperf8b0e702016-06-30 19:59:01 -0400340 }
341 if m.hasEarlyData {
342 extensions.addU16(extensionEarlyData)
David Benjaminc5665c92016-11-15 18:12:58 +0900343 extensions.addU16(0) // The length is zero.
Nick Harperf8b0e702016-06-30 19:59:01 -0400344 }
David Benjamin3baa6e12016-10-07 21:10:38 -0400345 if len(m.tls13Cookie) > 0 {
346 extensions.addU16(extensionCookie)
347 body := extensions.addU16LengthPrefixed()
348 body.addU16LengthPrefixed().addBytes(m.tls13Cookie)
349 }
Adam Langley95c29f32014-06-20 12:00:00 -0700350 if m.ticketSupported {
351 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400352 extensions.addU16(extensionSessionTicket)
353 sessionTicketExtension := extensions.addU16LengthPrefixed()
354 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700355 }
Nick Harper60edffd2016-06-21 15:19:24 -0700356 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700357 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400358 extensions.addU16(extensionSignatureAlgorithms)
359 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
360 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700361 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400362 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700363 }
364 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400365 if len(m.supportedVersions) > 0 {
366 extensions.addU16(extensionSupportedVersions)
367 supportedVersionsExtension := extensions.addU16LengthPrefixed()
368 supportedVersions := supportedVersionsExtension.addU8LengthPrefixed()
369 for _, version := range m.supportedVersions {
370 supportedVersions.addU16(uint16(version))
371 }
372 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700373 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400374 extensions.addU16(extensionRenegotiationInfo)
375 secureRenegoExt := extensions.addU16LengthPrefixed()
376 secureRenego := secureRenegoExt.addU8LengthPrefixed()
377 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700378 }
David Benjaminfa055a22014-09-15 16:51:51 -0400379 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400380 // https://tools.ietf.org/html/rfc7301#section-3.1
381 extensions.addU16(extensionALPN)
382 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400383
Nick Harper8dda5cc2016-06-30 18:51:11 -0400384 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400385 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400386 protocolName := protocolNameList.addU8LengthPrefixed()
387 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400388 }
David Benjaminfa055a22014-09-15 16:51:51 -0400389 }
David Benjamind30a9902014-08-24 01:44:23 -0400390 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400391 extensions.addU16(extensionChannelID)
392 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400393 }
Steven Valdeza833c352016-11-01 13:39:36 -0400394 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400395 extensions.addU16(extensionNextProtoNeg)
396 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400397 }
David Benjamin35a7a442014-07-05 00:23:20 -0400398 if m.duplicateExtension {
399 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400400 extensions.addU16(0xffff)
401 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400402 }
Adam Langley75712922014-10-10 16:23:43 -0700403 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500404 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400405 extensions.addU16(extensionExtendedMasterSecret)
406 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700407 }
David Benjaminca6c8262014-11-15 19:06:08 -0500408 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400409 // https://tools.ietf.org/html/rfc5764#section-4.1.1
410 extensions.addU16(extensionUseSRTP)
411 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500412
Nick Harper8dda5cc2016-06-30 18:51:11 -0400413 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500414 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400415 // An SRTPProtectionProfile is defined as uint8[2],
416 // not uint16. For some reason, we're storing it
417 // as a uint16.
418 srtpProtectionProfiles.addU8(byte(p >> 8))
419 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500420 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400421 srtpMki := useSrtpExt.addU8LengthPrefixed()
422 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500423 }
David Benjamin61f95272014-11-25 01:55:35 -0500424 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400425 extensions.addU16(extensionSignedCertificateTimestamp)
426 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500427 }
Adam Langley09505632015-07-30 18:10:13 -0700428 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400429 extensions.addU16(extensionCustom)
430 customExt := extensions.addU16LengthPrefixed()
431 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700432 }
David Benjamin6f600d62016-12-21 16:06:54 -0500433 if m.shortHeaderSupported {
434 extensions.addU16(extensionShortHeader)
435 extensions.addU16(0) // Length is always 0
436 }
Steven Valdeza833c352016-11-01 13:39:36 -0400437 // The PSK extension must be last (draft-ietf-tls-tls13-18 section 4.2.6).
438 if len(m.pskIdentities) > 0 && !m.pskBinderFirst {
439 extensions.addU16(extensionPreSharedKey)
440 pskExtension := extensions.addU16LengthPrefixed()
441
442 pskIdentities := pskExtension.addU16LengthPrefixed()
443 for _, psk := range m.pskIdentities {
444 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
445 pskIdentities.addU32(psk.obfuscatedTicketAge)
446 }
447 pskBinders := pskExtension.addU16LengthPrefixed()
448 for _, binder := range m.pskBinders {
449 pskBinders.addU8LengthPrefixed().addBytes(binder)
450 }
451 }
Adam Langley95c29f32014-06-20 12:00:00 -0700452
Nick Harper8dda5cc2016-06-30 18:51:11 -0400453 if extensions.len() == 0 {
454 hello.discardChild()
455 }
Adam Langley95c29f32014-06-20 12:00:00 -0700456
Nick Harper8dda5cc2016-06-30 18:51:11 -0400457 m.raw = handshakeMsg.finish()
458 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700459}
460
461func (m *clientHelloMsg) unmarshal(data []byte) bool {
462 if len(data) < 42 {
463 return false
464 }
465 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400466 m.vers = uint16(data[4])<<8 | uint16(data[5])
Adam Langley95c29f32014-06-20 12:00:00 -0700467 m.random = data[6:38]
468 sessionIdLen := int(data[38])
469 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
470 return false
471 }
472 m.sessionId = data[39 : 39+sessionIdLen]
473 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400474 if m.isDTLS {
475 if len(data) < 1 {
476 return false
477 }
478 cookieLen := int(data[0])
479 if cookieLen > 32 || len(data) < 1+cookieLen {
480 return false
481 }
482 m.cookie = data[1 : 1+cookieLen]
483 data = data[1+cookieLen:]
484 }
Adam Langley95c29f32014-06-20 12:00:00 -0700485 if len(data) < 2 {
486 return false
487 }
488 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
489 // they are uint16s, the number must be even.
490 cipherSuiteLen := int(data[0])<<8 | int(data[1])
491 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
492 return false
493 }
494 numCipherSuites := cipherSuiteLen / 2
495 m.cipherSuites = make([]uint16, numCipherSuites)
496 for i := 0; i < numCipherSuites; i++ {
497 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
498 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700499 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700500 }
501 }
502 data = data[2+cipherSuiteLen:]
503 if len(data) < 1 {
504 return false
505 }
506 compressionMethodsLen := int(data[0])
507 if len(data) < 1+compressionMethodsLen {
508 return false
509 }
510 m.compressionMethods = data[1 : 1+compressionMethodsLen]
511
512 data = data[1+compressionMethodsLen:]
513
514 m.nextProtoNeg = false
515 m.serverName = ""
516 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400517 m.keyShares = nil
518 m.pskIdentities = nil
519 m.hasEarlyData = false
Adam Langley95c29f32014-06-20 12:00:00 -0700520 m.ticketSupported = false
521 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700522 m.signatureAlgorithms = nil
Steven Valdezfdd10992016-09-15 16:27:05 -0400523 m.supportedVersions = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400524 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700525 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700526 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700527
528 if len(data) == 0 {
529 // ClientHello is optionally followed by extension data
530 return true
531 }
532 if len(data) < 2 {
533 return false
534 }
535
536 extensionsLength := int(data[0])<<8 | int(data[1])
537 data = data[2:]
538 if extensionsLength != len(data) {
539 return false
540 }
541
542 for len(data) != 0 {
543 if len(data) < 4 {
544 return false
545 }
546 extension := uint16(data[0])<<8 | uint16(data[1])
547 length := int(data[2])<<8 | int(data[3])
548 data = data[4:]
549 if len(data) < length {
550 return false
551 }
552
553 switch extension {
554 case extensionServerName:
555 if length < 2 {
556 return false
557 }
558 numNames := int(data[0])<<8 | int(data[1])
559 d := data[2:]
560 for i := 0; i < numNames; i++ {
561 if len(d) < 3 {
562 return false
563 }
564 nameType := d[0]
565 nameLen := int(d[1])<<8 | int(d[2])
566 d = d[3:]
567 if len(d) < nameLen {
568 return false
569 }
570 if nameType == 0 {
571 m.serverName = string(d[0:nameLen])
572 break
573 }
574 d = d[nameLen:]
575 }
576 case extensionNextProtoNeg:
577 if length > 0 {
578 return false
579 }
580 m.nextProtoNeg = true
581 case extensionStatusRequest:
582 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
583 case extensionSupportedCurves:
584 // http://tools.ietf.org/html/rfc4492#section-5.5.1
585 if length < 2 {
586 return false
587 }
588 l := int(data[0])<<8 | int(data[1])
589 if l%2 == 1 || length != l+2 {
590 return false
591 }
592 numCurves := l / 2
593 m.supportedCurves = make([]CurveID, numCurves)
594 d := data[2:]
595 for i := 0; i < numCurves; i++ {
596 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
597 d = d[2:]
598 }
599 case extensionSupportedPoints:
600 // http://tools.ietf.org/html/rfc4492#section-5.5.2
601 if length < 1 {
602 return false
603 }
604 l := int(data[0])
605 if length != l+1 {
606 return false
607 }
David Benjamina81967b2016-12-22 09:16:57 -0500608 m.supportedPoints = data[1 : 1+l]
Adam Langley95c29f32014-06-20 12:00:00 -0700609 case extensionSessionTicket:
610 // http://tools.ietf.org/html/rfc5077#section-3.2
611 m.ticketSupported = true
612 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400613 case extensionKeyShare:
614 // draft-ietf-tls-tls13 section 6.3.2.3
615 if length < 2 {
616 return false
617 }
618 l := int(data[0])<<8 | int(data[1])
619 if l != length-2 {
620 return false
621 }
622 d := data[2:length]
Nick Harperdcfbc672016-07-16 17:47:31 +0200623 m.hasKeyShares = true
Nick Harperf8b0e702016-06-30 19:59:01 -0400624 for len(d) > 0 {
625 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
626 // key_exchange (2-byte length prefix with at least 1 byte of content).
627 if len(d) < 5 {
628 return false
629 }
630 entry := keyShareEntry{}
631 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
632 keyExchLen := int(d[2])<<8 | int(d[3])
633 d = d[4:]
634 if len(d) < keyExchLen {
635 return false
636 }
637 entry.keyExchange = d[:keyExchLen]
638 d = d[keyExchLen:]
639 m.keyShares = append(m.keyShares, entry)
640 }
641 case extensionPreSharedKey:
Steven Valdeza833c352016-11-01 13:39:36 -0400642 // draft-ietf-tls-tls13-18 section 4.2.6
Nick Harperf8b0e702016-06-30 19:59:01 -0400643 if length < 2 {
644 return false
645 }
646 l := int(data[0])<<8 | int(data[1])
Steven Valdeza833c352016-11-01 13:39:36 -0400647 d := data[2 : l+2]
648 // Parse PSK identities.
Nick Harperf8b0e702016-06-30 19:59:01 -0400649 for len(d) > 0 {
650 if len(d) < 2 {
651 return false
652 }
653 pskLen := int(d[0])<<8 | int(d[1])
654 d = d[2:]
Steven Valdez5b986082016-09-01 12:29:49 -0400655
Steven Valdeza833c352016-11-01 13:39:36 -0400656 if len(d) < pskLen+4 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400657 return false
658 }
Steven Valdeza833c352016-11-01 13:39:36 -0400659 ticket := d[:pskLen]
660 obfuscatedTicketAge := uint32(d[pskLen])<<24 | uint32(d[pskLen+1])<<16 | uint32(d[pskLen+2])<<8 | uint32(d[pskLen+3])
661 psk := pskIdentity{
662 ticket: ticket,
663 obfuscatedTicketAge: obfuscatedTicketAge,
664 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400665 m.pskIdentities = append(m.pskIdentities, psk)
Steven Valdeza833c352016-11-01 13:39:36 -0400666 d = d[pskLen+4:]
Nick Harperf8b0e702016-06-30 19:59:01 -0400667 }
Steven Valdeza833c352016-11-01 13:39:36 -0400668 d = data[l+2:]
669 if len(d) < 2 {
670 return false
671 }
672 l = int(d[0])<<8 | int(d[1])
673 d = d[2:]
674 if l != len(d) {
675 return false
676 }
677 // Parse PSK binders.
678 for len(d) > 0 {
679 if len(d) < 1 {
680 return false
681 }
682 binderLen := int(d[0])
683 d = d[1:]
684 if binderLen > len(d) {
685 return false
686 }
687 m.pskBinders = append(m.pskBinders, d[:binderLen])
688 d = d[binderLen:]
689 }
690
691 // There must be the same number of identities as binders.
692 if len(m.pskIdentities) != len(m.pskBinders) {
693 return false
694 }
695 case extensionPSKKeyExchangeModes:
696 // draft-ietf-tls-tls13-18 section 4.2.7
697 if length < 1 {
698 return false
699 }
700 l := int(data[0])
701 if l != length-1 {
702 return false
703 }
704 m.pskKEModes = data[1:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400705 case extensionEarlyData:
706 // draft-ietf-tls-tls13 section 6.3.2.5
David Benjaminc5665c92016-11-15 18:12:58 +0900707 if length != 0 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400708 return false
709 }
710 m.hasEarlyData = true
David Benjamin3baa6e12016-10-07 21:10:38 -0400711 case extensionCookie:
712 if length < 2 {
713 return false
714 }
715 l := int(data[0])<<8 | int(data[1])
716 if l != length-2 || l == 0 {
717 return false
718 }
719 m.tls13Cookie = data[2 : 2+l]
Adam Langley95c29f32014-06-20 12:00:00 -0700720 case extensionSignatureAlgorithms:
721 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
722 if length < 2 || length&1 != 0 {
723 return false
724 }
725 l := int(data[0])<<8 | int(data[1])
726 if l != length-2 {
727 return false
728 }
729 n := l / 2
730 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700731 m.signatureAlgorithms = make([]signatureAlgorithm, n)
732 for i := range m.signatureAlgorithms {
733 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700734 d = d[2:]
735 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400736 case extensionSupportedVersions:
737 if length < 1+2 {
738 return false
739 }
740 l := int(data[0])
741 if l != length-1 || l%2 == 1 || l < 2 {
742 return false
743 }
744 n := l / 2
745 d := data[1:]
746 m.supportedVersions = make([]uint16, n)
747 for i := range m.supportedVersions {
748 m.supportedVersions[i] = uint16(d[0])<<8 | uint16(d[1])
749 d = d[2:]
750 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700751 case extensionRenegotiationInfo:
752 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700753 return false
754 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700755 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400756 case extensionALPN:
757 if length < 2 {
758 return false
759 }
760 l := int(data[0])<<8 | int(data[1])
761 if l != length-2 {
762 return false
763 }
764 d := data[2:length]
765 for len(d) != 0 {
766 stringLen := int(d[0])
767 d = d[1:]
768 if stringLen == 0 || stringLen > len(d) {
769 return false
770 }
771 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
772 d = d[stringLen:]
773 }
David Benjamind30a9902014-08-24 01:44:23 -0400774 case extensionChannelID:
775 if length > 0 {
776 return false
777 }
778 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700779 case extensionExtendedMasterSecret:
780 if length != 0 {
781 return false
782 }
783 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500784 case extensionUseSRTP:
785 if length < 2 {
786 return false
787 }
788 l := int(data[0])<<8 | int(data[1])
789 if l > length-2 || l%2 != 0 {
790 return false
791 }
792 n := l / 2
793 m.srtpProtectionProfiles = make([]uint16, n)
794 d := data[2:length]
795 for i := 0; i < n; i++ {
796 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
797 d = d[2:]
798 }
799 if len(d) < 1 || int(d[0]) != len(d)-1 {
800 return false
801 }
802 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500803 case extensionSignedCertificateTimestamp:
804 if length != 0 {
805 return false
806 }
807 m.sctListSupported = true
David Benjamin6f600d62016-12-21 16:06:54 -0500808 case extensionShortHeader:
809 if length != 0 {
810 return false
811 }
812 m.shortHeaderSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700813 case extensionCustom:
814 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700815 }
816 data = data[length:]
David Benjamin65ac9972016-09-02 21:35:25 -0400817
818 if isGREASEValue(extension) {
819 m.hasGREASEExtension = true
820 }
Adam Langley95c29f32014-06-20 12:00:00 -0700821 }
822
823 return true
824}
825
826type serverHelloMsg struct {
Nick Harperf2511f12016-12-06 16:02:31 -0800827 raw []byte
828 isDTLS bool
829 vers uint16
830 versOverride uint16
831 random []byte
832 sessionId []byte
833 cipherSuite uint16
834 hasKeyShare bool
835 keyShare keyShareEntry
836 hasPSKIdentity bool
837 pskIdentity uint16
838 compressionMethod uint8
839 customExtension string
840 unencryptedALPN string
841 shortHeader bool
842 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700843}
844
Adam Langley95c29f32014-06-20 12:00:00 -0700845func (m *serverHelloMsg) marshal() []byte {
846 if m.raw != nil {
847 return m.raw
848 }
849
Nick Harper5212ef82016-06-30 19:26:07 -0400850 handshakeMsg := newByteBuilder()
851 handshakeMsg.addU8(typeServerHello)
852 hello := handshakeMsg.addU24LengthPrefixed()
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400853
854 // m.vers is used both to determine the format of the rest of the
855 // ServerHello and to override the value, so include a second version
856 // field.
857 vers, ok := wireToVersion(m.vers, m.isDTLS)
858 if !ok {
859 panic("unknown version")
860 }
861 if m.versOverride != 0 {
862 hello.addU16(m.versOverride)
863 } else {
864 hello.addU16(m.vers)
865 }
866
Nick Harper5212ef82016-06-30 19:26:07 -0400867 hello.addBytes(m.random)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400868 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400869 sessionId := hello.addU8LengthPrefixed()
870 sessionId.addBytes(m.sessionId)
871 }
Nick Harper5212ef82016-06-30 19:26:07 -0400872 hello.addU16(m.cipherSuite)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400873 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400874 hello.addU8(m.compressionMethod)
875 }
Adam Langley95c29f32014-06-20 12:00:00 -0700876
Nick Harper5212ef82016-06-30 19:26:07 -0400877 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400878
David Benjamin6f600d62016-12-21 16:06:54 -0500879 if m.shortHeader {
880 extensions.addU16(extensionShortHeader)
881 extensions.addU16(0) // Length
882 }
883
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400884 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400885 if m.hasKeyShare {
886 extensions.addU16(extensionKeyShare)
887 keyShare := extensions.addU16LengthPrefixed()
888 keyShare.addU16(uint16(m.keyShare.group))
889 keyExchange := keyShare.addU16LengthPrefixed()
890 keyExchange.addBytes(m.keyShare.keyExchange)
891 }
892 if m.hasPSKIdentity {
893 extensions.addU16(extensionPreSharedKey)
894 extensions.addU16(2) // Length
895 extensions.addU16(m.pskIdentity)
896 }
David Benjamin490469f2016-10-05 22:44:38 -0400897 if len(m.customExtension) > 0 {
898 extensions.addU16(extensionCustom)
899 customExt := extensions.addU16LengthPrefixed()
900 customExt.addBytes([]byte(m.customExtension))
901 }
902 if len(m.unencryptedALPN) > 0 {
903 extensions.addU16(extensionALPN)
904 extension := extensions.addU16LengthPrefixed()
905
906 protocolNameList := extension.addU16LengthPrefixed()
907 protocolName := protocolNameList.addU8LengthPrefixed()
908 protocolName.addBytes([]byte(m.unencryptedALPN))
909 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400910 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400911 m.extensions.marshal(extensions)
Nick Harperb41d2e42016-07-01 17:50:32 -0400912 if extensions.len() == 0 {
913 hello.discardChild()
914 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400915 }
916
917 m.raw = handshakeMsg.finish()
918 return m.raw
919}
920
921func (m *serverHelloMsg) unmarshal(data []byte) bool {
922 if len(data) < 42 {
923 return false
924 }
925 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400926 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400927 vers, ok := wireToVersion(m.vers, m.isDTLS)
928 if !ok {
929 return false
930 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400931 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400932 data = data[38:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400933 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400934 sessionIdLen := int(data[0])
935 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
936 return false
937 }
938 m.sessionId = data[1 : 1+sessionIdLen]
939 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400940 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400941 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400942 return false
943 }
944 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400945 data = data[2:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400946 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400947 if len(data) < 1 {
948 return false
949 }
950 m.compressionMethod = data[0]
951 data = data[1:]
952 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400953
David Benjamin8d315d72016-07-18 01:03:18 +0200954 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400955 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400956 m.extensions = serverExtensions{}
957 return true
958 }
959 if len(data) < 2 {
960 return false
961 }
962
963 extensionsLength := int(data[0])<<8 | int(data[1])
964 data = data[2:]
965 if len(data) != extensionsLength {
966 return false
967 }
968
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400969 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400970 for len(data) != 0 {
971 if len(data) < 4 {
972 return false
973 }
974 extension := uint16(data[0])<<8 | uint16(data[1])
975 length := int(data[2])<<8 | int(data[3])
976 data = data[4:]
977
978 if len(data) < length {
979 return false
980 }
981 d := data[:length]
982 data = data[length:]
983
984 switch extension {
985 case extensionKeyShare:
986 m.hasKeyShare = true
987 if len(d) < 4 {
988 return false
989 }
990 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
991 keyExchLen := int(d[2])<<8 | int(d[3])
992 if keyExchLen != len(d)-4 {
993 return false
994 }
995 m.keyShare.keyExchange = make([]byte, keyExchLen)
996 copy(m.keyShare.keyExchange, d[4:])
997 case extensionPreSharedKey:
998 if len(d) != 2 {
999 return false
1000 }
1001 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
1002 m.hasPSKIdentity = true
David Benjamin6f600d62016-12-21 16:06:54 -05001003 case extensionShortHeader:
1004 if len(d) != 0 {
1005 return false
1006 }
1007 m.shortHeader = true
Nick Harperb41d2e42016-07-01 17:50:32 -04001008 default:
1009 // Only allow the 3 extensions that are sent in
1010 // the clear in TLS 1.3.
1011 return false
1012 }
1013 }
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001014 } else if !m.extensions.unmarshal(data, vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -04001015 return false
1016 }
1017
1018 return true
1019}
1020
Nick Harperb41d2e42016-07-01 17:50:32 -04001021type encryptedExtensionsMsg struct {
1022 raw []byte
1023 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -04001024 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001025}
1026
1027func (m *encryptedExtensionsMsg) marshal() []byte {
1028 if m.raw != nil {
1029 return m.raw
1030 }
1031
1032 encryptedExtensionsMsg := newByteBuilder()
1033 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
1034 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -04001035 if !m.empty {
1036 extensions := encryptedExtensions.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001037 m.extensions.marshal(extensions)
Steven Valdez143e8b32016-07-11 13:19:03 -04001038 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001039
1040 m.raw = encryptedExtensionsMsg.finish()
1041 return m.raw
1042}
1043
1044func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -04001045 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001046 if len(data) < 6 {
1047 return false
1048 }
1049 if data[0] != typeEncryptedExtensions {
1050 return false
1051 }
1052 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1053 data = data[4:]
1054 if len(data) != msgLen {
1055 return false
1056 }
1057 extLen := int(data[0])<<8 | int(data[1])
1058 data = data[2:]
1059 if extLen != len(data) {
1060 return false
1061 }
David Benjamin44b33bc2016-07-01 22:40:23 -04001062 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -04001063}
1064
Nick Harperb3d51be2016-07-01 11:43:18 -04001065type serverExtensions struct {
1066 nextProtoNeg bool
1067 nextProtos []string
1068 ocspStapling bool
1069 ticketSupported bool
1070 secureRenegotiation []byte
1071 alpnProtocol string
1072 alpnProtocolEmpty bool
1073 duplicateExtension bool
1074 channelIDRequested bool
1075 extendedMasterSecret bool
1076 srtpProtectionProfile uint16
1077 srtpMasterKeyIdentifier string
1078 sctList []byte
1079 customExtension string
Steven Valdeza833c352016-11-01 13:39:36 -04001080 npnAfterAlpn bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001081 hasKeyShare bool
Nick Harperf2511f12016-12-06 16:02:31 -08001082 hasEarlyData bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001083 keyShare keyShareEntry
David Benjamina81967b2016-12-22 09:16:57 -05001084 supportedPoints []uint8
Nick Harperb3d51be2016-07-01 11:43:18 -04001085}
1086
Steven Valdeza833c352016-11-01 13:39:36 -04001087func (m *serverExtensions) marshal(extensions *byteBuilder) {
David Benjamin35a7a442014-07-05 00:23:20 -04001088 if m.duplicateExtension {
1089 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001090 extensions.addU16(0xffff)
1091 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -04001092 }
Steven Valdeza833c352016-11-01 13:39:36 -04001093 if m.nextProtoNeg && !m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001094 extensions.addU16(extensionNextProtoNeg)
1095 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001096
1097 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001098 if len(v) > 255 {
1099 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -07001100 }
Nick Harper5212ef82016-06-30 19:26:07 -04001101 npn := extension.addU8LengthPrefixed()
1102 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -07001103 }
1104 }
Steven Valdeza833c352016-11-01 13:39:36 -04001105 if m.ocspStapling {
1106 extensions.addU16(extensionStatusRequest)
1107 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001108 }
1109 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -04001110 extensions.addU16(extensionSessionTicket)
1111 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001112 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001113 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001114 extensions.addU16(extensionRenegotiationInfo)
1115 extension := extensions.addU16LengthPrefixed()
1116 secureRenego := extension.addU8LengthPrefixed()
1117 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -07001118 }
Nick Harper5212ef82016-06-30 19:26:07 -04001119 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
1120 extensions.addU16(extensionALPN)
1121 extension := extensions.addU16LengthPrefixed()
1122
1123 protocolNameList := extension.addU16LengthPrefixed()
1124 protocolName := protocolNameList.addU8LengthPrefixed()
1125 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -04001126 }
David Benjamind30a9902014-08-24 01:44:23 -04001127 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -04001128 extensions.addU16(extensionChannelID)
1129 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -04001130 }
David Benjamin35a7a442014-07-05 00:23:20 -04001131 if m.duplicateExtension {
1132 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001133 extensions.addU16(0xffff)
1134 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -04001135 }
Adam Langley75712922014-10-10 16:23:43 -07001136 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -04001137 extensions.addU16(extensionExtendedMasterSecret)
1138 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -07001139 }
David Benjaminca6c8262014-11-15 19:06:08 -05001140 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001141 extensions.addU16(extensionUseSRTP)
1142 extension := extensions.addU16LengthPrefixed()
1143
1144 srtpProtectionProfiles := extension.addU16LengthPrefixed()
1145 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
1146 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
1147 srtpMki := extension.addU8LengthPrefixed()
1148 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -05001149 }
David Benjamin61f95272014-11-25 01:55:35 -05001150 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001151 extensions.addU16(extensionSignedCertificateTimestamp)
1152 extension := extensions.addU16LengthPrefixed()
1153 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -05001154 }
Adam Langley09505632015-07-30 18:10:13 -07001155 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001156 extensions.addU16(extensionCustom)
1157 customExt := extensions.addU16LengthPrefixed()
1158 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -07001159 }
Steven Valdeza833c352016-11-01 13:39:36 -04001160 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001161 extensions.addU16(extensionNextProtoNeg)
1162 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -04001163
1164 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001165 if len(v) > 255 {
1166 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -04001167 }
Nick Harper5212ef82016-06-30 19:26:07 -04001168 npn := extension.addU8LengthPrefixed()
1169 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001170 }
1171 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001172 if m.hasKeyShare {
1173 extensions.addU16(extensionKeyShare)
1174 keyShare := extensions.addU16LengthPrefixed()
1175 keyShare.addU16(uint16(m.keyShare.group))
1176 keyExchange := keyShare.addU16LengthPrefixed()
1177 keyExchange.addBytes(m.keyShare.keyExchange)
1178 }
David Benjamina81967b2016-12-22 09:16:57 -05001179 if len(m.supportedPoints) > 0 {
1180 // http://tools.ietf.org/html/rfc4492#section-5.1.2
1181 extensions.addU16(extensionSupportedPoints)
1182 supportedPointsList := extensions.addU16LengthPrefixed()
1183 supportedPoints := supportedPointsList.addU8LengthPrefixed()
1184 supportedPoints.addBytes(m.supportedPoints)
1185 }
Nick Harperf2511f12016-12-06 16:02:31 -08001186 if m.hasEarlyData {
1187 extensions.addU16(extensionEarlyData)
1188 extensions.addBytes([]byte{0, 0})
1189 }
Adam Langley95c29f32014-06-20 12:00:00 -07001190}
1191
David Benjamin44b33bc2016-07-01 22:40:23 -04001192func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001193 // Reset all fields.
1194 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001195
1196 for len(data) != 0 {
1197 if len(data) < 4 {
1198 return false
1199 }
1200 extension := uint16(data[0])<<8 | uint16(data[1])
1201 length := int(data[2])<<8 | int(data[3])
1202 data = data[4:]
1203 if len(data) < length {
1204 return false
1205 }
1206
1207 switch extension {
1208 case extensionNextProtoNeg:
1209 m.nextProtoNeg = true
1210 d := data[:length]
1211 for len(d) > 0 {
1212 l := int(d[0])
1213 d = d[1:]
1214 if l == 0 || l > len(d) {
1215 return false
1216 }
1217 m.nextProtos = append(m.nextProtos, string(d[:l]))
1218 d = d[l:]
1219 }
1220 case extensionStatusRequest:
Steven Valdeza833c352016-11-01 13:39:36 -04001221 if length > 0 {
1222 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001223 }
Steven Valdeza833c352016-11-01 13:39:36 -04001224 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001225 case extensionSessionTicket:
1226 if length > 0 {
1227 return false
1228 }
1229 m.ticketSupported = true
1230 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001231 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001232 return false
1233 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001234 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001235 case extensionALPN:
1236 d := data[:length]
1237 if len(d) < 3 {
1238 return false
1239 }
1240 l := int(d[0])<<8 | int(d[1])
1241 if l != len(d)-2 {
1242 return false
1243 }
1244 d = d[2:]
1245 l = int(d[0])
1246 if l != len(d)-1 {
1247 return false
1248 }
1249 d = d[1:]
1250 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001251 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001252 case extensionChannelID:
1253 if length > 0 {
1254 return false
1255 }
1256 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001257 case extensionExtendedMasterSecret:
1258 if length != 0 {
1259 return false
1260 }
1261 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001262 case extensionUseSRTP:
1263 if length < 2+2+1 {
1264 return false
1265 }
1266 if data[0] != 0 || data[1] != 2 {
1267 return false
1268 }
1269 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1270 d := data[4:length]
1271 l := int(d[0])
1272 if l != len(d)-1 {
1273 return false
1274 }
1275 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001276 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001277 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001278 case extensionCustom:
1279 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001280 case extensionServerName:
1281 if length != 0 {
1282 return false
1283 }
1284 // Ignore this extension from the server.
1285 case extensionSupportedPoints:
1286 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001287 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001288 return false
1289 }
David Benjamina81967b2016-12-22 09:16:57 -05001290 // http://tools.ietf.org/html/rfc4492#section-5.5.2
1291 if length < 1 {
1292 return false
1293 }
1294 l := int(data[0])
1295 if length != l+1 {
1296 return false
1297 }
1298 m.supportedPoints = data[1 : 1+l]
David Benjamin4ee027f2016-07-17 12:34:41 +02001299 case extensionSupportedCurves:
1300 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001301 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001302 return false
1303 }
Nick Harperf2511f12016-12-06 16:02:31 -08001304 case extensionEarlyData:
1305 if version < VersionTLS13 || length != 0 {
1306 return false
1307 }
1308 m.hasEarlyData = true
David Benjamin46f94bd2016-07-14 16:43:37 -04001309 default:
1310 // Unknown extensions are illegal from the server.
1311 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001312 }
1313 data = data[length:]
1314 }
1315
1316 return true
1317}
1318
Nick Harperdcfbc672016-07-16 17:47:31 +02001319type helloRetryRequestMsg struct {
David Benjamin3baa6e12016-10-07 21:10:38 -04001320 raw []byte
1321 vers uint16
1322 hasSelectedGroup bool
1323 selectedGroup CurveID
1324 cookie []byte
1325 customExtension string
1326 duplicateExtensions bool
Nick Harperdcfbc672016-07-16 17:47:31 +02001327}
1328
1329func (m *helloRetryRequestMsg) marshal() []byte {
1330 if m.raw != nil {
1331 return m.raw
1332 }
1333
1334 retryRequestMsg := newByteBuilder()
1335 retryRequestMsg.addU8(typeHelloRetryRequest)
1336 retryRequest := retryRequestMsg.addU24LengthPrefixed()
1337 retryRequest.addU16(m.vers)
David Benjamin3baa6e12016-10-07 21:10:38 -04001338 extensions := retryRequest.addU16LengthPrefixed()
1339
1340 count := 1
1341 if m.duplicateExtensions {
1342 count = 2
1343 }
1344
1345 for i := 0; i < count; i++ {
1346 if m.hasSelectedGroup {
1347 extensions.addU16(extensionKeyShare)
1348 extensions.addU16(2) // length
1349 extensions.addU16(uint16(m.selectedGroup))
1350 }
1351 if len(m.cookie) > 0 {
1352 extensions.addU16(extensionCookie)
1353 body := extensions.addU16LengthPrefixed()
1354 body.addU16LengthPrefixed().addBytes(m.cookie)
1355 }
1356 if len(m.customExtension) > 0 {
1357 extensions.addU16(extensionCustom)
1358 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
1359 }
1360 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001361
1362 m.raw = retryRequestMsg.finish()
1363 return m.raw
1364}
1365
1366func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1367 m.raw = data
David Benjamin3baa6e12016-10-07 21:10:38 -04001368 if len(data) < 8 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001369 return false
1370 }
1371 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin3baa6e12016-10-07 21:10:38 -04001372 extLen := int(data[6])<<8 | int(data[7])
1373 data = data[8:]
1374 if len(data) != extLen || len(data) == 0 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001375 return false
1376 }
David Benjamin3baa6e12016-10-07 21:10:38 -04001377 for len(data) > 0 {
1378 if len(data) < 4 {
1379 return false
1380 }
1381 extension := uint16(data[0])<<8 | uint16(data[1])
1382 length := int(data[2])<<8 | int(data[3])
1383 data = data[4:]
1384 if len(data) < length {
1385 return false
1386 }
1387
1388 switch extension {
1389 case extensionKeyShare:
1390 if length != 2 {
1391 return false
1392 }
1393 m.hasSelectedGroup = true
1394 m.selectedGroup = CurveID(data[0])<<8 | CurveID(data[1])
1395 case extensionCookie:
1396 if length < 2 {
1397 return false
1398 }
1399 cookieLen := int(data[0])<<8 | int(data[1])
1400 if 2+cookieLen != length {
1401 return false
1402 }
1403 m.cookie = data[2 : 2+cookieLen]
1404 default:
1405 // Unknown extensions are illegal from the server.
1406 return false
1407 }
1408 data = data[length:]
1409 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001410 return true
1411}
1412
Steven Valdeza833c352016-11-01 13:39:36 -04001413type certificateEntry struct {
1414 data []byte
1415 ocspResponse []byte
1416 sctList []byte
1417 duplicateExtensions bool
1418 extraExtension []byte
1419}
1420
Adam Langley95c29f32014-06-20 12:00:00 -07001421type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001422 raw []byte
1423 hasRequestContext bool
1424 requestContext []byte
Steven Valdeza833c352016-11-01 13:39:36 -04001425 certificates []certificateEntry
Adam Langley95c29f32014-06-20 12:00:00 -07001426}
1427
Adam Langley95c29f32014-06-20 12:00:00 -07001428func (m *certificateMsg) marshal() (x []byte) {
1429 if m.raw != nil {
1430 return m.raw
1431 }
1432
Nick Harper7e0442a2016-07-01 17:40:09 -04001433 certMsg := newByteBuilder()
1434 certMsg.addU8(typeCertificate)
1435 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001436 if m.hasRequestContext {
1437 context := certificate.addU8LengthPrefixed()
1438 context.addBytes(m.requestContext)
1439 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001440 certificateList := certificate.addU24LengthPrefixed()
1441 for _, cert := range m.certificates {
1442 certEntry := certificateList.addU24LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001443 certEntry.addBytes(cert.data)
1444 if m.hasRequestContext {
1445 extensions := certificateList.addU16LengthPrefixed()
1446 count := 1
1447 if cert.duplicateExtensions {
1448 count = 2
1449 }
1450
1451 for i := 0; i < count; i++ {
1452 if cert.ocspResponse != nil {
1453 extensions.addU16(extensionStatusRequest)
1454 body := extensions.addU16LengthPrefixed()
1455 body.addU8(statusTypeOCSP)
1456 response := body.addU24LengthPrefixed()
1457 response.addBytes(cert.ocspResponse)
1458 }
1459
1460 if cert.sctList != nil {
1461 extensions.addU16(extensionSignedCertificateTimestamp)
1462 extension := extensions.addU16LengthPrefixed()
1463 extension.addBytes(cert.sctList)
1464 }
1465 }
1466 if cert.extraExtension != nil {
1467 extensions.addBytes(cert.extraExtension)
1468 }
1469 }
Adam Langley95c29f32014-06-20 12:00:00 -07001470 }
1471
Nick Harper7e0442a2016-07-01 17:40:09 -04001472 m.raw = certMsg.finish()
1473 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001474}
1475
1476func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001477 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001478 return false
1479 }
1480
1481 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001482 data = data[4:]
1483
1484 if m.hasRequestContext {
1485 if len(data) == 0 {
1486 return false
1487 }
1488 contextLen := int(data[0])
1489 if len(data) < 1+contextLen {
1490 return false
1491 }
1492 m.requestContext = make([]byte, contextLen)
1493 copy(m.requestContext, data[1:])
1494 data = data[1+contextLen:]
1495 }
1496
1497 if len(data) < 3 {
1498 return false
1499 }
1500 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1501 data = data[3:]
1502 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001503 return false
1504 }
1505
Steven Valdeza833c352016-11-01 13:39:36 -04001506 m.certificates = nil
1507 for len(data) != 0 {
1508 if len(data) < 3 {
Adam Langley95c29f32014-06-20 12:00:00 -07001509 return false
1510 }
Steven Valdeza833c352016-11-01 13:39:36 -04001511 certLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1512 if len(data) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001513 return false
1514 }
Steven Valdeza833c352016-11-01 13:39:36 -04001515 cert := certificateEntry{
1516 data: data[3 : 3+certLen],
1517 }
1518 data = data[3+certLen:]
1519 if m.hasRequestContext {
1520 if len(data) < 2 {
1521 return false
1522 }
1523 extensionsLen := int(data[0])<<8 | int(data[1])
1524 if len(data) < 2+extensionsLen {
1525 return false
1526 }
1527 extensions := data[2 : 2+extensionsLen]
1528 data = data[2+extensionsLen:]
1529 for len(extensions) != 0 {
1530 if len(extensions) < 4 {
1531 return false
1532 }
1533 extension := uint16(extensions[0])<<8 | uint16(extensions[1])
1534 length := int(extensions[2])<<8 | int(extensions[3])
1535 if len(extensions) < 4+length {
1536 return false
1537 }
1538 contents := extensions[4 : 4+length]
1539 extensions = extensions[4+length:]
Adam Langley95c29f32014-06-20 12:00:00 -07001540
Steven Valdeza833c352016-11-01 13:39:36 -04001541 switch extension {
1542 case extensionStatusRequest:
1543 if length < 4 {
1544 return false
1545 }
1546 if contents[0] != statusTypeOCSP {
1547 return false
1548 }
1549 respLen := int(contents[1])<<16 | int(contents[2])<<8 | int(contents[3])
1550 if respLen+4 != len(contents) || respLen == 0 {
1551 return false
1552 }
1553 cert.ocspResponse = contents[4:]
1554 case extensionSignedCertificateTimestamp:
1555 cert.sctList = contents
1556 default:
1557 return false
1558 }
1559 }
1560 }
1561 m.certificates = append(m.certificates, cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001562 }
1563
1564 return true
1565}
1566
1567type serverKeyExchangeMsg struct {
1568 raw []byte
1569 key []byte
1570}
1571
Adam Langley95c29f32014-06-20 12:00:00 -07001572func (m *serverKeyExchangeMsg) marshal() []byte {
1573 if m.raw != nil {
1574 return m.raw
1575 }
1576 length := len(m.key)
1577 x := make([]byte, length+4)
1578 x[0] = typeServerKeyExchange
1579 x[1] = uint8(length >> 16)
1580 x[2] = uint8(length >> 8)
1581 x[3] = uint8(length)
1582 copy(x[4:], m.key)
1583
1584 m.raw = x
1585 return x
1586}
1587
1588func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1589 m.raw = data
1590 if len(data) < 4 {
1591 return false
1592 }
1593 m.key = data[4:]
1594 return true
1595}
1596
1597type certificateStatusMsg struct {
1598 raw []byte
1599 statusType uint8
1600 response []byte
1601}
1602
Adam Langley95c29f32014-06-20 12:00:00 -07001603func (m *certificateStatusMsg) marshal() []byte {
1604 if m.raw != nil {
1605 return m.raw
1606 }
1607
1608 var x []byte
1609 if m.statusType == statusTypeOCSP {
1610 x = make([]byte, 4+4+len(m.response))
1611 x[0] = typeCertificateStatus
1612 l := len(m.response) + 4
1613 x[1] = byte(l >> 16)
1614 x[2] = byte(l >> 8)
1615 x[3] = byte(l)
1616 x[4] = statusTypeOCSP
1617
1618 l -= 4
1619 x[5] = byte(l >> 16)
1620 x[6] = byte(l >> 8)
1621 x[7] = byte(l)
1622 copy(x[8:], m.response)
1623 } else {
1624 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1625 }
1626
1627 m.raw = x
1628 return x
1629}
1630
1631func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1632 m.raw = data
1633 if len(data) < 5 {
1634 return false
1635 }
1636 m.statusType = data[4]
1637
1638 m.response = nil
1639 if m.statusType == statusTypeOCSP {
1640 if len(data) < 8 {
1641 return false
1642 }
1643 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1644 if uint32(len(data)) != 4+4+respLen {
1645 return false
1646 }
1647 m.response = data[8:]
1648 }
1649 return true
1650}
1651
1652type serverHelloDoneMsg struct{}
1653
Adam Langley95c29f32014-06-20 12:00:00 -07001654func (m *serverHelloDoneMsg) marshal() []byte {
1655 x := make([]byte, 4)
1656 x[0] = typeServerHelloDone
1657 return x
1658}
1659
1660func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1661 return len(data) == 4
1662}
1663
1664type clientKeyExchangeMsg struct {
1665 raw []byte
1666 ciphertext []byte
1667}
1668
Adam Langley95c29f32014-06-20 12:00:00 -07001669func (m *clientKeyExchangeMsg) marshal() []byte {
1670 if m.raw != nil {
1671 return m.raw
1672 }
1673 length := len(m.ciphertext)
1674 x := make([]byte, length+4)
1675 x[0] = typeClientKeyExchange
1676 x[1] = uint8(length >> 16)
1677 x[2] = uint8(length >> 8)
1678 x[3] = uint8(length)
1679 copy(x[4:], m.ciphertext)
1680
1681 m.raw = x
1682 return x
1683}
1684
1685func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1686 m.raw = data
1687 if len(data) < 4 {
1688 return false
1689 }
1690 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1691 if l != len(data)-4 {
1692 return false
1693 }
1694 m.ciphertext = data[4:]
1695 return true
1696}
1697
1698type finishedMsg struct {
1699 raw []byte
1700 verifyData []byte
1701}
1702
Adam Langley95c29f32014-06-20 12:00:00 -07001703func (m *finishedMsg) marshal() (x []byte) {
1704 if m.raw != nil {
1705 return m.raw
1706 }
1707
1708 x = make([]byte, 4+len(m.verifyData))
1709 x[0] = typeFinished
1710 x[3] = byte(len(m.verifyData))
1711 copy(x[4:], m.verifyData)
1712 m.raw = x
1713 return
1714}
1715
1716func (m *finishedMsg) unmarshal(data []byte) bool {
1717 m.raw = data
1718 if len(data) < 4 {
1719 return false
1720 }
1721 m.verifyData = data[4:]
1722 return true
1723}
1724
1725type nextProtoMsg struct {
1726 raw []byte
1727 proto string
1728}
1729
Adam Langley95c29f32014-06-20 12:00:00 -07001730func (m *nextProtoMsg) marshal() []byte {
1731 if m.raw != nil {
1732 return m.raw
1733 }
1734 l := len(m.proto)
1735 if l > 255 {
1736 l = 255
1737 }
1738
1739 padding := 32 - (l+2)%32
1740 length := l + padding + 2
1741 x := make([]byte, length+4)
1742 x[0] = typeNextProtocol
1743 x[1] = uint8(length >> 16)
1744 x[2] = uint8(length >> 8)
1745 x[3] = uint8(length)
1746
1747 y := x[4:]
1748 y[0] = byte(l)
1749 copy(y[1:], []byte(m.proto[0:l]))
1750 y = y[1+l:]
1751 y[0] = byte(padding)
1752
1753 m.raw = x
1754
1755 return x
1756}
1757
1758func (m *nextProtoMsg) unmarshal(data []byte) bool {
1759 m.raw = data
1760
1761 if len(data) < 5 {
1762 return false
1763 }
1764 data = data[4:]
1765 protoLen := int(data[0])
1766 data = data[1:]
1767 if len(data) < protoLen {
1768 return false
1769 }
1770 m.proto = string(data[0:protoLen])
1771 data = data[protoLen:]
1772
1773 if len(data) < 1 {
1774 return false
1775 }
1776 paddingLen := int(data[0])
1777 data = data[1:]
1778 if len(data) != paddingLen {
1779 return false
1780 }
1781
1782 return true
1783}
1784
1785type certificateRequestMsg struct {
1786 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001787 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001788 // of signature and hash functions. This change was introduced with TLS
1789 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001790 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001791 // hasRequestContext indicates whether this message includes a context
1792 // field instead of certificateTypes. This change was introduced with
1793 // TLS 1.3.
1794 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001795
1796 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001797 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001798 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001799 certificateAuthorities [][]byte
1800}
1801
Nick Harper7e0442a2016-07-01 17:40:09 -04001802func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001803 if m.raw != nil {
1804 return m.raw
1805 }
1806
1807 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001808 builder := newByteBuilder()
1809 builder.addU8(typeCertificateRequest)
1810 body := builder.addU24LengthPrefixed()
1811
Nick Harperb41d2e42016-07-01 17:50:32 -04001812 if m.hasRequestContext {
1813 requestContext := body.addU8LengthPrefixed()
1814 requestContext.addBytes(m.requestContext)
1815 } else {
1816 certificateTypes := body.addU8LengthPrefixed()
1817 certificateTypes.addBytes(m.certificateTypes)
1818 }
Adam Langley95c29f32014-06-20 12:00:00 -07001819
Nick Harper60edffd2016-06-21 15:19:24 -07001820 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001821 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001822 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001823 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001824 }
1825 }
1826
Nick Harper7e0442a2016-07-01 17:40:09 -04001827 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001828 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001829 caEntry := certificateAuthorities.addU16LengthPrefixed()
1830 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001831 }
1832
David Benjamin8d343b42016-07-09 14:26:01 -07001833 if m.hasRequestContext {
1834 // Emit no certificate extensions.
1835 body.addU16(0)
1836 }
1837
Nick Harper7e0442a2016-07-01 17:40:09 -04001838 m.raw = builder.finish()
1839 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001840}
1841
1842func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1843 m.raw = data
1844
1845 if len(data) < 5 {
1846 return false
1847 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001848 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001849
Nick Harperb41d2e42016-07-01 17:50:32 -04001850 if m.hasRequestContext {
1851 contextLen := int(data[0])
1852 if len(data) < 1+contextLen {
1853 return false
1854 }
1855 m.requestContext = make([]byte, contextLen)
1856 copy(m.requestContext, data[1:])
1857 data = data[1+contextLen:]
1858 } else {
1859 numCertTypes := int(data[0])
1860 if len(data) < 1+numCertTypes {
1861 return false
1862 }
1863 m.certificateTypes = make([]byte, numCertTypes)
1864 copy(m.certificateTypes, data[1:])
1865 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001866 }
1867
Nick Harper60edffd2016-06-21 15:19:24 -07001868 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001869 if len(data) < 2 {
1870 return false
1871 }
Nick Harper60edffd2016-06-21 15:19:24 -07001872 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001873 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001874 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001875 return false
1876 }
Nick Harper60edffd2016-06-21 15:19:24 -07001877 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001878 return false
1879 }
Nick Harper60edffd2016-06-21 15:19:24 -07001880 numSigAlgs := sigAlgsLen / 2
1881 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1882 for i := range m.signatureAlgorithms {
1883 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001884 data = data[2:]
1885 }
1886 }
1887
1888 if len(data) < 2 {
1889 return false
1890 }
1891 casLength := uint16(data[0])<<8 | uint16(data[1])
1892 data = data[2:]
1893 if len(data) < int(casLength) {
1894 return false
1895 }
1896 cas := make([]byte, casLength)
1897 copy(cas, data)
1898 data = data[casLength:]
1899
1900 m.certificateAuthorities = nil
1901 for len(cas) > 0 {
1902 if len(cas) < 2 {
1903 return false
1904 }
1905 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1906 cas = cas[2:]
1907
1908 if len(cas) < int(caLen) {
1909 return false
1910 }
1911
1912 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1913 cas = cas[caLen:]
1914 }
David Benjamin8d343b42016-07-09 14:26:01 -07001915
1916 if m.hasRequestContext {
1917 // Ignore certificate extensions.
1918 if len(data) < 2 {
1919 return false
1920 }
1921 extsLength := int(data[0])<<8 | int(data[1])
1922 if len(data) < 2+extsLength {
1923 return false
1924 }
1925 data = data[2+extsLength:]
1926 }
1927
Adam Langley95c29f32014-06-20 12:00:00 -07001928 if len(data) > 0 {
1929 return false
1930 }
1931
1932 return true
1933}
1934
1935type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07001936 raw []byte
1937 hasSignatureAlgorithm bool
1938 signatureAlgorithm signatureAlgorithm
1939 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001940}
1941
Adam Langley95c29f32014-06-20 12:00:00 -07001942func (m *certificateVerifyMsg) marshal() (x []byte) {
1943 if m.raw != nil {
1944 return m.raw
1945 }
1946
1947 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1948 siglength := len(m.signature)
1949 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07001950 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001951 length += 2
1952 }
1953 x = make([]byte, 4+length)
1954 x[0] = typeCertificateVerify
1955 x[1] = uint8(length >> 16)
1956 x[2] = uint8(length >> 8)
1957 x[3] = uint8(length)
1958 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001959 if m.hasSignatureAlgorithm {
1960 y[0] = byte(m.signatureAlgorithm >> 8)
1961 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07001962 y = y[2:]
1963 }
1964 y[0] = uint8(siglength >> 8)
1965 y[1] = uint8(siglength)
1966 copy(y[2:], m.signature)
1967
1968 m.raw = x
1969
1970 return
1971}
1972
1973func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1974 m.raw = data
1975
1976 if len(data) < 6 {
1977 return false
1978 }
1979
1980 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1981 if uint32(len(data))-4 != length {
1982 return false
1983 }
1984
1985 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001986 if m.hasSignatureAlgorithm {
1987 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001988 data = data[2:]
1989 }
1990
1991 if len(data) < 2 {
1992 return false
1993 }
1994 siglength := int(data[0])<<8 + int(data[1])
1995 data = data[2:]
1996 if len(data) != siglength {
1997 return false
1998 }
1999
2000 m.signature = data
2001
2002 return true
2003}
2004
2005type newSessionTicketMsg struct {
David Benjamin9c33ae82017-01-08 06:04:43 -05002006 raw []byte
2007 version uint16
2008 ticketLifetime uint32
2009 ticketAgeAdd uint32
2010 ticket []byte
Nick Harperf2511f12016-12-06 16:02:31 -08002011 maxEarlyDataSize uint32
David Benjamin9c33ae82017-01-08 06:04:43 -05002012 customExtension string
2013 duplicateEarlyDataInfo bool
2014 hasGREASEExtension bool
Adam Langley95c29f32014-06-20 12:00:00 -07002015}
2016
David Benjamin58104882016-07-18 01:25:41 +02002017func (m *newSessionTicketMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07002018 if m.raw != nil {
2019 return m.raw
2020 }
2021
2022 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjamin58104882016-07-18 01:25:41 +02002023 ticketMsg := newByteBuilder()
2024 ticketMsg.addU8(typeNewSessionTicket)
2025 body := ticketMsg.addU24LengthPrefixed()
2026 body.addU32(m.ticketLifetime)
2027 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002028 body.addU32(m.ticketAgeAdd)
Steven Valdez5b986082016-09-01 12:29:49 -04002029 }
2030
2031 ticket := body.addU16LengthPrefixed()
2032 ticket.addBytes(m.ticket)
2033
2034 if m.version >= VersionTLS13 {
David Benjamin1286bee2016-10-07 15:25:06 -04002035 extensions := body.addU16LengthPrefixed()
Nick Harperf2511f12016-12-06 16:02:31 -08002036 if m.maxEarlyDataSize > 0 {
Steven Valdez08b65f42016-12-07 15:29:45 -05002037 extensions.addU16(extensionTicketEarlyDataInfo)
Nick Harperf2511f12016-12-06 16:02:31 -08002038 extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
David Benjamin9c33ae82017-01-08 06:04:43 -05002039 if m.duplicateEarlyDataInfo {
2040 extensions.addU16(extensionTicketEarlyDataInfo)
Nick Harperf2511f12016-12-06 16:02:31 -08002041 extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
David Benjamin9c33ae82017-01-08 06:04:43 -05002042 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002043 }
David Benjamin1286bee2016-10-07 15:25:06 -04002044 if len(m.customExtension) > 0 {
Steven Valdez08b65f42016-12-07 15:29:45 -05002045 extensions.addU16(extensionCustom)
David Benjamin1286bee2016-10-07 15:25:06 -04002046 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
2047 }
David Benjamin58104882016-07-18 01:25:41 +02002048 }
Adam Langley95c29f32014-06-20 12:00:00 -07002049
David Benjamin58104882016-07-18 01:25:41 +02002050 m.raw = ticketMsg.finish()
2051 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07002052}
2053
2054func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
2055 m.raw = data
2056
David Benjamin58104882016-07-18 01:25:41 +02002057 if len(data) < 8 {
2058 return false
2059 }
2060 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
2061 data = data[8:]
2062
2063 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002064 if len(data) < 4 {
David Benjamin58104882016-07-18 01:25:41 +02002065 return false
2066 }
Steven Valdeza833c352016-11-01 13:39:36 -04002067 m.ticketAgeAdd = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2068 data = data[4:]
David Benjamin58104882016-07-18 01:25:41 +02002069 }
2070
2071 if len(data) < 2 {
2072 return false
2073 }
2074 ticketLen := int(data[0])<<8 + int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002075 data = data[2:]
2076 if len(data) < ticketLen {
David Benjamin58104882016-07-18 01:25:41 +02002077 return false
2078 }
Steven Valdez5b986082016-09-01 12:29:49 -04002079
David Benjamin58104882016-07-18 01:25:41 +02002080 if m.version >= VersionTLS13 && ticketLen == 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07002081 return false
2082 }
2083
Steven Valdez5b986082016-09-01 12:29:49 -04002084 m.ticket = data[:ticketLen]
2085 data = data[ticketLen:]
2086
2087 if m.version >= VersionTLS13 {
2088 if len(data) < 2 {
2089 return false
2090 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002091
2092 extensionsLength := int(data[0])<<8 | int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002093 data = data[2:]
Steven Valdez08b65f42016-12-07 15:29:45 -05002094 if extensionsLength != len(data) {
Steven Valdez5b986082016-09-01 12:29:49 -04002095 return false
2096 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002097
Steven Valdez08b65f42016-12-07 15:29:45 -05002098 for len(data) != 0 {
2099 if len(data) < 4 {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002100 return false
2101 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002102 extension := uint16(data[0])<<8 | uint16(data[1])
2103 length := int(data[2])<<8 | int(data[3])
2104 data = data[4:]
2105 if len(data) < length {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002106 return false
2107 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002108
Steven Valdez08b65f42016-12-07 15:29:45 -05002109 switch extension {
2110 case extensionTicketEarlyDataInfo:
2111 if length != 4 {
2112 return false
2113 }
Nick Harperf2511f12016-12-06 16:02:31 -08002114 m.maxEarlyDataSize = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
Steven Valdez08b65f42016-12-07 15:29:45 -05002115 default:
2116 if isGREASEValue(extension) {
2117 m.hasGREASEExtension = true
2118 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002119 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002120
2121 data = data[length:]
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002122 }
Steven Valdez5b986082016-09-01 12:29:49 -04002123 }
2124
2125 if len(data) > 0 {
2126 return false
2127 }
Adam Langley95c29f32014-06-20 12:00:00 -07002128
2129 return true
2130}
2131
David Benjamind86c7672014-08-02 04:07:12 -04002132type v2ClientHelloMsg struct {
2133 raw []byte
2134 vers uint16
2135 cipherSuites []uint16
2136 sessionId []byte
2137 challenge []byte
2138}
2139
David Benjamind86c7672014-08-02 04:07:12 -04002140func (m *v2ClientHelloMsg) marshal() []byte {
2141 if m.raw != nil {
2142 return m.raw
2143 }
2144
2145 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
2146
2147 x := make([]byte, length)
2148 x[0] = 1
2149 x[1] = uint8(m.vers >> 8)
2150 x[2] = uint8(m.vers)
2151 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
2152 x[4] = uint8(len(m.cipherSuites) * 3)
2153 x[5] = uint8(len(m.sessionId) >> 8)
2154 x[6] = uint8(len(m.sessionId))
2155 x[7] = uint8(len(m.challenge) >> 8)
2156 x[8] = uint8(len(m.challenge))
2157 y := x[9:]
2158 for i, spec := range m.cipherSuites {
2159 y[i*3] = 0
2160 y[i*3+1] = uint8(spec >> 8)
2161 y[i*3+2] = uint8(spec)
2162 }
2163 y = y[len(m.cipherSuites)*3:]
2164 copy(y, m.sessionId)
2165 y = y[len(m.sessionId):]
2166 copy(y, m.challenge)
2167
2168 m.raw = x
2169
2170 return x
2171}
2172
David Benjamin83c0bc92014-08-04 01:23:53 -04002173type helloVerifyRequestMsg struct {
2174 raw []byte
2175 vers uint16
2176 cookie []byte
2177}
2178
David Benjamin83c0bc92014-08-04 01:23:53 -04002179func (m *helloVerifyRequestMsg) marshal() []byte {
2180 if m.raw != nil {
2181 return m.raw
2182 }
2183
2184 length := 2 + 1 + len(m.cookie)
2185
2186 x := make([]byte, 4+length)
2187 x[0] = typeHelloVerifyRequest
2188 x[1] = uint8(length >> 16)
2189 x[2] = uint8(length >> 8)
2190 x[3] = uint8(length)
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002191 vers := m.vers
David Benjamin83c0bc92014-08-04 01:23:53 -04002192 x[4] = uint8(vers >> 8)
2193 x[5] = uint8(vers)
2194 x[6] = uint8(len(m.cookie))
2195 copy(x[7:7+len(m.cookie)], m.cookie)
2196
2197 return x
2198}
2199
2200func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
2201 if len(data) < 4+2+1 {
2202 return false
2203 }
2204 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002205 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin83c0bc92014-08-04 01:23:53 -04002206 cookieLen := int(data[6])
2207 if cookieLen > 32 || len(data) != 7+cookieLen {
2208 return false
2209 }
2210 m.cookie = data[7 : 7+cookieLen]
2211
2212 return true
2213}
2214
David Benjamin24599a82016-06-30 18:56:53 -04002215type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04002216 raw []byte
2217 channelID []byte
2218}
2219
David Benjamin24599a82016-06-30 18:56:53 -04002220func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04002221 if m.raw != nil {
2222 return m.raw
2223 }
2224
2225 length := 2 + 2 + len(m.channelID)
2226
2227 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04002228 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04002229 x[1] = uint8(length >> 16)
2230 x[2] = uint8(length >> 8)
2231 x[3] = uint8(length)
2232 x[4] = uint8(extensionChannelID >> 8)
2233 x[5] = uint8(extensionChannelID & 0xff)
2234 x[6] = uint8(len(m.channelID) >> 8)
2235 x[7] = uint8(len(m.channelID) & 0xff)
2236 copy(x[8:], m.channelID)
2237
2238 return x
2239}
2240
David Benjamin24599a82016-06-30 18:56:53 -04002241func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04002242 if len(data) != 4+2+2+128 {
2243 return false
2244 }
2245 m.raw = data
2246 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
2247 return false
2248 }
2249 if int(data[6])<<8|int(data[7]) != 128 {
2250 return false
2251 }
2252 m.channelID = data[4+2+2:]
2253
2254 return true
2255}
2256
Adam Langley2ae77d22014-10-28 17:29:33 -07002257type helloRequestMsg struct {
2258}
2259
2260func (*helloRequestMsg) marshal() []byte {
2261 return []byte{typeHelloRequest, 0, 0, 0}
2262}
2263
2264func (*helloRequestMsg) unmarshal(data []byte) bool {
2265 return len(data) == 4
2266}
2267
David Benjamin21c00282016-07-18 21:56:23 +02002268type keyUpdateMsg struct {
Steven Valdezc4aa7272016-10-03 12:25:56 -04002269 raw []byte
2270 keyUpdateRequest byte
David Benjamin21c00282016-07-18 21:56:23 +02002271}
2272
Steven Valdezc4aa7272016-10-03 12:25:56 -04002273func (m *keyUpdateMsg) marshal() []byte {
2274 if m.raw != nil {
2275 return m.raw
2276 }
2277
2278 return []byte{typeKeyUpdate, 0, 0, 1, m.keyUpdateRequest}
David Benjamin21c00282016-07-18 21:56:23 +02002279}
2280
Steven Valdezc4aa7272016-10-03 12:25:56 -04002281func (m *keyUpdateMsg) unmarshal(data []byte) bool {
2282 m.raw = data
2283
2284 if len(data) != 5 {
2285 return false
2286 }
2287
2288 length := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
2289 if len(data)-4 != length {
2290 return false
2291 }
2292
2293 m.keyUpdateRequest = data[4]
2294 return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
David Benjamin21c00282016-07-18 21:56:23 +02002295}
2296
David Benjamin053fee92017-01-02 08:30:36 -05002297// ssl3NoCertificateMsg is a dummy message to handle SSL 3.0 using a warning
2298// alert in the handshake.
2299type ssl3NoCertificateMsg struct{}
2300
Adam Langley95c29f32014-06-20 12:00:00 -07002301func eqUint16s(x, y []uint16) bool {
2302 if len(x) != len(y) {
2303 return false
2304 }
2305 for i, v := range x {
2306 if y[i] != v {
2307 return false
2308 }
2309 }
2310 return true
2311}
2312
2313func eqCurveIDs(x, y []CurveID) bool {
2314 if len(x) != len(y) {
2315 return false
2316 }
2317 for i, v := range x {
2318 if y[i] != v {
2319 return false
2320 }
2321 }
2322 return true
2323}
2324
2325func eqStrings(x, y []string) bool {
2326 if len(x) != len(y) {
2327 return false
2328 }
2329 for i, v := range x {
2330 if y[i] != v {
2331 return false
2332 }
2333 }
2334 return true
2335}
2336
2337func eqByteSlices(x, y [][]byte) bool {
2338 if len(x) != len(y) {
2339 return false
2340 }
2341 for i, v := range x {
2342 if !bytes.Equal(v, y[i]) {
2343 return false
2344 }
2345 }
2346 return true
2347}
2348
Nick Harper60edffd2016-06-21 15:19:24 -07002349func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07002350 if len(x) != len(y) {
2351 return false
2352 }
2353 for i, v := range x {
2354 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07002355 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07002356 return false
2357 }
2358 }
2359 return true
2360}
Nick Harperf8b0e702016-06-30 19:59:01 -04002361
2362func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2363 if len(x) != len(y) {
2364 return false
2365 }
2366 for i, v := range x {
2367 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2368 return false
2369 }
2370 }
2371 return true
2372
2373}
Steven Valdez5b986082016-09-01 12:29:49 -04002374
2375func eqPSKIdentityLists(x, y []pskIdentity) bool {
2376 if len(x) != len(y) {
2377 return false
2378 }
2379 for i, v := range x {
Steven Valdeza833c352016-11-01 13:39:36 -04002380 if !bytes.Equal(y[i].ticket, v.ticket) || y[i].obfuscatedTicketAge != v.obfuscatedTicketAge {
Steven Valdez5b986082016-09-01 12:29:49 -04002381 return false
2382 }
2383 }
2384 return true
2385
2386}