blob: 1f87ad239c6d54774b068f75c721e6654e525d33 [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()
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)
David Benjaminc5665c92016-11-15 18:12:58 +0900345 extensions.addU16(0) // The length is zero.
Nick Harperf8b0e702016-06-30 19:59:01 -0400346 }
David Benjamin3baa6e12016-10-07 21:10:38 -0400347 if len(m.tls13Cookie) > 0 {
348 extensions.addU16(extensionCookie)
349 body := extensions.addU16LengthPrefixed()
350 body.addU16LengthPrefixed().addBytes(m.tls13Cookie)
351 }
Adam Langley95c29f32014-06-20 12:00:00 -0700352 if m.ticketSupported {
353 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400354 extensions.addU16(extensionSessionTicket)
355 sessionTicketExtension := extensions.addU16LengthPrefixed()
356 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700357 }
Nick Harper60edffd2016-06-21 15:19:24 -0700358 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700359 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400360 extensions.addU16(extensionSignatureAlgorithms)
361 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
362 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700363 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400364 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700365 }
366 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400367 if len(m.supportedVersions) > 0 {
368 extensions.addU16(extensionSupportedVersions)
369 supportedVersionsExtension := extensions.addU16LengthPrefixed()
370 supportedVersions := supportedVersionsExtension.addU8LengthPrefixed()
371 for _, version := range m.supportedVersions {
372 supportedVersions.addU16(uint16(version))
373 }
374 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700375 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400376 extensions.addU16(extensionRenegotiationInfo)
377 secureRenegoExt := extensions.addU16LengthPrefixed()
378 secureRenego := secureRenegoExt.addU8LengthPrefixed()
379 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700380 }
David Benjaminfa055a22014-09-15 16:51:51 -0400381 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400382 // https://tools.ietf.org/html/rfc7301#section-3.1
383 extensions.addU16(extensionALPN)
384 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400385
Nick Harper8dda5cc2016-06-30 18:51:11 -0400386 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400387 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400388 protocolName := protocolNameList.addU8LengthPrefixed()
389 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400390 }
David Benjaminfa055a22014-09-15 16:51:51 -0400391 }
David Benjamind30a9902014-08-24 01:44:23 -0400392 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400393 extensions.addU16(extensionChannelID)
394 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400395 }
Steven Valdeza833c352016-11-01 13:39:36 -0400396 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400397 extensions.addU16(extensionNextProtoNeg)
398 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400399 }
David Benjamin35a7a442014-07-05 00:23:20 -0400400 if m.duplicateExtension {
401 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400402 extensions.addU16(0xffff)
403 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400404 }
Adam Langley75712922014-10-10 16:23:43 -0700405 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500406 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400407 extensions.addU16(extensionExtendedMasterSecret)
408 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700409 }
David Benjaminca6c8262014-11-15 19:06:08 -0500410 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400411 // https://tools.ietf.org/html/rfc5764#section-4.1.1
412 extensions.addU16(extensionUseSRTP)
413 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500414
Nick Harper8dda5cc2016-06-30 18:51:11 -0400415 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500416 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400417 // An SRTPProtectionProfile is defined as uint8[2],
418 // not uint16. For some reason, we're storing it
419 // as a uint16.
420 srtpProtectionProfiles.addU8(byte(p >> 8))
421 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500422 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400423 srtpMki := useSrtpExt.addU8LengthPrefixed()
424 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500425 }
David Benjamin61f95272014-11-25 01:55:35 -0500426 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400427 extensions.addU16(extensionSignedCertificateTimestamp)
428 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500429 }
Adam Langley09505632015-07-30 18:10:13 -0700430 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400431 extensions.addU16(extensionCustom)
432 customExt := extensions.addU16LengthPrefixed()
433 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700434 }
David Benjamin6f600d62016-12-21 16:06:54 -0500435 if m.shortHeaderSupported {
436 extensions.addU16(extensionShortHeader)
437 extensions.addU16(0) // Length is always 0
438 }
Steven Valdeza833c352016-11-01 13:39:36 -0400439 // The PSK extension must be last (draft-ietf-tls-tls13-18 section 4.2.6).
440 if len(m.pskIdentities) > 0 && !m.pskBinderFirst {
441 extensions.addU16(extensionPreSharedKey)
442 pskExtension := extensions.addU16LengthPrefixed()
443
444 pskIdentities := pskExtension.addU16LengthPrefixed()
445 for _, psk := range m.pskIdentities {
446 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
447 pskIdentities.addU32(psk.obfuscatedTicketAge)
448 }
449 pskBinders := pskExtension.addU16LengthPrefixed()
450 for _, binder := range m.pskBinders {
451 pskBinders.addU8LengthPrefixed().addBytes(binder)
452 }
453 }
Adam Langley95c29f32014-06-20 12:00:00 -0700454
Nick Harper8dda5cc2016-06-30 18:51:11 -0400455 if extensions.len() == 0 {
456 hello.discardChild()
457 }
Adam Langley95c29f32014-06-20 12:00:00 -0700458
Nick Harper8dda5cc2016-06-30 18:51:11 -0400459 m.raw = handshakeMsg.finish()
460 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700461}
462
463func (m *clientHelloMsg) unmarshal(data []byte) bool {
464 if len(data) < 42 {
465 return false
466 }
467 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400468 m.vers = uint16(data[4])<<8 | uint16(data[5])
Adam Langley95c29f32014-06-20 12:00:00 -0700469 m.random = data[6:38]
470 sessionIdLen := int(data[38])
471 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
472 return false
473 }
474 m.sessionId = data[39 : 39+sessionIdLen]
475 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400476 if m.isDTLS {
477 if len(data) < 1 {
478 return false
479 }
480 cookieLen := int(data[0])
481 if cookieLen > 32 || len(data) < 1+cookieLen {
482 return false
483 }
484 m.cookie = data[1 : 1+cookieLen]
485 data = data[1+cookieLen:]
486 }
Adam Langley95c29f32014-06-20 12:00:00 -0700487 if len(data) < 2 {
488 return false
489 }
490 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
491 // they are uint16s, the number must be even.
492 cipherSuiteLen := int(data[0])<<8 | int(data[1])
493 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
494 return false
495 }
496 numCipherSuites := cipherSuiteLen / 2
497 m.cipherSuites = make([]uint16, numCipherSuites)
498 for i := 0; i < numCipherSuites; i++ {
499 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
500 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700501 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700502 }
503 }
504 data = data[2+cipherSuiteLen:]
505 if len(data) < 1 {
506 return false
507 }
508 compressionMethodsLen := int(data[0])
509 if len(data) < 1+compressionMethodsLen {
510 return false
511 }
512 m.compressionMethods = data[1 : 1+compressionMethodsLen]
513
514 data = data[1+compressionMethodsLen:]
515
516 m.nextProtoNeg = false
517 m.serverName = ""
518 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400519 m.keyShares = nil
520 m.pskIdentities = nil
521 m.hasEarlyData = false
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
David Benjaminc5665c92016-11-15 18:12:58 +0900710 if length != 0 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400711 return false
712 }
713 m.hasEarlyData = true
David Benjamin3baa6e12016-10-07 21:10:38 -0400714 case extensionCookie:
715 if length < 2 {
716 return false
717 }
718 l := int(data[0])<<8 | int(data[1])
719 if l != length-2 || l == 0 {
720 return false
721 }
722 m.tls13Cookie = data[2 : 2+l]
Adam Langley95c29f32014-06-20 12:00:00 -0700723 case extensionSignatureAlgorithms:
724 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
725 if length < 2 || length&1 != 0 {
726 return false
727 }
728 l := int(data[0])<<8 | int(data[1])
729 if l != length-2 {
730 return false
731 }
732 n := l / 2
733 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700734 m.signatureAlgorithms = make([]signatureAlgorithm, n)
735 for i := range m.signatureAlgorithms {
736 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700737 d = d[2:]
738 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400739 case extensionSupportedVersions:
740 if length < 1+2 {
741 return false
742 }
743 l := int(data[0])
744 if l != length-1 || l%2 == 1 || l < 2 {
745 return false
746 }
747 n := l / 2
748 d := data[1:]
749 m.supportedVersions = make([]uint16, n)
750 for i := range m.supportedVersions {
751 m.supportedVersions[i] = uint16(d[0])<<8 | uint16(d[1])
752 d = d[2:]
753 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700754 case extensionRenegotiationInfo:
755 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700756 return false
757 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700758 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400759 case extensionALPN:
760 if length < 2 {
761 return false
762 }
763 l := int(data[0])<<8 | int(data[1])
764 if l != length-2 {
765 return false
766 }
767 d := data[2:length]
768 for len(d) != 0 {
769 stringLen := int(d[0])
770 d = d[1:]
771 if stringLen == 0 || stringLen > len(d) {
772 return false
773 }
774 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
775 d = d[stringLen:]
776 }
David Benjamind30a9902014-08-24 01:44:23 -0400777 case extensionChannelID:
778 if length > 0 {
779 return false
780 }
781 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700782 case extensionExtendedMasterSecret:
783 if length != 0 {
784 return false
785 }
786 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500787 case extensionUseSRTP:
788 if length < 2 {
789 return false
790 }
791 l := int(data[0])<<8 | int(data[1])
792 if l > length-2 || l%2 != 0 {
793 return false
794 }
795 n := l / 2
796 m.srtpProtectionProfiles = make([]uint16, n)
797 d := data[2:length]
798 for i := 0; i < n; i++ {
799 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
800 d = d[2:]
801 }
802 if len(d) < 1 || int(d[0]) != len(d)-1 {
803 return false
804 }
805 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500806 case extensionSignedCertificateTimestamp:
807 if length != 0 {
808 return false
809 }
810 m.sctListSupported = true
David Benjamin6f600d62016-12-21 16:06:54 -0500811 case extensionShortHeader:
812 if length != 0 {
813 return false
814 }
815 m.shortHeaderSupported = 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
David Benjamin6f600d62016-12-21 16:06:54 -0500845 shortHeader bool
Nick Harperb41d2e42016-07-01 17:50:32 -0400846 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700847}
848
Adam Langley95c29f32014-06-20 12:00:00 -0700849func (m *serverHelloMsg) marshal() []byte {
850 if m.raw != nil {
851 return m.raw
852 }
853
Nick Harper5212ef82016-06-30 19:26:07 -0400854 handshakeMsg := newByteBuilder()
855 handshakeMsg.addU8(typeServerHello)
856 hello := handshakeMsg.addU24LengthPrefixed()
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400857
858 // m.vers is used both to determine the format of the rest of the
859 // ServerHello and to override the value, so include a second version
860 // field.
861 vers, ok := wireToVersion(m.vers, m.isDTLS)
862 if !ok {
863 panic("unknown version")
864 }
865 if m.versOverride != 0 {
866 hello.addU16(m.versOverride)
867 } else {
868 hello.addU16(m.vers)
869 }
870
Nick Harper5212ef82016-06-30 19:26:07 -0400871 hello.addBytes(m.random)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400872 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400873 sessionId := hello.addU8LengthPrefixed()
874 sessionId.addBytes(m.sessionId)
875 }
Nick Harper5212ef82016-06-30 19:26:07 -0400876 hello.addU16(m.cipherSuite)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400877 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400878 hello.addU8(m.compressionMethod)
879 }
Adam Langley95c29f32014-06-20 12:00:00 -0700880
Nick Harper5212ef82016-06-30 19:26:07 -0400881 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400882
David Benjamin6f600d62016-12-21 16:06:54 -0500883 if m.shortHeader {
884 extensions.addU16(extensionShortHeader)
885 extensions.addU16(0) // Length
886 }
887
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400888 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400889 if m.hasKeyShare {
890 extensions.addU16(extensionKeyShare)
891 keyShare := extensions.addU16LengthPrefixed()
892 keyShare.addU16(uint16(m.keyShare.group))
893 keyExchange := keyShare.addU16LengthPrefixed()
894 keyExchange.addBytes(m.keyShare.keyExchange)
895 }
896 if m.hasPSKIdentity {
897 extensions.addU16(extensionPreSharedKey)
898 extensions.addU16(2) // Length
899 extensions.addU16(m.pskIdentity)
900 }
901 if m.earlyDataIndication {
902 extensions.addU16(extensionEarlyData)
903 extensions.addU16(0) // Length
904 }
David Benjamin490469f2016-10-05 22:44:38 -0400905 if len(m.customExtension) > 0 {
906 extensions.addU16(extensionCustom)
907 customExt := extensions.addU16LengthPrefixed()
908 customExt.addBytes([]byte(m.customExtension))
909 }
910 if len(m.unencryptedALPN) > 0 {
911 extensions.addU16(extensionALPN)
912 extension := extensions.addU16LengthPrefixed()
913
914 protocolNameList := extension.addU16LengthPrefixed()
915 protocolName := protocolNameList.addU8LengthPrefixed()
916 protocolName.addBytes([]byte(m.unencryptedALPN))
917 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400918 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400919 m.extensions.marshal(extensions)
Nick Harperb41d2e42016-07-01 17:50:32 -0400920 if extensions.len() == 0 {
921 hello.discardChild()
922 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400923 }
924
925 m.raw = handshakeMsg.finish()
926 return m.raw
927}
928
929func (m *serverHelloMsg) unmarshal(data []byte) bool {
930 if len(data) < 42 {
931 return false
932 }
933 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400934 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400935 vers, ok := wireToVersion(m.vers, m.isDTLS)
936 if !ok {
937 return false
938 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400939 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400940 data = data[38:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400941 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400942 sessionIdLen := int(data[0])
943 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
944 return false
945 }
946 m.sessionId = data[1 : 1+sessionIdLen]
947 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400948 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400949 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400950 return false
951 }
952 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400953 data = data[2:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400954 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400955 if len(data) < 1 {
956 return false
957 }
958 m.compressionMethod = data[0]
959 data = data[1:]
960 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400961
David Benjamin8d315d72016-07-18 01:03:18 +0200962 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400963 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400964 m.extensions = serverExtensions{}
965 return true
966 }
967 if len(data) < 2 {
968 return false
969 }
970
971 extensionsLength := int(data[0])<<8 | int(data[1])
972 data = data[2:]
973 if len(data) != extensionsLength {
974 return false
975 }
976
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400977 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400978 for len(data) != 0 {
979 if len(data) < 4 {
980 return false
981 }
982 extension := uint16(data[0])<<8 | uint16(data[1])
983 length := int(data[2])<<8 | int(data[3])
984 data = data[4:]
985
986 if len(data) < length {
987 return false
988 }
989 d := data[:length]
990 data = data[length:]
991
992 switch extension {
993 case extensionKeyShare:
994 m.hasKeyShare = true
995 if len(d) < 4 {
996 return false
997 }
998 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
999 keyExchLen := int(d[2])<<8 | int(d[3])
1000 if keyExchLen != len(d)-4 {
1001 return false
1002 }
1003 m.keyShare.keyExchange = make([]byte, keyExchLen)
1004 copy(m.keyShare.keyExchange, d[4:])
1005 case extensionPreSharedKey:
1006 if len(d) != 2 {
1007 return false
1008 }
1009 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
1010 m.hasPSKIdentity = true
1011 case extensionEarlyData:
1012 if len(d) != 0 {
1013 return false
1014 }
1015 m.earlyDataIndication = true
David Benjamin6f600d62016-12-21 16:06:54 -05001016 case extensionShortHeader:
1017 if len(d) != 0 {
1018 return false
1019 }
1020 m.shortHeader = true
Nick Harperb41d2e42016-07-01 17:50:32 -04001021 default:
1022 // Only allow the 3 extensions that are sent in
1023 // the clear in TLS 1.3.
1024 return false
1025 }
1026 }
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001027 } else if !m.extensions.unmarshal(data, vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -04001028 return false
1029 }
1030
1031 return true
1032}
1033
Nick Harperb41d2e42016-07-01 17:50:32 -04001034type encryptedExtensionsMsg struct {
1035 raw []byte
1036 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -04001037 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001038}
1039
1040func (m *encryptedExtensionsMsg) marshal() []byte {
1041 if m.raw != nil {
1042 return m.raw
1043 }
1044
1045 encryptedExtensionsMsg := newByteBuilder()
1046 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
1047 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -04001048 if !m.empty {
1049 extensions := encryptedExtensions.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001050 m.extensions.marshal(extensions)
Steven Valdez143e8b32016-07-11 13:19:03 -04001051 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001052
1053 m.raw = encryptedExtensionsMsg.finish()
1054 return m.raw
1055}
1056
1057func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -04001058 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001059 if len(data) < 6 {
1060 return false
1061 }
1062 if data[0] != typeEncryptedExtensions {
1063 return false
1064 }
1065 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1066 data = data[4:]
1067 if len(data) != msgLen {
1068 return false
1069 }
1070 extLen := int(data[0])<<8 | int(data[1])
1071 data = data[2:]
1072 if extLen != len(data) {
1073 return false
1074 }
David Benjamin44b33bc2016-07-01 22:40:23 -04001075 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -04001076}
1077
Nick Harperb3d51be2016-07-01 11:43:18 -04001078type serverExtensions struct {
1079 nextProtoNeg bool
1080 nextProtos []string
1081 ocspStapling bool
1082 ticketSupported bool
1083 secureRenegotiation []byte
1084 alpnProtocol string
1085 alpnProtocolEmpty bool
1086 duplicateExtension bool
1087 channelIDRequested bool
1088 extendedMasterSecret bool
1089 srtpProtectionProfile uint16
1090 srtpMasterKeyIdentifier string
1091 sctList []byte
1092 customExtension string
Steven Valdeza833c352016-11-01 13:39:36 -04001093 npnAfterAlpn bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001094 hasKeyShare bool
1095 keyShare keyShareEntry
Nick Harperb3d51be2016-07-01 11:43:18 -04001096}
1097
Steven Valdeza833c352016-11-01 13:39:36 -04001098func (m *serverExtensions) marshal(extensions *byteBuilder) {
David Benjamin35a7a442014-07-05 00:23:20 -04001099 if m.duplicateExtension {
1100 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001101 extensions.addU16(0xffff)
1102 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -04001103 }
Steven Valdeza833c352016-11-01 13:39:36 -04001104 if m.nextProtoNeg && !m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001105 extensions.addU16(extensionNextProtoNeg)
1106 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001107
1108 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001109 if len(v) > 255 {
1110 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -07001111 }
Nick Harper5212ef82016-06-30 19:26:07 -04001112 npn := extension.addU8LengthPrefixed()
1113 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -07001114 }
1115 }
Steven Valdeza833c352016-11-01 13:39:36 -04001116 if m.ocspStapling {
1117 extensions.addU16(extensionStatusRequest)
1118 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001119 }
1120 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -04001121 extensions.addU16(extensionSessionTicket)
1122 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001123 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001124 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001125 extensions.addU16(extensionRenegotiationInfo)
1126 extension := extensions.addU16LengthPrefixed()
1127 secureRenego := extension.addU8LengthPrefixed()
1128 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -07001129 }
Nick Harper5212ef82016-06-30 19:26:07 -04001130 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
1131 extensions.addU16(extensionALPN)
1132 extension := extensions.addU16LengthPrefixed()
1133
1134 protocolNameList := extension.addU16LengthPrefixed()
1135 protocolName := protocolNameList.addU8LengthPrefixed()
1136 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -04001137 }
David Benjamind30a9902014-08-24 01:44:23 -04001138 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -04001139 extensions.addU16(extensionChannelID)
1140 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -04001141 }
David Benjamin35a7a442014-07-05 00:23:20 -04001142 if m.duplicateExtension {
1143 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001144 extensions.addU16(0xffff)
1145 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -04001146 }
Adam Langley75712922014-10-10 16:23:43 -07001147 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -04001148 extensions.addU16(extensionExtendedMasterSecret)
1149 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -07001150 }
David Benjaminca6c8262014-11-15 19:06:08 -05001151 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001152 extensions.addU16(extensionUseSRTP)
1153 extension := extensions.addU16LengthPrefixed()
1154
1155 srtpProtectionProfiles := extension.addU16LengthPrefixed()
1156 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
1157 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
1158 srtpMki := extension.addU8LengthPrefixed()
1159 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -05001160 }
David Benjamin61f95272014-11-25 01:55:35 -05001161 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001162 extensions.addU16(extensionSignedCertificateTimestamp)
1163 extension := extensions.addU16LengthPrefixed()
1164 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -05001165 }
Adam Langley09505632015-07-30 18:10:13 -07001166 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001167 extensions.addU16(extensionCustom)
1168 customExt := extensions.addU16LengthPrefixed()
1169 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -07001170 }
Steven Valdeza833c352016-11-01 13:39:36 -04001171 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001172 extensions.addU16(extensionNextProtoNeg)
1173 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -04001174
1175 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001176 if len(v) > 255 {
1177 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -04001178 }
Nick Harper5212ef82016-06-30 19:26:07 -04001179 npn := extension.addU8LengthPrefixed()
1180 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001181 }
1182 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001183 if m.hasKeyShare {
1184 extensions.addU16(extensionKeyShare)
1185 keyShare := extensions.addU16LengthPrefixed()
1186 keyShare.addU16(uint16(m.keyShare.group))
1187 keyExchange := keyShare.addU16LengthPrefixed()
1188 keyExchange.addBytes(m.keyShare.keyExchange)
1189 }
Adam Langley95c29f32014-06-20 12:00:00 -07001190}
1191
David Benjamin44b33bc2016-07-01 22:40:23 -04001192func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001193 // Reset all fields.
1194 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001195
1196 for len(data) != 0 {
1197 if len(data) < 4 {
1198 return false
1199 }
1200 extension := uint16(data[0])<<8 | uint16(data[1])
1201 length := int(data[2])<<8 | int(data[3])
1202 data = data[4:]
1203 if len(data) < length {
1204 return false
1205 }
1206
1207 switch extension {
1208 case extensionNextProtoNeg:
1209 m.nextProtoNeg = true
1210 d := data[:length]
1211 for len(d) > 0 {
1212 l := int(d[0])
1213 d = d[1:]
1214 if l == 0 || l > len(d) {
1215 return false
1216 }
1217 m.nextProtos = append(m.nextProtos, string(d[:l]))
1218 d = d[l:]
1219 }
1220 case extensionStatusRequest:
Steven Valdeza833c352016-11-01 13:39:36 -04001221 if length > 0 {
1222 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001223 }
Steven Valdeza833c352016-11-01 13:39:36 -04001224 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001225 case extensionSessionTicket:
1226 if length > 0 {
1227 return false
1228 }
1229 m.ticketSupported = true
1230 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001231 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001232 return false
1233 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001234 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001235 case extensionALPN:
1236 d := data[:length]
1237 if len(d) < 3 {
1238 return false
1239 }
1240 l := int(d[0])<<8 | int(d[1])
1241 if l != len(d)-2 {
1242 return false
1243 }
1244 d = d[2:]
1245 l = int(d[0])
1246 if l != len(d)-1 {
1247 return false
1248 }
1249 d = d[1:]
1250 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001251 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001252 case extensionChannelID:
1253 if length > 0 {
1254 return false
1255 }
1256 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001257 case extensionExtendedMasterSecret:
1258 if length != 0 {
1259 return false
1260 }
1261 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001262 case extensionUseSRTP:
1263 if length < 2+2+1 {
1264 return false
1265 }
1266 if data[0] != 0 || data[1] != 2 {
1267 return false
1268 }
1269 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1270 d := data[4:length]
1271 l := int(d[0])
1272 if l != len(d)-1 {
1273 return false
1274 }
1275 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001276 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001277 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001278 case extensionCustom:
1279 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001280 case extensionServerName:
1281 if length != 0 {
1282 return false
1283 }
1284 // Ignore this extension from the server.
1285 case extensionSupportedPoints:
1286 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001287 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001288 return false
1289 }
1290 // Ignore this extension from the server.
David Benjamin4ee027f2016-07-17 12:34:41 +02001291 case extensionSupportedCurves:
1292 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001293 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001294 return false
1295 }
David Benjamin46f94bd2016-07-14 16:43:37 -04001296 default:
1297 // Unknown extensions are illegal from the server.
1298 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001299 }
1300 data = data[length:]
1301 }
1302
1303 return true
1304}
1305
Nick Harperdcfbc672016-07-16 17:47:31 +02001306type helloRetryRequestMsg struct {
David Benjamin3baa6e12016-10-07 21:10:38 -04001307 raw []byte
1308 vers uint16
1309 hasSelectedGroup bool
1310 selectedGroup CurveID
1311 cookie []byte
1312 customExtension string
1313 duplicateExtensions bool
Nick Harperdcfbc672016-07-16 17:47:31 +02001314}
1315
1316func (m *helloRetryRequestMsg) marshal() []byte {
1317 if m.raw != nil {
1318 return m.raw
1319 }
1320
1321 retryRequestMsg := newByteBuilder()
1322 retryRequestMsg.addU8(typeHelloRetryRequest)
1323 retryRequest := retryRequestMsg.addU24LengthPrefixed()
1324 retryRequest.addU16(m.vers)
David Benjamin3baa6e12016-10-07 21:10:38 -04001325 extensions := retryRequest.addU16LengthPrefixed()
1326
1327 count := 1
1328 if m.duplicateExtensions {
1329 count = 2
1330 }
1331
1332 for i := 0; i < count; i++ {
1333 if m.hasSelectedGroup {
1334 extensions.addU16(extensionKeyShare)
1335 extensions.addU16(2) // length
1336 extensions.addU16(uint16(m.selectedGroup))
1337 }
1338 if len(m.cookie) > 0 {
1339 extensions.addU16(extensionCookie)
1340 body := extensions.addU16LengthPrefixed()
1341 body.addU16LengthPrefixed().addBytes(m.cookie)
1342 }
1343 if len(m.customExtension) > 0 {
1344 extensions.addU16(extensionCustom)
1345 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
1346 }
1347 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001348
1349 m.raw = retryRequestMsg.finish()
1350 return m.raw
1351}
1352
1353func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1354 m.raw = data
David Benjamin3baa6e12016-10-07 21:10:38 -04001355 if len(data) < 8 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001356 return false
1357 }
1358 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin3baa6e12016-10-07 21:10:38 -04001359 extLen := int(data[6])<<8 | int(data[7])
1360 data = data[8:]
1361 if len(data) != extLen || len(data) == 0 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001362 return false
1363 }
David Benjamin3baa6e12016-10-07 21:10:38 -04001364 for len(data) > 0 {
1365 if len(data) < 4 {
1366 return false
1367 }
1368 extension := uint16(data[0])<<8 | uint16(data[1])
1369 length := int(data[2])<<8 | int(data[3])
1370 data = data[4:]
1371 if len(data) < length {
1372 return false
1373 }
1374
1375 switch extension {
1376 case extensionKeyShare:
1377 if length != 2 {
1378 return false
1379 }
1380 m.hasSelectedGroup = true
1381 m.selectedGroup = CurveID(data[0])<<8 | CurveID(data[1])
1382 case extensionCookie:
1383 if length < 2 {
1384 return false
1385 }
1386 cookieLen := int(data[0])<<8 | int(data[1])
1387 if 2+cookieLen != length {
1388 return false
1389 }
1390 m.cookie = data[2 : 2+cookieLen]
1391 default:
1392 // Unknown extensions are illegal from the server.
1393 return false
1394 }
1395 data = data[length:]
1396 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001397 return true
1398}
1399
Steven Valdeza833c352016-11-01 13:39:36 -04001400type certificateEntry struct {
1401 data []byte
1402 ocspResponse []byte
1403 sctList []byte
1404 duplicateExtensions bool
1405 extraExtension []byte
1406}
1407
Adam Langley95c29f32014-06-20 12:00:00 -07001408type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001409 raw []byte
1410 hasRequestContext bool
1411 requestContext []byte
Steven Valdeza833c352016-11-01 13:39:36 -04001412 certificates []certificateEntry
Adam Langley95c29f32014-06-20 12:00:00 -07001413}
1414
Adam Langley95c29f32014-06-20 12:00:00 -07001415func (m *certificateMsg) marshal() (x []byte) {
1416 if m.raw != nil {
1417 return m.raw
1418 }
1419
Nick Harper7e0442a2016-07-01 17:40:09 -04001420 certMsg := newByteBuilder()
1421 certMsg.addU8(typeCertificate)
1422 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001423 if m.hasRequestContext {
1424 context := certificate.addU8LengthPrefixed()
1425 context.addBytes(m.requestContext)
1426 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001427 certificateList := certificate.addU24LengthPrefixed()
1428 for _, cert := range m.certificates {
1429 certEntry := certificateList.addU24LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001430 certEntry.addBytes(cert.data)
1431 if m.hasRequestContext {
1432 extensions := certificateList.addU16LengthPrefixed()
1433 count := 1
1434 if cert.duplicateExtensions {
1435 count = 2
1436 }
1437
1438 for i := 0; i < count; i++ {
1439 if cert.ocspResponse != nil {
1440 extensions.addU16(extensionStatusRequest)
1441 body := extensions.addU16LengthPrefixed()
1442 body.addU8(statusTypeOCSP)
1443 response := body.addU24LengthPrefixed()
1444 response.addBytes(cert.ocspResponse)
1445 }
1446
1447 if cert.sctList != nil {
1448 extensions.addU16(extensionSignedCertificateTimestamp)
1449 extension := extensions.addU16LengthPrefixed()
1450 extension.addBytes(cert.sctList)
1451 }
1452 }
1453 if cert.extraExtension != nil {
1454 extensions.addBytes(cert.extraExtension)
1455 }
1456 }
Adam Langley95c29f32014-06-20 12:00:00 -07001457 }
1458
Nick Harper7e0442a2016-07-01 17:40:09 -04001459 m.raw = certMsg.finish()
1460 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001461}
1462
1463func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001464 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001465 return false
1466 }
1467
1468 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001469 data = data[4:]
1470
1471 if m.hasRequestContext {
1472 if len(data) == 0 {
1473 return false
1474 }
1475 contextLen := int(data[0])
1476 if len(data) < 1+contextLen {
1477 return false
1478 }
1479 m.requestContext = make([]byte, contextLen)
1480 copy(m.requestContext, data[1:])
1481 data = data[1+contextLen:]
1482 }
1483
1484 if len(data) < 3 {
1485 return false
1486 }
1487 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1488 data = data[3:]
1489 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001490 return false
1491 }
1492
Steven Valdeza833c352016-11-01 13:39:36 -04001493 m.certificates = nil
1494 for len(data) != 0 {
1495 if len(data) < 3 {
Adam Langley95c29f32014-06-20 12:00:00 -07001496 return false
1497 }
Steven Valdeza833c352016-11-01 13:39:36 -04001498 certLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1499 if len(data) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001500 return false
1501 }
Steven Valdeza833c352016-11-01 13:39:36 -04001502 cert := certificateEntry{
1503 data: data[3 : 3+certLen],
1504 }
1505 data = data[3+certLen:]
1506 if m.hasRequestContext {
1507 if len(data) < 2 {
1508 return false
1509 }
1510 extensionsLen := int(data[0])<<8 | int(data[1])
1511 if len(data) < 2+extensionsLen {
1512 return false
1513 }
1514 extensions := data[2 : 2+extensionsLen]
1515 data = data[2+extensionsLen:]
1516 for len(extensions) != 0 {
1517 if len(extensions) < 4 {
1518 return false
1519 }
1520 extension := uint16(extensions[0])<<8 | uint16(extensions[1])
1521 length := int(extensions[2])<<8 | int(extensions[3])
1522 if len(extensions) < 4+length {
1523 return false
1524 }
1525 contents := extensions[4 : 4+length]
1526 extensions = extensions[4+length:]
Adam Langley95c29f32014-06-20 12:00:00 -07001527
Steven Valdeza833c352016-11-01 13:39:36 -04001528 switch extension {
1529 case extensionStatusRequest:
1530 if length < 4 {
1531 return false
1532 }
1533 if contents[0] != statusTypeOCSP {
1534 return false
1535 }
1536 respLen := int(contents[1])<<16 | int(contents[2])<<8 | int(contents[3])
1537 if respLen+4 != len(contents) || respLen == 0 {
1538 return false
1539 }
1540 cert.ocspResponse = contents[4:]
1541 case extensionSignedCertificateTimestamp:
1542 cert.sctList = contents
1543 default:
1544 return false
1545 }
1546 }
1547 }
1548 m.certificates = append(m.certificates, cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001549 }
1550
1551 return true
1552}
1553
1554type serverKeyExchangeMsg struct {
1555 raw []byte
1556 key []byte
1557}
1558
Adam Langley95c29f32014-06-20 12:00:00 -07001559func (m *serverKeyExchangeMsg) marshal() []byte {
1560 if m.raw != nil {
1561 return m.raw
1562 }
1563 length := len(m.key)
1564 x := make([]byte, length+4)
1565 x[0] = typeServerKeyExchange
1566 x[1] = uint8(length >> 16)
1567 x[2] = uint8(length >> 8)
1568 x[3] = uint8(length)
1569 copy(x[4:], m.key)
1570
1571 m.raw = x
1572 return x
1573}
1574
1575func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1576 m.raw = data
1577 if len(data) < 4 {
1578 return false
1579 }
1580 m.key = data[4:]
1581 return true
1582}
1583
1584type certificateStatusMsg struct {
1585 raw []byte
1586 statusType uint8
1587 response []byte
1588}
1589
Adam Langley95c29f32014-06-20 12:00:00 -07001590func (m *certificateStatusMsg) marshal() []byte {
1591 if m.raw != nil {
1592 return m.raw
1593 }
1594
1595 var x []byte
1596 if m.statusType == statusTypeOCSP {
1597 x = make([]byte, 4+4+len(m.response))
1598 x[0] = typeCertificateStatus
1599 l := len(m.response) + 4
1600 x[1] = byte(l >> 16)
1601 x[2] = byte(l >> 8)
1602 x[3] = byte(l)
1603 x[4] = statusTypeOCSP
1604
1605 l -= 4
1606 x[5] = byte(l >> 16)
1607 x[6] = byte(l >> 8)
1608 x[7] = byte(l)
1609 copy(x[8:], m.response)
1610 } else {
1611 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1612 }
1613
1614 m.raw = x
1615 return x
1616}
1617
1618func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1619 m.raw = data
1620 if len(data) < 5 {
1621 return false
1622 }
1623 m.statusType = data[4]
1624
1625 m.response = nil
1626 if m.statusType == statusTypeOCSP {
1627 if len(data) < 8 {
1628 return false
1629 }
1630 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1631 if uint32(len(data)) != 4+4+respLen {
1632 return false
1633 }
1634 m.response = data[8:]
1635 }
1636 return true
1637}
1638
1639type serverHelloDoneMsg struct{}
1640
Adam Langley95c29f32014-06-20 12:00:00 -07001641func (m *serverHelloDoneMsg) marshal() []byte {
1642 x := make([]byte, 4)
1643 x[0] = typeServerHelloDone
1644 return x
1645}
1646
1647func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1648 return len(data) == 4
1649}
1650
1651type clientKeyExchangeMsg struct {
1652 raw []byte
1653 ciphertext []byte
1654}
1655
Adam Langley95c29f32014-06-20 12:00:00 -07001656func (m *clientKeyExchangeMsg) marshal() []byte {
1657 if m.raw != nil {
1658 return m.raw
1659 }
1660 length := len(m.ciphertext)
1661 x := make([]byte, length+4)
1662 x[0] = typeClientKeyExchange
1663 x[1] = uint8(length >> 16)
1664 x[2] = uint8(length >> 8)
1665 x[3] = uint8(length)
1666 copy(x[4:], m.ciphertext)
1667
1668 m.raw = x
1669 return x
1670}
1671
1672func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1673 m.raw = data
1674 if len(data) < 4 {
1675 return false
1676 }
1677 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1678 if l != len(data)-4 {
1679 return false
1680 }
1681 m.ciphertext = data[4:]
1682 return true
1683}
1684
1685type finishedMsg struct {
1686 raw []byte
1687 verifyData []byte
1688}
1689
Adam Langley95c29f32014-06-20 12:00:00 -07001690func (m *finishedMsg) marshal() (x []byte) {
1691 if m.raw != nil {
1692 return m.raw
1693 }
1694
1695 x = make([]byte, 4+len(m.verifyData))
1696 x[0] = typeFinished
1697 x[3] = byte(len(m.verifyData))
1698 copy(x[4:], m.verifyData)
1699 m.raw = x
1700 return
1701}
1702
1703func (m *finishedMsg) unmarshal(data []byte) bool {
1704 m.raw = data
1705 if len(data) < 4 {
1706 return false
1707 }
1708 m.verifyData = data[4:]
1709 return true
1710}
1711
1712type nextProtoMsg struct {
1713 raw []byte
1714 proto string
1715}
1716
Adam Langley95c29f32014-06-20 12:00:00 -07001717func (m *nextProtoMsg) marshal() []byte {
1718 if m.raw != nil {
1719 return m.raw
1720 }
1721 l := len(m.proto)
1722 if l > 255 {
1723 l = 255
1724 }
1725
1726 padding := 32 - (l+2)%32
1727 length := l + padding + 2
1728 x := make([]byte, length+4)
1729 x[0] = typeNextProtocol
1730 x[1] = uint8(length >> 16)
1731 x[2] = uint8(length >> 8)
1732 x[3] = uint8(length)
1733
1734 y := x[4:]
1735 y[0] = byte(l)
1736 copy(y[1:], []byte(m.proto[0:l]))
1737 y = y[1+l:]
1738 y[0] = byte(padding)
1739
1740 m.raw = x
1741
1742 return x
1743}
1744
1745func (m *nextProtoMsg) unmarshal(data []byte) bool {
1746 m.raw = data
1747
1748 if len(data) < 5 {
1749 return false
1750 }
1751 data = data[4:]
1752 protoLen := int(data[0])
1753 data = data[1:]
1754 if len(data) < protoLen {
1755 return false
1756 }
1757 m.proto = string(data[0:protoLen])
1758 data = data[protoLen:]
1759
1760 if len(data) < 1 {
1761 return false
1762 }
1763 paddingLen := int(data[0])
1764 data = data[1:]
1765 if len(data) != paddingLen {
1766 return false
1767 }
1768
1769 return true
1770}
1771
1772type certificateRequestMsg struct {
1773 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001774 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001775 // of signature and hash functions. This change was introduced with TLS
1776 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001777 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001778 // hasRequestContext indicates whether this message includes a context
1779 // field instead of certificateTypes. This change was introduced with
1780 // TLS 1.3.
1781 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001782
1783 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001784 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001785 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001786 certificateAuthorities [][]byte
1787}
1788
Nick Harper7e0442a2016-07-01 17:40:09 -04001789func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001790 if m.raw != nil {
1791 return m.raw
1792 }
1793
1794 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001795 builder := newByteBuilder()
1796 builder.addU8(typeCertificateRequest)
1797 body := builder.addU24LengthPrefixed()
1798
Nick Harperb41d2e42016-07-01 17:50:32 -04001799 if m.hasRequestContext {
1800 requestContext := body.addU8LengthPrefixed()
1801 requestContext.addBytes(m.requestContext)
1802 } else {
1803 certificateTypes := body.addU8LengthPrefixed()
1804 certificateTypes.addBytes(m.certificateTypes)
1805 }
Adam Langley95c29f32014-06-20 12:00:00 -07001806
Nick Harper60edffd2016-06-21 15:19:24 -07001807 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001808 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001809 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001810 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001811 }
1812 }
1813
Nick Harper7e0442a2016-07-01 17:40:09 -04001814 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001815 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001816 caEntry := certificateAuthorities.addU16LengthPrefixed()
1817 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001818 }
1819
David Benjamin8d343b42016-07-09 14:26:01 -07001820 if m.hasRequestContext {
1821 // Emit no certificate extensions.
1822 body.addU16(0)
1823 }
1824
Nick Harper7e0442a2016-07-01 17:40:09 -04001825 m.raw = builder.finish()
1826 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001827}
1828
1829func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1830 m.raw = data
1831
1832 if len(data) < 5 {
1833 return false
1834 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001835 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001836
Nick Harperb41d2e42016-07-01 17:50:32 -04001837 if m.hasRequestContext {
1838 contextLen := int(data[0])
1839 if len(data) < 1+contextLen {
1840 return false
1841 }
1842 m.requestContext = make([]byte, contextLen)
1843 copy(m.requestContext, data[1:])
1844 data = data[1+contextLen:]
1845 } else {
1846 numCertTypes := int(data[0])
1847 if len(data) < 1+numCertTypes {
1848 return false
1849 }
1850 m.certificateTypes = make([]byte, numCertTypes)
1851 copy(m.certificateTypes, data[1:])
1852 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001853 }
1854
Nick Harper60edffd2016-06-21 15:19:24 -07001855 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001856 if len(data) < 2 {
1857 return false
1858 }
Nick Harper60edffd2016-06-21 15:19:24 -07001859 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001860 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001861 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001862 return false
1863 }
Nick Harper60edffd2016-06-21 15:19:24 -07001864 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001865 return false
1866 }
Nick Harper60edffd2016-06-21 15:19:24 -07001867 numSigAlgs := sigAlgsLen / 2
1868 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1869 for i := range m.signatureAlgorithms {
1870 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001871 data = data[2:]
1872 }
1873 }
1874
1875 if len(data) < 2 {
1876 return false
1877 }
1878 casLength := uint16(data[0])<<8 | uint16(data[1])
1879 data = data[2:]
1880 if len(data) < int(casLength) {
1881 return false
1882 }
1883 cas := make([]byte, casLength)
1884 copy(cas, data)
1885 data = data[casLength:]
1886
1887 m.certificateAuthorities = nil
1888 for len(cas) > 0 {
1889 if len(cas) < 2 {
1890 return false
1891 }
1892 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1893 cas = cas[2:]
1894
1895 if len(cas) < int(caLen) {
1896 return false
1897 }
1898
1899 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1900 cas = cas[caLen:]
1901 }
David Benjamin8d343b42016-07-09 14:26:01 -07001902
1903 if m.hasRequestContext {
1904 // Ignore certificate extensions.
1905 if len(data) < 2 {
1906 return false
1907 }
1908 extsLength := int(data[0])<<8 | int(data[1])
1909 if len(data) < 2+extsLength {
1910 return false
1911 }
1912 data = data[2+extsLength:]
1913 }
1914
Adam Langley95c29f32014-06-20 12:00:00 -07001915 if len(data) > 0 {
1916 return false
1917 }
1918
1919 return true
1920}
1921
1922type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07001923 raw []byte
1924 hasSignatureAlgorithm bool
1925 signatureAlgorithm signatureAlgorithm
1926 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001927}
1928
Adam Langley95c29f32014-06-20 12:00:00 -07001929func (m *certificateVerifyMsg) marshal() (x []byte) {
1930 if m.raw != nil {
1931 return m.raw
1932 }
1933
1934 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1935 siglength := len(m.signature)
1936 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07001937 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001938 length += 2
1939 }
1940 x = make([]byte, 4+length)
1941 x[0] = typeCertificateVerify
1942 x[1] = uint8(length >> 16)
1943 x[2] = uint8(length >> 8)
1944 x[3] = uint8(length)
1945 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001946 if m.hasSignatureAlgorithm {
1947 y[0] = byte(m.signatureAlgorithm >> 8)
1948 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07001949 y = y[2:]
1950 }
1951 y[0] = uint8(siglength >> 8)
1952 y[1] = uint8(siglength)
1953 copy(y[2:], m.signature)
1954
1955 m.raw = x
1956
1957 return
1958}
1959
1960func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1961 m.raw = data
1962
1963 if len(data) < 6 {
1964 return false
1965 }
1966
1967 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1968 if uint32(len(data))-4 != length {
1969 return false
1970 }
1971
1972 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001973 if m.hasSignatureAlgorithm {
1974 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001975 data = data[2:]
1976 }
1977
1978 if len(data) < 2 {
1979 return false
1980 }
1981 siglength := int(data[0])<<8 + int(data[1])
1982 data = data[2:]
1983 if len(data) != siglength {
1984 return false
1985 }
1986
1987 m.signature = data
1988
1989 return true
1990}
1991
1992type newSessionTicketMsg struct {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04001993 raw []byte
1994 version uint16
1995 ticketLifetime uint32
Steven Valdeza833c352016-11-01 13:39:36 -04001996 ticketAgeAdd uint32
David Benjamin1a5e8ec2016-10-07 15:19:18 -04001997 ticket []byte
David Benjamin1286bee2016-10-07 15:25:06 -04001998 customExtension string
David Benjamin1a5e8ec2016-10-07 15:19:18 -04001999 hasGREASEExtension bool
Adam Langley95c29f32014-06-20 12:00:00 -07002000}
2001
David Benjamin58104882016-07-18 01:25:41 +02002002func (m *newSessionTicketMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07002003 if m.raw != nil {
2004 return m.raw
2005 }
2006
2007 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjamin58104882016-07-18 01:25:41 +02002008 ticketMsg := newByteBuilder()
2009 ticketMsg.addU8(typeNewSessionTicket)
2010 body := ticketMsg.addU24LengthPrefixed()
2011 body.addU32(m.ticketLifetime)
2012 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002013 body.addU32(m.ticketAgeAdd)
Steven Valdez5b986082016-09-01 12:29:49 -04002014 }
2015
2016 ticket := body.addU16LengthPrefixed()
2017 ticket.addBytes(m.ticket)
2018
2019 if m.version >= VersionTLS13 {
David Benjamin1286bee2016-10-07 15:25:06 -04002020 extensions := body.addU16LengthPrefixed()
2021 if len(m.customExtension) > 0 {
2022 extensions.addU16(ticketExtensionCustom)
2023 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
2024 }
David Benjamin58104882016-07-18 01:25:41 +02002025 }
Adam Langley95c29f32014-06-20 12:00:00 -07002026
David Benjamin58104882016-07-18 01:25:41 +02002027 m.raw = ticketMsg.finish()
2028 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07002029}
2030
2031func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
2032 m.raw = data
2033
David Benjamin58104882016-07-18 01:25:41 +02002034 if len(data) < 8 {
2035 return false
2036 }
2037 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
2038 data = data[8:]
2039
2040 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002041 if len(data) < 4 {
David Benjamin58104882016-07-18 01:25:41 +02002042 return false
2043 }
Steven Valdeza833c352016-11-01 13:39:36 -04002044 m.ticketAgeAdd = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2045 data = data[4:]
David Benjamin58104882016-07-18 01:25:41 +02002046 }
2047
2048 if len(data) < 2 {
2049 return false
2050 }
2051 ticketLen := int(data[0])<<8 + int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002052 data = data[2:]
2053 if len(data) < ticketLen {
David Benjamin58104882016-07-18 01:25:41 +02002054 return false
2055 }
Steven Valdez5b986082016-09-01 12:29:49 -04002056
David Benjamin58104882016-07-18 01:25:41 +02002057 if m.version >= VersionTLS13 && ticketLen == 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07002058 return false
2059 }
2060
Steven Valdez5b986082016-09-01 12:29:49 -04002061 m.ticket = data[:ticketLen]
2062 data = data[ticketLen:]
2063
2064 if m.version >= VersionTLS13 {
2065 if len(data) < 2 {
2066 return false
2067 }
2068 extsLength := int(data[0])<<8 + int(data[1])
2069 data = data[2:]
2070 if len(data) < extsLength {
2071 return false
2072 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002073 extensions := data[:extsLength]
Steven Valdez5b986082016-09-01 12:29:49 -04002074 data = data[extsLength:]
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002075
2076 for len(extensions) > 0 {
2077 if len(extensions) < 4 {
2078 return false
2079 }
2080 extValue := uint16(extensions[0])<<8 | uint16(extensions[1])
2081 extLength := int(extensions[2])<<8 | int(extensions[3])
2082 if len(extensions) < 4+extLength {
2083 return false
2084 }
2085 extensions = extensions[4+extLength:]
2086
2087 if isGREASEValue(extValue) {
2088 m.hasGREASEExtension = true
2089 }
2090 }
Steven Valdez5b986082016-09-01 12:29:49 -04002091 }
2092
2093 if len(data) > 0 {
2094 return false
2095 }
Adam Langley95c29f32014-06-20 12:00:00 -07002096
2097 return true
2098}
2099
David Benjamind86c7672014-08-02 04:07:12 -04002100type v2ClientHelloMsg struct {
2101 raw []byte
2102 vers uint16
2103 cipherSuites []uint16
2104 sessionId []byte
2105 challenge []byte
2106}
2107
David Benjamind86c7672014-08-02 04:07:12 -04002108func (m *v2ClientHelloMsg) marshal() []byte {
2109 if m.raw != nil {
2110 return m.raw
2111 }
2112
2113 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
2114
2115 x := make([]byte, length)
2116 x[0] = 1
2117 x[1] = uint8(m.vers >> 8)
2118 x[2] = uint8(m.vers)
2119 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
2120 x[4] = uint8(len(m.cipherSuites) * 3)
2121 x[5] = uint8(len(m.sessionId) >> 8)
2122 x[6] = uint8(len(m.sessionId))
2123 x[7] = uint8(len(m.challenge) >> 8)
2124 x[8] = uint8(len(m.challenge))
2125 y := x[9:]
2126 for i, spec := range m.cipherSuites {
2127 y[i*3] = 0
2128 y[i*3+1] = uint8(spec >> 8)
2129 y[i*3+2] = uint8(spec)
2130 }
2131 y = y[len(m.cipherSuites)*3:]
2132 copy(y, m.sessionId)
2133 y = y[len(m.sessionId):]
2134 copy(y, m.challenge)
2135
2136 m.raw = x
2137
2138 return x
2139}
2140
David Benjamin83c0bc92014-08-04 01:23:53 -04002141type helloVerifyRequestMsg struct {
2142 raw []byte
2143 vers uint16
2144 cookie []byte
2145}
2146
David Benjamin83c0bc92014-08-04 01:23:53 -04002147func (m *helloVerifyRequestMsg) marshal() []byte {
2148 if m.raw != nil {
2149 return m.raw
2150 }
2151
2152 length := 2 + 1 + len(m.cookie)
2153
2154 x := make([]byte, 4+length)
2155 x[0] = typeHelloVerifyRequest
2156 x[1] = uint8(length >> 16)
2157 x[2] = uint8(length >> 8)
2158 x[3] = uint8(length)
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002159 vers := m.vers
David Benjamin83c0bc92014-08-04 01:23:53 -04002160 x[4] = uint8(vers >> 8)
2161 x[5] = uint8(vers)
2162 x[6] = uint8(len(m.cookie))
2163 copy(x[7:7+len(m.cookie)], m.cookie)
2164
2165 return x
2166}
2167
2168func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
2169 if len(data) < 4+2+1 {
2170 return false
2171 }
2172 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002173 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin83c0bc92014-08-04 01:23:53 -04002174 cookieLen := int(data[6])
2175 if cookieLen > 32 || len(data) != 7+cookieLen {
2176 return false
2177 }
2178 m.cookie = data[7 : 7+cookieLen]
2179
2180 return true
2181}
2182
David Benjamin24599a82016-06-30 18:56:53 -04002183type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04002184 raw []byte
2185 channelID []byte
2186}
2187
David Benjamin24599a82016-06-30 18:56:53 -04002188func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04002189 if m.raw != nil {
2190 return m.raw
2191 }
2192
2193 length := 2 + 2 + len(m.channelID)
2194
2195 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04002196 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04002197 x[1] = uint8(length >> 16)
2198 x[2] = uint8(length >> 8)
2199 x[3] = uint8(length)
2200 x[4] = uint8(extensionChannelID >> 8)
2201 x[5] = uint8(extensionChannelID & 0xff)
2202 x[6] = uint8(len(m.channelID) >> 8)
2203 x[7] = uint8(len(m.channelID) & 0xff)
2204 copy(x[8:], m.channelID)
2205
2206 return x
2207}
2208
David Benjamin24599a82016-06-30 18:56:53 -04002209func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04002210 if len(data) != 4+2+2+128 {
2211 return false
2212 }
2213 m.raw = data
2214 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
2215 return false
2216 }
2217 if int(data[6])<<8|int(data[7]) != 128 {
2218 return false
2219 }
2220 m.channelID = data[4+2+2:]
2221
2222 return true
2223}
2224
Adam Langley2ae77d22014-10-28 17:29:33 -07002225type helloRequestMsg struct {
2226}
2227
2228func (*helloRequestMsg) marshal() []byte {
2229 return []byte{typeHelloRequest, 0, 0, 0}
2230}
2231
2232func (*helloRequestMsg) unmarshal(data []byte) bool {
2233 return len(data) == 4
2234}
2235
David Benjamin21c00282016-07-18 21:56:23 +02002236type keyUpdateMsg struct {
Steven Valdezc4aa7272016-10-03 12:25:56 -04002237 raw []byte
2238 keyUpdateRequest byte
David Benjamin21c00282016-07-18 21:56:23 +02002239}
2240
Steven Valdezc4aa7272016-10-03 12:25:56 -04002241func (m *keyUpdateMsg) marshal() []byte {
2242 if m.raw != nil {
2243 return m.raw
2244 }
2245
2246 return []byte{typeKeyUpdate, 0, 0, 1, m.keyUpdateRequest}
David Benjamin21c00282016-07-18 21:56:23 +02002247}
2248
Steven Valdezc4aa7272016-10-03 12:25:56 -04002249func (m *keyUpdateMsg) unmarshal(data []byte) bool {
2250 m.raw = data
2251
2252 if len(data) != 5 {
2253 return false
2254 }
2255
2256 length := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
2257 if len(data)-4 != length {
2258 return false
2259 }
2260
2261 m.keyUpdateRequest = data[4]
2262 return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
David Benjamin21c00282016-07-18 21:56:23 +02002263}
2264
Adam Langley95c29f32014-06-20 12:00:00 -07002265func eqUint16s(x, y []uint16) bool {
2266 if len(x) != len(y) {
2267 return false
2268 }
2269 for i, v := range x {
2270 if y[i] != v {
2271 return false
2272 }
2273 }
2274 return true
2275}
2276
2277func eqCurveIDs(x, y []CurveID) bool {
2278 if len(x) != len(y) {
2279 return false
2280 }
2281 for i, v := range x {
2282 if y[i] != v {
2283 return false
2284 }
2285 }
2286 return true
2287}
2288
2289func eqStrings(x, y []string) bool {
2290 if len(x) != len(y) {
2291 return false
2292 }
2293 for i, v := range x {
2294 if y[i] != v {
2295 return false
2296 }
2297 }
2298 return true
2299}
2300
2301func eqByteSlices(x, y [][]byte) bool {
2302 if len(x) != len(y) {
2303 return false
2304 }
2305 for i, v := range x {
2306 if !bytes.Equal(v, y[i]) {
2307 return false
2308 }
2309 }
2310 return true
2311}
2312
Nick Harper60edffd2016-06-21 15:19:24 -07002313func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07002314 if len(x) != len(y) {
2315 return false
2316 }
2317 for i, v := range x {
2318 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07002319 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07002320 return false
2321 }
2322 }
2323 return true
2324}
Nick Harperf8b0e702016-06-30 19:59:01 -04002325
2326func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2327 if len(x) != len(y) {
2328 return false
2329 }
2330 for i, v := range x {
2331 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2332 return false
2333 }
2334 }
2335 return true
2336
2337}
Steven Valdez5b986082016-09-01 12:29:49 -04002338
2339func eqPSKIdentityLists(x, y []pskIdentity) bool {
2340 if len(x) != len(y) {
2341 return false
2342 }
2343 for i, v := range x {
Steven Valdeza833c352016-11-01 13:39:36 -04002344 if !bytes.Equal(y[i].ticket, v.ticket) || y[i].obfuscatedTicketAge != v.obfuscatedTicketAge {
Steven Valdez5b986082016-09-01 12:29:49 -04002345 return false
2346 }
2347 }
2348 return true
2349
2350}