blob: a431cb559d1da868aa8060701eb837c6a52e2dda [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 Harperb41d2e42016-07-01 17:50:32 -0400827 raw []byte
828 isDTLS bool
829 vers uint16
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400830 versOverride uint16
Nick Harperb41d2e42016-07-01 17:50:32 -0400831 random []byte
832 sessionId []byte
833 cipherSuite uint16
834 hasKeyShare bool
835 keyShare keyShareEntry
836 hasPSKIdentity bool
837 pskIdentity uint16
838 earlyDataIndication bool
839 compressionMethod uint8
David Benjamin490469f2016-10-05 22:44:38 -0400840 customExtension string
841 unencryptedALPN string
David Benjamin6f600d62016-12-21 16:06:54 -0500842 shortHeader bool
Nick Harperb41d2e42016-07-01 17:50:32 -0400843 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700844}
845
Adam Langley95c29f32014-06-20 12:00:00 -0700846func (m *serverHelloMsg) marshal() []byte {
847 if m.raw != nil {
848 return m.raw
849 }
850
Nick Harper5212ef82016-06-30 19:26:07 -0400851 handshakeMsg := newByteBuilder()
852 handshakeMsg.addU8(typeServerHello)
853 hello := handshakeMsg.addU24LengthPrefixed()
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400854
855 // m.vers is used both to determine the format of the rest of the
856 // ServerHello and to override the value, so include a second version
857 // field.
858 vers, ok := wireToVersion(m.vers, m.isDTLS)
859 if !ok {
860 panic("unknown version")
861 }
862 if m.versOverride != 0 {
863 hello.addU16(m.versOverride)
864 } else {
865 hello.addU16(m.vers)
866 }
867
Nick Harper5212ef82016-06-30 19:26:07 -0400868 hello.addBytes(m.random)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400869 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400870 sessionId := hello.addU8LengthPrefixed()
871 sessionId.addBytes(m.sessionId)
872 }
Nick Harper5212ef82016-06-30 19:26:07 -0400873 hello.addU16(m.cipherSuite)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400874 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400875 hello.addU8(m.compressionMethod)
876 }
Adam Langley95c29f32014-06-20 12:00:00 -0700877
Nick Harper5212ef82016-06-30 19:26:07 -0400878 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400879
David Benjamin6f600d62016-12-21 16:06:54 -0500880 if m.shortHeader {
881 extensions.addU16(extensionShortHeader)
882 extensions.addU16(0) // Length
883 }
884
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400885 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400886 if m.hasKeyShare {
887 extensions.addU16(extensionKeyShare)
888 keyShare := extensions.addU16LengthPrefixed()
889 keyShare.addU16(uint16(m.keyShare.group))
890 keyExchange := keyShare.addU16LengthPrefixed()
891 keyExchange.addBytes(m.keyShare.keyExchange)
892 }
893 if m.hasPSKIdentity {
894 extensions.addU16(extensionPreSharedKey)
895 extensions.addU16(2) // Length
896 extensions.addU16(m.pskIdentity)
897 }
898 if m.earlyDataIndication {
899 extensions.addU16(extensionEarlyData)
900 extensions.addU16(0) // Length
901 }
David Benjamin490469f2016-10-05 22:44:38 -0400902 if len(m.customExtension) > 0 {
903 extensions.addU16(extensionCustom)
904 customExt := extensions.addU16LengthPrefixed()
905 customExt.addBytes([]byte(m.customExtension))
906 }
907 if len(m.unencryptedALPN) > 0 {
908 extensions.addU16(extensionALPN)
909 extension := extensions.addU16LengthPrefixed()
910
911 protocolNameList := extension.addU16LengthPrefixed()
912 protocolName := protocolNameList.addU8LengthPrefixed()
913 protocolName.addBytes([]byte(m.unencryptedALPN))
914 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400915 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400916 m.extensions.marshal(extensions)
Nick Harperb41d2e42016-07-01 17:50:32 -0400917 if extensions.len() == 0 {
918 hello.discardChild()
919 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400920 }
921
922 m.raw = handshakeMsg.finish()
923 return m.raw
924}
925
926func (m *serverHelloMsg) unmarshal(data []byte) bool {
927 if len(data) < 42 {
928 return false
929 }
930 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400931 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400932 vers, ok := wireToVersion(m.vers, m.isDTLS)
933 if !ok {
934 return false
935 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400936 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400937 data = data[38:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400938 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400939 sessionIdLen := int(data[0])
940 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
941 return false
942 }
943 m.sessionId = data[1 : 1+sessionIdLen]
944 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400945 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400946 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400947 return false
948 }
949 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400950 data = data[2:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400951 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400952 if len(data) < 1 {
953 return false
954 }
955 m.compressionMethod = data[0]
956 data = data[1:]
957 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400958
David Benjamin8d315d72016-07-18 01:03:18 +0200959 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400960 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400961 m.extensions = serverExtensions{}
962 return true
963 }
964 if len(data) < 2 {
965 return false
966 }
967
968 extensionsLength := int(data[0])<<8 | int(data[1])
969 data = data[2:]
970 if len(data) != extensionsLength {
971 return false
972 }
973
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400974 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400975 for len(data) != 0 {
976 if len(data) < 4 {
977 return false
978 }
979 extension := uint16(data[0])<<8 | uint16(data[1])
980 length := int(data[2])<<8 | int(data[3])
981 data = data[4:]
982
983 if len(data) < length {
984 return false
985 }
986 d := data[:length]
987 data = data[length:]
988
989 switch extension {
990 case extensionKeyShare:
991 m.hasKeyShare = true
992 if len(d) < 4 {
993 return false
994 }
995 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
996 keyExchLen := int(d[2])<<8 | int(d[3])
997 if keyExchLen != len(d)-4 {
998 return false
999 }
1000 m.keyShare.keyExchange = make([]byte, keyExchLen)
1001 copy(m.keyShare.keyExchange, d[4:])
1002 case extensionPreSharedKey:
1003 if len(d) != 2 {
1004 return false
1005 }
1006 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
1007 m.hasPSKIdentity = true
1008 case extensionEarlyData:
1009 if len(d) != 0 {
1010 return false
1011 }
1012 m.earlyDataIndication = true
David Benjamin6f600d62016-12-21 16:06:54 -05001013 case extensionShortHeader:
1014 if len(d) != 0 {
1015 return false
1016 }
1017 m.shortHeader = true
Nick Harperb41d2e42016-07-01 17:50:32 -04001018 default:
1019 // Only allow the 3 extensions that are sent in
1020 // the clear in TLS 1.3.
1021 return false
1022 }
1023 }
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001024 } else if !m.extensions.unmarshal(data, vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -04001025 return false
1026 }
1027
1028 return true
1029}
1030
Nick Harperb41d2e42016-07-01 17:50:32 -04001031type encryptedExtensionsMsg struct {
1032 raw []byte
1033 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -04001034 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001035}
1036
1037func (m *encryptedExtensionsMsg) marshal() []byte {
1038 if m.raw != nil {
1039 return m.raw
1040 }
1041
1042 encryptedExtensionsMsg := newByteBuilder()
1043 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
1044 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -04001045 if !m.empty {
1046 extensions := encryptedExtensions.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001047 m.extensions.marshal(extensions)
Steven Valdez143e8b32016-07-11 13:19:03 -04001048 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001049
1050 m.raw = encryptedExtensionsMsg.finish()
1051 return m.raw
1052}
1053
1054func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -04001055 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001056 if len(data) < 6 {
1057 return false
1058 }
1059 if data[0] != typeEncryptedExtensions {
1060 return false
1061 }
1062 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1063 data = data[4:]
1064 if len(data) != msgLen {
1065 return false
1066 }
1067 extLen := int(data[0])<<8 | int(data[1])
1068 data = data[2:]
1069 if extLen != len(data) {
1070 return false
1071 }
David Benjamin44b33bc2016-07-01 22:40:23 -04001072 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -04001073}
1074
Nick Harperb3d51be2016-07-01 11:43:18 -04001075type serverExtensions struct {
1076 nextProtoNeg bool
1077 nextProtos []string
1078 ocspStapling bool
1079 ticketSupported bool
1080 secureRenegotiation []byte
1081 alpnProtocol string
1082 alpnProtocolEmpty bool
1083 duplicateExtension bool
1084 channelIDRequested bool
1085 extendedMasterSecret bool
1086 srtpProtectionProfile uint16
1087 srtpMasterKeyIdentifier string
1088 sctList []byte
1089 customExtension string
Steven Valdeza833c352016-11-01 13:39:36 -04001090 npnAfterAlpn bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001091 hasKeyShare bool
1092 keyShare keyShareEntry
David Benjamina81967b2016-12-22 09:16:57 -05001093 supportedPoints []uint8
Nick Harperb3d51be2016-07-01 11:43:18 -04001094}
1095
Steven Valdeza833c352016-11-01 13:39:36 -04001096func (m *serverExtensions) marshal(extensions *byteBuilder) {
David Benjamin35a7a442014-07-05 00:23:20 -04001097 if m.duplicateExtension {
1098 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001099 extensions.addU16(0xffff)
1100 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -04001101 }
Steven Valdeza833c352016-11-01 13:39:36 -04001102 if m.nextProtoNeg && !m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001103 extensions.addU16(extensionNextProtoNeg)
1104 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001105
1106 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001107 if len(v) > 255 {
1108 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -07001109 }
Nick Harper5212ef82016-06-30 19:26:07 -04001110 npn := extension.addU8LengthPrefixed()
1111 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -07001112 }
1113 }
Steven Valdeza833c352016-11-01 13:39:36 -04001114 if m.ocspStapling {
1115 extensions.addU16(extensionStatusRequest)
1116 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001117 }
1118 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -04001119 extensions.addU16(extensionSessionTicket)
1120 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001121 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001122 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001123 extensions.addU16(extensionRenegotiationInfo)
1124 extension := extensions.addU16LengthPrefixed()
1125 secureRenego := extension.addU8LengthPrefixed()
1126 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -07001127 }
Nick Harper5212ef82016-06-30 19:26:07 -04001128 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
1129 extensions.addU16(extensionALPN)
1130 extension := extensions.addU16LengthPrefixed()
1131
1132 protocolNameList := extension.addU16LengthPrefixed()
1133 protocolName := protocolNameList.addU8LengthPrefixed()
1134 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -04001135 }
David Benjamind30a9902014-08-24 01:44:23 -04001136 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -04001137 extensions.addU16(extensionChannelID)
1138 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -04001139 }
David Benjamin35a7a442014-07-05 00:23:20 -04001140 if m.duplicateExtension {
1141 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001142 extensions.addU16(0xffff)
1143 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -04001144 }
Adam Langley75712922014-10-10 16:23:43 -07001145 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -04001146 extensions.addU16(extensionExtendedMasterSecret)
1147 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -07001148 }
David Benjaminca6c8262014-11-15 19:06:08 -05001149 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001150 extensions.addU16(extensionUseSRTP)
1151 extension := extensions.addU16LengthPrefixed()
1152
1153 srtpProtectionProfiles := extension.addU16LengthPrefixed()
1154 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
1155 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
1156 srtpMki := extension.addU8LengthPrefixed()
1157 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -05001158 }
David Benjamin61f95272014-11-25 01:55:35 -05001159 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001160 extensions.addU16(extensionSignedCertificateTimestamp)
1161 extension := extensions.addU16LengthPrefixed()
1162 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -05001163 }
Adam Langley09505632015-07-30 18:10:13 -07001164 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001165 extensions.addU16(extensionCustom)
1166 customExt := extensions.addU16LengthPrefixed()
1167 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -07001168 }
Steven Valdeza833c352016-11-01 13:39:36 -04001169 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001170 extensions.addU16(extensionNextProtoNeg)
1171 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -04001172
1173 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001174 if len(v) > 255 {
1175 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -04001176 }
Nick Harper5212ef82016-06-30 19:26:07 -04001177 npn := extension.addU8LengthPrefixed()
1178 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001179 }
1180 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001181 if m.hasKeyShare {
1182 extensions.addU16(extensionKeyShare)
1183 keyShare := extensions.addU16LengthPrefixed()
1184 keyShare.addU16(uint16(m.keyShare.group))
1185 keyExchange := keyShare.addU16LengthPrefixed()
1186 keyExchange.addBytes(m.keyShare.keyExchange)
1187 }
David Benjamina81967b2016-12-22 09:16:57 -05001188 if len(m.supportedPoints) > 0 {
1189 // http://tools.ietf.org/html/rfc4492#section-5.1.2
1190 extensions.addU16(extensionSupportedPoints)
1191 supportedPointsList := extensions.addU16LengthPrefixed()
1192 supportedPoints := supportedPointsList.addU8LengthPrefixed()
1193 supportedPoints.addBytes(m.supportedPoints)
1194 }
Adam Langley95c29f32014-06-20 12:00:00 -07001195}
1196
David Benjamin44b33bc2016-07-01 22:40:23 -04001197func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001198 // Reset all fields.
1199 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001200
1201 for len(data) != 0 {
1202 if len(data) < 4 {
1203 return false
1204 }
1205 extension := uint16(data[0])<<8 | uint16(data[1])
1206 length := int(data[2])<<8 | int(data[3])
1207 data = data[4:]
1208 if len(data) < length {
1209 return false
1210 }
1211
1212 switch extension {
1213 case extensionNextProtoNeg:
1214 m.nextProtoNeg = true
1215 d := data[:length]
1216 for len(d) > 0 {
1217 l := int(d[0])
1218 d = d[1:]
1219 if l == 0 || l > len(d) {
1220 return false
1221 }
1222 m.nextProtos = append(m.nextProtos, string(d[:l]))
1223 d = d[l:]
1224 }
1225 case extensionStatusRequest:
Steven Valdeza833c352016-11-01 13:39:36 -04001226 if length > 0 {
1227 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001228 }
Steven Valdeza833c352016-11-01 13:39:36 -04001229 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001230 case extensionSessionTicket:
1231 if length > 0 {
1232 return false
1233 }
1234 m.ticketSupported = true
1235 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001236 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001237 return false
1238 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001239 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001240 case extensionALPN:
1241 d := data[:length]
1242 if len(d) < 3 {
1243 return false
1244 }
1245 l := int(d[0])<<8 | int(d[1])
1246 if l != len(d)-2 {
1247 return false
1248 }
1249 d = d[2:]
1250 l = int(d[0])
1251 if l != len(d)-1 {
1252 return false
1253 }
1254 d = d[1:]
1255 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001256 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001257 case extensionChannelID:
1258 if length > 0 {
1259 return false
1260 }
1261 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001262 case extensionExtendedMasterSecret:
1263 if length != 0 {
1264 return false
1265 }
1266 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001267 case extensionUseSRTP:
1268 if length < 2+2+1 {
1269 return false
1270 }
1271 if data[0] != 0 || data[1] != 2 {
1272 return false
1273 }
1274 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1275 d := data[4:length]
1276 l := int(d[0])
1277 if l != len(d)-1 {
1278 return false
1279 }
1280 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001281 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001282 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001283 case extensionCustom:
1284 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001285 case extensionServerName:
1286 if length != 0 {
1287 return false
1288 }
1289 // Ignore this extension from the server.
1290 case extensionSupportedPoints:
1291 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001292 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001293 return false
1294 }
David Benjamina81967b2016-12-22 09:16:57 -05001295 // http://tools.ietf.org/html/rfc4492#section-5.5.2
1296 if length < 1 {
1297 return false
1298 }
1299 l := int(data[0])
1300 if length != l+1 {
1301 return false
1302 }
1303 m.supportedPoints = data[1 : 1+l]
David Benjamin4ee027f2016-07-17 12:34:41 +02001304 case extensionSupportedCurves:
1305 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001306 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001307 return false
1308 }
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 Benjamin1a5e8ec2016-10-07 15:19:18 -04002006 raw []byte
2007 version uint16
2008 ticketLifetime uint32
Steven Valdeza833c352016-11-01 13:39:36 -04002009 ticketAgeAdd uint32
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002010 ticket []byte
Steven Valdez08b65f42016-12-07 15:29:45 -05002011 earlyDataInfo uint32
David Benjamin1286bee2016-10-07 15:25:06 -04002012 customExtension string
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002013 hasGREASEExtension bool
Adam Langley95c29f32014-06-20 12:00:00 -07002014}
2015
David Benjamin58104882016-07-18 01:25:41 +02002016func (m *newSessionTicketMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07002017 if m.raw != nil {
2018 return m.raw
2019 }
2020
2021 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjamin58104882016-07-18 01:25:41 +02002022 ticketMsg := newByteBuilder()
2023 ticketMsg.addU8(typeNewSessionTicket)
2024 body := ticketMsg.addU24LengthPrefixed()
2025 body.addU32(m.ticketLifetime)
2026 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002027 body.addU32(m.ticketAgeAdd)
Steven Valdez5b986082016-09-01 12:29:49 -04002028 }
2029
2030 ticket := body.addU16LengthPrefixed()
2031 ticket.addBytes(m.ticket)
2032
2033 if m.version >= VersionTLS13 {
David Benjamin1286bee2016-10-07 15:25:06 -04002034 extensions := body.addU16LengthPrefixed()
Steven Valdez08b65f42016-12-07 15:29:45 -05002035 if m.earlyDataInfo > 0 {
2036 extensions.addU16(extensionTicketEarlyDataInfo)
2037 extensions.addU16LengthPrefixed().addU32(m.earlyDataInfo)
2038 }
David Benjamin1286bee2016-10-07 15:25:06 -04002039 if len(m.customExtension) > 0 {
Steven Valdez08b65f42016-12-07 15:29:45 -05002040 extensions.addU16(extensionCustom)
David Benjamin1286bee2016-10-07 15:25:06 -04002041 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
2042 }
David Benjamin58104882016-07-18 01:25:41 +02002043 }
Adam Langley95c29f32014-06-20 12:00:00 -07002044
David Benjamin58104882016-07-18 01:25:41 +02002045 m.raw = ticketMsg.finish()
2046 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07002047}
2048
2049func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
2050 m.raw = data
2051
David Benjamin58104882016-07-18 01:25:41 +02002052 if len(data) < 8 {
2053 return false
2054 }
2055 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
2056 data = data[8:]
2057
2058 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002059 if len(data) < 4 {
David Benjamin58104882016-07-18 01:25:41 +02002060 return false
2061 }
Steven Valdeza833c352016-11-01 13:39:36 -04002062 m.ticketAgeAdd = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2063 data = data[4:]
David Benjamin58104882016-07-18 01:25:41 +02002064 }
2065
2066 if len(data) < 2 {
2067 return false
2068 }
2069 ticketLen := int(data[0])<<8 + int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002070 data = data[2:]
2071 if len(data) < ticketLen {
David Benjamin58104882016-07-18 01:25:41 +02002072 return false
2073 }
Steven Valdez5b986082016-09-01 12:29:49 -04002074
David Benjamin58104882016-07-18 01:25:41 +02002075 if m.version >= VersionTLS13 && ticketLen == 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07002076 return false
2077 }
2078
Steven Valdez5b986082016-09-01 12:29:49 -04002079 m.ticket = data[:ticketLen]
2080 data = data[ticketLen:]
2081
2082 if m.version >= VersionTLS13 {
2083 if len(data) < 2 {
2084 return false
2085 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002086
2087 extensionsLength := int(data[0])<<8 | int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002088 data = data[2:]
Steven Valdez08b65f42016-12-07 15:29:45 -05002089 if extensionsLength != len(data) {
Steven Valdez5b986082016-09-01 12:29:49 -04002090 return false
2091 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002092
Steven Valdez08b65f42016-12-07 15:29:45 -05002093 for len(data) != 0 {
2094 if len(data) < 4 {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002095 return false
2096 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002097 extension := uint16(data[0])<<8 | uint16(data[1])
2098 length := int(data[2])<<8 | int(data[3])
2099 data = data[4:]
2100 if len(data) < length {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002101 return false
2102 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002103
Steven Valdez08b65f42016-12-07 15:29:45 -05002104 switch extension {
2105 case extensionTicketEarlyDataInfo:
2106 if length != 4 {
2107 return false
2108 }
2109 m.earlyDataInfo = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2110 default:
2111 if isGREASEValue(extension) {
2112 m.hasGREASEExtension = true
2113 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002114 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002115
2116 data = data[length:]
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002117 }
Steven Valdez5b986082016-09-01 12:29:49 -04002118 }
2119
2120 if len(data) > 0 {
2121 return false
2122 }
Adam Langley95c29f32014-06-20 12:00:00 -07002123
2124 return true
2125}
2126
David Benjamind86c7672014-08-02 04:07:12 -04002127type v2ClientHelloMsg struct {
2128 raw []byte
2129 vers uint16
2130 cipherSuites []uint16
2131 sessionId []byte
2132 challenge []byte
2133}
2134
David Benjamind86c7672014-08-02 04:07:12 -04002135func (m *v2ClientHelloMsg) marshal() []byte {
2136 if m.raw != nil {
2137 return m.raw
2138 }
2139
2140 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
2141
2142 x := make([]byte, length)
2143 x[0] = 1
2144 x[1] = uint8(m.vers >> 8)
2145 x[2] = uint8(m.vers)
2146 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
2147 x[4] = uint8(len(m.cipherSuites) * 3)
2148 x[5] = uint8(len(m.sessionId) >> 8)
2149 x[6] = uint8(len(m.sessionId))
2150 x[7] = uint8(len(m.challenge) >> 8)
2151 x[8] = uint8(len(m.challenge))
2152 y := x[9:]
2153 for i, spec := range m.cipherSuites {
2154 y[i*3] = 0
2155 y[i*3+1] = uint8(spec >> 8)
2156 y[i*3+2] = uint8(spec)
2157 }
2158 y = y[len(m.cipherSuites)*3:]
2159 copy(y, m.sessionId)
2160 y = y[len(m.sessionId):]
2161 copy(y, m.challenge)
2162
2163 m.raw = x
2164
2165 return x
2166}
2167
David Benjamin83c0bc92014-08-04 01:23:53 -04002168type helloVerifyRequestMsg struct {
2169 raw []byte
2170 vers uint16
2171 cookie []byte
2172}
2173
David Benjamin83c0bc92014-08-04 01:23:53 -04002174func (m *helloVerifyRequestMsg) marshal() []byte {
2175 if m.raw != nil {
2176 return m.raw
2177 }
2178
2179 length := 2 + 1 + len(m.cookie)
2180
2181 x := make([]byte, 4+length)
2182 x[0] = typeHelloVerifyRequest
2183 x[1] = uint8(length >> 16)
2184 x[2] = uint8(length >> 8)
2185 x[3] = uint8(length)
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002186 vers := m.vers
David Benjamin83c0bc92014-08-04 01:23:53 -04002187 x[4] = uint8(vers >> 8)
2188 x[5] = uint8(vers)
2189 x[6] = uint8(len(m.cookie))
2190 copy(x[7:7+len(m.cookie)], m.cookie)
2191
2192 return x
2193}
2194
2195func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
2196 if len(data) < 4+2+1 {
2197 return false
2198 }
2199 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002200 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin83c0bc92014-08-04 01:23:53 -04002201 cookieLen := int(data[6])
2202 if cookieLen > 32 || len(data) != 7+cookieLen {
2203 return false
2204 }
2205 m.cookie = data[7 : 7+cookieLen]
2206
2207 return true
2208}
2209
David Benjamin24599a82016-06-30 18:56:53 -04002210type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04002211 raw []byte
2212 channelID []byte
2213}
2214
David Benjamin24599a82016-06-30 18:56:53 -04002215func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04002216 if m.raw != nil {
2217 return m.raw
2218 }
2219
2220 length := 2 + 2 + len(m.channelID)
2221
2222 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04002223 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04002224 x[1] = uint8(length >> 16)
2225 x[2] = uint8(length >> 8)
2226 x[3] = uint8(length)
2227 x[4] = uint8(extensionChannelID >> 8)
2228 x[5] = uint8(extensionChannelID & 0xff)
2229 x[6] = uint8(len(m.channelID) >> 8)
2230 x[7] = uint8(len(m.channelID) & 0xff)
2231 copy(x[8:], m.channelID)
2232
2233 return x
2234}
2235
David Benjamin24599a82016-06-30 18:56:53 -04002236func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04002237 if len(data) != 4+2+2+128 {
2238 return false
2239 }
2240 m.raw = data
2241 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
2242 return false
2243 }
2244 if int(data[6])<<8|int(data[7]) != 128 {
2245 return false
2246 }
2247 m.channelID = data[4+2+2:]
2248
2249 return true
2250}
2251
Adam Langley2ae77d22014-10-28 17:29:33 -07002252type helloRequestMsg struct {
2253}
2254
2255func (*helloRequestMsg) marshal() []byte {
2256 return []byte{typeHelloRequest, 0, 0, 0}
2257}
2258
2259func (*helloRequestMsg) unmarshal(data []byte) bool {
2260 return len(data) == 4
2261}
2262
David Benjamin21c00282016-07-18 21:56:23 +02002263type keyUpdateMsg struct {
Steven Valdezc4aa7272016-10-03 12:25:56 -04002264 raw []byte
2265 keyUpdateRequest byte
David Benjamin21c00282016-07-18 21:56:23 +02002266}
2267
Steven Valdezc4aa7272016-10-03 12:25:56 -04002268func (m *keyUpdateMsg) marshal() []byte {
2269 if m.raw != nil {
2270 return m.raw
2271 }
2272
2273 return []byte{typeKeyUpdate, 0, 0, 1, m.keyUpdateRequest}
David Benjamin21c00282016-07-18 21:56:23 +02002274}
2275
Steven Valdezc4aa7272016-10-03 12:25:56 -04002276func (m *keyUpdateMsg) unmarshal(data []byte) bool {
2277 m.raw = data
2278
2279 if len(data) != 5 {
2280 return false
2281 }
2282
2283 length := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
2284 if len(data)-4 != length {
2285 return false
2286 }
2287
2288 m.keyUpdateRequest = data[4]
2289 return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
David Benjamin21c00282016-07-18 21:56:23 +02002290}
2291
David Benjamin053fee92017-01-02 08:30:36 -05002292// ssl3NoCertificateMsg is a dummy message to handle SSL 3.0 using a warning
2293// alert in the handshake.
2294type ssl3NoCertificateMsg struct{}
2295
Adam Langley95c29f32014-06-20 12:00:00 -07002296func eqUint16s(x, y []uint16) bool {
2297 if len(x) != len(y) {
2298 return false
2299 }
2300 for i, v := range x {
2301 if y[i] != v {
2302 return false
2303 }
2304 }
2305 return true
2306}
2307
2308func eqCurveIDs(x, y []CurveID) bool {
2309 if len(x) != len(y) {
2310 return false
2311 }
2312 for i, v := range x {
2313 if y[i] != v {
2314 return false
2315 }
2316 }
2317 return true
2318}
2319
2320func eqStrings(x, y []string) bool {
2321 if len(x) != len(y) {
2322 return false
2323 }
2324 for i, v := range x {
2325 if y[i] != v {
2326 return false
2327 }
2328 }
2329 return true
2330}
2331
2332func eqByteSlices(x, y [][]byte) bool {
2333 if len(x) != len(y) {
2334 return false
2335 }
2336 for i, v := range x {
2337 if !bytes.Equal(v, y[i]) {
2338 return false
2339 }
2340 }
2341 return true
2342}
2343
Nick Harper60edffd2016-06-21 15:19:24 -07002344func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07002345 if len(x) != len(y) {
2346 return false
2347 }
2348 for i, v := range x {
2349 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07002350 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07002351 return false
2352 }
2353 }
2354 return true
2355}
Nick Harperf8b0e702016-06-30 19:59:01 -04002356
2357func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2358 if len(x) != len(y) {
2359 return false
2360 }
2361 for i, v := range x {
2362 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2363 return false
2364 }
2365 }
2366 return true
2367
2368}
Steven Valdez5b986082016-09-01 12:29:49 -04002369
2370func eqPSKIdentityLists(x, y []pskIdentity) bool {
2371 if len(x) != len(y) {
2372 return false
2373 }
2374 for i, v := range x {
Steven Valdeza833c352016-11-01 13:39:36 -04002375 if !bytes.Equal(y[i].ticket, v.ticket) || y[i].obfuscatedTicketAge != v.obfuscatedTicketAge {
Steven Valdez5b986082016-09-01 12:29:49 -04002376 return false
2377 }
2378 }
2379 return true
2380
2381}