blob: d2d7635628c9a048a3933dc0c479a7518fa4b440 [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
153 earlyDataContext []byte
David Benjamin3baa6e12016-10-07 21:10:38 -0400154 tls13Cookie []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500155 ticketSupported bool
156 sessionTicket []uint8
Nick Harper60edffd2016-06-21 15:19:24 -0700157 signatureAlgorithms []signatureAlgorithm
Steven Valdezfdd10992016-09-15 16:27:05 -0400158 supportedVersions []uint16
David Benjaminca6c8262014-11-15 19:06:08 -0500159 secureRenegotiation []byte
160 alpnProtocols []string
161 duplicateExtension bool
162 channelIDSupported bool
Steven Valdeza833c352016-11-01 13:39:36 -0400163 npnAfterAlpn bool
David Benjaminca6c8262014-11-15 19:06:08 -0500164 extendedMasterSecret bool
165 srtpProtectionProfiles []uint16
166 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -0500167 sctListSupported bool
Adam Langley09505632015-07-30 18:10:13 -0700168 customExtension string
David Benjamin65ac9972016-09-02 21:35:25 -0400169 hasGREASEExtension bool
Steven Valdeza833c352016-11-01 13:39:36 -0400170 pskBinderFirst 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 &&
199 bytes.Equal(m.earlyDataContext, m1.earlyDataContext) &&
David Benjamin3baa6e12016-10-07 21:10:38 -0400200 bytes.Equal(m.tls13Cookie, m1.tls13Cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700201 m.ticketSupported == m1.ticketSupported &&
202 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
Nick Harper60edffd2016-06-21 15:19:24 -0700203 eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
Steven Valdezfdd10992016-09-15 16:27:05 -0400204 eqUint16s(m.supportedVersions, m1.supportedVersions) &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700205 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
206 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400207 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -0400208 m.duplicateExtension == m1.duplicateExtension &&
David Benjaminfc7b0862014-09-06 13:21:53 -0400209 m.channelIDSupported == m1.channelIDSupported &&
Steven Valdeza833c352016-11-01 13:39:36 -0400210 m.npnAfterAlpn == m1.npnAfterAlpn &&
David Benjaminca6c8262014-11-15 19:06:08 -0500211 m.extendedMasterSecret == m1.extendedMasterSecret &&
212 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
David Benjamin61f95272014-11-25 01:55:35 -0500213 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
Adam Langley09505632015-07-30 18:10:13 -0700214 m.sctListSupported == m1.sctListSupported &&
David Benjamin65ac9972016-09-02 21:35:25 -0400215 m.customExtension == m1.customExtension &&
Steven Valdeza833c352016-11-01 13:39:36 -0400216 m.hasGREASEExtension == m1.hasGREASEExtension &&
217 m.pskBinderFirst == m1.pskBinderFirst
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()
Adam Langley95c29f32014-06-20 12:00:00 -0700319 for _, pointFormat := range m.supportedPoints {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400320 supportedPoints.addU8(pointFormat)
Adam Langley95c29f32014-06-20 12:00:00 -0700321 }
322 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200323 if m.hasKeyShares {
Nick Harperf8b0e702016-06-30 19:59:01 -0400324 extensions.addU16(extensionKeyShare)
325 keyShareList := extensions.addU16LengthPrefixed()
326
327 keyShares := keyShareList.addU16LengthPrefixed()
328 for _, keyShare := range m.keyShares {
329 keyShares.addU16(uint16(keyShare.group))
330 keyExchange := keyShares.addU16LengthPrefixed()
331 keyExchange.addBytes(keyShare.keyExchange)
332 }
David Benjamin7e1f9842016-09-20 19:24:40 -0400333
334 if m.trailingKeyShareData {
335 keyShares.addU8(0)
336 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400337 }
Steven Valdeza833c352016-11-01 13:39:36 -0400338 if len(m.pskKEModes) > 0 {
339 extensions.addU16(extensionPSKKeyExchangeModes)
340 pskModesExtension := extensions.addU16LengthPrefixed()
341 pskModesExtension.addU8LengthPrefixed().addBytes(m.pskKEModes)
Nick Harperf8b0e702016-06-30 19:59:01 -0400342 }
343 if m.hasEarlyData {
344 extensions.addU16(extensionEarlyData)
345 earlyDataIndication := extensions.addU16LengthPrefixed()
346
347 context := earlyDataIndication.addU8LengthPrefixed()
348 context.addBytes(m.earlyDataContext)
349 }
David Benjamin3baa6e12016-10-07 21:10:38 -0400350 if len(m.tls13Cookie) > 0 {
351 extensions.addU16(extensionCookie)
352 body := extensions.addU16LengthPrefixed()
353 body.addU16LengthPrefixed().addBytes(m.tls13Cookie)
354 }
Adam Langley95c29f32014-06-20 12:00:00 -0700355 if m.ticketSupported {
356 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400357 extensions.addU16(extensionSessionTicket)
358 sessionTicketExtension := extensions.addU16LengthPrefixed()
359 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700360 }
Nick Harper60edffd2016-06-21 15:19:24 -0700361 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700362 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400363 extensions.addU16(extensionSignatureAlgorithms)
364 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
365 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700366 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400367 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700368 }
369 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400370 if len(m.supportedVersions) > 0 {
371 extensions.addU16(extensionSupportedVersions)
372 supportedVersionsExtension := extensions.addU16LengthPrefixed()
373 supportedVersions := supportedVersionsExtension.addU8LengthPrefixed()
374 for _, version := range m.supportedVersions {
375 supportedVersions.addU16(uint16(version))
376 }
377 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700378 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400379 extensions.addU16(extensionRenegotiationInfo)
380 secureRenegoExt := extensions.addU16LengthPrefixed()
381 secureRenego := secureRenegoExt.addU8LengthPrefixed()
382 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700383 }
David Benjaminfa055a22014-09-15 16:51:51 -0400384 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400385 // https://tools.ietf.org/html/rfc7301#section-3.1
386 extensions.addU16(extensionALPN)
387 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400388
Nick Harper8dda5cc2016-06-30 18:51:11 -0400389 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400390 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400391 protocolName := protocolNameList.addU8LengthPrefixed()
392 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400393 }
David Benjaminfa055a22014-09-15 16:51:51 -0400394 }
David Benjamind30a9902014-08-24 01:44:23 -0400395 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400396 extensions.addU16(extensionChannelID)
397 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400398 }
Steven Valdeza833c352016-11-01 13:39:36 -0400399 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400400 extensions.addU16(extensionNextProtoNeg)
401 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400402 }
David Benjamin35a7a442014-07-05 00:23:20 -0400403 if m.duplicateExtension {
404 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400405 extensions.addU16(0xffff)
406 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400407 }
Adam Langley75712922014-10-10 16:23:43 -0700408 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500409 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400410 extensions.addU16(extensionExtendedMasterSecret)
411 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700412 }
David Benjaminca6c8262014-11-15 19:06:08 -0500413 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400414 // https://tools.ietf.org/html/rfc5764#section-4.1.1
415 extensions.addU16(extensionUseSRTP)
416 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500417
Nick Harper8dda5cc2016-06-30 18:51:11 -0400418 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500419 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400420 // An SRTPProtectionProfile is defined as uint8[2],
421 // not uint16. For some reason, we're storing it
422 // as a uint16.
423 srtpProtectionProfiles.addU8(byte(p >> 8))
424 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500425 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400426 srtpMki := useSrtpExt.addU8LengthPrefixed()
427 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500428 }
David Benjamin61f95272014-11-25 01:55:35 -0500429 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400430 extensions.addU16(extensionSignedCertificateTimestamp)
431 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500432 }
Adam Langley09505632015-07-30 18:10:13 -0700433 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400434 extensions.addU16(extensionCustom)
435 customExt := extensions.addU16LengthPrefixed()
436 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700437 }
Steven Valdeza833c352016-11-01 13:39:36 -0400438 // The PSK extension must be last (draft-ietf-tls-tls13-18 section 4.2.6).
439 if len(m.pskIdentities) > 0 && !m.pskBinderFirst {
440 extensions.addU16(extensionPreSharedKey)
441 pskExtension := extensions.addU16LengthPrefixed()
442
443 pskIdentities := pskExtension.addU16LengthPrefixed()
444 for _, psk := range m.pskIdentities {
445 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
446 pskIdentities.addU32(psk.obfuscatedTicketAge)
447 }
448 pskBinders := pskExtension.addU16LengthPrefixed()
449 for _, binder := range m.pskBinders {
450 pskBinders.addU8LengthPrefixed().addBytes(binder)
451 }
452 }
Adam Langley95c29f32014-06-20 12:00:00 -0700453
Nick Harper8dda5cc2016-06-30 18:51:11 -0400454 if extensions.len() == 0 {
455 hello.discardChild()
456 }
Adam Langley95c29f32014-06-20 12:00:00 -0700457
Nick Harper8dda5cc2016-06-30 18:51:11 -0400458 m.raw = handshakeMsg.finish()
459 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700460}
461
462func (m *clientHelloMsg) unmarshal(data []byte) bool {
463 if len(data) < 42 {
464 return false
465 }
466 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400467 m.vers = uint16(data[4])<<8 | uint16(data[5])
Adam Langley95c29f32014-06-20 12:00:00 -0700468 m.random = data[6:38]
469 sessionIdLen := int(data[38])
470 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
471 return false
472 }
473 m.sessionId = data[39 : 39+sessionIdLen]
474 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400475 if m.isDTLS {
476 if len(data) < 1 {
477 return false
478 }
479 cookieLen := int(data[0])
480 if cookieLen > 32 || len(data) < 1+cookieLen {
481 return false
482 }
483 m.cookie = data[1 : 1+cookieLen]
484 data = data[1+cookieLen:]
485 }
Adam Langley95c29f32014-06-20 12:00:00 -0700486 if len(data) < 2 {
487 return false
488 }
489 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
490 // they are uint16s, the number must be even.
491 cipherSuiteLen := int(data[0])<<8 | int(data[1])
492 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
493 return false
494 }
495 numCipherSuites := cipherSuiteLen / 2
496 m.cipherSuites = make([]uint16, numCipherSuites)
497 for i := 0; i < numCipherSuites; i++ {
498 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
499 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700500 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700501 }
502 }
503 data = data[2+cipherSuiteLen:]
504 if len(data) < 1 {
505 return false
506 }
507 compressionMethodsLen := int(data[0])
508 if len(data) < 1+compressionMethodsLen {
509 return false
510 }
511 m.compressionMethods = data[1 : 1+compressionMethodsLen]
512
513 data = data[1+compressionMethodsLen:]
514
515 m.nextProtoNeg = false
516 m.serverName = ""
517 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400518 m.keyShares = nil
519 m.pskIdentities = nil
520 m.hasEarlyData = false
521 m.earlyDataContext = nil
Adam Langley95c29f32014-06-20 12:00:00 -0700522 m.ticketSupported = false
523 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700524 m.signatureAlgorithms = nil
Steven Valdezfdd10992016-09-15 16:27:05 -0400525 m.supportedVersions = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400526 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700527 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700528 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700529
530 if len(data) == 0 {
531 // ClientHello is optionally followed by extension data
532 return true
533 }
534 if len(data) < 2 {
535 return false
536 }
537
538 extensionsLength := int(data[0])<<8 | int(data[1])
539 data = data[2:]
540 if extensionsLength != len(data) {
541 return false
542 }
543
544 for len(data) != 0 {
545 if len(data) < 4 {
546 return false
547 }
548 extension := uint16(data[0])<<8 | uint16(data[1])
549 length := int(data[2])<<8 | int(data[3])
550 data = data[4:]
551 if len(data) < length {
552 return false
553 }
554
555 switch extension {
556 case extensionServerName:
557 if length < 2 {
558 return false
559 }
560 numNames := int(data[0])<<8 | int(data[1])
561 d := data[2:]
562 for i := 0; i < numNames; i++ {
563 if len(d) < 3 {
564 return false
565 }
566 nameType := d[0]
567 nameLen := int(d[1])<<8 | int(d[2])
568 d = d[3:]
569 if len(d) < nameLen {
570 return false
571 }
572 if nameType == 0 {
573 m.serverName = string(d[0:nameLen])
574 break
575 }
576 d = d[nameLen:]
577 }
578 case extensionNextProtoNeg:
579 if length > 0 {
580 return false
581 }
582 m.nextProtoNeg = true
583 case extensionStatusRequest:
584 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
585 case extensionSupportedCurves:
586 // http://tools.ietf.org/html/rfc4492#section-5.5.1
587 if length < 2 {
588 return false
589 }
590 l := int(data[0])<<8 | int(data[1])
591 if l%2 == 1 || length != l+2 {
592 return false
593 }
594 numCurves := l / 2
595 m.supportedCurves = make([]CurveID, numCurves)
596 d := data[2:]
597 for i := 0; i < numCurves; i++ {
598 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
599 d = d[2:]
600 }
601 case extensionSupportedPoints:
602 // http://tools.ietf.org/html/rfc4492#section-5.5.2
603 if length < 1 {
604 return false
605 }
606 l := int(data[0])
607 if length != l+1 {
608 return false
609 }
610 m.supportedPoints = make([]uint8, l)
611 copy(m.supportedPoints, data[1:])
612 case extensionSessionTicket:
613 // http://tools.ietf.org/html/rfc5077#section-3.2
614 m.ticketSupported = true
615 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400616 case extensionKeyShare:
617 // draft-ietf-tls-tls13 section 6.3.2.3
618 if length < 2 {
619 return false
620 }
621 l := int(data[0])<<8 | int(data[1])
622 if l != length-2 {
623 return false
624 }
625 d := data[2:length]
Nick Harperdcfbc672016-07-16 17:47:31 +0200626 m.hasKeyShares = true
Nick Harperf8b0e702016-06-30 19:59:01 -0400627 for len(d) > 0 {
628 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
629 // key_exchange (2-byte length prefix with at least 1 byte of content).
630 if len(d) < 5 {
631 return false
632 }
633 entry := keyShareEntry{}
634 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
635 keyExchLen := int(d[2])<<8 | int(d[3])
636 d = d[4:]
637 if len(d) < keyExchLen {
638 return false
639 }
640 entry.keyExchange = d[:keyExchLen]
641 d = d[keyExchLen:]
642 m.keyShares = append(m.keyShares, entry)
643 }
644 case extensionPreSharedKey:
Steven Valdeza833c352016-11-01 13:39:36 -0400645 // draft-ietf-tls-tls13-18 section 4.2.6
Nick Harperf8b0e702016-06-30 19:59:01 -0400646 if length < 2 {
647 return false
648 }
649 l := int(data[0])<<8 | int(data[1])
Steven Valdeza833c352016-11-01 13:39:36 -0400650 d := data[2 : l+2]
651 // Parse PSK identities.
Nick Harperf8b0e702016-06-30 19:59:01 -0400652 for len(d) > 0 {
653 if len(d) < 2 {
654 return false
655 }
656 pskLen := int(d[0])<<8 | int(d[1])
657 d = d[2:]
Steven Valdez5b986082016-09-01 12:29:49 -0400658
Steven Valdeza833c352016-11-01 13:39:36 -0400659 if len(d) < pskLen+4 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400660 return false
661 }
Steven Valdeza833c352016-11-01 13:39:36 -0400662 ticket := d[:pskLen]
663 obfuscatedTicketAge := uint32(d[pskLen])<<24 | uint32(d[pskLen+1])<<16 | uint32(d[pskLen+2])<<8 | uint32(d[pskLen+3])
664 psk := pskIdentity{
665 ticket: ticket,
666 obfuscatedTicketAge: obfuscatedTicketAge,
667 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400668 m.pskIdentities = append(m.pskIdentities, psk)
Steven Valdeza833c352016-11-01 13:39:36 -0400669 d = d[pskLen+4:]
Nick Harperf8b0e702016-06-30 19:59:01 -0400670 }
Steven Valdeza833c352016-11-01 13:39:36 -0400671 d = data[l+2:]
672 if len(d) < 2 {
673 return false
674 }
675 l = int(d[0])<<8 | int(d[1])
676 d = d[2:]
677 if l != len(d) {
678 return false
679 }
680 // Parse PSK binders.
681 for len(d) > 0 {
682 if len(d) < 1 {
683 return false
684 }
685 binderLen := int(d[0])
686 d = d[1:]
687 if binderLen > len(d) {
688 return false
689 }
690 m.pskBinders = append(m.pskBinders, d[:binderLen])
691 d = d[binderLen:]
692 }
693
694 // There must be the same number of identities as binders.
695 if len(m.pskIdentities) != len(m.pskBinders) {
696 return false
697 }
698 case extensionPSKKeyExchangeModes:
699 // draft-ietf-tls-tls13-18 section 4.2.7
700 if length < 1 {
701 return false
702 }
703 l := int(data[0])
704 if l != length-1 {
705 return false
706 }
707 m.pskKEModes = data[1:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400708 case extensionEarlyData:
709 // draft-ietf-tls-tls13 section 6.3.2.5
710 if length < 1 {
711 return false
712 }
713 l := int(data[0])
714 if length != l+1 {
715 return false
716 }
717 m.hasEarlyData = true
718 m.earlyDataContext = data[1:length]
David Benjamin3baa6e12016-10-07 21:10:38 -0400719 case extensionCookie:
720 if length < 2 {
721 return false
722 }
723 l := int(data[0])<<8 | int(data[1])
724 if l != length-2 || l == 0 {
725 return false
726 }
727 m.tls13Cookie = data[2 : 2+l]
Adam Langley95c29f32014-06-20 12:00:00 -0700728 case extensionSignatureAlgorithms:
729 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
730 if length < 2 || length&1 != 0 {
731 return false
732 }
733 l := int(data[0])<<8 | int(data[1])
734 if l != length-2 {
735 return false
736 }
737 n := l / 2
738 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700739 m.signatureAlgorithms = make([]signatureAlgorithm, n)
740 for i := range m.signatureAlgorithms {
741 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700742 d = d[2:]
743 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400744 case extensionSupportedVersions:
745 if length < 1+2 {
746 return false
747 }
748 l := int(data[0])
749 if l != length-1 || l%2 == 1 || l < 2 {
750 return false
751 }
752 n := l / 2
753 d := data[1:]
754 m.supportedVersions = make([]uint16, n)
755 for i := range m.supportedVersions {
756 m.supportedVersions[i] = uint16(d[0])<<8 | uint16(d[1])
757 d = d[2:]
758 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700759 case extensionRenegotiationInfo:
760 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700761 return false
762 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700763 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400764 case extensionALPN:
765 if length < 2 {
766 return false
767 }
768 l := int(data[0])<<8 | int(data[1])
769 if l != length-2 {
770 return false
771 }
772 d := data[2:length]
773 for len(d) != 0 {
774 stringLen := int(d[0])
775 d = d[1:]
776 if stringLen == 0 || stringLen > len(d) {
777 return false
778 }
779 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
780 d = d[stringLen:]
781 }
David Benjamind30a9902014-08-24 01:44:23 -0400782 case extensionChannelID:
783 if length > 0 {
784 return false
785 }
786 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700787 case extensionExtendedMasterSecret:
788 if length != 0 {
789 return false
790 }
791 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500792 case extensionUseSRTP:
793 if length < 2 {
794 return false
795 }
796 l := int(data[0])<<8 | int(data[1])
797 if l > length-2 || l%2 != 0 {
798 return false
799 }
800 n := l / 2
801 m.srtpProtectionProfiles = make([]uint16, n)
802 d := data[2:length]
803 for i := 0; i < n; i++ {
804 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
805 d = d[2:]
806 }
807 if len(d) < 1 || int(d[0]) != len(d)-1 {
808 return false
809 }
810 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500811 case extensionSignedCertificateTimestamp:
812 if length != 0 {
813 return false
814 }
815 m.sctListSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700816 case extensionCustom:
817 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700818 }
819 data = data[length:]
David Benjamin65ac9972016-09-02 21:35:25 -0400820
821 if isGREASEValue(extension) {
822 m.hasGREASEExtension = true
823 }
Adam Langley95c29f32014-06-20 12:00:00 -0700824 }
825
826 return true
827}
828
829type serverHelloMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -0400830 raw []byte
831 isDTLS bool
832 vers uint16
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400833 versOverride uint16
Nick Harperb41d2e42016-07-01 17:50:32 -0400834 random []byte
835 sessionId []byte
836 cipherSuite uint16
837 hasKeyShare bool
838 keyShare keyShareEntry
839 hasPSKIdentity bool
840 pskIdentity uint16
841 earlyDataIndication bool
842 compressionMethod uint8
David Benjamin490469f2016-10-05 22:44:38 -0400843 customExtension string
844 unencryptedALPN string
Nick Harperb41d2e42016-07-01 17:50:32 -0400845 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700846}
847
Adam Langley95c29f32014-06-20 12:00:00 -0700848func (m *serverHelloMsg) marshal() []byte {
849 if m.raw != nil {
850 return m.raw
851 }
852
Nick Harper5212ef82016-06-30 19:26:07 -0400853 handshakeMsg := newByteBuilder()
854 handshakeMsg.addU8(typeServerHello)
855 hello := handshakeMsg.addU24LengthPrefixed()
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400856
857 // m.vers is used both to determine the format of the rest of the
858 // ServerHello and to override the value, so include a second version
859 // field.
860 vers, ok := wireToVersion(m.vers, m.isDTLS)
861 if !ok {
862 panic("unknown version")
863 }
864 if m.versOverride != 0 {
865 hello.addU16(m.versOverride)
866 } else {
867 hello.addU16(m.vers)
868 }
869
Nick Harper5212ef82016-06-30 19:26:07 -0400870 hello.addBytes(m.random)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400871 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400872 sessionId := hello.addU8LengthPrefixed()
873 sessionId.addBytes(m.sessionId)
874 }
Nick Harper5212ef82016-06-30 19:26:07 -0400875 hello.addU16(m.cipherSuite)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400876 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400877 hello.addU8(m.compressionMethod)
878 }
Adam Langley95c29f32014-06-20 12:00:00 -0700879
Nick Harper5212ef82016-06-30 19:26:07 -0400880 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400881
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400882 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400883 if m.hasKeyShare {
884 extensions.addU16(extensionKeyShare)
885 keyShare := extensions.addU16LengthPrefixed()
886 keyShare.addU16(uint16(m.keyShare.group))
887 keyExchange := keyShare.addU16LengthPrefixed()
888 keyExchange.addBytes(m.keyShare.keyExchange)
889 }
890 if m.hasPSKIdentity {
891 extensions.addU16(extensionPreSharedKey)
892 extensions.addU16(2) // Length
893 extensions.addU16(m.pskIdentity)
894 }
895 if m.earlyDataIndication {
896 extensions.addU16(extensionEarlyData)
897 extensions.addU16(0) // Length
898 }
David Benjamin490469f2016-10-05 22:44:38 -0400899 if len(m.customExtension) > 0 {
900 extensions.addU16(extensionCustom)
901 customExt := extensions.addU16LengthPrefixed()
902 customExt.addBytes([]byte(m.customExtension))
903 }
904 if len(m.unencryptedALPN) > 0 {
905 extensions.addU16(extensionALPN)
906 extension := extensions.addU16LengthPrefixed()
907
908 protocolNameList := extension.addU16LengthPrefixed()
909 protocolName := protocolNameList.addU8LengthPrefixed()
910 protocolName.addBytes([]byte(m.unencryptedALPN))
911 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400912 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400913 m.extensions.marshal(extensions)
Nick Harperb41d2e42016-07-01 17:50:32 -0400914 if extensions.len() == 0 {
915 hello.discardChild()
916 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400917 }
918
919 m.raw = handshakeMsg.finish()
920 return m.raw
921}
922
923func (m *serverHelloMsg) unmarshal(data []byte) bool {
924 if len(data) < 42 {
925 return false
926 }
927 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400928 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400929 vers, ok := wireToVersion(m.vers, m.isDTLS)
930 if !ok {
931 return false
932 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400933 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400934 data = data[38:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400935 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400936 sessionIdLen := int(data[0])
937 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
938 return false
939 }
940 m.sessionId = data[1 : 1+sessionIdLen]
941 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400942 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400943 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400944 return false
945 }
946 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400947 data = data[2:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400948 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400949 if len(data) < 1 {
950 return false
951 }
952 m.compressionMethod = data[0]
953 data = data[1:]
954 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400955
David Benjamin8d315d72016-07-18 01:03:18 +0200956 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400957 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400958 m.extensions = serverExtensions{}
959 return true
960 }
961 if len(data) < 2 {
962 return false
963 }
964
965 extensionsLength := int(data[0])<<8 | int(data[1])
966 data = data[2:]
967 if len(data) != extensionsLength {
968 return false
969 }
970
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400971 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400972 for len(data) != 0 {
973 if len(data) < 4 {
974 return false
975 }
976 extension := uint16(data[0])<<8 | uint16(data[1])
977 length := int(data[2])<<8 | int(data[3])
978 data = data[4:]
979
980 if len(data) < length {
981 return false
982 }
983 d := data[:length]
984 data = data[length:]
985
986 switch extension {
987 case extensionKeyShare:
988 m.hasKeyShare = true
989 if len(d) < 4 {
990 return false
991 }
992 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
993 keyExchLen := int(d[2])<<8 | int(d[3])
994 if keyExchLen != len(d)-4 {
995 return false
996 }
997 m.keyShare.keyExchange = make([]byte, keyExchLen)
998 copy(m.keyShare.keyExchange, d[4:])
999 case extensionPreSharedKey:
1000 if len(d) != 2 {
1001 return false
1002 }
1003 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
1004 m.hasPSKIdentity = true
1005 case extensionEarlyData:
1006 if len(d) != 0 {
1007 return false
1008 }
1009 m.earlyDataIndication = true
1010 default:
1011 // Only allow the 3 extensions that are sent in
1012 // the clear in TLS 1.3.
1013 return false
1014 }
1015 }
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001016 } else if !m.extensions.unmarshal(data, vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -04001017 return false
1018 }
1019
1020 return true
1021}
1022
Nick Harperb41d2e42016-07-01 17:50:32 -04001023type encryptedExtensionsMsg struct {
1024 raw []byte
1025 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -04001026 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001027}
1028
1029func (m *encryptedExtensionsMsg) marshal() []byte {
1030 if m.raw != nil {
1031 return m.raw
1032 }
1033
1034 encryptedExtensionsMsg := newByteBuilder()
1035 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
1036 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -04001037 if !m.empty {
1038 extensions := encryptedExtensions.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001039 m.extensions.marshal(extensions)
Steven Valdez143e8b32016-07-11 13:19:03 -04001040 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001041
1042 m.raw = encryptedExtensionsMsg.finish()
1043 return m.raw
1044}
1045
1046func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -04001047 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001048 if len(data) < 6 {
1049 return false
1050 }
1051 if data[0] != typeEncryptedExtensions {
1052 return false
1053 }
1054 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1055 data = data[4:]
1056 if len(data) != msgLen {
1057 return false
1058 }
1059 extLen := int(data[0])<<8 | int(data[1])
1060 data = data[2:]
1061 if extLen != len(data) {
1062 return false
1063 }
David Benjamin44b33bc2016-07-01 22:40:23 -04001064 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -04001065}
1066
Nick Harperb3d51be2016-07-01 11:43:18 -04001067type serverExtensions struct {
1068 nextProtoNeg bool
1069 nextProtos []string
1070 ocspStapling bool
1071 ticketSupported bool
1072 secureRenegotiation []byte
1073 alpnProtocol string
1074 alpnProtocolEmpty bool
1075 duplicateExtension bool
1076 channelIDRequested bool
1077 extendedMasterSecret bool
1078 srtpProtectionProfile uint16
1079 srtpMasterKeyIdentifier string
1080 sctList []byte
1081 customExtension string
Steven Valdeza833c352016-11-01 13:39:36 -04001082 npnAfterAlpn bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001083 hasKeyShare bool
1084 keyShare keyShareEntry
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 }
Adam Langley95c29f32014-06-20 12:00:00 -07001179}
1180
David Benjamin44b33bc2016-07-01 22:40:23 -04001181func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001182 // Reset all fields.
1183 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001184
1185 for len(data) != 0 {
1186 if len(data) < 4 {
1187 return false
1188 }
1189 extension := uint16(data[0])<<8 | uint16(data[1])
1190 length := int(data[2])<<8 | int(data[3])
1191 data = data[4:]
1192 if len(data) < length {
1193 return false
1194 }
1195
1196 switch extension {
1197 case extensionNextProtoNeg:
1198 m.nextProtoNeg = true
1199 d := data[:length]
1200 for len(d) > 0 {
1201 l := int(d[0])
1202 d = d[1:]
1203 if l == 0 || l > len(d) {
1204 return false
1205 }
1206 m.nextProtos = append(m.nextProtos, string(d[:l]))
1207 d = d[l:]
1208 }
1209 case extensionStatusRequest:
Steven Valdeza833c352016-11-01 13:39:36 -04001210 if length > 0 {
1211 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001212 }
Steven Valdeza833c352016-11-01 13:39:36 -04001213 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001214 case extensionSessionTicket:
1215 if length > 0 {
1216 return false
1217 }
1218 m.ticketSupported = true
1219 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001220 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001221 return false
1222 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001223 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001224 case extensionALPN:
1225 d := data[:length]
1226 if len(d) < 3 {
1227 return false
1228 }
1229 l := int(d[0])<<8 | int(d[1])
1230 if l != len(d)-2 {
1231 return false
1232 }
1233 d = d[2:]
1234 l = int(d[0])
1235 if l != len(d)-1 {
1236 return false
1237 }
1238 d = d[1:]
1239 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001240 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001241 case extensionChannelID:
1242 if length > 0 {
1243 return false
1244 }
1245 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001246 case extensionExtendedMasterSecret:
1247 if length != 0 {
1248 return false
1249 }
1250 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001251 case extensionUseSRTP:
1252 if length < 2+2+1 {
1253 return false
1254 }
1255 if data[0] != 0 || data[1] != 2 {
1256 return false
1257 }
1258 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1259 d := data[4:length]
1260 l := int(d[0])
1261 if l != len(d)-1 {
1262 return false
1263 }
1264 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001265 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001266 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001267 case extensionCustom:
1268 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001269 case extensionServerName:
1270 if length != 0 {
1271 return false
1272 }
1273 // Ignore this extension from the server.
1274 case extensionSupportedPoints:
1275 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001276 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001277 return false
1278 }
1279 // Ignore this extension from the server.
David Benjamin4ee027f2016-07-17 12:34:41 +02001280 case extensionSupportedCurves:
1281 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001282 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001283 return false
1284 }
David Benjamin46f94bd2016-07-14 16:43:37 -04001285 default:
1286 // Unknown extensions are illegal from the server.
1287 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001288 }
1289 data = data[length:]
1290 }
1291
1292 return true
1293}
1294
Nick Harperdcfbc672016-07-16 17:47:31 +02001295type helloRetryRequestMsg struct {
David Benjamin3baa6e12016-10-07 21:10:38 -04001296 raw []byte
1297 vers uint16
1298 hasSelectedGroup bool
1299 selectedGroup CurveID
1300 cookie []byte
1301 customExtension string
1302 duplicateExtensions bool
Nick Harperdcfbc672016-07-16 17:47:31 +02001303}
1304
1305func (m *helloRetryRequestMsg) marshal() []byte {
1306 if m.raw != nil {
1307 return m.raw
1308 }
1309
1310 retryRequestMsg := newByteBuilder()
1311 retryRequestMsg.addU8(typeHelloRetryRequest)
1312 retryRequest := retryRequestMsg.addU24LengthPrefixed()
1313 retryRequest.addU16(m.vers)
David Benjamin3baa6e12016-10-07 21:10:38 -04001314 extensions := retryRequest.addU16LengthPrefixed()
1315
1316 count := 1
1317 if m.duplicateExtensions {
1318 count = 2
1319 }
1320
1321 for i := 0; i < count; i++ {
1322 if m.hasSelectedGroup {
1323 extensions.addU16(extensionKeyShare)
1324 extensions.addU16(2) // length
1325 extensions.addU16(uint16(m.selectedGroup))
1326 }
1327 if len(m.cookie) > 0 {
1328 extensions.addU16(extensionCookie)
1329 body := extensions.addU16LengthPrefixed()
1330 body.addU16LengthPrefixed().addBytes(m.cookie)
1331 }
1332 if len(m.customExtension) > 0 {
1333 extensions.addU16(extensionCustom)
1334 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
1335 }
1336 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001337
1338 m.raw = retryRequestMsg.finish()
1339 return m.raw
1340}
1341
1342func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1343 m.raw = data
David Benjamin3baa6e12016-10-07 21:10:38 -04001344 if len(data) < 8 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001345 return false
1346 }
1347 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin3baa6e12016-10-07 21:10:38 -04001348 extLen := int(data[6])<<8 | int(data[7])
1349 data = data[8:]
1350 if len(data) != extLen || len(data) == 0 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001351 return false
1352 }
David Benjamin3baa6e12016-10-07 21:10:38 -04001353 for len(data) > 0 {
1354 if len(data) < 4 {
1355 return false
1356 }
1357 extension := uint16(data[0])<<8 | uint16(data[1])
1358 length := int(data[2])<<8 | int(data[3])
1359 data = data[4:]
1360 if len(data) < length {
1361 return false
1362 }
1363
1364 switch extension {
1365 case extensionKeyShare:
1366 if length != 2 {
1367 return false
1368 }
1369 m.hasSelectedGroup = true
1370 m.selectedGroup = CurveID(data[0])<<8 | CurveID(data[1])
1371 case extensionCookie:
1372 if length < 2 {
1373 return false
1374 }
1375 cookieLen := int(data[0])<<8 | int(data[1])
1376 if 2+cookieLen != length {
1377 return false
1378 }
1379 m.cookie = data[2 : 2+cookieLen]
1380 default:
1381 // Unknown extensions are illegal from the server.
1382 return false
1383 }
1384 data = data[length:]
1385 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001386 return true
1387}
1388
Steven Valdeza833c352016-11-01 13:39:36 -04001389type certificateEntry struct {
1390 data []byte
1391 ocspResponse []byte
1392 sctList []byte
1393 duplicateExtensions bool
1394 extraExtension []byte
1395}
1396
Adam Langley95c29f32014-06-20 12:00:00 -07001397type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001398 raw []byte
1399 hasRequestContext bool
1400 requestContext []byte
Steven Valdeza833c352016-11-01 13:39:36 -04001401 certificates []certificateEntry
Adam Langley95c29f32014-06-20 12:00:00 -07001402}
1403
Adam Langley95c29f32014-06-20 12:00:00 -07001404func (m *certificateMsg) marshal() (x []byte) {
1405 if m.raw != nil {
1406 return m.raw
1407 }
1408
Nick Harper7e0442a2016-07-01 17:40:09 -04001409 certMsg := newByteBuilder()
1410 certMsg.addU8(typeCertificate)
1411 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001412 if m.hasRequestContext {
1413 context := certificate.addU8LengthPrefixed()
1414 context.addBytes(m.requestContext)
1415 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001416 certificateList := certificate.addU24LengthPrefixed()
1417 for _, cert := range m.certificates {
1418 certEntry := certificateList.addU24LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001419 certEntry.addBytes(cert.data)
1420 if m.hasRequestContext {
1421 extensions := certificateList.addU16LengthPrefixed()
1422 count := 1
1423 if cert.duplicateExtensions {
1424 count = 2
1425 }
1426
1427 for i := 0; i < count; i++ {
1428 if cert.ocspResponse != nil {
1429 extensions.addU16(extensionStatusRequest)
1430 body := extensions.addU16LengthPrefixed()
1431 body.addU8(statusTypeOCSP)
1432 response := body.addU24LengthPrefixed()
1433 response.addBytes(cert.ocspResponse)
1434 }
1435
1436 if cert.sctList != nil {
1437 extensions.addU16(extensionSignedCertificateTimestamp)
1438 extension := extensions.addU16LengthPrefixed()
1439 extension.addBytes(cert.sctList)
1440 }
1441 }
1442 if cert.extraExtension != nil {
1443 extensions.addBytes(cert.extraExtension)
1444 }
1445 }
Adam Langley95c29f32014-06-20 12:00:00 -07001446 }
1447
Nick Harper7e0442a2016-07-01 17:40:09 -04001448 m.raw = certMsg.finish()
1449 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001450}
1451
1452func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001453 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001454 return false
1455 }
1456
1457 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001458 data = data[4:]
1459
1460 if m.hasRequestContext {
1461 if len(data) == 0 {
1462 return false
1463 }
1464 contextLen := int(data[0])
1465 if len(data) < 1+contextLen {
1466 return false
1467 }
1468 m.requestContext = make([]byte, contextLen)
1469 copy(m.requestContext, data[1:])
1470 data = data[1+contextLen:]
1471 }
1472
1473 if len(data) < 3 {
1474 return false
1475 }
1476 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1477 data = data[3:]
1478 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001479 return false
1480 }
1481
Steven Valdeza833c352016-11-01 13:39:36 -04001482 m.certificates = nil
1483 for len(data) != 0 {
1484 if len(data) < 3 {
Adam Langley95c29f32014-06-20 12:00:00 -07001485 return false
1486 }
Steven Valdeza833c352016-11-01 13:39:36 -04001487 certLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1488 if len(data) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001489 return false
1490 }
Steven Valdeza833c352016-11-01 13:39:36 -04001491 cert := certificateEntry{
1492 data: data[3 : 3+certLen],
1493 }
1494 data = data[3+certLen:]
1495 if m.hasRequestContext {
1496 if len(data) < 2 {
1497 return false
1498 }
1499 extensionsLen := int(data[0])<<8 | int(data[1])
1500 if len(data) < 2+extensionsLen {
1501 return false
1502 }
1503 extensions := data[2 : 2+extensionsLen]
1504 data = data[2+extensionsLen:]
1505 for len(extensions) != 0 {
1506 if len(extensions) < 4 {
1507 return false
1508 }
1509 extension := uint16(extensions[0])<<8 | uint16(extensions[1])
1510 length := int(extensions[2])<<8 | int(extensions[3])
1511 if len(extensions) < 4+length {
1512 return false
1513 }
1514 contents := extensions[4 : 4+length]
1515 extensions = extensions[4+length:]
Adam Langley95c29f32014-06-20 12:00:00 -07001516
Steven Valdeza833c352016-11-01 13:39:36 -04001517 switch extension {
1518 case extensionStatusRequest:
1519 if length < 4 {
1520 return false
1521 }
1522 if contents[0] != statusTypeOCSP {
1523 return false
1524 }
1525 respLen := int(contents[1])<<16 | int(contents[2])<<8 | int(contents[3])
1526 if respLen+4 != len(contents) || respLen == 0 {
1527 return false
1528 }
1529 cert.ocspResponse = contents[4:]
1530 case extensionSignedCertificateTimestamp:
1531 cert.sctList = contents
1532 default:
1533 return false
1534 }
1535 }
1536 }
1537 m.certificates = append(m.certificates, cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001538 }
1539
1540 return true
1541}
1542
1543type serverKeyExchangeMsg struct {
1544 raw []byte
1545 key []byte
1546}
1547
Adam Langley95c29f32014-06-20 12:00:00 -07001548func (m *serverKeyExchangeMsg) marshal() []byte {
1549 if m.raw != nil {
1550 return m.raw
1551 }
1552 length := len(m.key)
1553 x := make([]byte, length+4)
1554 x[0] = typeServerKeyExchange
1555 x[1] = uint8(length >> 16)
1556 x[2] = uint8(length >> 8)
1557 x[3] = uint8(length)
1558 copy(x[4:], m.key)
1559
1560 m.raw = x
1561 return x
1562}
1563
1564func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1565 m.raw = data
1566 if len(data) < 4 {
1567 return false
1568 }
1569 m.key = data[4:]
1570 return true
1571}
1572
1573type certificateStatusMsg struct {
1574 raw []byte
1575 statusType uint8
1576 response []byte
1577}
1578
Adam Langley95c29f32014-06-20 12:00:00 -07001579func (m *certificateStatusMsg) marshal() []byte {
1580 if m.raw != nil {
1581 return m.raw
1582 }
1583
1584 var x []byte
1585 if m.statusType == statusTypeOCSP {
1586 x = make([]byte, 4+4+len(m.response))
1587 x[0] = typeCertificateStatus
1588 l := len(m.response) + 4
1589 x[1] = byte(l >> 16)
1590 x[2] = byte(l >> 8)
1591 x[3] = byte(l)
1592 x[4] = statusTypeOCSP
1593
1594 l -= 4
1595 x[5] = byte(l >> 16)
1596 x[6] = byte(l >> 8)
1597 x[7] = byte(l)
1598 copy(x[8:], m.response)
1599 } else {
1600 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1601 }
1602
1603 m.raw = x
1604 return x
1605}
1606
1607func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1608 m.raw = data
1609 if len(data) < 5 {
1610 return false
1611 }
1612 m.statusType = data[4]
1613
1614 m.response = nil
1615 if m.statusType == statusTypeOCSP {
1616 if len(data) < 8 {
1617 return false
1618 }
1619 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1620 if uint32(len(data)) != 4+4+respLen {
1621 return false
1622 }
1623 m.response = data[8:]
1624 }
1625 return true
1626}
1627
1628type serverHelloDoneMsg struct{}
1629
Adam Langley95c29f32014-06-20 12:00:00 -07001630func (m *serverHelloDoneMsg) marshal() []byte {
1631 x := make([]byte, 4)
1632 x[0] = typeServerHelloDone
1633 return x
1634}
1635
1636func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1637 return len(data) == 4
1638}
1639
1640type clientKeyExchangeMsg struct {
1641 raw []byte
1642 ciphertext []byte
1643}
1644
Adam Langley95c29f32014-06-20 12:00:00 -07001645func (m *clientKeyExchangeMsg) marshal() []byte {
1646 if m.raw != nil {
1647 return m.raw
1648 }
1649 length := len(m.ciphertext)
1650 x := make([]byte, length+4)
1651 x[0] = typeClientKeyExchange
1652 x[1] = uint8(length >> 16)
1653 x[2] = uint8(length >> 8)
1654 x[3] = uint8(length)
1655 copy(x[4:], m.ciphertext)
1656
1657 m.raw = x
1658 return x
1659}
1660
1661func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1662 m.raw = data
1663 if len(data) < 4 {
1664 return false
1665 }
1666 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1667 if l != len(data)-4 {
1668 return false
1669 }
1670 m.ciphertext = data[4:]
1671 return true
1672}
1673
1674type finishedMsg struct {
1675 raw []byte
1676 verifyData []byte
1677}
1678
Adam Langley95c29f32014-06-20 12:00:00 -07001679func (m *finishedMsg) marshal() (x []byte) {
1680 if m.raw != nil {
1681 return m.raw
1682 }
1683
1684 x = make([]byte, 4+len(m.verifyData))
1685 x[0] = typeFinished
1686 x[3] = byte(len(m.verifyData))
1687 copy(x[4:], m.verifyData)
1688 m.raw = x
1689 return
1690}
1691
1692func (m *finishedMsg) unmarshal(data []byte) bool {
1693 m.raw = data
1694 if len(data) < 4 {
1695 return false
1696 }
1697 m.verifyData = data[4:]
1698 return true
1699}
1700
1701type nextProtoMsg struct {
1702 raw []byte
1703 proto string
1704}
1705
Adam Langley95c29f32014-06-20 12:00:00 -07001706func (m *nextProtoMsg) marshal() []byte {
1707 if m.raw != nil {
1708 return m.raw
1709 }
1710 l := len(m.proto)
1711 if l > 255 {
1712 l = 255
1713 }
1714
1715 padding := 32 - (l+2)%32
1716 length := l + padding + 2
1717 x := make([]byte, length+4)
1718 x[0] = typeNextProtocol
1719 x[1] = uint8(length >> 16)
1720 x[2] = uint8(length >> 8)
1721 x[3] = uint8(length)
1722
1723 y := x[4:]
1724 y[0] = byte(l)
1725 copy(y[1:], []byte(m.proto[0:l]))
1726 y = y[1+l:]
1727 y[0] = byte(padding)
1728
1729 m.raw = x
1730
1731 return x
1732}
1733
1734func (m *nextProtoMsg) unmarshal(data []byte) bool {
1735 m.raw = data
1736
1737 if len(data) < 5 {
1738 return false
1739 }
1740 data = data[4:]
1741 protoLen := int(data[0])
1742 data = data[1:]
1743 if len(data) < protoLen {
1744 return false
1745 }
1746 m.proto = string(data[0:protoLen])
1747 data = data[protoLen:]
1748
1749 if len(data) < 1 {
1750 return false
1751 }
1752 paddingLen := int(data[0])
1753 data = data[1:]
1754 if len(data) != paddingLen {
1755 return false
1756 }
1757
1758 return true
1759}
1760
1761type certificateRequestMsg struct {
1762 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001763 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001764 // of signature and hash functions. This change was introduced with TLS
1765 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001766 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001767 // hasRequestContext indicates whether this message includes a context
1768 // field instead of certificateTypes. This change was introduced with
1769 // TLS 1.3.
1770 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001771
1772 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001773 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001774 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001775 certificateAuthorities [][]byte
1776}
1777
Nick Harper7e0442a2016-07-01 17:40:09 -04001778func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001779 if m.raw != nil {
1780 return m.raw
1781 }
1782
1783 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001784 builder := newByteBuilder()
1785 builder.addU8(typeCertificateRequest)
1786 body := builder.addU24LengthPrefixed()
1787
Nick Harperb41d2e42016-07-01 17:50:32 -04001788 if m.hasRequestContext {
1789 requestContext := body.addU8LengthPrefixed()
1790 requestContext.addBytes(m.requestContext)
1791 } else {
1792 certificateTypes := body.addU8LengthPrefixed()
1793 certificateTypes.addBytes(m.certificateTypes)
1794 }
Adam Langley95c29f32014-06-20 12:00:00 -07001795
Nick Harper60edffd2016-06-21 15:19:24 -07001796 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001797 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001798 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001799 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001800 }
1801 }
1802
Nick Harper7e0442a2016-07-01 17:40:09 -04001803 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001804 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001805 caEntry := certificateAuthorities.addU16LengthPrefixed()
1806 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001807 }
1808
David Benjamin8d343b42016-07-09 14:26:01 -07001809 if m.hasRequestContext {
1810 // Emit no certificate extensions.
1811 body.addU16(0)
1812 }
1813
Nick Harper7e0442a2016-07-01 17:40:09 -04001814 m.raw = builder.finish()
1815 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001816}
1817
1818func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1819 m.raw = data
1820
1821 if len(data) < 5 {
1822 return false
1823 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001824 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001825
Nick Harperb41d2e42016-07-01 17:50:32 -04001826 if m.hasRequestContext {
1827 contextLen := int(data[0])
1828 if len(data) < 1+contextLen {
1829 return false
1830 }
1831 m.requestContext = make([]byte, contextLen)
1832 copy(m.requestContext, data[1:])
1833 data = data[1+contextLen:]
1834 } else {
1835 numCertTypes := int(data[0])
1836 if len(data) < 1+numCertTypes {
1837 return false
1838 }
1839 m.certificateTypes = make([]byte, numCertTypes)
1840 copy(m.certificateTypes, data[1:])
1841 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001842 }
1843
Nick Harper60edffd2016-06-21 15:19:24 -07001844 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001845 if len(data) < 2 {
1846 return false
1847 }
Nick Harper60edffd2016-06-21 15:19:24 -07001848 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001849 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001850 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001851 return false
1852 }
Nick Harper60edffd2016-06-21 15:19:24 -07001853 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001854 return false
1855 }
Nick Harper60edffd2016-06-21 15:19:24 -07001856 numSigAlgs := sigAlgsLen / 2
1857 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1858 for i := range m.signatureAlgorithms {
1859 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001860 data = data[2:]
1861 }
1862 }
1863
1864 if len(data) < 2 {
1865 return false
1866 }
1867 casLength := uint16(data[0])<<8 | uint16(data[1])
1868 data = data[2:]
1869 if len(data) < int(casLength) {
1870 return false
1871 }
1872 cas := make([]byte, casLength)
1873 copy(cas, data)
1874 data = data[casLength:]
1875
1876 m.certificateAuthorities = nil
1877 for len(cas) > 0 {
1878 if len(cas) < 2 {
1879 return false
1880 }
1881 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1882 cas = cas[2:]
1883
1884 if len(cas) < int(caLen) {
1885 return false
1886 }
1887
1888 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1889 cas = cas[caLen:]
1890 }
David Benjamin8d343b42016-07-09 14:26:01 -07001891
1892 if m.hasRequestContext {
1893 // Ignore certificate extensions.
1894 if len(data) < 2 {
1895 return false
1896 }
1897 extsLength := int(data[0])<<8 | int(data[1])
1898 if len(data) < 2+extsLength {
1899 return false
1900 }
1901 data = data[2+extsLength:]
1902 }
1903
Adam Langley95c29f32014-06-20 12:00:00 -07001904 if len(data) > 0 {
1905 return false
1906 }
1907
1908 return true
1909}
1910
1911type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07001912 raw []byte
1913 hasSignatureAlgorithm bool
1914 signatureAlgorithm signatureAlgorithm
1915 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001916}
1917
Adam Langley95c29f32014-06-20 12:00:00 -07001918func (m *certificateVerifyMsg) marshal() (x []byte) {
1919 if m.raw != nil {
1920 return m.raw
1921 }
1922
1923 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1924 siglength := len(m.signature)
1925 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07001926 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001927 length += 2
1928 }
1929 x = make([]byte, 4+length)
1930 x[0] = typeCertificateVerify
1931 x[1] = uint8(length >> 16)
1932 x[2] = uint8(length >> 8)
1933 x[3] = uint8(length)
1934 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001935 if m.hasSignatureAlgorithm {
1936 y[0] = byte(m.signatureAlgorithm >> 8)
1937 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07001938 y = y[2:]
1939 }
1940 y[0] = uint8(siglength >> 8)
1941 y[1] = uint8(siglength)
1942 copy(y[2:], m.signature)
1943
1944 m.raw = x
1945
1946 return
1947}
1948
1949func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1950 m.raw = data
1951
1952 if len(data) < 6 {
1953 return false
1954 }
1955
1956 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1957 if uint32(len(data))-4 != length {
1958 return false
1959 }
1960
1961 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001962 if m.hasSignatureAlgorithm {
1963 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001964 data = data[2:]
1965 }
1966
1967 if len(data) < 2 {
1968 return false
1969 }
1970 siglength := int(data[0])<<8 + int(data[1])
1971 data = data[2:]
1972 if len(data) != siglength {
1973 return false
1974 }
1975
1976 m.signature = data
1977
1978 return true
1979}
1980
1981type newSessionTicketMsg struct {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04001982 raw []byte
1983 version uint16
1984 ticketLifetime uint32
Steven Valdeza833c352016-11-01 13:39:36 -04001985 ticketAgeAdd uint32
David Benjamin1a5e8ec2016-10-07 15:19:18 -04001986 ticket []byte
David Benjamin1286bee2016-10-07 15:25:06 -04001987 customExtension string
David Benjamin1a5e8ec2016-10-07 15:19:18 -04001988 hasGREASEExtension bool
Adam Langley95c29f32014-06-20 12:00:00 -07001989}
1990
David Benjamin58104882016-07-18 01:25:41 +02001991func (m *newSessionTicketMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001992 if m.raw != nil {
1993 return m.raw
1994 }
1995
1996 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjamin58104882016-07-18 01:25:41 +02001997 ticketMsg := newByteBuilder()
1998 ticketMsg.addU8(typeNewSessionTicket)
1999 body := ticketMsg.addU24LengthPrefixed()
2000 body.addU32(m.ticketLifetime)
2001 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002002 body.addU32(m.ticketAgeAdd)
Steven Valdez5b986082016-09-01 12:29:49 -04002003 }
2004
2005 ticket := body.addU16LengthPrefixed()
2006 ticket.addBytes(m.ticket)
2007
2008 if m.version >= VersionTLS13 {
David Benjamin1286bee2016-10-07 15:25:06 -04002009 extensions := body.addU16LengthPrefixed()
2010 if len(m.customExtension) > 0 {
2011 extensions.addU16(ticketExtensionCustom)
2012 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
2013 }
David Benjamin58104882016-07-18 01:25:41 +02002014 }
Adam Langley95c29f32014-06-20 12:00:00 -07002015
David Benjamin58104882016-07-18 01:25:41 +02002016 m.raw = ticketMsg.finish()
2017 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07002018}
2019
2020func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
2021 m.raw = data
2022
David Benjamin58104882016-07-18 01:25:41 +02002023 if len(data) < 8 {
2024 return false
2025 }
2026 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
2027 data = data[8:]
2028
2029 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002030 if len(data) < 4 {
David Benjamin58104882016-07-18 01:25:41 +02002031 return false
2032 }
Steven Valdeza833c352016-11-01 13:39:36 -04002033 m.ticketAgeAdd = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2034 data = data[4:]
David Benjamin58104882016-07-18 01:25:41 +02002035 }
2036
2037 if len(data) < 2 {
2038 return false
2039 }
2040 ticketLen := int(data[0])<<8 + int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002041 data = data[2:]
2042 if len(data) < ticketLen {
David Benjamin58104882016-07-18 01:25:41 +02002043 return false
2044 }
Steven Valdez5b986082016-09-01 12:29:49 -04002045
David Benjamin58104882016-07-18 01:25:41 +02002046 if m.version >= VersionTLS13 && ticketLen == 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07002047 return false
2048 }
2049
Steven Valdez5b986082016-09-01 12:29:49 -04002050 m.ticket = data[:ticketLen]
2051 data = data[ticketLen:]
2052
2053 if m.version >= VersionTLS13 {
2054 if len(data) < 2 {
2055 return false
2056 }
2057 extsLength := int(data[0])<<8 + int(data[1])
2058 data = data[2:]
2059 if len(data) < extsLength {
2060 return false
2061 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002062 extensions := data[:extsLength]
Steven Valdez5b986082016-09-01 12:29:49 -04002063 data = data[extsLength:]
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002064
2065 for len(extensions) > 0 {
2066 if len(extensions) < 4 {
2067 return false
2068 }
2069 extValue := uint16(extensions[0])<<8 | uint16(extensions[1])
2070 extLength := int(extensions[2])<<8 | int(extensions[3])
2071 if len(extensions) < 4+extLength {
2072 return false
2073 }
2074 extensions = extensions[4+extLength:]
2075
2076 if isGREASEValue(extValue) {
2077 m.hasGREASEExtension = true
2078 }
2079 }
Steven Valdez5b986082016-09-01 12:29:49 -04002080 }
2081
2082 if len(data) > 0 {
2083 return false
2084 }
Adam Langley95c29f32014-06-20 12:00:00 -07002085
2086 return true
2087}
2088
David Benjamind86c7672014-08-02 04:07:12 -04002089type v2ClientHelloMsg struct {
2090 raw []byte
2091 vers uint16
2092 cipherSuites []uint16
2093 sessionId []byte
2094 challenge []byte
2095}
2096
David Benjamind86c7672014-08-02 04:07:12 -04002097func (m *v2ClientHelloMsg) marshal() []byte {
2098 if m.raw != nil {
2099 return m.raw
2100 }
2101
2102 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
2103
2104 x := make([]byte, length)
2105 x[0] = 1
2106 x[1] = uint8(m.vers >> 8)
2107 x[2] = uint8(m.vers)
2108 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
2109 x[4] = uint8(len(m.cipherSuites) * 3)
2110 x[5] = uint8(len(m.sessionId) >> 8)
2111 x[6] = uint8(len(m.sessionId))
2112 x[7] = uint8(len(m.challenge) >> 8)
2113 x[8] = uint8(len(m.challenge))
2114 y := x[9:]
2115 for i, spec := range m.cipherSuites {
2116 y[i*3] = 0
2117 y[i*3+1] = uint8(spec >> 8)
2118 y[i*3+2] = uint8(spec)
2119 }
2120 y = y[len(m.cipherSuites)*3:]
2121 copy(y, m.sessionId)
2122 y = y[len(m.sessionId):]
2123 copy(y, m.challenge)
2124
2125 m.raw = x
2126
2127 return x
2128}
2129
David Benjamin83c0bc92014-08-04 01:23:53 -04002130type helloVerifyRequestMsg struct {
2131 raw []byte
2132 vers uint16
2133 cookie []byte
2134}
2135
David Benjamin83c0bc92014-08-04 01:23:53 -04002136func (m *helloVerifyRequestMsg) marshal() []byte {
2137 if m.raw != nil {
2138 return m.raw
2139 }
2140
2141 length := 2 + 1 + len(m.cookie)
2142
2143 x := make([]byte, 4+length)
2144 x[0] = typeHelloVerifyRequest
2145 x[1] = uint8(length >> 16)
2146 x[2] = uint8(length >> 8)
2147 x[3] = uint8(length)
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002148 vers := m.vers
David Benjamin83c0bc92014-08-04 01:23:53 -04002149 x[4] = uint8(vers >> 8)
2150 x[5] = uint8(vers)
2151 x[6] = uint8(len(m.cookie))
2152 copy(x[7:7+len(m.cookie)], m.cookie)
2153
2154 return x
2155}
2156
2157func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
2158 if len(data) < 4+2+1 {
2159 return false
2160 }
2161 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002162 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin83c0bc92014-08-04 01:23:53 -04002163 cookieLen := int(data[6])
2164 if cookieLen > 32 || len(data) != 7+cookieLen {
2165 return false
2166 }
2167 m.cookie = data[7 : 7+cookieLen]
2168
2169 return true
2170}
2171
David Benjamin24599a82016-06-30 18:56:53 -04002172type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04002173 raw []byte
2174 channelID []byte
2175}
2176
David Benjamin24599a82016-06-30 18:56:53 -04002177func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04002178 if m.raw != nil {
2179 return m.raw
2180 }
2181
2182 length := 2 + 2 + len(m.channelID)
2183
2184 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04002185 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04002186 x[1] = uint8(length >> 16)
2187 x[2] = uint8(length >> 8)
2188 x[3] = uint8(length)
2189 x[4] = uint8(extensionChannelID >> 8)
2190 x[5] = uint8(extensionChannelID & 0xff)
2191 x[6] = uint8(len(m.channelID) >> 8)
2192 x[7] = uint8(len(m.channelID) & 0xff)
2193 copy(x[8:], m.channelID)
2194
2195 return x
2196}
2197
David Benjamin24599a82016-06-30 18:56:53 -04002198func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04002199 if len(data) != 4+2+2+128 {
2200 return false
2201 }
2202 m.raw = data
2203 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
2204 return false
2205 }
2206 if int(data[6])<<8|int(data[7]) != 128 {
2207 return false
2208 }
2209 m.channelID = data[4+2+2:]
2210
2211 return true
2212}
2213
Adam Langley2ae77d22014-10-28 17:29:33 -07002214type helloRequestMsg struct {
2215}
2216
2217func (*helloRequestMsg) marshal() []byte {
2218 return []byte{typeHelloRequest, 0, 0, 0}
2219}
2220
2221func (*helloRequestMsg) unmarshal(data []byte) bool {
2222 return len(data) == 4
2223}
2224
David Benjamin21c00282016-07-18 21:56:23 +02002225type keyUpdateMsg struct {
Steven Valdezc4aa7272016-10-03 12:25:56 -04002226 raw []byte
2227 keyUpdateRequest byte
David Benjamin21c00282016-07-18 21:56:23 +02002228}
2229
Steven Valdezc4aa7272016-10-03 12:25:56 -04002230func (m *keyUpdateMsg) marshal() []byte {
2231 if m.raw != nil {
2232 return m.raw
2233 }
2234
2235 return []byte{typeKeyUpdate, 0, 0, 1, m.keyUpdateRequest}
David Benjamin21c00282016-07-18 21:56:23 +02002236}
2237
Steven Valdezc4aa7272016-10-03 12:25:56 -04002238func (m *keyUpdateMsg) unmarshal(data []byte) bool {
2239 m.raw = data
2240
2241 if len(data) != 5 {
2242 return false
2243 }
2244
2245 length := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
2246 if len(data)-4 != length {
2247 return false
2248 }
2249
2250 m.keyUpdateRequest = data[4]
2251 return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
David Benjamin21c00282016-07-18 21:56:23 +02002252}
2253
Adam Langley95c29f32014-06-20 12:00:00 -07002254func eqUint16s(x, y []uint16) bool {
2255 if len(x) != len(y) {
2256 return false
2257 }
2258 for i, v := range x {
2259 if y[i] != v {
2260 return false
2261 }
2262 }
2263 return true
2264}
2265
2266func eqCurveIDs(x, y []CurveID) bool {
2267 if len(x) != len(y) {
2268 return false
2269 }
2270 for i, v := range x {
2271 if y[i] != v {
2272 return false
2273 }
2274 }
2275 return true
2276}
2277
2278func eqStrings(x, y []string) bool {
2279 if len(x) != len(y) {
2280 return false
2281 }
2282 for i, v := range x {
2283 if y[i] != v {
2284 return false
2285 }
2286 }
2287 return true
2288}
2289
2290func eqByteSlices(x, y [][]byte) bool {
2291 if len(x) != len(y) {
2292 return false
2293 }
2294 for i, v := range x {
2295 if !bytes.Equal(v, y[i]) {
2296 return false
2297 }
2298 }
2299 return true
2300}
2301
Nick Harper60edffd2016-06-21 15:19:24 -07002302func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07002303 if len(x) != len(y) {
2304 return false
2305 }
2306 for i, v := range x {
2307 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07002308 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07002309 return false
2310 }
2311 }
2312 return true
2313}
Nick Harperf8b0e702016-06-30 19:59:01 -04002314
2315func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2316 if len(x) != len(y) {
2317 return false
2318 }
2319 for i, v := range x {
2320 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2321 return false
2322 }
2323 }
2324 return true
2325
2326}
Steven Valdez5b986082016-09-01 12:29:49 -04002327
2328func eqPSKIdentityLists(x, y []pskIdentity) bool {
2329 if len(x) != len(y) {
2330 return false
2331 }
2332 for i, v := range x {
Steven Valdeza833c352016-11-01 13:39:36 -04002333 if !bytes.Equal(y[i].ticket, v.ticket) || y[i].obfuscatedTicketAge != v.obfuscatedTicketAge {
Steven Valdez5b986082016-09-01 12:29:49 -04002334 return false
2335 }
2336 }
2337 return true
2338
2339}