blob: 8a338f0ba6a56a852aa70c3af93784ffd2a21e89 [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
Adam Langley95c29f32014-06-20 12:00:00 -0700170}
171
172func (m *clientHelloMsg) equal(i interface{}) bool {
173 m1, ok := i.(*clientHelloMsg)
174 if !ok {
175 return false
176 }
177
178 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400179 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700180 m.vers == m1.vers &&
181 bytes.Equal(m.random, m1.random) &&
182 bytes.Equal(m.sessionId, m1.sessionId) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400183 bytes.Equal(m.cookie, m1.cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700184 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
185 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
186 m.nextProtoNeg == m1.nextProtoNeg &&
187 m.serverName == m1.serverName &&
188 m.ocspStapling == m1.ocspStapling &&
189 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
190 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
Nick Harperdcfbc672016-07-16 17:47:31 +0200191 m.hasKeyShares == m1.hasKeyShares &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400192 eqKeyShareEntryLists(m.keyShares, m1.keyShares) &&
David Benjamin7e1f9842016-09-20 19:24:40 -0400193 m.trailingKeyShareData == m1.trailingKeyShareData &&
Steven Valdez5b986082016-09-01 12:29:49 -0400194 eqPSKIdentityLists(m.pskIdentities, m1.pskIdentities) &&
Steven Valdeza833c352016-11-01 13:39:36 -0400195 bytes.Equal(m.pskKEModes, m1.pskKEModes) &&
196 eqByteSlices(m.pskBinders, m1.pskBinders) &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400197 m.hasEarlyData == m1.hasEarlyData &&
David Benjamin3baa6e12016-10-07 21:10:38 -0400198 bytes.Equal(m.tls13Cookie, m1.tls13Cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700199 m.ticketSupported == m1.ticketSupported &&
200 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
Nick Harper60edffd2016-06-21 15:19:24 -0700201 eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
Steven Valdezfdd10992016-09-15 16:27:05 -0400202 eqUint16s(m.supportedVersions, m1.supportedVersions) &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700203 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
204 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400205 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -0400206 m.duplicateExtension == m1.duplicateExtension &&
David Benjaminfc7b0862014-09-06 13:21:53 -0400207 m.channelIDSupported == m1.channelIDSupported &&
Steven Valdeza833c352016-11-01 13:39:36 -0400208 m.npnAfterAlpn == m1.npnAfterAlpn &&
David Benjaminca6c8262014-11-15 19:06:08 -0500209 m.extendedMasterSecret == m1.extendedMasterSecret &&
210 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
David Benjamin61f95272014-11-25 01:55:35 -0500211 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
Adam Langley09505632015-07-30 18:10:13 -0700212 m.sctListSupported == m1.sctListSupported &&
David Benjamin65ac9972016-09-02 21:35:25 -0400213 m.customExtension == m1.customExtension &&
Steven Valdeza833c352016-11-01 13:39:36 -0400214 m.hasGREASEExtension == m1.hasGREASEExtension &&
215 m.pskBinderFirst == m1.pskBinderFirst
Adam Langley95c29f32014-06-20 12:00:00 -0700216}
217
218func (m *clientHelloMsg) marshal() []byte {
219 if m.raw != nil {
220 return m.raw
221 }
222
Nick Harper8dda5cc2016-06-30 18:51:11 -0400223 handshakeMsg := newByteBuilder()
224 handshakeMsg.addU8(typeClientHello)
225 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400226 hello.addU16(m.vers)
Nick Harper8dda5cc2016-06-30 18:51:11 -0400227 hello.addBytes(m.random)
228 sessionId := hello.addU8LengthPrefixed()
229 sessionId.addBytes(m.sessionId)
David Benjamin83c0bc92014-08-04 01:23:53 -0400230 if m.isDTLS {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400231 cookie := hello.addU8LengthPrefixed()
232 cookie.addBytes(m.cookie)
David Benjamin83c0bc92014-08-04 01:23:53 -0400233 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400234 cipherSuites := hello.addU16LengthPrefixed()
235 for _, suite := range m.cipherSuites {
236 cipherSuites.addU16(suite)
Adam Langley95c29f32014-06-20 12:00:00 -0700237 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400238 compressionMethods := hello.addU8LengthPrefixed()
239 compressionMethods.addBytes(m.compressionMethods)
Adam Langley95c29f32014-06-20 12:00:00 -0700240
Nick Harper8dda5cc2016-06-30 18:51:11 -0400241 extensions := hello.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -0400242 if len(m.pskIdentities) > 0 && m.pskBinderFirst {
243 extensions.addU16(extensionPreSharedKey)
244 pskExtension := extensions.addU16LengthPrefixed()
245
246 pskIdentities := pskExtension.addU16LengthPrefixed()
247 for _, psk := range m.pskIdentities {
248 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
249 pskIdentities.addU32(psk.obfuscatedTicketAge)
250 }
251 pskBinders := pskExtension.addU16LengthPrefixed()
252 for _, binder := range m.pskBinders {
253 pskBinders.addU8LengthPrefixed().addBytes(binder)
254 }
255 }
David Benjamin35a7a442014-07-05 00:23:20 -0400256 if m.duplicateExtension {
257 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400258 extensions.addU16(0xffff)
259 extensions.addU16(0) // 0-length for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400260 }
Steven Valdeza833c352016-11-01 13:39:36 -0400261 if m.nextProtoNeg && !m.npnAfterAlpn {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400262 extensions.addU16(extensionNextProtoNeg)
263 extensions.addU16(0) // The length is always 0
Adam Langley95c29f32014-06-20 12:00:00 -0700264 }
265 if len(m.serverName) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400266 extensions.addU16(extensionServerName)
267 serverNameList := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700268
269 // RFC 3546, section 3.1
270 //
271 // struct {
272 // NameType name_type;
273 // select (name_type) {
274 // case host_name: HostName;
275 // } name;
276 // } ServerName;
277 //
278 // enum {
279 // host_name(0), (255)
280 // } NameType;
281 //
282 // opaque HostName<1..2^16-1>;
283 //
284 // struct {
285 // ServerName server_name_list<1..2^16-1>
286 // } ServerNameList;
287
Nick Harper8dda5cc2016-06-30 18:51:11 -0400288 serverName := serverNameList.addU16LengthPrefixed()
289 serverName.addU8(0) // NameType host_name(0)
290 hostName := serverName.addU16LengthPrefixed()
291 hostName.addBytes([]byte(m.serverName))
Adam Langley95c29f32014-06-20 12:00:00 -0700292 }
293 if m.ocspStapling {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400294 extensions.addU16(extensionStatusRequest)
295 certificateStatusRequest := extensions.addU16LengthPrefixed()
296
Adam Langley95c29f32014-06-20 12:00:00 -0700297 // RFC 4366, section 3.6
Nick Harper8dda5cc2016-06-30 18:51:11 -0400298 certificateStatusRequest.addU8(1) // OCSP type
Adam Langley95c29f32014-06-20 12:00:00 -0700299 // Two zero valued uint16s for the two lengths.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400300 certificateStatusRequest.addU16(0) // ResponderID length
301 certificateStatusRequest.addU16(0) // Extensions length
Adam Langley95c29f32014-06-20 12:00:00 -0700302 }
303 if len(m.supportedCurves) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400304 // http://tools.ietf.org/html/rfc4492#section-5.1.1
305 extensions.addU16(extensionSupportedCurves)
306 supportedCurvesList := extensions.addU16LengthPrefixed()
307 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700308 for _, curve := range m.supportedCurves {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400309 supportedCurves.addU16(uint16(curve))
Adam Langley95c29f32014-06-20 12:00:00 -0700310 }
311 }
312 if len(m.supportedPoints) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400313 // http://tools.ietf.org/html/rfc4492#section-5.1.2
314 extensions.addU16(extensionSupportedPoints)
315 supportedPointsList := extensions.addU16LengthPrefixed()
316 supportedPoints := supportedPointsList.addU8LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700317 for _, pointFormat := range m.supportedPoints {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400318 supportedPoints.addU8(pointFormat)
Adam Langley95c29f32014-06-20 12:00:00 -0700319 }
320 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200321 if m.hasKeyShares {
Nick Harperf8b0e702016-06-30 19:59:01 -0400322 extensions.addU16(extensionKeyShare)
323 keyShareList := extensions.addU16LengthPrefixed()
324
325 keyShares := keyShareList.addU16LengthPrefixed()
326 for _, keyShare := range m.keyShares {
327 keyShares.addU16(uint16(keyShare.group))
328 keyExchange := keyShares.addU16LengthPrefixed()
329 keyExchange.addBytes(keyShare.keyExchange)
330 }
David Benjamin7e1f9842016-09-20 19:24:40 -0400331
332 if m.trailingKeyShareData {
333 keyShares.addU8(0)
334 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400335 }
Steven Valdeza833c352016-11-01 13:39:36 -0400336 if len(m.pskKEModes) > 0 {
337 extensions.addU16(extensionPSKKeyExchangeModes)
338 pskModesExtension := extensions.addU16LengthPrefixed()
339 pskModesExtension.addU8LengthPrefixed().addBytes(m.pskKEModes)
Nick Harperf8b0e702016-06-30 19:59:01 -0400340 }
341 if m.hasEarlyData {
342 extensions.addU16(extensionEarlyData)
David Benjaminc5665c92016-11-15 18:12:58 +0900343 extensions.addU16(0) // The length is zero.
Nick Harperf8b0e702016-06-30 19:59:01 -0400344 }
David Benjamin3baa6e12016-10-07 21:10:38 -0400345 if len(m.tls13Cookie) > 0 {
346 extensions.addU16(extensionCookie)
347 body := extensions.addU16LengthPrefixed()
348 body.addU16LengthPrefixed().addBytes(m.tls13Cookie)
349 }
Adam Langley95c29f32014-06-20 12:00:00 -0700350 if m.ticketSupported {
351 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400352 extensions.addU16(extensionSessionTicket)
353 sessionTicketExtension := extensions.addU16LengthPrefixed()
354 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700355 }
Nick Harper60edffd2016-06-21 15:19:24 -0700356 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700357 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400358 extensions.addU16(extensionSignatureAlgorithms)
359 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
360 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700361 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400362 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700363 }
364 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400365 if len(m.supportedVersions) > 0 {
366 extensions.addU16(extensionSupportedVersions)
367 supportedVersionsExtension := extensions.addU16LengthPrefixed()
368 supportedVersions := supportedVersionsExtension.addU8LengthPrefixed()
369 for _, version := range m.supportedVersions {
370 supportedVersions.addU16(uint16(version))
371 }
372 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700373 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400374 extensions.addU16(extensionRenegotiationInfo)
375 secureRenegoExt := extensions.addU16LengthPrefixed()
376 secureRenego := secureRenegoExt.addU8LengthPrefixed()
377 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700378 }
David Benjaminfa055a22014-09-15 16:51:51 -0400379 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400380 // https://tools.ietf.org/html/rfc7301#section-3.1
381 extensions.addU16(extensionALPN)
382 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400383
Nick Harper8dda5cc2016-06-30 18:51:11 -0400384 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400385 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400386 protocolName := protocolNameList.addU8LengthPrefixed()
387 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400388 }
David Benjaminfa055a22014-09-15 16:51:51 -0400389 }
David Benjamind30a9902014-08-24 01:44:23 -0400390 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400391 extensions.addU16(extensionChannelID)
392 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400393 }
Steven Valdeza833c352016-11-01 13:39:36 -0400394 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400395 extensions.addU16(extensionNextProtoNeg)
396 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400397 }
David Benjamin35a7a442014-07-05 00:23:20 -0400398 if m.duplicateExtension {
399 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400400 extensions.addU16(0xffff)
401 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400402 }
Adam Langley75712922014-10-10 16:23:43 -0700403 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500404 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400405 extensions.addU16(extensionExtendedMasterSecret)
406 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700407 }
David Benjaminca6c8262014-11-15 19:06:08 -0500408 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400409 // https://tools.ietf.org/html/rfc5764#section-4.1.1
410 extensions.addU16(extensionUseSRTP)
411 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500412
Nick Harper8dda5cc2016-06-30 18:51:11 -0400413 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500414 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400415 // An SRTPProtectionProfile is defined as uint8[2],
416 // not uint16. For some reason, we're storing it
417 // as a uint16.
418 srtpProtectionProfiles.addU8(byte(p >> 8))
419 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500420 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400421 srtpMki := useSrtpExt.addU8LengthPrefixed()
422 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500423 }
David Benjamin61f95272014-11-25 01:55:35 -0500424 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400425 extensions.addU16(extensionSignedCertificateTimestamp)
426 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500427 }
Adam Langley09505632015-07-30 18:10:13 -0700428 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400429 extensions.addU16(extensionCustom)
430 customExt := extensions.addU16LengthPrefixed()
431 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700432 }
Steven Valdeza833c352016-11-01 13:39:36 -0400433 // The PSK extension must be last (draft-ietf-tls-tls13-18 section 4.2.6).
434 if len(m.pskIdentities) > 0 && !m.pskBinderFirst {
435 extensions.addU16(extensionPreSharedKey)
436 pskExtension := extensions.addU16LengthPrefixed()
437
438 pskIdentities := pskExtension.addU16LengthPrefixed()
439 for _, psk := range m.pskIdentities {
440 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
441 pskIdentities.addU32(psk.obfuscatedTicketAge)
442 }
443 pskBinders := pskExtension.addU16LengthPrefixed()
444 for _, binder := range m.pskBinders {
445 pskBinders.addU8LengthPrefixed().addBytes(binder)
446 }
447 }
Adam Langley95c29f32014-06-20 12:00:00 -0700448
Nick Harper8dda5cc2016-06-30 18:51:11 -0400449 if extensions.len() == 0 {
450 hello.discardChild()
451 }
Adam Langley95c29f32014-06-20 12:00:00 -0700452
Nick Harper8dda5cc2016-06-30 18:51:11 -0400453 m.raw = handshakeMsg.finish()
454 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700455}
456
457func (m *clientHelloMsg) unmarshal(data []byte) bool {
458 if len(data) < 42 {
459 return false
460 }
461 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400462 m.vers = uint16(data[4])<<8 | uint16(data[5])
Adam Langley95c29f32014-06-20 12:00:00 -0700463 m.random = data[6:38]
464 sessionIdLen := int(data[38])
465 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
466 return false
467 }
468 m.sessionId = data[39 : 39+sessionIdLen]
469 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400470 if m.isDTLS {
471 if len(data) < 1 {
472 return false
473 }
474 cookieLen := int(data[0])
475 if cookieLen > 32 || len(data) < 1+cookieLen {
476 return false
477 }
478 m.cookie = data[1 : 1+cookieLen]
479 data = data[1+cookieLen:]
480 }
Adam Langley95c29f32014-06-20 12:00:00 -0700481 if len(data) < 2 {
482 return false
483 }
484 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
485 // they are uint16s, the number must be even.
486 cipherSuiteLen := int(data[0])<<8 | int(data[1])
487 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
488 return false
489 }
490 numCipherSuites := cipherSuiteLen / 2
491 m.cipherSuites = make([]uint16, numCipherSuites)
492 for i := 0; i < numCipherSuites; i++ {
493 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
494 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700495 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700496 }
497 }
498 data = data[2+cipherSuiteLen:]
499 if len(data) < 1 {
500 return false
501 }
502 compressionMethodsLen := int(data[0])
503 if len(data) < 1+compressionMethodsLen {
504 return false
505 }
506 m.compressionMethods = data[1 : 1+compressionMethodsLen]
507
508 data = data[1+compressionMethodsLen:]
509
510 m.nextProtoNeg = false
511 m.serverName = ""
512 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400513 m.keyShares = nil
514 m.pskIdentities = nil
515 m.hasEarlyData = false
Adam Langley95c29f32014-06-20 12:00:00 -0700516 m.ticketSupported = false
517 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700518 m.signatureAlgorithms = nil
Steven Valdezfdd10992016-09-15 16:27:05 -0400519 m.supportedVersions = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400520 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700521 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700522 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700523
524 if len(data) == 0 {
525 // ClientHello is optionally followed by extension data
526 return true
527 }
528 if len(data) < 2 {
529 return false
530 }
531
532 extensionsLength := int(data[0])<<8 | int(data[1])
533 data = data[2:]
534 if extensionsLength != len(data) {
535 return false
536 }
537
538 for len(data) != 0 {
539 if len(data) < 4 {
540 return false
541 }
542 extension := uint16(data[0])<<8 | uint16(data[1])
543 length := int(data[2])<<8 | int(data[3])
544 data = data[4:]
545 if len(data) < length {
546 return false
547 }
548
549 switch extension {
550 case extensionServerName:
551 if length < 2 {
552 return false
553 }
554 numNames := int(data[0])<<8 | int(data[1])
555 d := data[2:]
556 for i := 0; i < numNames; i++ {
557 if len(d) < 3 {
558 return false
559 }
560 nameType := d[0]
561 nameLen := int(d[1])<<8 | int(d[2])
562 d = d[3:]
563 if len(d) < nameLen {
564 return false
565 }
566 if nameType == 0 {
567 m.serverName = string(d[0:nameLen])
568 break
569 }
570 d = d[nameLen:]
571 }
572 case extensionNextProtoNeg:
573 if length > 0 {
574 return false
575 }
576 m.nextProtoNeg = true
577 case extensionStatusRequest:
578 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
579 case extensionSupportedCurves:
580 // http://tools.ietf.org/html/rfc4492#section-5.5.1
581 if length < 2 {
582 return false
583 }
584 l := int(data[0])<<8 | int(data[1])
585 if l%2 == 1 || length != l+2 {
586 return false
587 }
588 numCurves := l / 2
589 m.supportedCurves = make([]CurveID, numCurves)
590 d := data[2:]
591 for i := 0; i < numCurves; i++ {
592 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
593 d = d[2:]
594 }
595 case extensionSupportedPoints:
596 // http://tools.ietf.org/html/rfc4492#section-5.5.2
597 if length < 1 {
598 return false
599 }
600 l := int(data[0])
601 if length != l+1 {
602 return false
603 }
604 m.supportedPoints = make([]uint8, l)
605 copy(m.supportedPoints, data[1:])
606 case extensionSessionTicket:
607 // http://tools.ietf.org/html/rfc5077#section-3.2
608 m.ticketSupported = true
609 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400610 case extensionKeyShare:
611 // draft-ietf-tls-tls13 section 6.3.2.3
612 if length < 2 {
613 return false
614 }
615 l := int(data[0])<<8 | int(data[1])
616 if l != length-2 {
617 return false
618 }
619 d := data[2:length]
Nick Harperdcfbc672016-07-16 17:47:31 +0200620 m.hasKeyShares = true
Nick Harperf8b0e702016-06-30 19:59:01 -0400621 for len(d) > 0 {
622 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
623 // key_exchange (2-byte length prefix with at least 1 byte of content).
624 if len(d) < 5 {
625 return false
626 }
627 entry := keyShareEntry{}
628 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
629 keyExchLen := int(d[2])<<8 | int(d[3])
630 d = d[4:]
631 if len(d) < keyExchLen {
632 return false
633 }
634 entry.keyExchange = d[:keyExchLen]
635 d = d[keyExchLen:]
636 m.keyShares = append(m.keyShares, entry)
637 }
638 case extensionPreSharedKey:
Steven Valdeza833c352016-11-01 13:39:36 -0400639 // draft-ietf-tls-tls13-18 section 4.2.6
Nick Harperf8b0e702016-06-30 19:59:01 -0400640 if length < 2 {
641 return false
642 }
643 l := int(data[0])<<8 | int(data[1])
Steven Valdeza833c352016-11-01 13:39:36 -0400644 d := data[2 : l+2]
645 // Parse PSK identities.
Nick Harperf8b0e702016-06-30 19:59:01 -0400646 for len(d) > 0 {
647 if len(d) < 2 {
648 return false
649 }
650 pskLen := int(d[0])<<8 | int(d[1])
651 d = d[2:]
Steven Valdez5b986082016-09-01 12:29:49 -0400652
Steven Valdeza833c352016-11-01 13:39:36 -0400653 if len(d) < pskLen+4 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400654 return false
655 }
Steven Valdeza833c352016-11-01 13:39:36 -0400656 ticket := d[:pskLen]
657 obfuscatedTicketAge := uint32(d[pskLen])<<24 | uint32(d[pskLen+1])<<16 | uint32(d[pskLen+2])<<8 | uint32(d[pskLen+3])
658 psk := pskIdentity{
659 ticket: ticket,
660 obfuscatedTicketAge: obfuscatedTicketAge,
661 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400662 m.pskIdentities = append(m.pskIdentities, psk)
Steven Valdeza833c352016-11-01 13:39:36 -0400663 d = d[pskLen+4:]
Nick Harperf8b0e702016-06-30 19:59:01 -0400664 }
Steven Valdeza833c352016-11-01 13:39:36 -0400665 d = data[l+2:]
666 if len(d) < 2 {
667 return false
668 }
669 l = int(d[0])<<8 | int(d[1])
670 d = d[2:]
671 if l != len(d) {
672 return false
673 }
674 // Parse PSK binders.
675 for len(d) > 0 {
676 if len(d) < 1 {
677 return false
678 }
679 binderLen := int(d[0])
680 d = d[1:]
681 if binderLen > len(d) {
682 return false
683 }
684 m.pskBinders = append(m.pskBinders, d[:binderLen])
685 d = d[binderLen:]
686 }
687
688 // There must be the same number of identities as binders.
689 if len(m.pskIdentities) != len(m.pskBinders) {
690 return false
691 }
692 case extensionPSKKeyExchangeModes:
693 // draft-ietf-tls-tls13-18 section 4.2.7
694 if length < 1 {
695 return false
696 }
697 l := int(data[0])
698 if l != length-1 {
699 return false
700 }
701 m.pskKEModes = data[1:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400702 case extensionEarlyData:
703 // draft-ietf-tls-tls13 section 6.3.2.5
David Benjaminc5665c92016-11-15 18:12:58 +0900704 if length != 0 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400705 return false
706 }
707 m.hasEarlyData = true
David Benjamin3baa6e12016-10-07 21:10:38 -0400708 case extensionCookie:
709 if length < 2 {
710 return false
711 }
712 l := int(data[0])<<8 | int(data[1])
713 if l != length-2 || l == 0 {
714 return false
715 }
716 m.tls13Cookie = data[2 : 2+l]
Adam Langley95c29f32014-06-20 12:00:00 -0700717 case extensionSignatureAlgorithms:
718 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
719 if length < 2 || length&1 != 0 {
720 return false
721 }
722 l := int(data[0])<<8 | int(data[1])
723 if l != length-2 {
724 return false
725 }
726 n := l / 2
727 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700728 m.signatureAlgorithms = make([]signatureAlgorithm, n)
729 for i := range m.signatureAlgorithms {
730 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700731 d = d[2:]
732 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400733 case extensionSupportedVersions:
734 if length < 1+2 {
735 return false
736 }
737 l := int(data[0])
738 if l != length-1 || l%2 == 1 || l < 2 {
739 return false
740 }
741 n := l / 2
742 d := data[1:]
743 m.supportedVersions = make([]uint16, n)
744 for i := range m.supportedVersions {
745 m.supportedVersions[i] = uint16(d[0])<<8 | uint16(d[1])
746 d = d[2:]
747 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700748 case extensionRenegotiationInfo:
749 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700750 return false
751 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700752 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400753 case extensionALPN:
754 if length < 2 {
755 return false
756 }
757 l := int(data[0])<<8 | int(data[1])
758 if l != length-2 {
759 return false
760 }
761 d := data[2:length]
762 for len(d) != 0 {
763 stringLen := int(d[0])
764 d = d[1:]
765 if stringLen == 0 || stringLen > len(d) {
766 return false
767 }
768 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
769 d = d[stringLen:]
770 }
David Benjamind30a9902014-08-24 01:44:23 -0400771 case extensionChannelID:
772 if length > 0 {
773 return false
774 }
775 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700776 case extensionExtendedMasterSecret:
777 if length != 0 {
778 return false
779 }
780 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500781 case extensionUseSRTP:
782 if length < 2 {
783 return false
784 }
785 l := int(data[0])<<8 | int(data[1])
786 if l > length-2 || l%2 != 0 {
787 return false
788 }
789 n := l / 2
790 m.srtpProtectionProfiles = make([]uint16, n)
791 d := data[2:length]
792 for i := 0; i < n; i++ {
793 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
794 d = d[2:]
795 }
796 if len(d) < 1 || int(d[0]) != len(d)-1 {
797 return false
798 }
799 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500800 case extensionSignedCertificateTimestamp:
801 if length != 0 {
802 return false
803 }
804 m.sctListSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700805 case extensionCustom:
806 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700807 }
808 data = data[length:]
David Benjamin65ac9972016-09-02 21:35:25 -0400809
810 if isGREASEValue(extension) {
811 m.hasGREASEExtension = true
812 }
Adam Langley95c29f32014-06-20 12:00:00 -0700813 }
814
815 return true
816}
817
818type serverHelloMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -0400819 raw []byte
820 isDTLS bool
821 vers uint16
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400822 versOverride uint16
Nick Harperb41d2e42016-07-01 17:50:32 -0400823 random []byte
824 sessionId []byte
825 cipherSuite uint16
826 hasKeyShare bool
827 keyShare keyShareEntry
828 hasPSKIdentity bool
829 pskIdentity uint16
830 earlyDataIndication bool
831 compressionMethod uint8
David Benjamin490469f2016-10-05 22:44:38 -0400832 customExtension string
833 unencryptedALPN string
Nick Harperb41d2e42016-07-01 17:50:32 -0400834 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700835}
836
Adam Langley95c29f32014-06-20 12:00:00 -0700837func (m *serverHelloMsg) marshal() []byte {
838 if m.raw != nil {
839 return m.raw
840 }
841
Nick Harper5212ef82016-06-30 19:26:07 -0400842 handshakeMsg := newByteBuilder()
843 handshakeMsg.addU8(typeServerHello)
844 hello := handshakeMsg.addU24LengthPrefixed()
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400845
846 // m.vers is used both to determine the format of the rest of the
847 // ServerHello and to override the value, so include a second version
848 // field.
849 vers, ok := wireToVersion(m.vers, m.isDTLS)
850 if !ok {
851 panic("unknown version")
852 }
853 if m.versOverride != 0 {
854 hello.addU16(m.versOverride)
855 } else {
856 hello.addU16(m.vers)
857 }
858
Nick Harper5212ef82016-06-30 19:26:07 -0400859 hello.addBytes(m.random)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400860 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400861 sessionId := hello.addU8LengthPrefixed()
862 sessionId.addBytes(m.sessionId)
863 }
Nick Harper5212ef82016-06-30 19:26:07 -0400864 hello.addU16(m.cipherSuite)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400865 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400866 hello.addU8(m.compressionMethod)
867 }
Adam Langley95c29f32014-06-20 12:00:00 -0700868
Nick Harper5212ef82016-06-30 19:26:07 -0400869 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400870
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400871 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400872 if m.hasKeyShare {
873 extensions.addU16(extensionKeyShare)
874 keyShare := extensions.addU16LengthPrefixed()
875 keyShare.addU16(uint16(m.keyShare.group))
876 keyExchange := keyShare.addU16LengthPrefixed()
877 keyExchange.addBytes(m.keyShare.keyExchange)
878 }
879 if m.hasPSKIdentity {
880 extensions.addU16(extensionPreSharedKey)
881 extensions.addU16(2) // Length
882 extensions.addU16(m.pskIdentity)
883 }
884 if m.earlyDataIndication {
885 extensions.addU16(extensionEarlyData)
886 extensions.addU16(0) // Length
887 }
David Benjamin490469f2016-10-05 22:44:38 -0400888 if len(m.customExtension) > 0 {
889 extensions.addU16(extensionCustom)
890 customExt := extensions.addU16LengthPrefixed()
891 customExt.addBytes([]byte(m.customExtension))
892 }
893 if len(m.unencryptedALPN) > 0 {
894 extensions.addU16(extensionALPN)
895 extension := extensions.addU16LengthPrefixed()
896
897 protocolNameList := extension.addU16LengthPrefixed()
898 protocolName := protocolNameList.addU8LengthPrefixed()
899 protocolName.addBytes([]byte(m.unencryptedALPN))
900 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400901 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400902 m.extensions.marshal(extensions)
Nick Harperb41d2e42016-07-01 17:50:32 -0400903 if extensions.len() == 0 {
904 hello.discardChild()
905 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400906 }
907
908 m.raw = handshakeMsg.finish()
909 return m.raw
910}
911
912func (m *serverHelloMsg) unmarshal(data []byte) bool {
913 if len(data) < 42 {
914 return false
915 }
916 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400917 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400918 vers, ok := wireToVersion(m.vers, m.isDTLS)
919 if !ok {
920 return false
921 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400922 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400923 data = data[38:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400924 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400925 sessionIdLen := int(data[0])
926 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
927 return false
928 }
929 m.sessionId = data[1 : 1+sessionIdLen]
930 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400931 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400932 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400933 return false
934 }
935 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400936 data = data[2:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400937 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400938 if len(data) < 1 {
939 return false
940 }
941 m.compressionMethod = data[0]
942 data = data[1:]
943 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400944
David Benjamin8d315d72016-07-18 01:03:18 +0200945 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400946 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400947 m.extensions = serverExtensions{}
948 return true
949 }
950 if len(data) < 2 {
951 return false
952 }
953
954 extensionsLength := int(data[0])<<8 | int(data[1])
955 data = data[2:]
956 if len(data) != extensionsLength {
957 return false
958 }
959
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400960 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400961 for len(data) != 0 {
962 if len(data) < 4 {
963 return false
964 }
965 extension := uint16(data[0])<<8 | uint16(data[1])
966 length := int(data[2])<<8 | int(data[3])
967 data = data[4:]
968
969 if len(data) < length {
970 return false
971 }
972 d := data[:length]
973 data = data[length:]
974
975 switch extension {
976 case extensionKeyShare:
977 m.hasKeyShare = true
978 if len(d) < 4 {
979 return false
980 }
981 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
982 keyExchLen := int(d[2])<<8 | int(d[3])
983 if keyExchLen != len(d)-4 {
984 return false
985 }
986 m.keyShare.keyExchange = make([]byte, keyExchLen)
987 copy(m.keyShare.keyExchange, d[4:])
988 case extensionPreSharedKey:
989 if len(d) != 2 {
990 return false
991 }
992 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
993 m.hasPSKIdentity = true
994 case extensionEarlyData:
995 if len(d) != 0 {
996 return false
997 }
998 m.earlyDataIndication = true
999 default:
1000 // Only allow the 3 extensions that are sent in
1001 // the clear in TLS 1.3.
1002 return false
1003 }
1004 }
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001005 } else if !m.extensions.unmarshal(data, vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -04001006 return false
1007 }
1008
1009 return true
1010}
1011
Nick Harperb41d2e42016-07-01 17:50:32 -04001012type encryptedExtensionsMsg struct {
1013 raw []byte
1014 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -04001015 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001016}
1017
1018func (m *encryptedExtensionsMsg) marshal() []byte {
1019 if m.raw != nil {
1020 return m.raw
1021 }
1022
1023 encryptedExtensionsMsg := newByteBuilder()
1024 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
1025 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -04001026 if !m.empty {
1027 extensions := encryptedExtensions.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001028 m.extensions.marshal(extensions)
Steven Valdez143e8b32016-07-11 13:19:03 -04001029 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001030
1031 m.raw = encryptedExtensionsMsg.finish()
1032 return m.raw
1033}
1034
1035func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -04001036 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001037 if len(data) < 6 {
1038 return false
1039 }
1040 if data[0] != typeEncryptedExtensions {
1041 return false
1042 }
1043 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1044 data = data[4:]
1045 if len(data) != msgLen {
1046 return false
1047 }
1048 extLen := int(data[0])<<8 | int(data[1])
1049 data = data[2:]
1050 if extLen != len(data) {
1051 return false
1052 }
David Benjamin44b33bc2016-07-01 22:40:23 -04001053 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -04001054}
1055
Nick Harperb3d51be2016-07-01 11:43:18 -04001056type serverExtensions struct {
1057 nextProtoNeg bool
1058 nextProtos []string
1059 ocspStapling bool
1060 ticketSupported bool
1061 secureRenegotiation []byte
1062 alpnProtocol string
1063 alpnProtocolEmpty bool
1064 duplicateExtension bool
1065 channelIDRequested bool
1066 extendedMasterSecret bool
1067 srtpProtectionProfile uint16
1068 srtpMasterKeyIdentifier string
1069 sctList []byte
1070 customExtension string
Steven Valdeza833c352016-11-01 13:39:36 -04001071 npnAfterAlpn bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001072 hasKeyShare bool
1073 keyShare keyShareEntry
Nick Harperb3d51be2016-07-01 11:43:18 -04001074}
1075
Steven Valdeza833c352016-11-01 13:39:36 -04001076func (m *serverExtensions) marshal(extensions *byteBuilder) {
David Benjamin35a7a442014-07-05 00:23:20 -04001077 if m.duplicateExtension {
1078 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001079 extensions.addU16(0xffff)
1080 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -04001081 }
Steven Valdeza833c352016-11-01 13:39:36 -04001082 if m.nextProtoNeg && !m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001083 extensions.addU16(extensionNextProtoNeg)
1084 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001085
1086 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001087 if len(v) > 255 {
1088 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -07001089 }
Nick Harper5212ef82016-06-30 19:26:07 -04001090 npn := extension.addU8LengthPrefixed()
1091 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -07001092 }
1093 }
Steven Valdeza833c352016-11-01 13:39:36 -04001094 if m.ocspStapling {
1095 extensions.addU16(extensionStatusRequest)
1096 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001097 }
1098 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -04001099 extensions.addU16(extensionSessionTicket)
1100 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001101 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001102 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001103 extensions.addU16(extensionRenegotiationInfo)
1104 extension := extensions.addU16LengthPrefixed()
1105 secureRenego := extension.addU8LengthPrefixed()
1106 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -07001107 }
Nick Harper5212ef82016-06-30 19:26:07 -04001108 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
1109 extensions.addU16(extensionALPN)
1110 extension := extensions.addU16LengthPrefixed()
1111
1112 protocolNameList := extension.addU16LengthPrefixed()
1113 protocolName := protocolNameList.addU8LengthPrefixed()
1114 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -04001115 }
David Benjamind30a9902014-08-24 01:44:23 -04001116 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -04001117 extensions.addU16(extensionChannelID)
1118 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -04001119 }
David Benjamin35a7a442014-07-05 00:23:20 -04001120 if m.duplicateExtension {
1121 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001122 extensions.addU16(0xffff)
1123 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -04001124 }
Adam Langley75712922014-10-10 16:23:43 -07001125 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -04001126 extensions.addU16(extensionExtendedMasterSecret)
1127 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -07001128 }
David Benjaminca6c8262014-11-15 19:06:08 -05001129 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001130 extensions.addU16(extensionUseSRTP)
1131 extension := extensions.addU16LengthPrefixed()
1132
1133 srtpProtectionProfiles := extension.addU16LengthPrefixed()
1134 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
1135 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
1136 srtpMki := extension.addU8LengthPrefixed()
1137 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -05001138 }
David Benjamin61f95272014-11-25 01:55:35 -05001139 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001140 extensions.addU16(extensionSignedCertificateTimestamp)
1141 extension := extensions.addU16LengthPrefixed()
1142 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -05001143 }
Adam Langley09505632015-07-30 18:10:13 -07001144 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001145 extensions.addU16(extensionCustom)
1146 customExt := extensions.addU16LengthPrefixed()
1147 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -07001148 }
Steven Valdeza833c352016-11-01 13:39:36 -04001149 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001150 extensions.addU16(extensionNextProtoNeg)
1151 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -04001152
1153 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001154 if len(v) > 255 {
1155 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -04001156 }
Nick Harper5212ef82016-06-30 19:26:07 -04001157 npn := extension.addU8LengthPrefixed()
1158 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001159 }
1160 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001161 if m.hasKeyShare {
1162 extensions.addU16(extensionKeyShare)
1163 keyShare := extensions.addU16LengthPrefixed()
1164 keyShare.addU16(uint16(m.keyShare.group))
1165 keyExchange := keyShare.addU16LengthPrefixed()
1166 keyExchange.addBytes(m.keyShare.keyExchange)
1167 }
Adam Langley95c29f32014-06-20 12:00:00 -07001168}
1169
David Benjamin44b33bc2016-07-01 22:40:23 -04001170func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001171 // Reset all fields.
1172 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001173
1174 for len(data) != 0 {
1175 if len(data) < 4 {
1176 return false
1177 }
1178 extension := uint16(data[0])<<8 | uint16(data[1])
1179 length := int(data[2])<<8 | int(data[3])
1180 data = data[4:]
1181 if len(data) < length {
1182 return false
1183 }
1184
1185 switch extension {
1186 case extensionNextProtoNeg:
1187 m.nextProtoNeg = true
1188 d := data[:length]
1189 for len(d) > 0 {
1190 l := int(d[0])
1191 d = d[1:]
1192 if l == 0 || l > len(d) {
1193 return false
1194 }
1195 m.nextProtos = append(m.nextProtos, string(d[:l]))
1196 d = d[l:]
1197 }
1198 case extensionStatusRequest:
Steven Valdeza833c352016-11-01 13:39:36 -04001199 if length > 0 {
1200 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001201 }
Steven Valdeza833c352016-11-01 13:39:36 -04001202 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001203 case extensionSessionTicket:
1204 if length > 0 {
1205 return false
1206 }
1207 m.ticketSupported = true
1208 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001209 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001210 return false
1211 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001212 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001213 case extensionALPN:
1214 d := data[:length]
1215 if len(d) < 3 {
1216 return false
1217 }
1218 l := int(d[0])<<8 | int(d[1])
1219 if l != len(d)-2 {
1220 return false
1221 }
1222 d = d[2:]
1223 l = int(d[0])
1224 if l != len(d)-1 {
1225 return false
1226 }
1227 d = d[1:]
1228 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001229 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001230 case extensionChannelID:
1231 if length > 0 {
1232 return false
1233 }
1234 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001235 case extensionExtendedMasterSecret:
1236 if length != 0 {
1237 return false
1238 }
1239 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001240 case extensionUseSRTP:
1241 if length < 2+2+1 {
1242 return false
1243 }
1244 if data[0] != 0 || data[1] != 2 {
1245 return false
1246 }
1247 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1248 d := data[4:length]
1249 l := int(d[0])
1250 if l != len(d)-1 {
1251 return false
1252 }
1253 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001254 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001255 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001256 case extensionCustom:
1257 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001258 case extensionServerName:
1259 if length != 0 {
1260 return false
1261 }
1262 // Ignore this extension from the server.
1263 case extensionSupportedPoints:
1264 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001265 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001266 return false
1267 }
1268 // Ignore this extension from the server.
David Benjamin4ee027f2016-07-17 12:34:41 +02001269 case extensionSupportedCurves:
1270 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001271 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001272 return false
1273 }
David Benjamin46f94bd2016-07-14 16:43:37 -04001274 default:
1275 // Unknown extensions are illegal from the server.
1276 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001277 }
1278 data = data[length:]
1279 }
1280
1281 return true
1282}
1283
Nick Harperdcfbc672016-07-16 17:47:31 +02001284type helloRetryRequestMsg struct {
David Benjamin3baa6e12016-10-07 21:10:38 -04001285 raw []byte
1286 vers uint16
1287 hasSelectedGroup bool
1288 selectedGroup CurveID
1289 cookie []byte
1290 customExtension string
1291 duplicateExtensions bool
Nick Harperdcfbc672016-07-16 17:47:31 +02001292}
1293
1294func (m *helloRetryRequestMsg) marshal() []byte {
1295 if m.raw != nil {
1296 return m.raw
1297 }
1298
1299 retryRequestMsg := newByteBuilder()
1300 retryRequestMsg.addU8(typeHelloRetryRequest)
1301 retryRequest := retryRequestMsg.addU24LengthPrefixed()
1302 retryRequest.addU16(m.vers)
David Benjamin3baa6e12016-10-07 21:10:38 -04001303 extensions := retryRequest.addU16LengthPrefixed()
1304
1305 count := 1
1306 if m.duplicateExtensions {
1307 count = 2
1308 }
1309
1310 for i := 0; i < count; i++ {
1311 if m.hasSelectedGroup {
1312 extensions.addU16(extensionKeyShare)
1313 extensions.addU16(2) // length
1314 extensions.addU16(uint16(m.selectedGroup))
1315 }
1316 if len(m.cookie) > 0 {
1317 extensions.addU16(extensionCookie)
1318 body := extensions.addU16LengthPrefixed()
1319 body.addU16LengthPrefixed().addBytes(m.cookie)
1320 }
1321 if len(m.customExtension) > 0 {
1322 extensions.addU16(extensionCustom)
1323 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
1324 }
1325 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001326
1327 m.raw = retryRequestMsg.finish()
1328 return m.raw
1329}
1330
1331func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1332 m.raw = data
David Benjamin3baa6e12016-10-07 21:10:38 -04001333 if len(data) < 8 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001334 return false
1335 }
1336 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin3baa6e12016-10-07 21:10:38 -04001337 extLen := int(data[6])<<8 | int(data[7])
1338 data = data[8:]
1339 if len(data) != extLen || len(data) == 0 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001340 return false
1341 }
David Benjamin3baa6e12016-10-07 21:10:38 -04001342 for len(data) > 0 {
1343 if len(data) < 4 {
1344 return false
1345 }
1346 extension := uint16(data[0])<<8 | uint16(data[1])
1347 length := int(data[2])<<8 | int(data[3])
1348 data = data[4:]
1349 if len(data) < length {
1350 return false
1351 }
1352
1353 switch extension {
1354 case extensionKeyShare:
1355 if length != 2 {
1356 return false
1357 }
1358 m.hasSelectedGroup = true
1359 m.selectedGroup = CurveID(data[0])<<8 | CurveID(data[1])
1360 case extensionCookie:
1361 if length < 2 {
1362 return false
1363 }
1364 cookieLen := int(data[0])<<8 | int(data[1])
1365 if 2+cookieLen != length {
1366 return false
1367 }
1368 m.cookie = data[2 : 2+cookieLen]
1369 default:
1370 // Unknown extensions are illegal from the server.
1371 return false
1372 }
1373 data = data[length:]
1374 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001375 return true
1376}
1377
Steven Valdeza833c352016-11-01 13:39:36 -04001378type certificateEntry struct {
1379 data []byte
1380 ocspResponse []byte
1381 sctList []byte
1382 duplicateExtensions bool
1383 extraExtension []byte
1384}
1385
Adam Langley95c29f32014-06-20 12:00:00 -07001386type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001387 raw []byte
1388 hasRequestContext bool
1389 requestContext []byte
Steven Valdeza833c352016-11-01 13:39:36 -04001390 certificates []certificateEntry
Adam Langley95c29f32014-06-20 12:00:00 -07001391}
1392
Adam Langley95c29f32014-06-20 12:00:00 -07001393func (m *certificateMsg) marshal() (x []byte) {
1394 if m.raw != nil {
1395 return m.raw
1396 }
1397
Nick Harper7e0442a2016-07-01 17:40:09 -04001398 certMsg := newByteBuilder()
1399 certMsg.addU8(typeCertificate)
1400 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001401 if m.hasRequestContext {
1402 context := certificate.addU8LengthPrefixed()
1403 context.addBytes(m.requestContext)
1404 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001405 certificateList := certificate.addU24LengthPrefixed()
1406 for _, cert := range m.certificates {
1407 certEntry := certificateList.addU24LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001408 certEntry.addBytes(cert.data)
1409 if m.hasRequestContext {
1410 extensions := certificateList.addU16LengthPrefixed()
1411 count := 1
1412 if cert.duplicateExtensions {
1413 count = 2
1414 }
1415
1416 for i := 0; i < count; i++ {
1417 if cert.ocspResponse != nil {
1418 extensions.addU16(extensionStatusRequest)
1419 body := extensions.addU16LengthPrefixed()
1420 body.addU8(statusTypeOCSP)
1421 response := body.addU24LengthPrefixed()
1422 response.addBytes(cert.ocspResponse)
1423 }
1424
1425 if cert.sctList != nil {
1426 extensions.addU16(extensionSignedCertificateTimestamp)
1427 extension := extensions.addU16LengthPrefixed()
1428 extension.addBytes(cert.sctList)
1429 }
1430 }
1431 if cert.extraExtension != nil {
1432 extensions.addBytes(cert.extraExtension)
1433 }
1434 }
Adam Langley95c29f32014-06-20 12:00:00 -07001435 }
1436
Nick Harper7e0442a2016-07-01 17:40:09 -04001437 m.raw = certMsg.finish()
1438 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001439}
1440
1441func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001442 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001443 return false
1444 }
1445
1446 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001447 data = data[4:]
1448
1449 if m.hasRequestContext {
1450 if len(data) == 0 {
1451 return false
1452 }
1453 contextLen := int(data[0])
1454 if len(data) < 1+contextLen {
1455 return false
1456 }
1457 m.requestContext = make([]byte, contextLen)
1458 copy(m.requestContext, data[1:])
1459 data = data[1+contextLen:]
1460 }
1461
1462 if len(data) < 3 {
1463 return false
1464 }
1465 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1466 data = data[3:]
1467 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001468 return false
1469 }
1470
Steven Valdeza833c352016-11-01 13:39:36 -04001471 m.certificates = nil
1472 for len(data) != 0 {
1473 if len(data) < 3 {
Adam Langley95c29f32014-06-20 12:00:00 -07001474 return false
1475 }
Steven Valdeza833c352016-11-01 13:39:36 -04001476 certLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1477 if len(data) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001478 return false
1479 }
Steven Valdeza833c352016-11-01 13:39:36 -04001480 cert := certificateEntry{
1481 data: data[3 : 3+certLen],
1482 }
1483 data = data[3+certLen:]
1484 if m.hasRequestContext {
1485 if len(data) < 2 {
1486 return false
1487 }
1488 extensionsLen := int(data[0])<<8 | int(data[1])
1489 if len(data) < 2+extensionsLen {
1490 return false
1491 }
1492 extensions := data[2 : 2+extensionsLen]
1493 data = data[2+extensionsLen:]
1494 for len(extensions) != 0 {
1495 if len(extensions) < 4 {
1496 return false
1497 }
1498 extension := uint16(extensions[0])<<8 | uint16(extensions[1])
1499 length := int(extensions[2])<<8 | int(extensions[3])
1500 if len(extensions) < 4+length {
1501 return false
1502 }
1503 contents := extensions[4 : 4+length]
1504 extensions = extensions[4+length:]
Adam Langley95c29f32014-06-20 12:00:00 -07001505
Steven Valdeza833c352016-11-01 13:39:36 -04001506 switch extension {
1507 case extensionStatusRequest:
1508 if length < 4 {
1509 return false
1510 }
1511 if contents[0] != statusTypeOCSP {
1512 return false
1513 }
1514 respLen := int(contents[1])<<16 | int(contents[2])<<8 | int(contents[3])
1515 if respLen+4 != len(contents) || respLen == 0 {
1516 return false
1517 }
1518 cert.ocspResponse = contents[4:]
1519 case extensionSignedCertificateTimestamp:
1520 cert.sctList = contents
1521 default:
1522 return false
1523 }
1524 }
1525 }
1526 m.certificates = append(m.certificates, cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001527 }
1528
1529 return true
1530}
1531
1532type serverKeyExchangeMsg struct {
1533 raw []byte
1534 key []byte
1535}
1536
Adam Langley95c29f32014-06-20 12:00:00 -07001537func (m *serverKeyExchangeMsg) marshal() []byte {
1538 if m.raw != nil {
1539 return m.raw
1540 }
1541 length := len(m.key)
1542 x := make([]byte, length+4)
1543 x[0] = typeServerKeyExchange
1544 x[1] = uint8(length >> 16)
1545 x[2] = uint8(length >> 8)
1546 x[3] = uint8(length)
1547 copy(x[4:], m.key)
1548
1549 m.raw = x
1550 return x
1551}
1552
1553func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1554 m.raw = data
1555 if len(data) < 4 {
1556 return false
1557 }
1558 m.key = data[4:]
1559 return true
1560}
1561
1562type certificateStatusMsg struct {
1563 raw []byte
1564 statusType uint8
1565 response []byte
1566}
1567
Adam Langley95c29f32014-06-20 12:00:00 -07001568func (m *certificateStatusMsg) marshal() []byte {
1569 if m.raw != nil {
1570 return m.raw
1571 }
1572
1573 var x []byte
1574 if m.statusType == statusTypeOCSP {
1575 x = make([]byte, 4+4+len(m.response))
1576 x[0] = typeCertificateStatus
1577 l := len(m.response) + 4
1578 x[1] = byte(l >> 16)
1579 x[2] = byte(l >> 8)
1580 x[3] = byte(l)
1581 x[4] = statusTypeOCSP
1582
1583 l -= 4
1584 x[5] = byte(l >> 16)
1585 x[6] = byte(l >> 8)
1586 x[7] = byte(l)
1587 copy(x[8:], m.response)
1588 } else {
1589 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1590 }
1591
1592 m.raw = x
1593 return x
1594}
1595
1596func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1597 m.raw = data
1598 if len(data) < 5 {
1599 return false
1600 }
1601 m.statusType = data[4]
1602
1603 m.response = nil
1604 if m.statusType == statusTypeOCSP {
1605 if len(data) < 8 {
1606 return false
1607 }
1608 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1609 if uint32(len(data)) != 4+4+respLen {
1610 return false
1611 }
1612 m.response = data[8:]
1613 }
1614 return true
1615}
1616
1617type serverHelloDoneMsg struct{}
1618
Adam Langley95c29f32014-06-20 12:00:00 -07001619func (m *serverHelloDoneMsg) marshal() []byte {
1620 x := make([]byte, 4)
1621 x[0] = typeServerHelloDone
1622 return x
1623}
1624
1625func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1626 return len(data) == 4
1627}
1628
1629type clientKeyExchangeMsg struct {
1630 raw []byte
1631 ciphertext []byte
1632}
1633
Adam Langley95c29f32014-06-20 12:00:00 -07001634func (m *clientKeyExchangeMsg) marshal() []byte {
1635 if m.raw != nil {
1636 return m.raw
1637 }
1638 length := len(m.ciphertext)
1639 x := make([]byte, length+4)
1640 x[0] = typeClientKeyExchange
1641 x[1] = uint8(length >> 16)
1642 x[2] = uint8(length >> 8)
1643 x[3] = uint8(length)
1644 copy(x[4:], m.ciphertext)
1645
1646 m.raw = x
1647 return x
1648}
1649
1650func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1651 m.raw = data
1652 if len(data) < 4 {
1653 return false
1654 }
1655 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1656 if l != len(data)-4 {
1657 return false
1658 }
1659 m.ciphertext = data[4:]
1660 return true
1661}
1662
1663type finishedMsg struct {
1664 raw []byte
1665 verifyData []byte
1666}
1667
Adam Langley95c29f32014-06-20 12:00:00 -07001668func (m *finishedMsg) marshal() (x []byte) {
1669 if m.raw != nil {
1670 return m.raw
1671 }
1672
1673 x = make([]byte, 4+len(m.verifyData))
1674 x[0] = typeFinished
1675 x[3] = byte(len(m.verifyData))
1676 copy(x[4:], m.verifyData)
1677 m.raw = x
1678 return
1679}
1680
1681func (m *finishedMsg) unmarshal(data []byte) bool {
1682 m.raw = data
1683 if len(data) < 4 {
1684 return false
1685 }
1686 m.verifyData = data[4:]
1687 return true
1688}
1689
1690type nextProtoMsg struct {
1691 raw []byte
1692 proto string
1693}
1694
Adam Langley95c29f32014-06-20 12:00:00 -07001695func (m *nextProtoMsg) marshal() []byte {
1696 if m.raw != nil {
1697 return m.raw
1698 }
1699 l := len(m.proto)
1700 if l > 255 {
1701 l = 255
1702 }
1703
1704 padding := 32 - (l+2)%32
1705 length := l + padding + 2
1706 x := make([]byte, length+4)
1707 x[0] = typeNextProtocol
1708 x[1] = uint8(length >> 16)
1709 x[2] = uint8(length >> 8)
1710 x[3] = uint8(length)
1711
1712 y := x[4:]
1713 y[0] = byte(l)
1714 copy(y[1:], []byte(m.proto[0:l]))
1715 y = y[1+l:]
1716 y[0] = byte(padding)
1717
1718 m.raw = x
1719
1720 return x
1721}
1722
1723func (m *nextProtoMsg) unmarshal(data []byte) bool {
1724 m.raw = data
1725
1726 if len(data) < 5 {
1727 return false
1728 }
1729 data = data[4:]
1730 protoLen := int(data[0])
1731 data = data[1:]
1732 if len(data) < protoLen {
1733 return false
1734 }
1735 m.proto = string(data[0:protoLen])
1736 data = data[protoLen:]
1737
1738 if len(data) < 1 {
1739 return false
1740 }
1741 paddingLen := int(data[0])
1742 data = data[1:]
1743 if len(data) != paddingLen {
1744 return false
1745 }
1746
1747 return true
1748}
1749
1750type certificateRequestMsg struct {
1751 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001752 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001753 // of signature and hash functions. This change was introduced with TLS
1754 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001755 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001756 // hasRequestContext indicates whether this message includes a context
1757 // field instead of certificateTypes. This change was introduced with
1758 // TLS 1.3.
1759 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001760
1761 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001762 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001763 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001764 certificateAuthorities [][]byte
1765}
1766
Nick Harper7e0442a2016-07-01 17:40:09 -04001767func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001768 if m.raw != nil {
1769 return m.raw
1770 }
1771
1772 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001773 builder := newByteBuilder()
1774 builder.addU8(typeCertificateRequest)
1775 body := builder.addU24LengthPrefixed()
1776
Nick Harperb41d2e42016-07-01 17:50:32 -04001777 if m.hasRequestContext {
1778 requestContext := body.addU8LengthPrefixed()
1779 requestContext.addBytes(m.requestContext)
1780 } else {
1781 certificateTypes := body.addU8LengthPrefixed()
1782 certificateTypes.addBytes(m.certificateTypes)
1783 }
Adam Langley95c29f32014-06-20 12:00:00 -07001784
Nick Harper60edffd2016-06-21 15:19:24 -07001785 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001786 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001787 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001788 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001789 }
1790 }
1791
Nick Harper7e0442a2016-07-01 17:40:09 -04001792 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001793 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001794 caEntry := certificateAuthorities.addU16LengthPrefixed()
1795 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001796 }
1797
David Benjamin8d343b42016-07-09 14:26:01 -07001798 if m.hasRequestContext {
1799 // Emit no certificate extensions.
1800 body.addU16(0)
1801 }
1802
Nick Harper7e0442a2016-07-01 17:40:09 -04001803 m.raw = builder.finish()
1804 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001805}
1806
1807func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1808 m.raw = data
1809
1810 if len(data) < 5 {
1811 return false
1812 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001813 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001814
Nick Harperb41d2e42016-07-01 17:50:32 -04001815 if m.hasRequestContext {
1816 contextLen := int(data[0])
1817 if len(data) < 1+contextLen {
1818 return false
1819 }
1820 m.requestContext = make([]byte, contextLen)
1821 copy(m.requestContext, data[1:])
1822 data = data[1+contextLen:]
1823 } else {
1824 numCertTypes := int(data[0])
1825 if len(data) < 1+numCertTypes {
1826 return false
1827 }
1828 m.certificateTypes = make([]byte, numCertTypes)
1829 copy(m.certificateTypes, data[1:])
1830 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001831 }
1832
Nick Harper60edffd2016-06-21 15:19:24 -07001833 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001834 if len(data) < 2 {
1835 return false
1836 }
Nick Harper60edffd2016-06-21 15:19:24 -07001837 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001838 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001839 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001840 return false
1841 }
Nick Harper60edffd2016-06-21 15:19:24 -07001842 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001843 return false
1844 }
Nick Harper60edffd2016-06-21 15:19:24 -07001845 numSigAlgs := sigAlgsLen / 2
1846 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1847 for i := range m.signatureAlgorithms {
1848 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001849 data = data[2:]
1850 }
1851 }
1852
1853 if len(data) < 2 {
1854 return false
1855 }
1856 casLength := uint16(data[0])<<8 | uint16(data[1])
1857 data = data[2:]
1858 if len(data) < int(casLength) {
1859 return false
1860 }
1861 cas := make([]byte, casLength)
1862 copy(cas, data)
1863 data = data[casLength:]
1864
1865 m.certificateAuthorities = nil
1866 for len(cas) > 0 {
1867 if len(cas) < 2 {
1868 return false
1869 }
1870 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1871 cas = cas[2:]
1872
1873 if len(cas) < int(caLen) {
1874 return false
1875 }
1876
1877 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1878 cas = cas[caLen:]
1879 }
David Benjamin8d343b42016-07-09 14:26:01 -07001880
1881 if m.hasRequestContext {
1882 // Ignore certificate extensions.
1883 if len(data) < 2 {
1884 return false
1885 }
1886 extsLength := int(data[0])<<8 | int(data[1])
1887 if len(data) < 2+extsLength {
1888 return false
1889 }
1890 data = data[2+extsLength:]
1891 }
1892
Adam Langley95c29f32014-06-20 12:00:00 -07001893 if len(data) > 0 {
1894 return false
1895 }
1896
1897 return true
1898}
1899
1900type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07001901 raw []byte
1902 hasSignatureAlgorithm bool
1903 signatureAlgorithm signatureAlgorithm
1904 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001905}
1906
Adam Langley95c29f32014-06-20 12:00:00 -07001907func (m *certificateVerifyMsg) marshal() (x []byte) {
1908 if m.raw != nil {
1909 return m.raw
1910 }
1911
1912 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1913 siglength := len(m.signature)
1914 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07001915 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001916 length += 2
1917 }
1918 x = make([]byte, 4+length)
1919 x[0] = typeCertificateVerify
1920 x[1] = uint8(length >> 16)
1921 x[2] = uint8(length >> 8)
1922 x[3] = uint8(length)
1923 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001924 if m.hasSignatureAlgorithm {
1925 y[0] = byte(m.signatureAlgorithm >> 8)
1926 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07001927 y = y[2:]
1928 }
1929 y[0] = uint8(siglength >> 8)
1930 y[1] = uint8(siglength)
1931 copy(y[2:], m.signature)
1932
1933 m.raw = x
1934
1935 return
1936}
1937
1938func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1939 m.raw = data
1940
1941 if len(data) < 6 {
1942 return false
1943 }
1944
1945 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1946 if uint32(len(data))-4 != length {
1947 return false
1948 }
1949
1950 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001951 if m.hasSignatureAlgorithm {
1952 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001953 data = data[2:]
1954 }
1955
1956 if len(data) < 2 {
1957 return false
1958 }
1959 siglength := int(data[0])<<8 + int(data[1])
1960 data = data[2:]
1961 if len(data) != siglength {
1962 return false
1963 }
1964
1965 m.signature = data
1966
1967 return true
1968}
1969
1970type newSessionTicketMsg struct {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04001971 raw []byte
1972 version uint16
1973 ticketLifetime uint32
Steven Valdeza833c352016-11-01 13:39:36 -04001974 ticketAgeAdd uint32
David Benjamin1a5e8ec2016-10-07 15:19:18 -04001975 ticket []byte
David Benjamin1286bee2016-10-07 15:25:06 -04001976 customExtension string
David Benjamin1a5e8ec2016-10-07 15:19:18 -04001977 hasGREASEExtension bool
Adam Langley95c29f32014-06-20 12:00:00 -07001978}
1979
David Benjamin58104882016-07-18 01:25:41 +02001980func (m *newSessionTicketMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001981 if m.raw != nil {
1982 return m.raw
1983 }
1984
1985 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjamin58104882016-07-18 01:25:41 +02001986 ticketMsg := newByteBuilder()
1987 ticketMsg.addU8(typeNewSessionTicket)
1988 body := ticketMsg.addU24LengthPrefixed()
1989 body.addU32(m.ticketLifetime)
1990 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04001991 body.addU32(m.ticketAgeAdd)
Steven Valdez5b986082016-09-01 12:29:49 -04001992 }
1993
1994 ticket := body.addU16LengthPrefixed()
1995 ticket.addBytes(m.ticket)
1996
1997 if m.version >= VersionTLS13 {
David Benjamin1286bee2016-10-07 15:25:06 -04001998 extensions := body.addU16LengthPrefixed()
1999 if len(m.customExtension) > 0 {
2000 extensions.addU16(ticketExtensionCustom)
2001 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
2002 }
David Benjamin58104882016-07-18 01:25:41 +02002003 }
Adam Langley95c29f32014-06-20 12:00:00 -07002004
David Benjamin58104882016-07-18 01:25:41 +02002005 m.raw = ticketMsg.finish()
2006 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07002007}
2008
2009func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
2010 m.raw = data
2011
David Benjamin58104882016-07-18 01:25:41 +02002012 if len(data) < 8 {
2013 return false
2014 }
2015 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
2016 data = data[8:]
2017
2018 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002019 if len(data) < 4 {
David Benjamin58104882016-07-18 01:25:41 +02002020 return false
2021 }
Steven Valdeza833c352016-11-01 13:39:36 -04002022 m.ticketAgeAdd = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2023 data = data[4:]
David Benjamin58104882016-07-18 01:25:41 +02002024 }
2025
2026 if len(data) < 2 {
2027 return false
2028 }
2029 ticketLen := int(data[0])<<8 + int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002030 data = data[2:]
2031 if len(data) < ticketLen {
David Benjamin58104882016-07-18 01:25:41 +02002032 return false
2033 }
Steven Valdez5b986082016-09-01 12:29:49 -04002034
David Benjamin58104882016-07-18 01:25:41 +02002035 if m.version >= VersionTLS13 && ticketLen == 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07002036 return false
2037 }
2038
Steven Valdez5b986082016-09-01 12:29:49 -04002039 m.ticket = data[:ticketLen]
2040 data = data[ticketLen:]
2041
2042 if m.version >= VersionTLS13 {
2043 if len(data) < 2 {
2044 return false
2045 }
2046 extsLength := int(data[0])<<8 + int(data[1])
2047 data = data[2:]
2048 if len(data) < extsLength {
2049 return false
2050 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002051 extensions := data[:extsLength]
Steven Valdez5b986082016-09-01 12:29:49 -04002052 data = data[extsLength:]
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002053
2054 for len(extensions) > 0 {
2055 if len(extensions) < 4 {
2056 return false
2057 }
2058 extValue := uint16(extensions[0])<<8 | uint16(extensions[1])
2059 extLength := int(extensions[2])<<8 | int(extensions[3])
2060 if len(extensions) < 4+extLength {
2061 return false
2062 }
2063 extensions = extensions[4+extLength:]
2064
2065 if isGREASEValue(extValue) {
2066 m.hasGREASEExtension = true
2067 }
2068 }
Steven Valdez5b986082016-09-01 12:29:49 -04002069 }
2070
2071 if len(data) > 0 {
2072 return false
2073 }
Adam Langley95c29f32014-06-20 12:00:00 -07002074
2075 return true
2076}
2077
David Benjamind86c7672014-08-02 04:07:12 -04002078type v2ClientHelloMsg struct {
2079 raw []byte
2080 vers uint16
2081 cipherSuites []uint16
2082 sessionId []byte
2083 challenge []byte
2084}
2085
David Benjamind86c7672014-08-02 04:07:12 -04002086func (m *v2ClientHelloMsg) marshal() []byte {
2087 if m.raw != nil {
2088 return m.raw
2089 }
2090
2091 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
2092
2093 x := make([]byte, length)
2094 x[0] = 1
2095 x[1] = uint8(m.vers >> 8)
2096 x[2] = uint8(m.vers)
2097 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
2098 x[4] = uint8(len(m.cipherSuites) * 3)
2099 x[5] = uint8(len(m.sessionId) >> 8)
2100 x[6] = uint8(len(m.sessionId))
2101 x[7] = uint8(len(m.challenge) >> 8)
2102 x[8] = uint8(len(m.challenge))
2103 y := x[9:]
2104 for i, spec := range m.cipherSuites {
2105 y[i*3] = 0
2106 y[i*3+1] = uint8(spec >> 8)
2107 y[i*3+2] = uint8(spec)
2108 }
2109 y = y[len(m.cipherSuites)*3:]
2110 copy(y, m.sessionId)
2111 y = y[len(m.sessionId):]
2112 copy(y, m.challenge)
2113
2114 m.raw = x
2115
2116 return x
2117}
2118
David Benjamin83c0bc92014-08-04 01:23:53 -04002119type helloVerifyRequestMsg struct {
2120 raw []byte
2121 vers uint16
2122 cookie []byte
2123}
2124
David Benjamin83c0bc92014-08-04 01:23:53 -04002125func (m *helloVerifyRequestMsg) marshal() []byte {
2126 if m.raw != nil {
2127 return m.raw
2128 }
2129
2130 length := 2 + 1 + len(m.cookie)
2131
2132 x := make([]byte, 4+length)
2133 x[0] = typeHelloVerifyRequest
2134 x[1] = uint8(length >> 16)
2135 x[2] = uint8(length >> 8)
2136 x[3] = uint8(length)
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002137 vers := m.vers
David Benjamin83c0bc92014-08-04 01:23:53 -04002138 x[4] = uint8(vers >> 8)
2139 x[5] = uint8(vers)
2140 x[6] = uint8(len(m.cookie))
2141 copy(x[7:7+len(m.cookie)], m.cookie)
2142
2143 return x
2144}
2145
2146func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
2147 if len(data) < 4+2+1 {
2148 return false
2149 }
2150 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002151 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin83c0bc92014-08-04 01:23:53 -04002152 cookieLen := int(data[6])
2153 if cookieLen > 32 || len(data) != 7+cookieLen {
2154 return false
2155 }
2156 m.cookie = data[7 : 7+cookieLen]
2157
2158 return true
2159}
2160
David Benjamin24599a82016-06-30 18:56:53 -04002161type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04002162 raw []byte
2163 channelID []byte
2164}
2165
David Benjamin24599a82016-06-30 18:56:53 -04002166func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04002167 if m.raw != nil {
2168 return m.raw
2169 }
2170
2171 length := 2 + 2 + len(m.channelID)
2172
2173 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04002174 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04002175 x[1] = uint8(length >> 16)
2176 x[2] = uint8(length >> 8)
2177 x[3] = uint8(length)
2178 x[4] = uint8(extensionChannelID >> 8)
2179 x[5] = uint8(extensionChannelID & 0xff)
2180 x[6] = uint8(len(m.channelID) >> 8)
2181 x[7] = uint8(len(m.channelID) & 0xff)
2182 copy(x[8:], m.channelID)
2183
2184 return x
2185}
2186
David Benjamin24599a82016-06-30 18:56:53 -04002187func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04002188 if len(data) != 4+2+2+128 {
2189 return false
2190 }
2191 m.raw = data
2192 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
2193 return false
2194 }
2195 if int(data[6])<<8|int(data[7]) != 128 {
2196 return false
2197 }
2198 m.channelID = data[4+2+2:]
2199
2200 return true
2201}
2202
Adam Langley2ae77d22014-10-28 17:29:33 -07002203type helloRequestMsg struct {
2204}
2205
2206func (*helloRequestMsg) marshal() []byte {
2207 return []byte{typeHelloRequest, 0, 0, 0}
2208}
2209
2210func (*helloRequestMsg) unmarshal(data []byte) bool {
2211 return len(data) == 4
2212}
2213
David Benjamin21c00282016-07-18 21:56:23 +02002214type keyUpdateMsg struct {
Steven Valdezc4aa7272016-10-03 12:25:56 -04002215 raw []byte
2216 keyUpdateRequest byte
David Benjamin21c00282016-07-18 21:56:23 +02002217}
2218
Steven Valdezc4aa7272016-10-03 12:25:56 -04002219func (m *keyUpdateMsg) marshal() []byte {
2220 if m.raw != nil {
2221 return m.raw
2222 }
2223
2224 return []byte{typeKeyUpdate, 0, 0, 1, m.keyUpdateRequest}
David Benjamin21c00282016-07-18 21:56:23 +02002225}
2226
Steven Valdezc4aa7272016-10-03 12:25:56 -04002227func (m *keyUpdateMsg) unmarshal(data []byte) bool {
2228 m.raw = data
2229
2230 if len(data) != 5 {
2231 return false
2232 }
2233
2234 length := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
2235 if len(data)-4 != length {
2236 return false
2237 }
2238
2239 m.keyUpdateRequest = data[4]
2240 return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
David Benjamin21c00282016-07-18 21:56:23 +02002241}
2242
Adam Langley95c29f32014-06-20 12:00:00 -07002243func eqUint16s(x, y []uint16) bool {
2244 if len(x) != len(y) {
2245 return false
2246 }
2247 for i, v := range x {
2248 if y[i] != v {
2249 return false
2250 }
2251 }
2252 return true
2253}
2254
2255func eqCurveIDs(x, y []CurveID) bool {
2256 if len(x) != len(y) {
2257 return false
2258 }
2259 for i, v := range x {
2260 if y[i] != v {
2261 return false
2262 }
2263 }
2264 return true
2265}
2266
2267func eqStrings(x, y []string) bool {
2268 if len(x) != len(y) {
2269 return false
2270 }
2271 for i, v := range x {
2272 if y[i] != v {
2273 return false
2274 }
2275 }
2276 return true
2277}
2278
2279func eqByteSlices(x, y [][]byte) bool {
2280 if len(x) != len(y) {
2281 return false
2282 }
2283 for i, v := range x {
2284 if !bytes.Equal(v, y[i]) {
2285 return false
2286 }
2287 }
2288 return true
2289}
2290
Nick Harper60edffd2016-06-21 15:19:24 -07002291func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07002292 if len(x) != len(y) {
2293 return false
2294 }
2295 for i, v := range x {
2296 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07002297 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07002298 return false
2299 }
2300 }
2301 return true
2302}
Nick Harperf8b0e702016-06-30 19:59:01 -04002303
2304func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2305 if len(x) != len(y) {
2306 return false
2307 }
2308 for i, v := range x {
2309 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2310 return false
2311 }
2312 }
2313 return true
2314
2315}
Steven Valdez5b986082016-09-01 12:29:49 -04002316
2317func eqPSKIdentityLists(x, y []pskIdentity) bool {
2318 if len(x) != len(y) {
2319 return false
2320 }
2321 for i, v := range x {
Steven Valdeza833c352016-11-01 13:39:36 -04002322 if !bytes.Equal(y[i].ticket, v.ticket) || y[i].obfuscatedTicketAge != v.obfuscatedTicketAge {
Steven Valdez5b986082016-09-01 12:29:49 -04002323 return false
2324 }
2325 }
2326 return true
2327
2328}