blob: 1e36f0813ab3aed90933b1d30b1c8e7f1093afb0 [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 &&
Steven Valdez924a3522017-03-02 16:05:03 -0500215 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()
David Benjamina81967b2016-12-22 09:16:57 -0500317 supportedPoints.addBytes(m.supportedPoints)
Adam Langley95c29f32014-06-20 12:00:00 -0700318 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200319 if m.hasKeyShares {
Nick Harperf8b0e702016-06-30 19:59:01 -0400320 extensions.addU16(extensionKeyShare)
321 keyShareList := extensions.addU16LengthPrefixed()
322
323 keyShares := keyShareList.addU16LengthPrefixed()
324 for _, keyShare := range m.keyShares {
325 keyShares.addU16(uint16(keyShare.group))
326 keyExchange := keyShares.addU16LengthPrefixed()
327 keyExchange.addBytes(keyShare.keyExchange)
328 }
David Benjamin7e1f9842016-09-20 19:24:40 -0400329
330 if m.trailingKeyShareData {
331 keyShares.addU8(0)
332 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400333 }
Steven Valdeza833c352016-11-01 13:39:36 -0400334 if len(m.pskKEModes) > 0 {
335 extensions.addU16(extensionPSKKeyExchangeModes)
336 pskModesExtension := extensions.addU16LengthPrefixed()
337 pskModesExtension.addU8LengthPrefixed().addBytes(m.pskKEModes)
Nick Harperf8b0e702016-06-30 19:59:01 -0400338 }
339 if m.hasEarlyData {
340 extensions.addU16(extensionEarlyData)
David Benjaminc5665c92016-11-15 18:12:58 +0900341 extensions.addU16(0) // The length is zero.
Nick Harperf8b0e702016-06-30 19:59:01 -0400342 }
David Benjamin3baa6e12016-10-07 21:10:38 -0400343 if len(m.tls13Cookie) > 0 {
344 extensions.addU16(extensionCookie)
345 body := extensions.addU16LengthPrefixed()
346 body.addU16LengthPrefixed().addBytes(m.tls13Cookie)
347 }
Adam Langley95c29f32014-06-20 12:00:00 -0700348 if m.ticketSupported {
349 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400350 extensions.addU16(extensionSessionTicket)
351 sessionTicketExtension := extensions.addU16LengthPrefixed()
352 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700353 }
Nick Harper60edffd2016-06-21 15:19:24 -0700354 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700355 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400356 extensions.addU16(extensionSignatureAlgorithms)
357 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
358 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700359 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400360 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700361 }
362 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400363 if len(m.supportedVersions) > 0 {
364 extensions.addU16(extensionSupportedVersions)
365 supportedVersionsExtension := extensions.addU16LengthPrefixed()
366 supportedVersions := supportedVersionsExtension.addU8LengthPrefixed()
367 for _, version := range m.supportedVersions {
368 supportedVersions.addU16(uint16(version))
369 }
370 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700371 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400372 extensions.addU16(extensionRenegotiationInfo)
373 secureRenegoExt := extensions.addU16LengthPrefixed()
374 secureRenego := secureRenegoExt.addU8LengthPrefixed()
375 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700376 }
David Benjaminfa055a22014-09-15 16:51:51 -0400377 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400378 // https://tools.ietf.org/html/rfc7301#section-3.1
379 extensions.addU16(extensionALPN)
380 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400381
Nick Harper8dda5cc2016-06-30 18:51:11 -0400382 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400383 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400384 protocolName := protocolNameList.addU8LengthPrefixed()
385 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400386 }
David Benjaminfa055a22014-09-15 16:51:51 -0400387 }
David Benjamind30a9902014-08-24 01:44:23 -0400388 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400389 extensions.addU16(extensionChannelID)
390 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400391 }
Steven Valdeza833c352016-11-01 13:39:36 -0400392 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400393 extensions.addU16(extensionNextProtoNeg)
394 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400395 }
David Benjamin35a7a442014-07-05 00:23:20 -0400396 if m.duplicateExtension {
397 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400398 extensions.addU16(0xffff)
399 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400400 }
Adam Langley75712922014-10-10 16:23:43 -0700401 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500402 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400403 extensions.addU16(extensionExtendedMasterSecret)
404 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700405 }
David Benjaminca6c8262014-11-15 19:06:08 -0500406 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400407 // https://tools.ietf.org/html/rfc5764#section-4.1.1
408 extensions.addU16(extensionUseSRTP)
409 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500410
Nick Harper8dda5cc2016-06-30 18:51:11 -0400411 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500412 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400413 // An SRTPProtectionProfile is defined as uint8[2],
414 // not uint16. For some reason, we're storing it
415 // as a uint16.
416 srtpProtectionProfiles.addU8(byte(p >> 8))
417 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500418 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400419 srtpMki := useSrtpExt.addU8LengthPrefixed()
420 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500421 }
David Benjamin61f95272014-11-25 01:55:35 -0500422 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400423 extensions.addU16(extensionSignedCertificateTimestamp)
424 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500425 }
Adam Langley09505632015-07-30 18:10:13 -0700426 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400427 extensions.addU16(extensionCustom)
428 customExt := extensions.addU16LengthPrefixed()
429 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700430 }
Steven Valdeza833c352016-11-01 13:39:36 -0400431 // The PSK extension must be last (draft-ietf-tls-tls13-18 section 4.2.6).
432 if len(m.pskIdentities) > 0 && !m.pskBinderFirst {
433 extensions.addU16(extensionPreSharedKey)
434 pskExtension := extensions.addU16LengthPrefixed()
435
436 pskIdentities := pskExtension.addU16LengthPrefixed()
437 for _, psk := range m.pskIdentities {
438 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
439 pskIdentities.addU32(psk.obfuscatedTicketAge)
440 }
441 pskBinders := pskExtension.addU16LengthPrefixed()
442 for _, binder := range m.pskBinders {
443 pskBinders.addU8LengthPrefixed().addBytes(binder)
444 }
445 }
Adam Langley95c29f32014-06-20 12:00:00 -0700446
Nick Harper8dda5cc2016-06-30 18:51:11 -0400447 if extensions.len() == 0 {
448 hello.discardChild()
449 }
Adam Langley95c29f32014-06-20 12:00:00 -0700450
Nick Harper8dda5cc2016-06-30 18:51:11 -0400451 m.raw = handshakeMsg.finish()
452 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700453}
454
455func (m *clientHelloMsg) unmarshal(data []byte) bool {
456 if len(data) < 42 {
457 return false
458 }
459 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400460 m.vers = uint16(data[4])<<8 | uint16(data[5])
Adam Langley95c29f32014-06-20 12:00:00 -0700461 m.random = data[6:38]
462 sessionIdLen := int(data[38])
463 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
464 return false
465 }
466 m.sessionId = data[39 : 39+sessionIdLen]
467 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400468 if m.isDTLS {
469 if len(data) < 1 {
470 return false
471 }
472 cookieLen := int(data[0])
473 if cookieLen > 32 || len(data) < 1+cookieLen {
474 return false
475 }
476 m.cookie = data[1 : 1+cookieLen]
477 data = data[1+cookieLen:]
478 }
Adam Langley95c29f32014-06-20 12:00:00 -0700479 if len(data) < 2 {
480 return false
481 }
482 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
483 // they are uint16s, the number must be even.
484 cipherSuiteLen := int(data[0])<<8 | int(data[1])
485 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
486 return false
487 }
488 numCipherSuites := cipherSuiteLen / 2
489 m.cipherSuites = make([]uint16, numCipherSuites)
490 for i := 0; i < numCipherSuites; i++ {
491 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
492 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700493 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700494 }
495 }
496 data = data[2+cipherSuiteLen:]
497 if len(data) < 1 {
498 return false
499 }
500 compressionMethodsLen := int(data[0])
501 if len(data) < 1+compressionMethodsLen {
502 return false
503 }
504 m.compressionMethods = data[1 : 1+compressionMethodsLen]
505
506 data = data[1+compressionMethodsLen:]
507
508 m.nextProtoNeg = false
509 m.serverName = ""
510 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400511 m.keyShares = nil
512 m.pskIdentities = nil
513 m.hasEarlyData = false
Adam Langley95c29f32014-06-20 12:00:00 -0700514 m.ticketSupported = false
515 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700516 m.signatureAlgorithms = nil
Steven Valdezfdd10992016-09-15 16:27:05 -0400517 m.supportedVersions = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400518 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700519 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700520 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700521
522 if len(data) == 0 {
523 // ClientHello is optionally followed by extension data
524 return true
525 }
526 if len(data) < 2 {
527 return false
528 }
529
530 extensionsLength := int(data[0])<<8 | int(data[1])
531 data = data[2:]
532 if extensionsLength != len(data) {
533 return false
534 }
535
536 for len(data) != 0 {
537 if len(data) < 4 {
538 return false
539 }
540 extension := uint16(data[0])<<8 | uint16(data[1])
541 length := int(data[2])<<8 | int(data[3])
542 data = data[4:]
543 if len(data) < length {
544 return false
545 }
546
547 switch extension {
548 case extensionServerName:
549 if length < 2 {
550 return false
551 }
552 numNames := int(data[0])<<8 | int(data[1])
553 d := data[2:]
554 for i := 0; i < numNames; i++ {
555 if len(d) < 3 {
556 return false
557 }
558 nameType := d[0]
559 nameLen := int(d[1])<<8 | int(d[2])
560 d = d[3:]
561 if len(d) < nameLen {
562 return false
563 }
564 if nameType == 0 {
565 m.serverName = string(d[0:nameLen])
566 break
567 }
568 d = d[nameLen:]
569 }
570 case extensionNextProtoNeg:
571 if length > 0 {
572 return false
573 }
574 m.nextProtoNeg = true
575 case extensionStatusRequest:
576 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
577 case extensionSupportedCurves:
578 // http://tools.ietf.org/html/rfc4492#section-5.5.1
579 if length < 2 {
580 return false
581 }
582 l := int(data[0])<<8 | int(data[1])
583 if l%2 == 1 || length != l+2 {
584 return false
585 }
586 numCurves := l / 2
587 m.supportedCurves = make([]CurveID, numCurves)
588 d := data[2:]
589 for i := 0; i < numCurves; i++ {
590 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
591 d = d[2:]
592 }
593 case extensionSupportedPoints:
594 // http://tools.ietf.org/html/rfc4492#section-5.5.2
595 if length < 1 {
596 return false
597 }
598 l := int(data[0])
599 if length != l+1 {
600 return false
601 }
David Benjamina81967b2016-12-22 09:16:57 -0500602 m.supportedPoints = data[1 : 1+l]
Adam Langley95c29f32014-06-20 12:00:00 -0700603 case extensionSessionTicket:
604 // http://tools.ietf.org/html/rfc5077#section-3.2
605 m.ticketSupported = true
606 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400607 case extensionKeyShare:
608 // draft-ietf-tls-tls13 section 6.3.2.3
609 if length < 2 {
610 return false
611 }
612 l := int(data[0])<<8 | int(data[1])
613 if l != length-2 {
614 return false
615 }
616 d := data[2:length]
Nick Harperdcfbc672016-07-16 17:47:31 +0200617 m.hasKeyShares = true
Nick Harperf8b0e702016-06-30 19:59:01 -0400618 for len(d) > 0 {
619 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
620 // key_exchange (2-byte length prefix with at least 1 byte of content).
621 if len(d) < 5 {
622 return false
623 }
624 entry := keyShareEntry{}
625 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
626 keyExchLen := int(d[2])<<8 | int(d[3])
627 d = d[4:]
628 if len(d) < keyExchLen {
629 return false
630 }
631 entry.keyExchange = d[:keyExchLen]
632 d = d[keyExchLen:]
633 m.keyShares = append(m.keyShares, entry)
634 }
635 case extensionPreSharedKey:
Steven Valdeza833c352016-11-01 13:39:36 -0400636 // draft-ietf-tls-tls13-18 section 4.2.6
Nick Harperf8b0e702016-06-30 19:59:01 -0400637 if length < 2 {
638 return false
639 }
640 l := int(data[0])<<8 | int(data[1])
Steven Valdeza833c352016-11-01 13:39:36 -0400641 d := data[2 : l+2]
642 // Parse PSK identities.
Nick Harperf8b0e702016-06-30 19:59:01 -0400643 for len(d) > 0 {
644 if len(d) < 2 {
645 return false
646 }
647 pskLen := int(d[0])<<8 | int(d[1])
648 d = d[2:]
Steven Valdez5b986082016-09-01 12:29:49 -0400649
Steven Valdeza833c352016-11-01 13:39:36 -0400650 if len(d) < pskLen+4 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400651 return false
652 }
Steven Valdeza833c352016-11-01 13:39:36 -0400653 ticket := d[:pskLen]
654 obfuscatedTicketAge := uint32(d[pskLen])<<24 | uint32(d[pskLen+1])<<16 | uint32(d[pskLen+2])<<8 | uint32(d[pskLen+3])
655 psk := pskIdentity{
656 ticket: ticket,
657 obfuscatedTicketAge: obfuscatedTicketAge,
658 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400659 m.pskIdentities = append(m.pskIdentities, psk)
Steven Valdeza833c352016-11-01 13:39:36 -0400660 d = d[pskLen+4:]
Nick Harperf8b0e702016-06-30 19:59:01 -0400661 }
Steven Valdeza833c352016-11-01 13:39:36 -0400662 d = data[l+2:]
663 if len(d) < 2 {
664 return false
665 }
666 l = int(d[0])<<8 | int(d[1])
667 d = d[2:]
668 if l != len(d) {
669 return false
670 }
671 // Parse PSK binders.
672 for len(d) > 0 {
673 if len(d) < 1 {
674 return false
675 }
676 binderLen := int(d[0])
677 d = d[1:]
678 if binderLen > len(d) {
679 return false
680 }
681 m.pskBinders = append(m.pskBinders, d[:binderLen])
682 d = d[binderLen:]
683 }
684
685 // There must be the same number of identities as binders.
686 if len(m.pskIdentities) != len(m.pskBinders) {
687 return false
688 }
689 case extensionPSKKeyExchangeModes:
690 // draft-ietf-tls-tls13-18 section 4.2.7
691 if length < 1 {
692 return false
693 }
694 l := int(data[0])
695 if l != length-1 {
696 return false
697 }
698 m.pskKEModes = data[1:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400699 case extensionEarlyData:
700 // draft-ietf-tls-tls13 section 6.3.2.5
David Benjaminc5665c92016-11-15 18:12:58 +0900701 if length != 0 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400702 return false
703 }
704 m.hasEarlyData = true
David Benjamin3baa6e12016-10-07 21:10:38 -0400705 case extensionCookie:
706 if length < 2 {
707 return false
708 }
709 l := int(data[0])<<8 | int(data[1])
710 if l != length-2 || l == 0 {
711 return false
712 }
713 m.tls13Cookie = data[2 : 2+l]
Adam Langley95c29f32014-06-20 12:00:00 -0700714 case extensionSignatureAlgorithms:
715 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
716 if length < 2 || length&1 != 0 {
717 return false
718 }
719 l := int(data[0])<<8 | int(data[1])
720 if l != length-2 {
721 return false
722 }
723 n := l / 2
724 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700725 m.signatureAlgorithms = make([]signatureAlgorithm, n)
726 for i := range m.signatureAlgorithms {
727 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700728 d = d[2:]
729 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400730 case extensionSupportedVersions:
731 if length < 1+2 {
732 return false
733 }
734 l := int(data[0])
735 if l != length-1 || l%2 == 1 || l < 2 {
736 return false
737 }
738 n := l / 2
739 d := data[1:]
740 m.supportedVersions = make([]uint16, n)
741 for i := range m.supportedVersions {
742 m.supportedVersions[i] = uint16(d[0])<<8 | uint16(d[1])
743 d = d[2:]
744 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700745 case extensionRenegotiationInfo:
746 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700747 return false
748 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700749 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400750 case extensionALPN:
751 if length < 2 {
752 return false
753 }
754 l := int(data[0])<<8 | int(data[1])
755 if l != length-2 {
756 return false
757 }
758 d := data[2:length]
759 for len(d) != 0 {
760 stringLen := int(d[0])
761 d = d[1:]
762 if stringLen == 0 || stringLen > len(d) {
763 return false
764 }
765 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
766 d = d[stringLen:]
767 }
David Benjamind30a9902014-08-24 01:44:23 -0400768 case extensionChannelID:
769 if length > 0 {
770 return false
771 }
772 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700773 case extensionExtendedMasterSecret:
774 if length != 0 {
775 return false
776 }
777 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500778 case extensionUseSRTP:
779 if length < 2 {
780 return false
781 }
782 l := int(data[0])<<8 | int(data[1])
783 if l > length-2 || l%2 != 0 {
784 return false
785 }
786 n := l / 2
787 m.srtpProtectionProfiles = make([]uint16, n)
788 d := data[2:length]
789 for i := 0; i < n; i++ {
790 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
791 d = d[2:]
792 }
793 if len(d) < 1 || int(d[0]) != len(d)-1 {
794 return false
795 }
796 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500797 case extensionSignedCertificateTimestamp:
798 if length != 0 {
799 return false
800 }
801 m.sctListSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700802 case extensionCustom:
803 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700804 }
805 data = data[length:]
David Benjamin65ac9972016-09-02 21:35:25 -0400806
807 if isGREASEValue(extension) {
808 m.hasGREASEExtension = true
809 }
Adam Langley95c29f32014-06-20 12:00:00 -0700810 }
811
812 return true
813}
814
815type serverHelloMsg struct {
Steven Valdez038da9b2017-07-10 12:57:25 -0400816 raw []byte
817 isDTLS bool
818 vers uint16
819 versOverride uint16
820 supportedVersOverride uint16
821 random []byte
822 sessionId []byte
823 cipherSuite uint16
824 hasKeyShare bool
825 keyShare keyShareEntry
826 hasPSKIdentity bool
827 pskIdentity uint16
828 compressionMethod uint8
829 customExtension string
830 unencryptedALPN string
831 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700832}
833
Adam Langley95c29f32014-06-20 12:00:00 -0700834func (m *serverHelloMsg) marshal() []byte {
835 if m.raw != nil {
836 return m.raw
837 }
838
Nick Harper5212ef82016-06-30 19:26:07 -0400839 handshakeMsg := newByteBuilder()
840 handshakeMsg.addU8(typeServerHello)
841 hello := handshakeMsg.addU24LengthPrefixed()
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400842
843 // m.vers is used both to determine the format of the rest of the
844 // ServerHello and to override the value, so include a second version
845 // field.
846 vers, ok := wireToVersion(m.vers, m.isDTLS)
847 if !ok {
848 panic("unknown version")
849 }
850 if m.versOverride != 0 {
851 hello.addU16(m.versOverride)
Steven Valdez038da9b2017-07-10 12:57:25 -0400852 } else if m.vers == tls13ExperimentVersion {
853 hello.addU16(VersionTLS12)
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400854 } else {
855 hello.addU16(m.vers)
856 }
857
Nick Harper5212ef82016-06-30 19:26:07 -0400858 hello.addBytes(m.random)
Steven Valdez520e1222017-06-13 12:45:25 -0400859 if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
Nick Harperb41d2e42016-07-01 17:50:32 -0400860 sessionId := hello.addU8LengthPrefixed()
861 sessionId.addBytes(m.sessionId)
862 }
Nick Harper5212ef82016-06-30 19:26:07 -0400863 hello.addU16(m.cipherSuite)
Steven Valdez520e1222017-06-13 12:45:25 -0400864 if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
Nick Harperb41d2e42016-07-01 17:50:32 -0400865 hello.addU8(m.compressionMethod)
866 }
Adam Langley95c29f32014-06-20 12:00:00 -0700867
Nick Harper5212ef82016-06-30 19:26:07 -0400868 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400869
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400870 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400871 if m.hasKeyShare {
872 extensions.addU16(extensionKeyShare)
873 keyShare := extensions.addU16LengthPrefixed()
874 keyShare.addU16(uint16(m.keyShare.group))
875 keyExchange := keyShare.addU16LengthPrefixed()
876 keyExchange.addBytes(m.keyShare.keyExchange)
877 }
878 if m.hasPSKIdentity {
879 extensions.addU16(extensionPreSharedKey)
880 extensions.addU16(2) // Length
881 extensions.addU16(m.pskIdentity)
882 }
Steven Valdez038da9b2017-07-10 12:57:25 -0400883 if m.vers == tls13ExperimentVersion || m.supportedVersOverride != 0 {
884 extensions.addU16(extensionSupportedVersions)
885 extensions.addU16(2) // Length
886 if m.supportedVersOverride != 0 {
887 extensions.addU16(m.supportedVersOverride)
888 } else {
889 extensions.addU16(m.vers)
890 }
891 }
David Benjamin490469f2016-10-05 22:44:38 -0400892 if len(m.customExtension) > 0 {
893 extensions.addU16(extensionCustom)
894 customExt := extensions.addU16LengthPrefixed()
895 customExt.addBytes([]byte(m.customExtension))
896 }
897 if len(m.unencryptedALPN) > 0 {
898 extensions.addU16(extensionALPN)
899 extension := extensions.addU16LengthPrefixed()
900
901 protocolNameList := extension.addU16LengthPrefixed()
902 protocolName := protocolNameList.addU8LengthPrefixed()
903 protocolName.addBytes([]byte(m.unencryptedALPN))
904 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400905 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400906 m.extensions.marshal(extensions)
Nick Harperb41d2e42016-07-01 17:50:32 -0400907 if extensions.len() == 0 {
908 hello.discardChild()
909 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400910 }
911
912 m.raw = handshakeMsg.finish()
913 return m.raw
914}
915
916func (m *serverHelloMsg) unmarshal(data []byte) bool {
917 if len(data) < 42 {
918 return false
919 }
920 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400921 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400922 vers, ok := wireToVersion(m.vers, m.isDTLS)
923 if !ok {
924 return false
925 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400926 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400927 data = data[38:]
Steven Valdez520e1222017-06-13 12:45:25 -0400928 if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
Nick Harperb41d2e42016-07-01 17:50:32 -0400929 sessionIdLen := int(data[0])
930 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
931 return false
932 }
933 m.sessionId = data[1 : 1+sessionIdLen]
934 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400935 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400936 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400937 return false
938 }
939 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400940 data = data[2:]
Steven Valdez520e1222017-06-13 12:45:25 -0400941 if vers < VersionTLS13 || m.vers == tls13ExperimentVersion {
Nick Harperb41d2e42016-07-01 17:50:32 -0400942 if len(data) < 1 {
943 return false
944 }
945 m.compressionMethod = data[0]
946 data = data[1:]
947 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400948
David Benjamin8d315d72016-07-18 01:03:18 +0200949 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400950 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400951 m.extensions = serverExtensions{}
952 return true
953 }
954 if len(data) < 2 {
955 return false
956 }
957
958 extensionsLength := int(data[0])<<8 | int(data[1])
959 data = data[2:]
960 if len(data) != extensionsLength {
961 return false
962 }
963
Steven Valdez038da9b2017-07-10 12:57:25 -0400964 // Parse out the version from supported_versions if available.
965 if m.vers == VersionTLS12 {
966 vdata := data
967 for len(vdata) != 0 {
968 if len(vdata) < 4 {
969 return false
970 }
971 extension := uint16(vdata[0])<<8 | uint16(vdata[1])
972 length := int(vdata[2])<<8 | int(vdata[3])
973 vdata = vdata[4:]
974
975 if len(vdata) < length {
976 return false
977 }
978 d := vdata[:length]
979 vdata = vdata[length:]
980
981 if extension == extensionSupportedVersions {
982 if len(d) < 2 {
983 return false
984 }
985 m.vers = uint16(d[0])<<8 | uint16(d[1])
986 vers, ok = wireToVersion(m.vers, m.isDTLS)
987 if !ok {
988 return false
989 }
990 }
991 }
992 }
993
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400994 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400995 for len(data) != 0 {
996 if len(data) < 4 {
997 return false
998 }
999 extension := uint16(data[0])<<8 | uint16(data[1])
1000 length := int(data[2])<<8 | int(data[3])
1001 data = data[4:]
1002
1003 if len(data) < length {
1004 return false
1005 }
1006 d := data[:length]
1007 data = data[length:]
1008
1009 switch extension {
1010 case extensionKeyShare:
1011 m.hasKeyShare = true
1012 if len(d) < 4 {
1013 return false
1014 }
1015 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
1016 keyExchLen := int(d[2])<<8 | int(d[3])
1017 if keyExchLen != len(d)-4 {
1018 return false
1019 }
1020 m.keyShare.keyExchange = make([]byte, keyExchLen)
1021 copy(m.keyShare.keyExchange, d[4:])
1022 case extensionPreSharedKey:
1023 if len(d) != 2 {
1024 return false
1025 }
1026 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
1027 m.hasPSKIdentity = true
Steven Valdez038da9b2017-07-10 12:57:25 -04001028 case extensionSupportedVersions:
1029 if m.vers != tls13ExperimentVersion {
1030 return false
1031 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001032 default:
1033 // Only allow the 3 extensions that are sent in
1034 // the clear in TLS 1.3.
1035 return false
1036 }
1037 }
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001038 } else if !m.extensions.unmarshal(data, vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -04001039 return false
1040 }
1041
1042 return true
1043}
1044
Nick Harperb41d2e42016-07-01 17:50:32 -04001045type encryptedExtensionsMsg struct {
1046 raw []byte
1047 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -04001048 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001049}
1050
1051func (m *encryptedExtensionsMsg) marshal() []byte {
1052 if m.raw != nil {
1053 return m.raw
1054 }
1055
1056 encryptedExtensionsMsg := newByteBuilder()
1057 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
1058 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -04001059 if !m.empty {
1060 extensions := encryptedExtensions.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001061 m.extensions.marshal(extensions)
Steven Valdez143e8b32016-07-11 13:19:03 -04001062 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001063
1064 m.raw = encryptedExtensionsMsg.finish()
1065 return m.raw
1066}
1067
1068func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -04001069 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001070 if len(data) < 6 {
1071 return false
1072 }
1073 if data[0] != typeEncryptedExtensions {
1074 return false
1075 }
1076 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1077 data = data[4:]
1078 if len(data) != msgLen {
1079 return false
1080 }
1081 extLen := int(data[0])<<8 | int(data[1])
1082 data = data[2:]
1083 if extLen != len(data) {
1084 return false
1085 }
David Benjamin44b33bc2016-07-01 22:40:23 -04001086 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -04001087}
1088
Nick Harperb3d51be2016-07-01 11:43:18 -04001089type serverExtensions struct {
1090 nextProtoNeg bool
1091 nextProtos []string
1092 ocspStapling bool
1093 ticketSupported bool
1094 secureRenegotiation []byte
1095 alpnProtocol string
1096 alpnProtocolEmpty bool
1097 duplicateExtension bool
1098 channelIDRequested bool
1099 extendedMasterSecret bool
1100 srtpProtectionProfile uint16
1101 srtpMasterKeyIdentifier string
1102 sctList []byte
1103 customExtension string
Steven Valdeza833c352016-11-01 13:39:36 -04001104 npnAfterAlpn bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001105 hasKeyShare bool
Nick Harperf2511f12016-12-06 16:02:31 -08001106 hasEarlyData bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001107 keyShare keyShareEntry
Steven Valdez038da9b2017-07-10 12:57:25 -04001108 supportedVersion uint16
David Benjamina81967b2016-12-22 09:16:57 -05001109 supportedPoints []uint8
David Benjamin023d4192017-02-06 13:49:07 -05001110 serverNameAck bool
Nick Harperb3d51be2016-07-01 11:43:18 -04001111}
1112
Steven Valdeza833c352016-11-01 13:39:36 -04001113func (m *serverExtensions) marshal(extensions *byteBuilder) {
David Benjamin35a7a442014-07-05 00:23:20 -04001114 if m.duplicateExtension {
1115 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001116 extensions.addU16(0xffff)
1117 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -04001118 }
Steven Valdeza833c352016-11-01 13:39:36 -04001119 if m.nextProtoNeg && !m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001120 extensions.addU16(extensionNextProtoNeg)
1121 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001122
1123 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001124 if len(v) > 255 {
1125 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -07001126 }
Nick Harper5212ef82016-06-30 19:26:07 -04001127 npn := extension.addU8LengthPrefixed()
1128 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -07001129 }
1130 }
Steven Valdeza833c352016-11-01 13:39:36 -04001131 if m.ocspStapling {
1132 extensions.addU16(extensionStatusRequest)
1133 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001134 }
1135 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -04001136 extensions.addU16(extensionSessionTicket)
1137 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001138 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001139 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001140 extensions.addU16(extensionRenegotiationInfo)
1141 extension := extensions.addU16LengthPrefixed()
1142 secureRenego := extension.addU8LengthPrefixed()
1143 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -07001144 }
Nick Harper5212ef82016-06-30 19:26:07 -04001145 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
1146 extensions.addU16(extensionALPN)
1147 extension := extensions.addU16LengthPrefixed()
1148
1149 protocolNameList := extension.addU16LengthPrefixed()
1150 protocolName := protocolNameList.addU8LengthPrefixed()
1151 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -04001152 }
David Benjamind30a9902014-08-24 01:44:23 -04001153 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -04001154 extensions.addU16(extensionChannelID)
1155 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -04001156 }
David Benjamin35a7a442014-07-05 00:23:20 -04001157 if m.duplicateExtension {
1158 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001159 extensions.addU16(0xffff)
1160 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -04001161 }
Adam Langley75712922014-10-10 16:23:43 -07001162 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -04001163 extensions.addU16(extensionExtendedMasterSecret)
1164 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -07001165 }
David Benjaminca6c8262014-11-15 19:06:08 -05001166 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001167 extensions.addU16(extensionUseSRTP)
1168 extension := extensions.addU16LengthPrefixed()
1169
1170 srtpProtectionProfiles := extension.addU16LengthPrefixed()
1171 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
1172 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
1173 srtpMki := extension.addU8LengthPrefixed()
1174 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -05001175 }
David Benjamin61f95272014-11-25 01:55:35 -05001176 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001177 extensions.addU16(extensionSignedCertificateTimestamp)
1178 extension := extensions.addU16LengthPrefixed()
1179 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -05001180 }
Adam Langley09505632015-07-30 18:10:13 -07001181 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001182 extensions.addU16(extensionCustom)
1183 customExt := extensions.addU16LengthPrefixed()
1184 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -07001185 }
Steven Valdeza833c352016-11-01 13:39:36 -04001186 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001187 extensions.addU16(extensionNextProtoNeg)
1188 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -04001189
1190 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001191 if len(v) > 255 {
1192 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -04001193 }
Nick Harper5212ef82016-06-30 19:26:07 -04001194 npn := extension.addU8LengthPrefixed()
1195 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001196 }
1197 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001198 if m.hasKeyShare {
1199 extensions.addU16(extensionKeyShare)
1200 keyShare := extensions.addU16LengthPrefixed()
1201 keyShare.addU16(uint16(m.keyShare.group))
1202 keyExchange := keyShare.addU16LengthPrefixed()
1203 keyExchange.addBytes(m.keyShare.keyExchange)
1204 }
Steven Valdez038da9b2017-07-10 12:57:25 -04001205 if m.supportedVersion != 0 {
1206 extensions.addU16(extensionSupportedVersions)
1207 extensions.addU16(2) // Length
1208 extensions.addU16(m.supportedVersion)
1209 }
David Benjamina81967b2016-12-22 09:16:57 -05001210 if len(m.supportedPoints) > 0 {
1211 // http://tools.ietf.org/html/rfc4492#section-5.1.2
1212 extensions.addU16(extensionSupportedPoints)
1213 supportedPointsList := extensions.addU16LengthPrefixed()
1214 supportedPoints := supportedPointsList.addU8LengthPrefixed()
1215 supportedPoints.addBytes(m.supportedPoints)
1216 }
Nick Harperf2511f12016-12-06 16:02:31 -08001217 if m.hasEarlyData {
1218 extensions.addU16(extensionEarlyData)
1219 extensions.addBytes([]byte{0, 0})
1220 }
David Benjamin023d4192017-02-06 13:49:07 -05001221 if m.serverNameAck {
1222 extensions.addU16(extensionServerName)
1223 extensions.addU16(0) // zero length
1224 }
Adam Langley95c29f32014-06-20 12:00:00 -07001225}
1226
David Benjamin44b33bc2016-07-01 22:40:23 -04001227func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001228 // Reset all fields.
1229 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001230
1231 for len(data) != 0 {
1232 if len(data) < 4 {
1233 return false
1234 }
1235 extension := uint16(data[0])<<8 | uint16(data[1])
1236 length := int(data[2])<<8 | int(data[3])
1237 data = data[4:]
1238 if len(data) < length {
1239 return false
1240 }
1241
1242 switch extension {
1243 case extensionNextProtoNeg:
1244 m.nextProtoNeg = true
1245 d := data[:length]
1246 for len(d) > 0 {
1247 l := int(d[0])
1248 d = d[1:]
1249 if l == 0 || l > len(d) {
1250 return false
1251 }
1252 m.nextProtos = append(m.nextProtos, string(d[:l]))
1253 d = d[l:]
1254 }
1255 case extensionStatusRequest:
Steven Valdeza833c352016-11-01 13:39:36 -04001256 if length > 0 {
1257 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001258 }
Steven Valdeza833c352016-11-01 13:39:36 -04001259 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001260 case extensionSessionTicket:
1261 if length > 0 {
1262 return false
1263 }
1264 m.ticketSupported = true
1265 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001266 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001267 return false
1268 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001269 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001270 case extensionALPN:
1271 d := data[:length]
1272 if len(d) < 3 {
1273 return false
1274 }
1275 l := int(d[0])<<8 | int(d[1])
1276 if l != len(d)-2 {
1277 return false
1278 }
1279 d = d[2:]
1280 l = int(d[0])
1281 if l != len(d)-1 {
1282 return false
1283 }
1284 d = d[1:]
1285 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001286 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001287 case extensionChannelID:
1288 if length > 0 {
1289 return false
1290 }
1291 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001292 case extensionExtendedMasterSecret:
1293 if length != 0 {
1294 return false
1295 }
1296 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001297 case extensionUseSRTP:
1298 if length < 2+2+1 {
1299 return false
1300 }
1301 if data[0] != 0 || data[1] != 2 {
1302 return false
1303 }
1304 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1305 d := data[4:length]
1306 l := int(d[0])
1307 if l != len(d)-1 {
1308 return false
1309 }
1310 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001311 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001312 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001313 case extensionCustom:
1314 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001315 case extensionServerName:
1316 if length != 0 {
1317 return false
1318 }
David Benjamin023d4192017-02-06 13:49:07 -05001319 m.serverNameAck = true
David Benjamin46f94bd2016-07-14 16:43:37 -04001320 case extensionSupportedPoints:
1321 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001322 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001323 return false
1324 }
David Benjamina81967b2016-12-22 09:16:57 -05001325 // http://tools.ietf.org/html/rfc4492#section-5.5.2
1326 if length < 1 {
1327 return false
1328 }
1329 l := int(data[0])
1330 if length != l+1 {
1331 return false
1332 }
1333 m.supportedPoints = data[1 : 1+l]
David Benjamin4ee027f2016-07-17 12:34:41 +02001334 case extensionSupportedCurves:
1335 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001336 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001337 return false
1338 }
Nick Harperf2511f12016-12-06 16:02:31 -08001339 case extensionEarlyData:
1340 if version < VersionTLS13 || length != 0 {
1341 return false
1342 }
1343 m.hasEarlyData = true
David Benjamin46f94bd2016-07-14 16:43:37 -04001344 default:
1345 // Unknown extensions are illegal from the server.
1346 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001347 }
1348 data = data[length:]
1349 }
1350
1351 return true
1352}
1353
Nick Harperdcfbc672016-07-16 17:47:31 +02001354type helloRetryRequestMsg struct {
David Benjamin3baa6e12016-10-07 21:10:38 -04001355 raw []byte
1356 vers uint16
1357 hasSelectedGroup bool
1358 selectedGroup CurveID
1359 cookie []byte
1360 customExtension string
1361 duplicateExtensions bool
Nick Harperdcfbc672016-07-16 17:47:31 +02001362}
1363
1364func (m *helloRetryRequestMsg) marshal() []byte {
1365 if m.raw != nil {
1366 return m.raw
1367 }
1368
1369 retryRequestMsg := newByteBuilder()
1370 retryRequestMsg.addU8(typeHelloRetryRequest)
1371 retryRequest := retryRequestMsg.addU24LengthPrefixed()
1372 retryRequest.addU16(m.vers)
David Benjamin3baa6e12016-10-07 21:10:38 -04001373 extensions := retryRequest.addU16LengthPrefixed()
1374
1375 count := 1
1376 if m.duplicateExtensions {
1377 count = 2
1378 }
1379
1380 for i := 0; i < count; i++ {
1381 if m.hasSelectedGroup {
1382 extensions.addU16(extensionKeyShare)
1383 extensions.addU16(2) // length
1384 extensions.addU16(uint16(m.selectedGroup))
1385 }
1386 if len(m.cookie) > 0 {
1387 extensions.addU16(extensionCookie)
1388 body := extensions.addU16LengthPrefixed()
1389 body.addU16LengthPrefixed().addBytes(m.cookie)
1390 }
1391 if len(m.customExtension) > 0 {
1392 extensions.addU16(extensionCustom)
1393 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
1394 }
1395 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001396
1397 m.raw = retryRequestMsg.finish()
1398 return m.raw
1399}
1400
1401func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1402 m.raw = data
David Benjamin3baa6e12016-10-07 21:10:38 -04001403 if len(data) < 8 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001404 return false
1405 }
1406 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin3baa6e12016-10-07 21:10:38 -04001407 extLen := int(data[6])<<8 | int(data[7])
1408 data = data[8:]
1409 if len(data) != extLen || len(data) == 0 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001410 return false
1411 }
David Benjamin3baa6e12016-10-07 21:10:38 -04001412 for len(data) > 0 {
1413 if len(data) < 4 {
1414 return false
1415 }
1416 extension := uint16(data[0])<<8 | uint16(data[1])
1417 length := int(data[2])<<8 | int(data[3])
1418 data = data[4:]
1419 if len(data) < length {
1420 return false
1421 }
1422
1423 switch extension {
1424 case extensionKeyShare:
1425 if length != 2 {
1426 return false
1427 }
1428 m.hasSelectedGroup = true
1429 m.selectedGroup = CurveID(data[0])<<8 | CurveID(data[1])
1430 case extensionCookie:
1431 if length < 2 {
1432 return false
1433 }
1434 cookieLen := int(data[0])<<8 | int(data[1])
1435 if 2+cookieLen != length {
1436 return false
1437 }
1438 m.cookie = data[2 : 2+cookieLen]
1439 default:
1440 // Unknown extensions are illegal from the server.
1441 return false
1442 }
1443 data = data[length:]
1444 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001445 return true
1446}
1447
Steven Valdeza833c352016-11-01 13:39:36 -04001448type certificateEntry struct {
1449 data []byte
1450 ocspResponse []byte
1451 sctList []byte
1452 duplicateExtensions bool
1453 extraExtension []byte
1454}
1455
Adam Langley95c29f32014-06-20 12:00:00 -07001456type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001457 raw []byte
1458 hasRequestContext bool
1459 requestContext []byte
Steven Valdeza833c352016-11-01 13:39:36 -04001460 certificates []certificateEntry
Adam Langley95c29f32014-06-20 12:00:00 -07001461}
1462
Adam Langley95c29f32014-06-20 12:00:00 -07001463func (m *certificateMsg) marshal() (x []byte) {
1464 if m.raw != nil {
1465 return m.raw
1466 }
1467
Nick Harper7e0442a2016-07-01 17:40:09 -04001468 certMsg := newByteBuilder()
1469 certMsg.addU8(typeCertificate)
1470 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001471 if m.hasRequestContext {
1472 context := certificate.addU8LengthPrefixed()
1473 context.addBytes(m.requestContext)
1474 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001475 certificateList := certificate.addU24LengthPrefixed()
1476 for _, cert := range m.certificates {
1477 certEntry := certificateList.addU24LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001478 certEntry.addBytes(cert.data)
1479 if m.hasRequestContext {
1480 extensions := certificateList.addU16LengthPrefixed()
1481 count := 1
1482 if cert.duplicateExtensions {
1483 count = 2
1484 }
1485
1486 for i := 0; i < count; i++ {
1487 if cert.ocspResponse != nil {
1488 extensions.addU16(extensionStatusRequest)
1489 body := extensions.addU16LengthPrefixed()
1490 body.addU8(statusTypeOCSP)
1491 response := body.addU24LengthPrefixed()
1492 response.addBytes(cert.ocspResponse)
1493 }
1494
1495 if cert.sctList != nil {
1496 extensions.addU16(extensionSignedCertificateTimestamp)
1497 extension := extensions.addU16LengthPrefixed()
1498 extension.addBytes(cert.sctList)
1499 }
1500 }
1501 if cert.extraExtension != nil {
1502 extensions.addBytes(cert.extraExtension)
1503 }
1504 }
Adam Langley95c29f32014-06-20 12:00:00 -07001505 }
1506
Nick Harper7e0442a2016-07-01 17:40:09 -04001507 m.raw = certMsg.finish()
1508 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001509}
1510
1511func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001512 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001513 return false
1514 }
1515
1516 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001517 data = data[4:]
1518
1519 if m.hasRequestContext {
1520 if len(data) == 0 {
1521 return false
1522 }
1523 contextLen := int(data[0])
1524 if len(data) < 1+contextLen {
1525 return false
1526 }
1527 m.requestContext = make([]byte, contextLen)
1528 copy(m.requestContext, data[1:])
1529 data = data[1+contextLen:]
1530 }
1531
1532 if len(data) < 3 {
1533 return false
1534 }
1535 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1536 data = data[3:]
1537 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001538 return false
1539 }
1540
Steven Valdeza833c352016-11-01 13:39:36 -04001541 m.certificates = nil
1542 for len(data) != 0 {
1543 if len(data) < 3 {
Adam Langley95c29f32014-06-20 12:00:00 -07001544 return false
1545 }
Steven Valdeza833c352016-11-01 13:39:36 -04001546 certLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1547 if len(data) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001548 return false
1549 }
Steven Valdeza833c352016-11-01 13:39:36 -04001550 cert := certificateEntry{
1551 data: data[3 : 3+certLen],
1552 }
1553 data = data[3+certLen:]
1554 if m.hasRequestContext {
1555 if len(data) < 2 {
1556 return false
1557 }
1558 extensionsLen := int(data[0])<<8 | int(data[1])
1559 if len(data) < 2+extensionsLen {
1560 return false
1561 }
1562 extensions := data[2 : 2+extensionsLen]
1563 data = data[2+extensionsLen:]
1564 for len(extensions) != 0 {
1565 if len(extensions) < 4 {
1566 return false
1567 }
1568 extension := uint16(extensions[0])<<8 | uint16(extensions[1])
1569 length := int(extensions[2])<<8 | int(extensions[3])
1570 if len(extensions) < 4+length {
1571 return false
1572 }
1573 contents := extensions[4 : 4+length]
1574 extensions = extensions[4+length:]
Adam Langley95c29f32014-06-20 12:00:00 -07001575
Steven Valdeza833c352016-11-01 13:39:36 -04001576 switch extension {
1577 case extensionStatusRequest:
1578 if length < 4 {
1579 return false
1580 }
1581 if contents[0] != statusTypeOCSP {
1582 return false
1583 }
1584 respLen := int(contents[1])<<16 | int(contents[2])<<8 | int(contents[3])
1585 if respLen+4 != len(contents) || respLen == 0 {
1586 return false
1587 }
1588 cert.ocspResponse = contents[4:]
1589 case extensionSignedCertificateTimestamp:
1590 cert.sctList = contents
1591 default:
1592 return false
1593 }
1594 }
1595 }
1596 m.certificates = append(m.certificates, cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001597 }
1598
1599 return true
1600}
1601
1602type serverKeyExchangeMsg struct {
1603 raw []byte
1604 key []byte
1605}
1606
Adam Langley95c29f32014-06-20 12:00:00 -07001607func (m *serverKeyExchangeMsg) marshal() []byte {
1608 if m.raw != nil {
1609 return m.raw
1610 }
1611 length := len(m.key)
1612 x := make([]byte, length+4)
1613 x[0] = typeServerKeyExchange
1614 x[1] = uint8(length >> 16)
1615 x[2] = uint8(length >> 8)
1616 x[3] = uint8(length)
1617 copy(x[4:], m.key)
1618
1619 m.raw = x
1620 return x
1621}
1622
1623func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1624 m.raw = data
1625 if len(data) < 4 {
1626 return false
1627 }
1628 m.key = data[4:]
1629 return true
1630}
1631
1632type certificateStatusMsg struct {
1633 raw []byte
1634 statusType uint8
1635 response []byte
1636}
1637
Adam Langley95c29f32014-06-20 12:00:00 -07001638func (m *certificateStatusMsg) marshal() []byte {
1639 if m.raw != nil {
1640 return m.raw
1641 }
1642
1643 var x []byte
1644 if m.statusType == statusTypeOCSP {
1645 x = make([]byte, 4+4+len(m.response))
1646 x[0] = typeCertificateStatus
1647 l := len(m.response) + 4
1648 x[1] = byte(l >> 16)
1649 x[2] = byte(l >> 8)
1650 x[3] = byte(l)
1651 x[4] = statusTypeOCSP
1652
1653 l -= 4
1654 x[5] = byte(l >> 16)
1655 x[6] = byte(l >> 8)
1656 x[7] = byte(l)
1657 copy(x[8:], m.response)
1658 } else {
1659 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1660 }
1661
1662 m.raw = x
1663 return x
1664}
1665
1666func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1667 m.raw = data
1668 if len(data) < 5 {
1669 return false
1670 }
1671 m.statusType = data[4]
1672
1673 m.response = nil
1674 if m.statusType == statusTypeOCSP {
1675 if len(data) < 8 {
1676 return false
1677 }
1678 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1679 if uint32(len(data)) != 4+4+respLen {
1680 return false
1681 }
1682 m.response = data[8:]
1683 }
1684 return true
1685}
1686
1687type serverHelloDoneMsg struct{}
1688
Adam Langley95c29f32014-06-20 12:00:00 -07001689func (m *serverHelloDoneMsg) marshal() []byte {
1690 x := make([]byte, 4)
1691 x[0] = typeServerHelloDone
1692 return x
1693}
1694
1695func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1696 return len(data) == 4
1697}
1698
1699type clientKeyExchangeMsg struct {
1700 raw []byte
1701 ciphertext []byte
1702}
1703
Adam Langley95c29f32014-06-20 12:00:00 -07001704func (m *clientKeyExchangeMsg) marshal() []byte {
1705 if m.raw != nil {
1706 return m.raw
1707 }
1708 length := len(m.ciphertext)
1709 x := make([]byte, length+4)
1710 x[0] = typeClientKeyExchange
1711 x[1] = uint8(length >> 16)
1712 x[2] = uint8(length >> 8)
1713 x[3] = uint8(length)
1714 copy(x[4:], m.ciphertext)
1715
1716 m.raw = x
1717 return x
1718}
1719
1720func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1721 m.raw = data
1722 if len(data) < 4 {
1723 return false
1724 }
1725 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1726 if l != len(data)-4 {
1727 return false
1728 }
1729 m.ciphertext = data[4:]
1730 return true
1731}
1732
1733type finishedMsg struct {
1734 raw []byte
1735 verifyData []byte
1736}
1737
Adam Langley95c29f32014-06-20 12:00:00 -07001738func (m *finishedMsg) marshal() (x []byte) {
1739 if m.raw != nil {
1740 return m.raw
1741 }
1742
1743 x = make([]byte, 4+len(m.verifyData))
1744 x[0] = typeFinished
1745 x[3] = byte(len(m.verifyData))
1746 copy(x[4:], m.verifyData)
1747 m.raw = x
1748 return
1749}
1750
1751func (m *finishedMsg) unmarshal(data []byte) bool {
1752 m.raw = data
1753 if len(data) < 4 {
1754 return false
1755 }
1756 m.verifyData = data[4:]
1757 return true
1758}
1759
1760type nextProtoMsg struct {
1761 raw []byte
1762 proto string
1763}
1764
Adam Langley95c29f32014-06-20 12:00:00 -07001765func (m *nextProtoMsg) marshal() []byte {
1766 if m.raw != nil {
1767 return m.raw
1768 }
1769 l := len(m.proto)
1770 if l > 255 {
1771 l = 255
1772 }
1773
1774 padding := 32 - (l+2)%32
1775 length := l + padding + 2
1776 x := make([]byte, length+4)
1777 x[0] = typeNextProtocol
1778 x[1] = uint8(length >> 16)
1779 x[2] = uint8(length >> 8)
1780 x[3] = uint8(length)
1781
1782 y := x[4:]
1783 y[0] = byte(l)
1784 copy(y[1:], []byte(m.proto[0:l]))
1785 y = y[1+l:]
1786 y[0] = byte(padding)
1787
1788 m.raw = x
1789
1790 return x
1791}
1792
1793func (m *nextProtoMsg) unmarshal(data []byte) bool {
1794 m.raw = data
1795
1796 if len(data) < 5 {
1797 return false
1798 }
1799 data = data[4:]
1800 protoLen := int(data[0])
1801 data = data[1:]
1802 if len(data) < protoLen {
1803 return false
1804 }
1805 m.proto = string(data[0:protoLen])
1806 data = data[protoLen:]
1807
1808 if len(data) < 1 {
1809 return false
1810 }
1811 paddingLen := int(data[0])
1812 data = data[1:]
1813 if len(data) != paddingLen {
1814 return false
1815 }
1816
1817 return true
1818}
1819
1820type certificateRequestMsg struct {
1821 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001822 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001823 // of signature and hash functions. This change was introduced with TLS
1824 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001825 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001826 // hasRequestContext indicates whether this message includes a context
1827 // field instead of certificateTypes. This change was introduced with
1828 // TLS 1.3.
1829 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001830
1831 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001832 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001833 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001834 certificateAuthorities [][]byte
1835}
1836
Nick Harper7e0442a2016-07-01 17:40:09 -04001837func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001838 if m.raw != nil {
1839 return m.raw
1840 }
1841
1842 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001843 builder := newByteBuilder()
1844 builder.addU8(typeCertificateRequest)
1845 body := builder.addU24LengthPrefixed()
1846
Nick Harperb41d2e42016-07-01 17:50:32 -04001847 if m.hasRequestContext {
1848 requestContext := body.addU8LengthPrefixed()
1849 requestContext.addBytes(m.requestContext)
1850 } else {
1851 certificateTypes := body.addU8LengthPrefixed()
1852 certificateTypes.addBytes(m.certificateTypes)
1853 }
Adam Langley95c29f32014-06-20 12:00:00 -07001854
Nick Harper60edffd2016-06-21 15:19:24 -07001855 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001856 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001857 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001858 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001859 }
1860 }
1861
Nick Harper7e0442a2016-07-01 17:40:09 -04001862 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001863 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001864 caEntry := certificateAuthorities.addU16LengthPrefixed()
1865 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001866 }
1867
David Benjamin8d343b42016-07-09 14:26:01 -07001868 if m.hasRequestContext {
1869 // Emit no certificate extensions.
1870 body.addU16(0)
1871 }
1872
Nick Harper7e0442a2016-07-01 17:40:09 -04001873 m.raw = builder.finish()
1874 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001875}
1876
1877func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1878 m.raw = data
1879
1880 if len(data) < 5 {
1881 return false
1882 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001883 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001884
Nick Harperb41d2e42016-07-01 17:50:32 -04001885 if m.hasRequestContext {
1886 contextLen := int(data[0])
1887 if len(data) < 1+contextLen {
1888 return false
1889 }
1890 m.requestContext = make([]byte, contextLen)
1891 copy(m.requestContext, data[1:])
1892 data = data[1+contextLen:]
1893 } else {
1894 numCertTypes := int(data[0])
1895 if len(data) < 1+numCertTypes {
1896 return false
1897 }
1898 m.certificateTypes = make([]byte, numCertTypes)
1899 copy(m.certificateTypes, data[1:])
1900 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001901 }
1902
Nick Harper60edffd2016-06-21 15:19:24 -07001903 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001904 if len(data) < 2 {
1905 return false
1906 }
Nick Harper60edffd2016-06-21 15:19:24 -07001907 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001908 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001909 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001910 return false
1911 }
Nick Harper60edffd2016-06-21 15:19:24 -07001912 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001913 return false
1914 }
Nick Harper60edffd2016-06-21 15:19:24 -07001915 numSigAlgs := sigAlgsLen / 2
1916 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1917 for i := range m.signatureAlgorithms {
1918 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001919 data = data[2:]
1920 }
1921 }
1922
1923 if len(data) < 2 {
1924 return false
1925 }
1926 casLength := uint16(data[0])<<8 | uint16(data[1])
1927 data = data[2:]
1928 if len(data) < int(casLength) {
1929 return false
1930 }
1931 cas := make([]byte, casLength)
1932 copy(cas, data)
1933 data = data[casLength:]
1934
1935 m.certificateAuthorities = nil
1936 for len(cas) > 0 {
1937 if len(cas) < 2 {
1938 return false
1939 }
1940 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1941 cas = cas[2:]
1942
1943 if len(cas) < int(caLen) {
1944 return false
1945 }
1946
1947 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1948 cas = cas[caLen:]
1949 }
David Benjamin8d343b42016-07-09 14:26:01 -07001950
1951 if m.hasRequestContext {
1952 // Ignore certificate extensions.
1953 if len(data) < 2 {
1954 return false
1955 }
1956 extsLength := int(data[0])<<8 | int(data[1])
1957 if len(data) < 2+extsLength {
1958 return false
1959 }
1960 data = data[2+extsLength:]
1961 }
1962
Adam Langley95c29f32014-06-20 12:00:00 -07001963 if len(data) > 0 {
1964 return false
1965 }
1966
1967 return true
1968}
1969
1970type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07001971 raw []byte
1972 hasSignatureAlgorithm bool
1973 signatureAlgorithm signatureAlgorithm
1974 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001975}
1976
Adam Langley95c29f32014-06-20 12:00:00 -07001977func (m *certificateVerifyMsg) marshal() (x []byte) {
1978 if m.raw != nil {
1979 return m.raw
1980 }
1981
1982 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1983 siglength := len(m.signature)
1984 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07001985 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001986 length += 2
1987 }
1988 x = make([]byte, 4+length)
1989 x[0] = typeCertificateVerify
1990 x[1] = uint8(length >> 16)
1991 x[2] = uint8(length >> 8)
1992 x[3] = uint8(length)
1993 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001994 if m.hasSignatureAlgorithm {
1995 y[0] = byte(m.signatureAlgorithm >> 8)
1996 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07001997 y = y[2:]
1998 }
1999 y[0] = uint8(siglength >> 8)
2000 y[1] = uint8(siglength)
2001 copy(y[2:], m.signature)
2002
2003 m.raw = x
2004
2005 return
2006}
2007
2008func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
2009 m.raw = data
2010
2011 if len(data) < 6 {
2012 return false
2013 }
2014
2015 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2016 if uint32(len(data))-4 != length {
2017 return false
2018 }
2019
2020 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07002021 if m.hasSignatureAlgorithm {
2022 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07002023 data = data[2:]
2024 }
2025
2026 if len(data) < 2 {
2027 return false
2028 }
2029 siglength := int(data[0])<<8 + int(data[1])
2030 data = data[2:]
2031 if len(data) != siglength {
2032 return false
2033 }
2034
2035 m.signature = data
2036
2037 return true
2038}
2039
2040type newSessionTicketMsg struct {
David Benjamin9c33ae82017-01-08 06:04:43 -05002041 raw []byte
2042 version uint16
2043 ticketLifetime uint32
2044 ticketAgeAdd uint32
2045 ticket []byte
Nick Harperf2511f12016-12-06 16:02:31 -08002046 maxEarlyDataSize uint32
David Benjamin9c33ae82017-01-08 06:04:43 -05002047 customExtension string
2048 duplicateEarlyDataInfo bool
2049 hasGREASEExtension bool
Adam Langley95c29f32014-06-20 12:00:00 -07002050}
2051
David Benjamin58104882016-07-18 01:25:41 +02002052func (m *newSessionTicketMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07002053 if m.raw != nil {
2054 return m.raw
2055 }
2056
2057 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjamin58104882016-07-18 01:25:41 +02002058 ticketMsg := newByteBuilder()
2059 ticketMsg.addU8(typeNewSessionTicket)
2060 body := ticketMsg.addU24LengthPrefixed()
2061 body.addU32(m.ticketLifetime)
2062 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002063 body.addU32(m.ticketAgeAdd)
Steven Valdez5b986082016-09-01 12:29:49 -04002064 }
2065
2066 ticket := body.addU16LengthPrefixed()
2067 ticket.addBytes(m.ticket)
2068
2069 if m.version >= VersionTLS13 {
David Benjamin1286bee2016-10-07 15:25:06 -04002070 extensions := body.addU16LengthPrefixed()
Nick Harperf2511f12016-12-06 16:02:31 -08002071 if m.maxEarlyDataSize > 0 {
Steven Valdez08b65f42016-12-07 15:29:45 -05002072 extensions.addU16(extensionTicketEarlyDataInfo)
Nick Harperf2511f12016-12-06 16:02:31 -08002073 extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
David Benjamin9c33ae82017-01-08 06:04:43 -05002074 if m.duplicateEarlyDataInfo {
2075 extensions.addU16(extensionTicketEarlyDataInfo)
Nick Harperf2511f12016-12-06 16:02:31 -08002076 extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
David Benjamin9c33ae82017-01-08 06:04:43 -05002077 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002078 }
David Benjamin1286bee2016-10-07 15:25:06 -04002079 if len(m.customExtension) > 0 {
Steven Valdez08b65f42016-12-07 15:29:45 -05002080 extensions.addU16(extensionCustom)
David Benjamin1286bee2016-10-07 15:25:06 -04002081 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
2082 }
David Benjamin58104882016-07-18 01:25:41 +02002083 }
Adam Langley95c29f32014-06-20 12:00:00 -07002084
David Benjamin58104882016-07-18 01:25:41 +02002085 m.raw = ticketMsg.finish()
2086 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07002087}
2088
2089func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
2090 m.raw = data
2091
David Benjamin58104882016-07-18 01:25:41 +02002092 if len(data) < 8 {
2093 return false
2094 }
2095 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
2096 data = data[8:]
2097
2098 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002099 if len(data) < 4 {
David Benjamin58104882016-07-18 01:25:41 +02002100 return false
2101 }
Steven Valdeza833c352016-11-01 13:39:36 -04002102 m.ticketAgeAdd = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2103 data = data[4:]
David Benjamin58104882016-07-18 01:25:41 +02002104 }
2105
2106 if len(data) < 2 {
2107 return false
2108 }
2109 ticketLen := int(data[0])<<8 + int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002110 data = data[2:]
2111 if len(data) < ticketLen {
David Benjamin58104882016-07-18 01:25:41 +02002112 return false
2113 }
Steven Valdez5b986082016-09-01 12:29:49 -04002114
David Benjamin58104882016-07-18 01:25:41 +02002115 if m.version >= VersionTLS13 && ticketLen == 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07002116 return false
2117 }
2118
Steven Valdez5b986082016-09-01 12:29:49 -04002119 m.ticket = data[:ticketLen]
2120 data = data[ticketLen:]
2121
2122 if m.version >= VersionTLS13 {
2123 if len(data) < 2 {
2124 return false
2125 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002126
2127 extensionsLength := int(data[0])<<8 | int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002128 data = data[2:]
Steven Valdez08b65f42016-12-07 15:29:45 -05002129 if extensionsLength != len(data) {
Steven Valdez5b986082016-09-01 12:29:49 -04002130 return false
2131 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002132
Steven Valdez08b65f42016-12-07 15:29:45 -05002133 for len(data) != 0 {
2134 if len(data) < 4 {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002135 return false
2136 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002137 extension := uint16(data[0])<<8 | uint16(data[1])
2138 length := int(data[2])<<8 | int(data[3])
2139 data = data[4:]
2140 if len(data) < length {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002141 return false
2142 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002143
Steven Valdez08b65f42016-12-07 15:29:45 -05002144 switch extension {
2145 case extensionTicketEarlyDataInfo:
2146 if length != 4 {
2147 return false
2148 }
Nick Harperf2511f12016-12-06 16:02:31 -08002149 m.maxEarlyDataSize = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
Steven Valdez08b65f42016-12-07 15:29:45 -05002150 default:
2151 if isGREASEValue(extension) {
2152 m.hasGREASEExtension = true
2153 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002154 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002155
2156 data = data[length:]
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002157 }
Steven Valdez5b986082016-09-01 12:29:49 -04002158 }
2159
2160 if len(data) > 0 {
2161 return false
2162 }
Adam Langley95c29f32014-06-20 12:00:00 -07002163
2164 return true
2165}
2166
David Benjamind86c7672014-08-02 04:07:12 -04002167type v2ClientHelloMsg struct {
2168 raw []byte
2169 vers uint16
2170 cipherSuites []uint16
2171 sessionId []byte
2172 challenge []byte
2173}
2174
David Benjamind86c7672014-08-02 04:07:12 -04002175func (m *v2ClientHelloMsg) marshal() []byte {
2176 if m.raw != nil {
2177 return m.raw
2178 }
2179
2180 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
2181
2182 x := make([]byte, length)
2183 x[0] = 1
2184 x[1] = uint8(m.vers >> 8)
2185 x[2] = uint8(m.vers)
2186 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
2187 x[4] = uint8(len(m.cipherSuites) * 3)
2188 x[5] = uint8(len(m.sessionId) >> 8)
2189 x[6] = uint8(len(m.sessionId))
2190 x[7] = uint8(len(m.challenge) >> 8)
2191 x[8] = uint8(len(m.challenge))
2192 y := x[9:]
2193 for i, spec := range m.cipherSuites {
2194 y[i*3] = 0
2195 y[i*3+1] = uint8(spec >> 8)
2196 y[i*3+2] = uint8(spec)
2197 }
2198 y = y[len(m.cipherSuites)*3:]
2199 copy(y, m.sessionId)
2200 y = y[len(m.sessionId):]
2201 copy(y, m.challenge)
2202
2203 m.raw = x
2204
2205 return x
2206}
2207
David Benjamin83c0bc92014-08-04 01:23:53 -04002208type helloVerifyRequestMsg struct {
2209 raw []byte
2210 vers uint16
2211 cookie []byte
2212}
2213
David Benjamin83c0bc92014-08-04 01:23:53 -04002214func (m *helloVerifyRequestMsg) marshal() []byte {
2215 if m.raw != nil {
2216 return m.raw
2217 }
2218
2219 length := 2 + 1 + len(m.cookie)
2220
2221 x := make([]byte, 4+length)
2222 x[0] = typeHelloVerifyRequest
2223 x[1] = uint8(length >> 16)
2224 x[2] = uint8(length >> 8)
2225 x[3] = uint8(length)
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002226 vers := m.vers
David Benjamin83c0bc92014-08-04 01:23:53 -04002227 x[4] = uint8(vers >> 8)
2228 x[5] = uint8(vers)
2229 x[6] = uint8(len(m.cookie))
2230 copy(x[7:7+len(m.cookie)], m.cookie)
2231
2232 return x
2233}
2234
2235func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
2236 if len(data) < 4+2+1 {
2237 return false
2238 }
2239 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002240 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin83c0bc92014-08-04 01:23:53 -04002241 cookieLen := int(data[6])
2242 if cookieLen > 32 || len(data) != 7+cookieLen {
2243 return false
2244 }
2245 m.cookie = data[7 : 7+cookieLen]
2246
2247 return true
2248}
2249
David Benjamin24599a82016-06-30 18:56:53 -04002250type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04002251 raw []byte
2252 channelID []byte
2253}
2254
David Benjamin24599a82016-06-30 18:56:53 -04002255func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04002256 if m.raw != nil {
2257 return m.raw
2258 }
2259
2260 length := 2 + 2 + len(m.channelID)
2261
2262 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04002263 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04002264 x[1] = uint8(length >> 16)
2265 x[2] = uint8(length >> 8)
2266 x[3] = uint8(length)
2267 x[4] = uint8(extensionChannelID >> 8)
2268 x[5] = uint8(extensionChannelID & 0xff)
2269 x[6] = uint8(len(m.channelID) >> 8)
2270 x[7] = uint8(len(m.channelID) & 0xff)
2271 copy(x[8:], m.channelID)
2272
2273 return x
2274}
2275
David Benjamin24599a82016-06-30 18:56:53 -04002276func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04002277 if len(data) != 4+2+2+128 {
2278 return false
2279 }
2280 m.raw = data
2281 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
2282 return false
2283 }
2284 if int(data[6])<<8|int(data[7]) != 128 {
2285 return false
2286 }
2287 m.channelID = data[4+2+2:]
2288
2289 return true
2290}
2291
Adam Langley2ae77d22014-10-28 17:29:33 -07002292type helloRequestMsg struct {
2293}
2294
2295func (*helloRequestMsg) marshal() []byte {
2296 return []byte{typeHelloRequest, 0, 0, 0}
2297}
2298
2299func (*helloRequestMsg) unmarshal(data []byte) bool {
2300 return len(data) == 4
2301}
2302
David Benjamin21c00282016-07-18 21:56:23 +02002303type keyUpdateMsg struct {
Steven Valdezc4aa7272016-10-03 12:25:56 -04002304 raw []byte
2305 keyUpdateRequest byte
David Benjamin21c00282016-07-18 21:56:23 +02002306}
2307
Steven Valdezc4aa7272016-10-03 12:25:56 -04002308func (m *keyUpdateMsg) marshal() []byte {
2309 if m.raw != nil {
2310 return m.raw
2311 }
2312
2313 return []byte{typeKeyUpdate, 0, 0, 1, m.keyUpdateRequest}
David Benjamin21c00282016-07-18 21:56:23 +02002314}
2315
Steven Valdezc4aa7272016-10-03 12:25:56 -04002316func (m *keyUpdateMsg) unmarshal(data []byte) bool {
2317 m.raw = data
2318
2319 if len(data) != 5 {
2320 return false
2321 }
2322
2323 length := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
2324 if len(data)-4 != length {
2325 return false
2326 }
2327
2328 m.keyUpdateRequest = data[4]
2329 return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
David Benjamin21c00282016-07-18 21:56:23 +02002330}
2331
David Benjamin053fee92017-01-02 08:30:36 -05002332// ssl3NoCertificateMsg is a dummy message to handle SSL 3.0 using a warning
2333// alert in the handshake.
2334type ssl3NoCertificateMsg struct{}
2335
Adam Langley95c29f32014-06-20 12:00:00 -07002336func eqUint16s(x, y []uint16) bool {
2337 if len(x) != len(y) {
2338 return false
2339 }
2340 for i, v := range x {
2341 if y[i] != v {
2342 return false
2343 }
2344 }
2345 return true
2346}
2347
2348func eqCurveIDs(x, y []CurveID) bool {
2349 if len(x) != len(y) {
2350 return false
2351 }
2352 for i, v := range x {
2353 if y[i] != v {
2354 return false
2355 }
2356 }
2357 return true
2358}
2359
2360func eqStrings(x, y []string) bool {
2361 if len(x) != len(y) {
2362 return false
2363 }
2364 for i, v := range x {
2365 if y[i] != v {
2366 return false
2367 }
2368 }
2369 return true
2370}
2371
2372func eqByteSlices(x, y [][]byte) bool {
2373 if len(x) != len(y) {
2374 return false
2375 }
2376 for i, v := range x {
2377 if !bytes.Equal(v, y[i]) {
2378 return false
2379 }
2380 }
2381 return true
2382}
2383
Nick Harper60edffd2016-06-21 15:19:24 -07002384func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07002385 if len(x) != len(y) {
2386 return false
2387 }
2388 for i, v := range x {
2389 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07002390 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07002391 return false
2392 }
2393 }
2394 return true
2395}
Nick Harperf8b0e702016-06-30 19:59:01 -04002396
2397func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2398 if len(x) != len(y) {
2399 return false
2400 }
2401 for i, v := range x {
2402 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2403 return false
2404 }
2405 }
2406 return true
2407
2408}
Steven Valdez5b986082016-09-01 12:29:49 -04002409
2410func eqPSKIdentityLists(x, y []pskIdentity) bool {
2411 if len(x) != len(y) {
2412 return false
2413 }
2414 for i, v := range x {
Steven Valdeza833c352016-11-01 13:39:36 -04002415 if !bytes.Equal(y[i].ticket, v.ticket) || y[i].obfuscatedTicketAge != v.obfuscatedTicketAge {
Steven Valdez5b986082016-09-01 12:29:49 -04002416 return false
2417 }
2418 }
2419 return true
2420
2421}