blob: 5dbcab9f08518c7c92dad7a29f7cf3f6b812a6dc [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"
David Benjaminb853f312017-07-14 18:40:34 -040010 "fmt"
Nick Harper0b3625b2016-07-25 16:16:28 -070011)
Adam Langley95c29f32014-06-20 12:00:00 -070012
Nick Harper8dda5cc2016-06-30 18:51:11 -040013func writeLen(buf []byte, v, size int) {
14 for i := 0; i < size; i++ {
15 buf[size-i-1] = byte(v)
16 v >>= 8
17 }
18 if v != 0 {
19 panic("length is too long")
20 }
21}
22
23type byteBuilder struct {
24 buf *[]byte
25 start int
26 prefixLen int
27 child *byteBuilder
28}
29
30func newByteBuilder() *byteBuilder {
31 buf := make([]byte, 0, 32)
32 return &byteBuilder{buf: &buf}
33}
34
35func (bb *byteBuilder) len() int {
36 return len(*bb.buf) - bb.start - bb.prefixLen
37}
38
David Benjaminb853f312017-07-14 18:40:34 -040039func (bb *byteBuilder) data() []byte {
40 bb.flush()
41 return (*bb.buf)[bb.start+bb.prefixLen:]
42}
43
Nick Harper8dda5cc2016-06-30 18:51:11 -040044func (bb *byteBuilder) flush() {
45 if bb.child == nil {
46 return
47 }
48 bb.child.flush()
49 writeLen((*bb.buf)[bb.child.start:], bb.child.len(), bb.child.prefixLen)
50 bb.child = nil
51 return
52}
53
54func (bb *byteBuilder) finish() []byte {
55 bb.flush()
56 return *bb.buf
57}
58
59func (bb *byteBuilder) addU8(u uint8) {
60 bb.flush()
61 *bb.buf = append(*bb.buf, u)
62}
63
64func (bb *byteBuilder) addU16(u uint16) {
65 bb.flush()
66 *bb.buf = append(*bb.buf, byte(u>>8), byte(u))
67}
68
69func (bb *byteBuilder) addU24(u int) {
70 bb.flush()
71 *bb.buf = append(*bb.buf, byte(u>>16), byte(u>>8), byte(u))
72}
73
74func (bb *byteBuilder) addU32(u uint32) {
75 bb.flush()
76 *bb.buf = append(*bb.buf, byte(u>>24), byte(u>>16), byte(u>>8), byte(u))
77}
78
Nick Harper0b3625b2016-07-25 16:16:28 -070079func (bb *byteBuilder) addU64(u uint64) {
80 bb.flush()
81 var b [8]byte
82 binary.BigEndian.PutUint64(b[:], u)
83 *bb.buf = append(*bb.buf, b[:]...)
84}
85
Nick Harper8dda5cc2016-06-30 18:51:11 -040086func (bb *byteBuilder) addU8LengthPrefixed() *byteBuilder {
87 return bb.createChild(1)
88}
89
90func (bb *byteBuilder) addU16LengthPrefixed() *byteBuilder {
91 return bb.createChild(2)
92}
93
94func (bb *byteBuilder) addU24LengthPrefixed() *byteBuilder {
95 return bb.createChild(3)
96}
97
Nick Harper0b3625b2016-07-25 16:16:28 -070098func (bb *byteBuilder) addU32LengthPrefixed() *byteBuilder {
99 return bb.createChild(4)
100}
101
Nick Harper8dda5cc2016-06-30 18:51:11 -0400102func (bb *byteBuilder) addBytes(b []byte) {
103 bb.flush()
104 *bb.buf = append(*bb.buf, b...)
105}
106
107func (bb *byteBuilder) createChild(lengthPrefixSize int) *byteBuilder {
108 bb.flush()
109 bb.child = &byteBuilder{
110 buf: bb.buf,
111 start: len(*bb.buf),
112 prefixLen: lengthPrefixSize,
113 }
114 for i := 0; i < lengthPrefixSize; i++ {
115 *bb.buf = append(*bb.buf, 0)
116 }
117 return bb.child
118}
119
120func (bb *byteBuilder) discardChild() {
David Benjaminb853f312017-07-14 18:40:34 -0400121 if bb.child == nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400122 return
123 }
David Benjaminb853f312017-07-14 18:40:34 -0400124 *bb.buf = (*bb.buf)[:bb.child.start]
Nick Harper8dda5cc2016-06-30 18:51:11 -0400125 bb.child = nil
Nick Harper8dda5cc2016-06-30 18:51:11 -0400126}
127
Nick Harperf8b0e702016-06-30 19:59:01 -0400128type keyShareEntry struct {
129 group CurveID
130 keyExchange []byte
131}
132
Steven Valdez5b986082016-09-01 12:29:49 -0400133type pskIdentity struct {
Steven Valdeza833c352016-11-01 13:39:36 -0400134 ticket []uint8
135 obfuscatedTicketAge uint32
Steven Valdez5b986082016-09-01 12:29:49 -0400136}
137
Adam Langley95c29f32014-06-20 12:00:00 -0700138type clientHelloMsg struct {
David Benjamin3baa6e12016-10-07 21:10:38 -0400139 raw []byte
140 isDTLS bool
141 vers uint16
142 random []byte
143 sessionId []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500144 cookie []byte
145 cipherSuites []uint16
146 compressionMethods []uint8
147 nextProtoNeg bool
148 serverName string
149 ocspStapling bool
150 supportedCurves []CurveID
151 supportedPoints []uint8
Nick Harperdcfbc672016-07-16 17:47:31 +0200152 hasKeyShares bool
Nick Harperf8b0e702016-06-30 19:59:01 -0400153 keyShares []keyShareEntry
David Benjamin7e1f9842016-09-20 19:24:40 -0400154 trailingKeyShareData bool
Steven Valdez5b986082016-09-01 12:29:49 -0400155 pskIdentities []pskIdentity
Steven Valdeza833c352016-11-01 13:39:36 -0400156 pskKEModes []byte
157 pskBinders [][]uint8
Nick Harperf8b0e702016-06-30 19:59:01 -0400158 hasEarlyData bool
David Benjamin3baa6e12016-10-07 21:10:38 -0400159 tls13Cookie []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500160 ticketSupported bool
161 sessionTicket []uint8
Nick Harper60edffd2016-06-21 15:19:24 -0700162 signatureAlgorithms []signatureAlgorithm
Steven Valdezfdd10992016-09-15 16:27:05 -0400163 supportedVersions []uint16
David Benjaminca6c8262014-11-15 19:06:08 -0500164 secureRenegotiation []byte
165 alpnProtocols []string
166 duplicateExtension bool
167 channelIDSupported bool
Steven Valdeza833c352016-11-01 13:39:36 -0400168 npnAfterAlpn bool
David Benjaminca6c8262014-11-15 19:06:08 -0500169 extendedMasterSecret bool
170 srtpProtectionProfiles []uint16
171 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -0500172 sctListSupported bool
Adam Langley09505632015-07-30 18:10:13 -0700173 customExtension string
David Benjamin65ac9972016-09-02 21:35:25 -0400174 hasGREASEExtension bool
Steven Valdeza833c352016-11-01 13:39:36 -0400175 pskBinderFirst bool
David Benjaminb853f312017-07-14 18:40:34 -0400176 omitExtensions bool
177 emptyExtensions bool
David Benjamine51fb0f2017-09-07 11:51:46 -0400178 pad int
Adam Langley95c29f32014-06-20 12:00:00 -0700179}
180
181func (m *clientHelloMsg) equal(i interface{}) bool {
182 m1, ok := i.(*clientHelloMsg)
183 if !ok {
184 return false
185 }
186
187 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400188 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700189 m.vers == m1.vers &&
190 bytes.Equal(m.random, m1.random) &&
191 bytes.Equal(m.sessionId, m1.sessionId) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400192 bytes.Equal(m.cookie, m1.cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700193 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
194 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
195 m.nextProtoNeg == m1.nextProtoNeg &&
196 m.serverName == m1.serverName &&
197 m.ocspStapling == m1.ocspStapling &&
198 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
199 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
Nick Harperdcfbc672016-07-16 17:47:31 +0200200 m.hasKeyShares == m1.hasKeyShares &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400201 eqKeyShareEntryLists(m.keyShares, m1.keyShares) &&
David Benjamin7e1f9842016-09-20 19:24:40 -0400202 m.trailingKeyShareData == m1.trailingKeyShareData &&
Steven Valdez5b986082016-09-01 12:29:49 -0400203 eqPSKIdentityLists(m.pskIdentities, m1.pskIdentities) &&
Steven Valdeza833c352016-11-01 13:39:36 -0400204 bytes.Equal(m.pskKEModes, m1.pskKEModes) &&
205 eqByteSlices(m.pskBinders, m1.pskBinders) &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400206 m.hasEarlyData == m1.hasEarlyData &&
David Benjamin3baa6e12016-10-07 21:10:38 -0400207 bytes.Equal(m.tls13Cookie, m1.tls13Cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700208 m.ticketSupported == m1.ticketSupported &&
209 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
Nick Harper60edffd2016-06-21 15:19:24 -0700210 eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
Steven Valdezfdd10992016-09-15 16:27:05 -0400211 eqUint16s(m.supportedVersions, m1.supportedVersions) &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700212 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
213 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400214 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -0400215 m.duplicateExtension == m1.duplicateExtension &&
David Benjaminfc7b0862014-09-06 13:21:53 -0400216 m.channelIDSupported == m1.channelIDSupported &&
Steven Valdeza833c352016-11-01 13:39:36 -0400217 m.npnAfterAlpn == m1.npnAfterAlpn &&
David Benjaminca6c8262014-11-15 19:06:08 -0500218 m.extendedMasterSecret == m1.extendedMasterSecret &&
219 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
David Benjamin61f95272014-11-25 01:55:35 -0500220 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
Adam Langley09505632015-07-30 18:10:13 -0700221 m.sctListSupported == m1.sctListSupported &&
David Benjamin65ac9972016-09-02 21:35:25 -0400222 m.customExtension == m1.customExtension &&
Steven Valdeza833c352016-11-01 13:39:36 -0400223 m.hasGREASEExtension == m1.hasGREASEExtension &&
David Benjaminb853f312017-07-14 18:40:34 -0400224 m.pskBinderFirst == m1.pskBinderFirst &&
225 m.omitExtensions == m1.omitExtensions &&
David Benjamine51fb0f2017-09-07 11:51:46 -0400226 m.emptyExtensions == m1.emptyExtensions &&
227 m.pad == m1.pad
Adam Langley95c29f32014-06-20 12:00:00 -0700228}
229
230func (m *clientHelloMsg) marshal() []byte {
231 if m.raw != nil {
232 return m.raw
233 }
234
Nick Harper8dda5cc2016-06-30 18:51:11 -0400235 handshakeMsg := newByteBuilder()
236 handshakeMsg.addU8(typeClientHello)
237 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400238 hello.addU16(m.vers)
Nick Harper8dda5cc2016-06-30 18:51:11 -0400239 hello.addBytes(m.random)
240 sessionId := hello.addU8LengthPrefixed()
241 sessionId.addBytes(m.sessionId)
David Benjamin83c0bc92014-08-04 01:23:53 -0400242 if m.isDTLS {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400243 cookie := hello.addU8LengthPrefixed()
244 cookie.addBytes(m.cookie)
David Benjamin83c0bc92014-08-04 01:23:53 -0400245 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400246 cipherSuites := hello.addU16LengthPrefixed()
247 for _, suite := range m.cipherSuites {
248 cipherSuites.addU16(suite)
Adam Langley95c29f32014-06-20 12:00:00 -0700249 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400250 compressionMethods := hello.addU8LengthPrefixed()
251 compressionMethods.addBytes(m.compressionMethods)
Adam Langley95c29f32014-06-20 12:00:00 -0700252
Nick Harper8dda5cc2016-06-30 18:51:11 -0400253 extensions := hello.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -0400254 if len(m.pskIdentities) > 0 && m.pskBinderFirst {
255 extensions.addU16(extensionPreSharedKey)
256 pskExtension := extensions.addU16LengthPrefixed()
257
258 pskIdentities := pskExtension.addU16LengthPrefixed()
259 for _, psk := range m.pskIdentities {
260 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
261 pskIdentities.addU32(psk.obfuscatedTicketAge)
262 }
263 pskBinders := pskExtension.addU16LengthPrefixed()
264 for _, binder := range m.pskBinders {
265 pskBinders.addU8LengthPrefixed().addBytes(binder)
266 }
267 }
David Benjamin35a7a442014-07-05 00:23:20 -0400268 if m.duplicateExtension {
269 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400270 extensions.addU16(0xffff)
271 extensions.addU16(0) // 0-length for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400272 }
Steven Valdeza833c352016-11-01 13:39:36 -0400273 if m.nextProtoNeg && !m.npnAfterAlpn {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400274 extensions.addU16(extensionNextProtoNeg)
275 extensions.addU16(0) // The length is always 0
Adam Langley95c29f32014-06-20 12:00:00 -0700276 }
277 if len(m.serverName) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400278 extensions.addU16(extensionServerName)
279 serverNameList := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700280
281 // RFC 3546, section 3.1
282 //
283 // struct {
284 // NameType name_type;
285 // select (name_type) {
286 // case host_name: HostName;
287 // } name;
288 // } ServerName;
289 //
290 // enum {
291 // host_name(0), (255)
292 // } NameType;
293 //
294 // opaque HostName<1..2^16-1>;
295 //
296 // struct {
297 // ServerName server_name_list<1..2^16-1>
298 // } ServerNameList;
299
Nick Harper8dda5cc2016-06-30 18:51:11 -0400300 serverName := serverNameList.addU16LengthPrefixed()
301 serverName.addU8(0) // NameType host_name(0)
302 hostName := serverName.addU16LengthPrefixed()
303 hostName.addBytes([]byte(m.serverName))
Adam Langley95c29f32014-06-20 12:00:00 -0700304 }
305 if m.ocspStapling {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400306 extensions.addU16(extensionStatusRequest)
307 certificateStatusRequest := extensions.addU16LengthPrefixed()
308
Adam Langley95c29f32014-06-20 12:00:00 -0700309 // RFC 4366, section 3.6
Nick Harper8dda5cc2016-06-30 18:51:11 -0400310 certificateStatusRequest.addU8(1) // OCSP type
Adam Langley95c29f32014-06-20 12:00:00 -0700311 // Two zero valued uint16s for the two lengths.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400312 certificateStatusRequest.addU16(0) // ResponderID length
313 certificateStatusRequest.addU16(0) // Extensions length
Adam Langley95c29f32014-06-20 12:00:00 -0700314 }
315 if len(m.supportedCurves) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400316 // http://tools.ietf.org/html/rfc4492#section-5.1.1
317 extensions.addU16(extensionSupportedCurves)
318 supportedCurvesList := extensions.addU16LengthPrefixed()
319 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700320 for _, curve := range m.supportedCurves {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400321 supportedCurves.addU16(uint16(curve))
Adam Langley95c29f32014-06-20 12:00:00 -0700322 }
323 }
324 if len(m.supportedPoints) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400325 // http://tools.ietf.org/html/rfc4492#section-5.1.2
326 extensions.addU16(extensionSupportedPoints)
327 supportedPointsList := extensions.addU16LengthPrefixed()
328 supportedPoints := supportedPointsList.addU8LengthPrefixed()
David Benjamina81967b2016-12-22 09:16:57 -0500329 supportedPoints.addBytes(m.supportedPoints)
Adam Langley95c29f32014-06-20 12:00:00 -0700330 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200331 if m.hasKeyShares {
Nick Harperf8b0e702016-06-30 19:59:01 -0400332 extensions.addU16(extensionKeyShare)
333 keyShareList := extensions.addU16LengthPrefixed()
334
335 keyShares := keyShareList.addU16LengthPrefixed()
336 for _, keyShare := range m.keyShares {
337 keyShares.addU16(uint16(keyShare.group))
338 keyExchange := keyShares.addU16LengthPrefixed()
339 keyExchange.addBytes(keyShare.keyExchange)
340 }
David Benjamin7e1f9842016-09-20 19:24:40 -0400341
342 if m.trailingKeyShareData {
343 keyShares.addU8(0)
344 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400345 }
Steven Valdeza833c352016-11-01 13:39:36 -0400346 if len(m.pskKEModes) > 0 {
347 extensions.addU16(extensionPSKKeyExchangeModes)
348 pskModesExtension := extensions.addU16LengthPrefixed()
349 pskModesExtension.addU8LengthPrefixed().addBytes(m.pskKEModes)
Nick Harperf8b0e702016-06-30 19:59:01 -0400350 }
351 if m.hasEarlyData {
352 extensions.addU16(extensionEarlyData)
David Benjaminc5665c92016-11-15 18:12:58 +0900353 extensions.addU16(0) // The length is zero.
Nick Harperf8b0e702016-06-30 19:59:01 -0400354 }
David Benjamin3baa6e12016-10-07 21:10:38 -0400355 if len(m.tls13Cookie) > 0 {
356 extensions.addU16(extensionCookie)
357 body := extensions.addU16LengthPrefixed()
358 body.addU16LengthPrefixed().addBytes(m.tls13Cookie)
359 }
Adam Langley95c29f32014-06-20 12:00:00 -0700360 if m.ticketSupported {
361 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400362 extensions.addU16(extensionSessionTicket)
363 sessionTicketExtension := extensions.addU16LengthPrefixed()
364 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700365 }
Nick Harper60edffd2016-06-21 15:19:24 -0700366 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700367 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400368 extensions.addU16(extensionSignatureAlgorithms)
369 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
370 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700371 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400372 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700373 }
374 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400375 if len(m.supportedVersions) > 0 {
376 extensions.addU16(extensionSupportedVersions)
377 supportedVersionsExtension := extensions.addU16LengthPrefixed()
378 supportedVersions := supportedVersionsExtension.addU8LengthPrefixed()
379 for _, version := range m.supportedVersions {
380 supportedVersions.addU16(uint16(version))
381 }
382 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700383 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400384 extensions.addU16(extensionRenegotiationInfo)
385 secureRenegoExt := extensions.addU16LengthPrefixed()
386 secureRenego := secureRenegoExt.addU8LengthPrefixed()
387 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700388 }
David Benjaminfa055a22014-09-15 16:51:51 -0400389 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400390 // https://tools.ietf.org/html/rfc7301#section-3.1
391 extensions.addU16(extensionALPN)
392 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400393
Nick Harper8dda5cc2016-06-30 18:51:11 -0400394 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400395 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400396 protocolName := protocolNameList.addU8LengthPrefixed()
397 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400398 }
David Benjaminfa055a22014-09-15 16:51:51 -0400399 }
David Benjamind30a9902014-08-24 01:44:23 -0400400 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400401 extensions.addU16(extensionChannelID)
402 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400403 }
Steven Valdeza833c352016-11-01 13:39:36 -0400404 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400405 extensions.addU16(extensionNextProtoNeg)
406 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400407 }
David Benjamin35a7a442014-07-05 00:23:20 -0400408 if m.duplicateExtension {
409 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400410 extensions.addU16(0xffff)
411 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400412 }
Adam Langley75712922014-10-10 16:23:43 -0700413 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500414 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400415 extensions.addU16(extensionExtendedMasterSecret)
416 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700417 }
David Benjaminca6c8262014-11-15 19:06:08 -0500418 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400419 // https://tools.ietf.org/html/rfc5764#section-4.1.1
420 extensions.addU16(extensionUseSRTP)
421 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500422
Nick Harper8dda5cc2016-06-30 18:51:11 -0400423 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500424 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400425 // An SRTPProtectionProfile is defined as uint8[2],
426 // not uint16. For some reason, we're storing it
427 // as a uint16.
428 srtpProtectionProfiles.addU8(byte(p >> 8))
429 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500430 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400431 srtpMki := useSrtpExt.addU8LengthPrefixed()
432 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500433 }
David Benjamin61f95272014-11-25 01:55:35 -0500434 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400435 extensions.addU16(extensionSignedCertificateTimestamp)
436 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500437 }
Adam Langley09505632015-07-30 18:10:13 -0700438 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400439 extensions.addU16(extensionCustom)
440 customExt := extensions.addU16LengthPrefixed()
441 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700442 }
Steven Valdeza833c352016-11-01 13:39:36 -0400443 // The PSK extension must be last (draft-ietf-tls-tls13-18 section 4.2.6).
444 if len(m.pskIdentities) > 0 && !m.pskBinderFirst {
445 extensions.addU16(extensionPreSharedKey)
446 pskExtension := extensions.addU16LengthPrefixed()
447
448 pskIdentities := pskExtension.addU16LengthPrefixed()
449 for _, psk := range m.pskIdentities {
450 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
451 pskIdentities.addU32(psk.obfuscatedTicketAge)
452 }
453 pskBinders := pskExtension.addU16LengthPrefixed()
454 for _, binder := range m.pskBinders {
455 pskBinders.addU8LengthPrefixed().addBytes(binder)
456 }
457 }
Adam Langley95c29f32014-06-20 12:00:00 -0700458
David Benjamine51fb0f2017-09-07 11:51:46 -0400459 if m.pad != 0 && hello.len()%m.pad != 0 {
460 extensions.addU16(extensionPadding)
461 padding := extensions.addU16LengthPrefixed()
462 // Note hello.len() has changed at this point from the length
463 // prefix.
464 if l := hello.len() % m.pad; l != 0 {
465 padding.addBytes(make([]byte, m.pad-l))
466 }
467 }
468
David Benjaminb853f312017-07-14 18:40:34 -0400469 if m.omitExtensions || m.emptyExtensions {
470 // Silently erase any extensions which were sent.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400471 hello.discardChild()
David Benjaminb853f312017-07-14 18:40:34 -0400472 if m.emptyExtensions {
473 hello.addU16(0)
474 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400475 }
Adam Langley95c29f32014-06-20 12:00:00 -0700476
Nick Harper8dda5cc2016-06-30 18:51:11 -0400477 m.raw = handshakeMsg.finish()
David Benjamine51fb0f2017-09-07 11:51:46 -0400478 // Sanity-check padding.
479 if m.pad != 0 && (len(m.raw)-4)%m.pad != 0 {
480 panic(fmt.Sprintf("%d is not a multiple of %d", len(m.raw)-4, m.pad))
481 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400482 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700483}
484
485func (m *clientHelloMsg) unmarshal(data []byte) bool {
486 if len(data) < 42 {
487 return false
488 }
489 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400490 m.vers = uint16(data[4])<<8 | uint16(data[5])
Adam Langley95c29f32014-06-20 12:00:00 -0700491 m.random = data[6:38]
492 sessionIdLen := int(data[38])
493 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
494 return false
495 }
496 m.sessionId = data[39 : 39+sessionIdLen]
497 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400498 if m.isDTLS {
499 if len(data) < 1 {
500 return false
501 }
502 cookieLen := int(data[0])
503 if cookieLen > 32 || len(data) < 1+cookieLen {
504 return false
505 }
506 m.cookie = data[1 : 1+cookieLen]
507 data = data[1+cookieLen:]
508 }
Adam Langley95c29f32014-06-20 12:00:00 -0700509 if len(data) < 2 {
510 return false
511 }
512 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
513 // they are uint16s, the number must be even.
514 cipherSuiteLen := int(data[0])<<8 | int(data[1])
515 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
516 return false
517 }
518 numCipherSuites := cipherSuiteLen / 2
519 m.cipherSuites = make([]uint16, numCipherSuites)
520 for i := 0; i < numCipherSuites; i++ {
521 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
522 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700523 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700524 }
525 }
526 data = data[2+cipherSuiteLen:]
527 if len(data) < 1 {
528 return false
529 }
530 compressionMethodsLen := int(data[0])
531 if len(data) < 1+compressionMethodsLen {
532 return false
533 }
534 m.compressionMethods = data[1 : 1+compressionMethodsLen]
535
536 data = data[1+compressionMethodsLen:]
537
538 m.nextProtoNeg = false
539 m.serverName = ""
540 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400541 m.keyShares = nil
542 m.pskIdentities = nil
543 m.hasEarlyData = false
Adam Langley95c29f32014-06-20 12:00:00 -0700544 m.ticketSupported = false
545 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700546 m.signatureAlgorithms = nil
Steven Valdezfdd10992016-09-15 16:27:05 -0400547 m.supportedVersions = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400548 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700549 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700550 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700551
552 if len(data) == 0 {
553 // ClientHello is optionally followed by extension data
554 return true
555 }
556 if len(data) < 2 {
557 return false
558 }
559
560 extensionsLength := int(data[0])<<8 | int(data[1])
561 data = data[2:]
562 if extensionsLength != len(data) {
563 return false
564 }
565
566 for len(data) != 0 {
567 if len(data) < 4 {
568 return false
569 }
570 extension := uint16(data[0])<<8 | uint16(data[1])
571 length := int(data[2])<<8 | int(data[3])
572 data = data[4:]
573 if len(data) < length {
574 return false
575 }
576
577 switch extension {
578 case extensionServerName:
579 if length < 2 {
580 return false
581 }
582 numNames := int(data[0])<<8 | int(data[1])
583 d := data[2:]
584 for i := 0; i < numNames; i++ {
585 if len(d) < 3 {
586 return false
587 }
588 nameType := d[0]
589 nameLen := int(d[1])<<8 | int(d[2])
590 d = d[3:]
591 if len(d) < nameLen {
592 return false
593 }
594 if nameType == 0 {
595 m.serverName = string(d[0:nameLen])
596 break
597 }
598 d = d[nameLen:]
599 }
600 case extensionNextProtoNeg:
601 if length > 0 {
602 return false
603 }
604 m.nextProtoNeg = true
605 case extensionStatusRequest:
606 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
607 case extensionSupportedCurves:
608 // http://tools.ietf.org/html/rfc4492#section-5.5.1
609 if length < 2 {
610 return false
611 }
612 l := int(data[0])<<8 | int(data[1])
613 if l%2 == 1 || length != l+2 {
614 return false
615 }
616 numCurves := l / 2
617 m.supportedCurves = make([]CurveID, numCurves)
618 d := data[2:]
619 for i := 0; i < numCurves; i++ {
620 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
621 d = d[2:]
622 }
623 case extensionSupportedPoints:
624 // http://tools.ietf.org/html/rfc4492#section-5.5.2
625 if length < 1 {
626 return false
627 }
628 l := int(data[0])
629 if length != l+1 {
630 return false
631 }
David Benjamina81967b2016-12-22 09:16:57 -0500632 m.supportedPoints = data[1 : 1+l]
Adam Langley95c29f32014-06-20 12:00:00 -0700633 case extensionSessionTicket:
634 // http://tools.ietf.org/html/rfc5077#section-3.2
635 m.ticketSupported = true
636 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400637 case extensionKeyShare:
638 // draft-ietf-tls-tls13 section 6.3.2.3
639 if length < 2 {
640 return false
641 }
642 l := int(data[0])<<8 | int(data[1])
643 if l != length-2 {
644 return false
645 }
646 d := data[2:length]
Nick Harperdcfbc672016-07-16 17:47:31 +0200647 m.hasKeyShares = true
Nick Harperf8b0e702016-06-30 19:59:01 -0400648 for len(d) > 0 {
649 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
650 // key_exchange (2-byte length prefix with at least 1 byte of content).
651 if len(d) < 5 {
652 return false
653 }
654 entry := keyShareEntry{}
655 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
656 keyExchLen := int(d[2])<<8 | int(d[3])
657 d = d[4:]
658 if len(d) < keyExchLen {
659 return false
660 }
661 entry.keyExchange = d[:keyExchLen]
662 d = d[keyExchLen:]
663 m.keyShares = append(m.keyShares, entry)
664 }
665 case extensionPreSharedKey:
Steven Valdeza833c352016-11-01 13:39:36 -0400666 // draft-ietf-tls-tls13-18 section 4.2.6
Nick Harperf8b0e702016-06-30 19:59:01 -0400667 if length < 2 {
668 return false
669 }
670 l := int(data[0])<<8 | int(data[1])
Steven Valdeza833c352016-11-01 13:39:36 -0400671 d := data[2 : l+2]
672 // Parse PSK identities.
Nick Harperf8b0e702016-06-30 19:59:01 -0400673 for len(d) > 0 {
674 if len(d) < 2 {
675 return false
676 }
677 pskLen := int(d[0])<<8 | int(d[1])
678 d = d[2:]
Steven Valdez5b986082016-09-01 12:29:49 -0400679
Steven Valdeza833c352016-11-01 13:39:36 -0400680 if len(d) < pskLen+4 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400681 return false
682 }
Steven Valdeza833c352016-11-01 13:39:36 -0400683 ticket := d[:pskLen]
684 obfuscatedTicketAge := uint32(d[pskLen])<<24 | uint32(d[pskLen+1])<<16 | uint32(d[pskLen+2])<<8 | uint32(d[pskLen+3])
685 psk := pskIdentity{
686 ticket: ticket,
687 obfuscatedTicketAge: obfuscatedTicketAge,
688 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400689 m.pskIdentities = append(m.pskIdentities, psk)
Steven Valdeza833c352016-11-01 13:39:36 -0400690 d = d[pskLen+4:]
Nick Harperf8b0e702016-06-30 19:59:01 -0400691 }
Steven Valdeza833c352016-11-01 13:39:36 -0400692 d = data[l+2:]
693 if len(d) < 2 {
694 return false
695 }
696 l = int(d[0])<<8 | int(d[1])
697 d = d[2:]
698 if l != len(d) {
699 return false
700 }
701 // Parse PSK binders.
702 for len(d) > 0 {
703 if len(d) < 1 {
704 return false
705 }
706 binderLen := int(d[0])
707 d = d[1:]
708 if binderLen > len(d) {
709 return false
710 }
711 m.pskBinders = append(m.pskBinders, d[:binderLen])
712 d = d[binderLen:]
713 }
714
715 // There must be the same number of identities as binders.
716 if len(m.pskIdentities) != len(m.pskBinders) {
717 return false
718 }
719 case extensionPSKKeyExchangeModes:
720 // draft-ietf-tls-tls13-18 section 4.2.7
721 if length < 1 {
722 return false
723 }
724 l := int(data[0])
725 if l != length-1 {
726 return false
727 }
728 m.pskKEModes = data[1:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400729 case extensionEarlyData:
730 // draft-ietf-tls-tls13 section 6.3.2.5
David Benjaminc5665c92016-11-15 18:12:58 +0900731 if length != 0 {
Nick Harperf8b0e702016-06-30 19:59:01 -0400732 return false
733 }
734 m.hasEarlyData = true
David Benjamin3baa6e12016-10-07 21:10:38 -0400735 case extensionCookie:
736 if length < 2 {
737 return false
738 }
739 l := int(data[0])<<8 | int(data[1])
740 if l != length-2 || l == 0 {
741 return false
742 }
743 m.tls13Cookie = data[2 : 2+l]
Adam Langley95c29f32014-06-20 12:00:00 -0700744 case extensionSignatureAlgorithms:
745 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
746 if length < 2 || length&1 != 0 {
747 return false
748 }
749 l := int(data[0])<<8 | int(data[1])
750 if l != length-2 {
751 return false
752 }
753 n := l / 2
754 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700755 m.signatureAlgorithms = make([]signatureAlgorithm, n)
756 for i := range m.signatureAlgorithms {
757 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700758 d = d[2:]
759 }
Steven Valdezfdd10992016-09-15 16:27:05 -0400760 case extensionSupportedVersions:
761 if length < 1+2 {
762 return false
763 }
764 l := int(data[0])
765 if l != length-1 || l%2 == 1 || l < 2 {
766 return false
767 }
768 n := l / 2
769 d := data[1:]
770 m.supportedVersions = make([]uint16, n)
771 for i := range m.supportedVersions {
772 m.supportedVersions[i] = uint16(d[0])<<8 | uint16(d[1])
773 d = d[2:]
774 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700775 case extensionRenegotiationInfo:
776 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700777 return false
778 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700779 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400780 case extensionALPN:
781 if length < 2 {
782 return false
783 }
784 l := int(data[0])<<8 | int(data[1])
785 if l != length-2 {
786 return false
787 }
788 d := data[2:length]
789 for len(d) != 0 {
790 stringLen := int(d[0])
791 d = d[1:]
792 if stringLen == 0 || stringLen > len(d) {
793 return false
794 }
795 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
796 d = d[stringLen:]
797 }
David Benjamind30a9902014-08-24 01:44:23 -0400798 case extensionChannelID:
799 if length > 0 {
800 return false
801 }
802 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700803 case extensionExtendedMasterSecret:
804 if length != 0 {
805 return false
806 }
807 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500808 case extensionUseSRTP:
809 if length < 2 {
810 return false
811 }
812 l := int(data[0])<<8 | int(data[1])
813 if l > length-2 || l%2 != 0 {
814 return false
815 }
816 n := l / 2
817 m.srtpProtectionProfiles = make([]uint16, n)
818 d := data[2:length]
819 for i := 0; i < n; i++ {
820 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
821 d = d[2:]
822 }
823 if len(d) < 1 || int(d[0]) != len(d)-1 {
824 return false
825 }
826 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500827 case extensionSignedCertificateTimestamp:
828 if length != 0 {
829 return false
830 }
831 m.sctListSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700832 case extensionCustom:
833 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700834 }
835 data = data[length:]
David Benjamin65ac9972016-09-02 21:35:25 -0400836
837 if isGREASEValue(extension) {
838 m.hasGREASEExtension = true
839 }
Adam Langley95c29f32014-06-20 12:00:00 -0700840 }
841
842 return true
843}
844
845type serverHelloMsg struct {
Steven Valdez038da9b2017-07-10 12:57:25 -0400846 raw []byte
847 isDTLS bool
848 vers uint16
849 versOverride uint16
850 supportedVersOverride uint16
851 random []byte
852 sessionId []byte
853 cipherSuite uint16
854 hasKeyShare bool
855 keyShare keyShareEntry
856 hasPSKIdentity bool
857 pskIdentity uint16
858 compressionMethod uint8
859 customExtension string
860 unencryptedALPN string
David Benjaminb853f312017-07-14 18:40:34 -0400861 omitExtensions bool
862 emptyExtensions bool
Steven Valdez038da9b2017-07-10 12:57:25 -0400863 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700864}
865
Adam Langley95c29f32014-06-20 12:00:00 -0700866func (m *serverHelloMsg) marshal() []byte {
867 if m.raw != nil {
868 return m.raw
869 }
870
Nick Harper5212ef82016-06-30 19:26:07 -0400871 handshakeMsg := newByteBuilder()
872 handshakeMsg.addU8(typeServerHello)
873 hello := handshakeMsg.addU24LengthPrefixed()
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400874
875 // m.vers is used both to determine the format of the rest of the
876 // ServerHello and to override the value, so include a second version
877 // field.
878 vers, ok := wireToVersion(m.vers, m.isDTLS)
879 if !ok {
880 panic("unknown version")
881 }
882 if m.versOverride != 0 {
883 hello.addU16(m.versOverride)
Steven Valdez16821262017-09-08 17:03:42 -0400884 } else if isResumptionExperiment(m.vers) {
Steven Valdez038da9b2017-07-10 12:57:25 -0400885 hello.addU16(VersionTLS12)
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400886 } else {
887 hello.addU16(m.vers)
888 }
889
Nick Harper5212ef82016-06-30 19:26:07 -0400890 hello.addBytes(m.random)
Steven Valdez16821262017-09-08 17:03:42 -0400891 if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
Nick Harperb41d2e42016-07-01 17:50:32 -0400892 sessionId := hello.addU8LengthPrefixed()
893 sessionId.addBytes(m.sessionId)
894 }
Nick Harper5212ef82016-06-30 19:26:07 -0400895 hello.addU16(m.cipherSuite)
Steven Valdez16821262017-09-08 17:03:42 -0400896 if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
Nick Harperb41d2e42016-07-01 17:50:32 -0400897 hello.addU8(m.compressionMethod)
898 }
Adam Langley95c29f32014-06-20 12:00:00 -0700899
Nick Harper5212ef82016-06-30 19:26:07 -0400900 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400901
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400902 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400903 if m.hasKeyShare {
904 extensions.addU16(extensionKeyShare)
905 keyShare := extensions.addU16LengthPrefixed()
906 keyShare.addU16(uint16(m.keyShare.group))
907 keyExchange := keyShare.addU16LengthPrefixed()
908 keyExchange.addBytes(m.keyShare.keyExchange)
909 }
910 if m.hasPSKIdentity {
911 extensions.addU16(extensionPreSharedKey)
912 extensions.addU16(2) // Length
913 extensions.addU16(m.pskIdentity)
914 }
Steven Valdez16821262017-09-08 17:03:42 -0400915 if isResumptionExperiment(m.vers) || m.supportedVersOverride != 0 {
Steven Valdez038da9b2017-07-10 12:57:25 -0400916 extensions.addU16(extensionSupportedVersions)
917 extensions.addU16(2) // Length
918 if m.supportedVersOverride != 0 {
919 extensions.addU16(m.supportedVersOverride)
920 } else {
921 extensions.addU16(m.vers)
922 }
923 }
David Benjamin490469f2016-10-05 22:44:38 -0400924 if len(m.customExtension) > 0 {
925 extensions.addU16(extensionCustom)
926 customExt := extensions.addU16LengthPrefixed()
927 customExt.addBytes([]byte(m.customExtension))
928 }
929 if len(m.unencryptedALPN) > 0 {
930 extensions.addU16(extensionALPN)
931 extension := extensions.addU16LengthPrefixed()
932
933 protocolNameList := extension.addU16LengthPrefixed()
934 protocolName := protocolNameList.addU8LengthPrefixed()
935 protocolName.addBytes([]byte(m.unencryptedALPN))
936 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400937 } else {
Steven Valdeza833c352016-11-01 13:39:36 -0400938 m.extensions.marshal(extensions)
David Benjaminb853f312017-07-14 18:40:34 -0400939 if m.omitExtensions || m.emptyExtensions {
940 // Silently erasing server extensions will break the handshake. Instead,
941 // assert that tests which use this field also disable all features which
942 // would write an extension.
943 if extensions.len() != 0 {
944 panic(fmt.Sprintf("ServerHello unexpectedly contained extensions: %x, %+v", extensions.data(), m))
945 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400946 hello.discardChild()
David Benjaminb853f312017-07-14 18:40:34 -0400947 if m.emptyExtensions {
948 hello.addU16(0)
949 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400950 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400951 }
952
953 m.raw = handshakeMsg.finish()
954 return m.raw
955}
956
957func (m *serverHelloMsg) unmarshal(data []byte) bool {
958 if len(data) < 42 {
959 return false
960 }
961 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400962 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400963 vers, ok := wireToVersion(m.vers, m.isDTLS)
964 if !ok {
965 return false
966 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400967 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400968 data = data[38:]
Steven Valdez16821262017-09-08 17:03:42 -0400969 if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
Nick Harperb41d2e42016-07-01 17:50:32 -0400970 sessionIdLen := int(data[0])
971 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
972 return false
973 }
974 m.sessionId = data[1 : 1+sessionIdLen]
975 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400976 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400977 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400978 return false
979 }
980 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400981 data = data[2:]
Steven Valdez16821262017-09-08 17:03:42 -0400982 if vers < VersionTLS13 || isResumptionExperiment(m.vers) {
Nick Harperb41d2e42016-07-01 17:50:32 -0400983 if len(data) < 1 {
984 return false
985 }
986 m.compressionMethod = data[0]
987 data = data[1:]
988 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400989
David Benjamin8d315d72016-07-18 01:03:18 +0200990 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400991 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400992 m.extensions = serverExtensions{}
David Benjamin0a471912017-08-31 00:19:57 -0400993 m.omitExtensions = true
Nick Harperb3d51be2016-07-01 11:43:18 -0400994 return true
995 }
996 if len(data) < 2 {
997 return false
998 }
999
1000 extensionsLength := int(data[0])<<8 | int(data[1])
1001 data = data[2:]
1002 if len(data) != extensionsLength {
1003 return false
1004 }
1005
Steven Valdez038da9b2017-07-10 12:57:25 -04001006 // Parse out the version from supported_versions if available.
1007 if m.vers == VersionTLS12 {
1008 vdata := data
1009 for len(vdata) != 0 {
1010 if len(vdata) < 4 {
1011 return false
1012 }
1013 extension := uint16(vdata[0])<<8 | uint16(vdata[1])
1014 length := int(vdata[2])<<8 | int(vdata[3])
1015 vdata = vdata[4:]
1016
1017 if len(vdata) < length {
1018 return false
1019 }
1020 d := vdata[:length]
1021 vdata = vdata[length:]
1022
1023 if extension == extensionSupportedVersions {
1024 if len(d) < 2 {
1025 return false
1026 }
1027 m.vers = uint16(d[0])<<8 | uint16(d[1])
1028 vers, ok = wireToVersion(m.vers, m.isDTLS)
1029 if !ok {
1030 return false
1031 }
1032 }
1033 }
1034 }
1035
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001036 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -04001037 for len(data) != 0 {
1038 if len(data) < 4 {
1039 return false
1040 }
1041 extension := uint16(data[0])<<8 | uint16(data[1])
1042 length := int(data[2])<<8 | int(data[3])
1043 data = data[4:]
1044
1045 if len(data) < length {
1046 return false
1047 }
1048 d := data[:length]
1049 data = data[length:]
1050
1051 switch extension {
1052 case extensionKeyShare:
1053 m.hasKeyShare = true
1054 if len(d) < 4 {
1055 return false
1056 }
1057 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
1058 keyExchLen := int(d[2])<<8 | int(d[3])
1059 if keyExchLen != len(d)-4 {
1060 return false
1061 }
1062 m.keyShare.keyExchange = make([]byte, keyExchLen)
1063 copy(m.keyShare.keyExchange, d[4:])
1064 case extensionPreSharedKey:
1065 if len(d) != 2 {
1066 return false
1067 }
1068 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
1069 m.hasPSKIdentity = true
Steven Valdez038da9b2017-07-10 12:57:25 -04001070 case extensionSupportedVersions:
Steven Valdez16821262017-09-08 17:03:42 -04001071 if !isResumptionExperiment(m.vers) {
Steven Valdez038da9b2017-07-10 12:57:25 -04001072 return false
1073 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001074 default:
1075 // Only allow the 3 extensions that are sent in
1076 // the clear in TLS 1.3.
1077 return false
1078 }
1079 }
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001080 } else if !m.extensions.unmarshal(data, vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -04001081 return false
1082 }
1083
1084 return true
1085}
1086
Nick Harperb41d2e42016-07-01 17:50:32 -04001087type encryptedExtensionsMsg struct {
1088 raw []byte
1089 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -04001090 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001091}
1092
1093func (m *encryptedExtensionsMsg) marshal() []byte {
1094 if m.raw != nil {
1095 return m.raw
1096 }
1097
1098 encryptedExtensionsMsg := newByteBuilder()
1099 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
1100 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -04001101 if !m.empty {
1102 extensions := encryptedExtensions.addU16LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001103 m.extensions.marshal(extensions)
Steven Valdez143e8b32016-07-11 13:19:03 -04001104 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001105
1106 m.raw = encryptedExtensionsMsg.finish()
1107 return m.raw
1108}
1109
1110func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -04001111 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001112 if len(data) < 6 {
1113 return false
1114 }
1115 if data[0] != typeEncryptedExtensions {
1116 return false
1117 }
1118 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1119 data = data[4:]
1120 if len(data) != msgLen {
1121 return false
1122 }
1123 extLen := int(data[0])<<8 | int(data[1])
1124 data = data[2:]
1125 if extLen != len(data) {
1126 return false
1127 }
David Benjamin44b33bc2016-07-01 22:40:23 -04001128 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -04001129}
1130
Nick Harperb3d51be2016-07-01 11:43:18 -04001131type serverExtensions struct {
1132 nextProtoNeg bool
1133 nextProtos []string
1134 ocspStapling bool
1135 ticketSupported bool
1136 secureRenegotiation []byte
1137 alpnProtocol string
1138 alpnProtocolEmpty bool
1139 duplicateExtension bool
1140 channelIDRequested bool
1141 extendedMasterSecret bool
1142 srtpProtectionProfile uint16
1143 srtpMasterKeyIdentifier string
1144 sctList []byte
1145 customExtension string
Steven Valdeza833c352016-11-01 13:39:36 -04001146 npnAfterAlpn bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001147 hasKeyShare bool
Nick Harperf2511f12016-12-06 16:02:31 -08001148 hasEarlyData bool
Steven Valdez143e8b32016-07-11 13:19:03 -04001149 keyShare keyShareEntry
Steven Valdez038da9b2017-07-10 12:57:25 -04001150 supportedVersion uint16
David Benjamina81967b2016-12-22 09:16:57 -05001151 supportedPoints []uint8
David Benjamin023d4192017-02-06 13:49:07 -05001152 serverNameAck bool
Nick Harperb3d51be2016-07-01 11:43:18 -04001153}
1154
Steven Valdeza833c352016-11-01 13:39:36 -04001155func (m *serverExtensions) marshal(extensions *byteBuilder) {
David Benjamin35a7a442014-07-05 00:23:20 -04001156 if m.duplicateExtension {
1157 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001158 extensions.addU16(0xffff)
1159 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -04001160 }
Steven Valdeza833c352016-11-01 13:39:36 -04001161 if m.nextProtoNeg && !m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001162 extensions.addU16(extensionNextProtoNeg)
1163 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001164
1165 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001166 if len(v) > 255 {
1167 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -07001168 }
Nick Harper5212ef82016-06-30 19:26:07 -04001169 npn := extension.addU8LengthPrefixed()
1170 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -07001171 }
1172 }
Steven Valdeza833c352016-11-01 13:39:36 -04001173 if m.ocspStapling {
1174 extensions.addU16(extensionStatusRequest)
1175 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001176 }
1177 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -04001178 extensions.addU16(extensionSessionTicket)
1179 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -07001180 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001181 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001182 extensions.addU16(extensionRenegotiationInfo)
1183 extension := extensions.addU16LengthPrefixed()
1184 secureRenego := extension.addU8LengthPrefixed()
1185 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -07001186 }
Nick Harper5212ef82016-06-30 19:26:07 -04001187 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
1188 extensions.addU16(extensionALPN)
1189 extension := extensions.addU16LengthPrefixed()
1190
1191 protocolNameList := extension.addU16LengthPrefixed()
1192 protocolName := protocolNameList.addU8LengthPrefixed()
1193 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -04001194 }
David Benjamind30a9902014-08-24 01:44:23 -04001195 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -04001196 extensions.addU16(extensionChannelID)
1197 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -04001198 }
David Benjamin35a7a442014-07-05 00:23:20 -04001199 if m.duplicateExtension {
1200 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001201 extensions.addU16(0xffff)
1202 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -04001203 }
Adam Langley75712922014-10-10 16:23:43 -07001204 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -04001205 extensions.addU16(extensionExtendedMasterSecret)
1206 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -07001207 }
David Benjaminca6c8262014-11-15 19:06:08 -05001208 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001209 extensions.addU16(extensionUseSRTP)
1210 extension := extensions.addU16LengthPrefixed()
1211
1212 srtpProtectionProfiles := extension.addU16LengthPrefixed()
1213 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
1214 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
1215 srtpMki := extension.addU8LengthPrefixed()
1216 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -05001217 }
David Benjamin61f95272014-11-25 01:55:35 -05001218 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001219 extensions.addU16(extensionSignedCertificateTimestamp)
1220 extension := extensions.addU16LengthPrefixed()
1221 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -05001222 }
Adam Langley09505632015-07-30 18:10:13 -07001223 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001224 extensions.addU16(extensionCustom)
1225 customExt := extensions.addU16LengthPrefixed()
1226 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -07001227 }
Steven Valdeza833c352016-11-01 13:39:36 -04001228 if m.nextProtoNeg && m.npnAfterAlpn {
Nick Harper5212ef82016-06-30 19:26:07 -04001229 extensions.addU16(extensionNextProtoNeg)
1230 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -04001231
1232 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001233 if len(v) > 255 {
1234 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -04001235 }
Nick Harper5212ef82016-06-30 19:26:07 -04001236 npn := extension.addU8LengthPrefixed()
1237 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001238 }
1239 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001240 if m.hasKeyShare {
1241 extensions.addU16(extensionKeyShare)
1242 keyShare := extensions.addU16LengthPrefixed()
1243 keyShare.addU16(uint16(m.keyShare.group))
1244 keyExchange := keyShare.addU16LengthPrefixed()
1245 keyExchange.addBytes(m.keyShare.keyExchange)
1246 }
Steven Valdez038da9b2017-07-10 12:57:25 -04001247 if m.supportedVersion != 0 {
1248 extensions.addU16(extensionSupportedVersions)
1249 extensions.addU16(2) // Length
1250 extensions.addU16(m.supportedVersion)
1251 }
David Benjamina81967b2016-12-22 09:16:57 -05001252 if len(m.supportedPoints) > 0 {
1253 // http://tools.ietf.org/html/rfc4492#section-5.1.2
1254 extensions.addU16(extensionSupportedPoints)
1255 supportedPointsList := extensions.addU16LengthPrefixed()
1256 supportedPoints := supportedPointsList.addU8LengthPrefixed()
1257 supportedPoints.addBytes(m.supportedPoints)
1258 }
Nick Harperf2511f12016-12-06 16:02:31 -08001259 if m.hasEarlyData {
1260 extensions.addU16(extensionEarlyData)
1261 extensions.addBytes([]byte{0, 0})
1262 }
David Benjamin023d4192017-02-06 13:49:07 -05001263 if m.serverNameAck {
1264 extensions.addU16(extensionServerName)
1265 extensions.addU16(0) // zero length
1266 }
Adam Langley95c29f32014-06-20 12:00:00 -07001267}
1268
David Benjamin44b33bc2016-07-01 22:40:23 -04001269func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001270 // Reset all fields.
1271 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001272
1273 for len(data) != 0 {
1274 if len(data) < 4 {
1275 return false
1276 }
1277 extension := uint16(data[0])<<8 | uint16(data[1])
1278 length := int(data[2])<<8 | int(data[3])
1279 data = data[4:]
1280 if len(data) < length {
1281 return false
1282 }
1283
1284 switch extension {
1285 case extensionNextProtoNeg:
1286 m.nextProtoNeg = true
1287 d := data[:length]
1288 for len(d) > 0 {
1289 l := int(d[0])
1290 d = d[1:]
1291 if l == 0 || l > len(d) {
1292 return false
1293 }
1294 m.nextProtos = append(m.nextProtos, string(d[:l]))
1295 d = d[l:]
1296 }
1297 case extensionStatusRequest:
Steven Valdeza833c352016-11-01 13:39:36 -04001298 if length > 0 {
1299 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001300 }
Steven Valdeza833c352016-11-01 13:39:36 -04001301 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001302 case extensionSessionTicket:
1303 if length > 0 {
1304 return false
1305 }
1306 m.ticketSupported = true
1307 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001308 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001309 return false
1310 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001311 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001312 case extensionALPN:
1313 d := data[:length]
1314 if len(d) < 3 {
1315 return false
1316 }
1317 l := int(d[0])<<8 | int(d[1])
1318 if l != len(d)-2 {
1319 return false
1320 }
1321 d = d[2:]
1322 l = int(d[0])
1323 if l != len(d)-1 {
1324 return false
1325 }
1326 d = d[1:]
1327 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001328 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001329 case extensionChannelID:
1330 if length > 0 {
1331 return false
1332 }
1333 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001334 case extensionExtendedMasterSecret:
1335 if length != 0 {
1336 return false
1337 }
1338 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001339 case extensionUseSRTP:
1340 if length < 2+2+1 {
1341 return false
1342 }
1343 if data[0] != 0 || data[1] != 2 {
1344 return false
1345 }
1346 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1347 d := data[4:length]
1348 l := int(d[0])
1349 if l != len(d)-1 {
1350 return false
1351 }
1352 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001353 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001354 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001355 case extensionCustom:
1356 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001357 case extensionServerName:
1358 if length != 0 {
1359 return false
1360 }
David Benjamin023d4192017-02-06 13:49:07 -05001361 m.serverNameAck = true
David Benjamin46f94bd2016-07-14 16:43:37 -04001362 case extensionSupportedPoints:
1363 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001364 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001365 return false
1366 }
David Benjamina81967b2016-12-22 09:16:57 -05001367 // http://tools.ietf.org/html/rfc4492#section-5.5.2
1368 if length < 1 {
1369 return false
1370 }
1371 l := int(data[0])
1372 if length != l+1 {
1373 return false
1374 }
1375 m.supportedPoints = data[1 : 1+l]
David Benjamin4ee027f2016-07-17 12:34:41 +02001376 case extensionSupportedCurves:
1377 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001378 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001379 return false
1380 }
Nick Harperf2511f12016-12-06 16:02:31 -08001381 case extensionEarlyData:
1382 if version < VersionTLS13 || length != 0 {
1383 return false
1384 }
1385 m.hasEarlyData = true
David Benjamin46f94bd2016-07-14 16:43:37 -04001386 default:
1387 // Unknown extensions are illegal from the server.
1388 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001389 }
1390 data = data[length:]
1391 }
1392
1393 return true
1394}
1395
Nick Harperdcfbc672016-07-16 17:47:31 +02001396type helloRetryRequestMsg struct {
David Benjamin3baa6e12016-10-07 21:10:38 -04001397 raw []byte
1398 vers uint16
1399 hasSelectedGroup bool
1400 selectedGroup CurveID
1401 cookie []byte
1402 customExtension string
1403 duplicateExtensions bool
Nick Harperdcfbc672016-07-16 17:47:31 +02001404}
1405
1406func (m *helloRetryRequestMsg) marshal() []byte {
1407 if m.raw != nil {
1408 return m.raw
1409 }
1410
1411 retryRequestMsg := newByteBuilder()
1412 retryRequestMsg.addU8(typeHelloRetryRequest)
1413 retryRequest := retryRequestMsg.addU24LengthPrefixed()
1414 retryRequest.addU16(m.vers)
David Benjamin3baa6e12016-10-07 21:10:38 -04001415 extensions := retryRequest.addU16LengthPrefixed()
1416
1417 count := 1
1418 if m.duplicateExtensions {
1419 count = 2
1420 }
1421
1422 for i := 0; i < count; i++ {
1423 if m.hasSelectedGroup {
1424 extensions.addU16(extensionKeyShare)
1425 extensions.addU16(2) // length
1426 extensions.addU16(uint16(m.selectedGroup))
1427 }
1428 if len(m.cookie) > 0 {
1429 extensions.addU16(extensionCookie)
1430 body := extensions.addU16LengthPrefixed()
1431 body.addU16LengthPrefixed().addBytes(m.cookie)
1432 }
1433 if len(m.customExtension) > 0 {
1434 extensions.addU16(extensionCustom)
1435 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
1436 }
1437 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001438
1439 m.raw = retryRequestMsg.finish()
1440 return m.raw
1441}
1442
1443func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1444 m.raw = data
David Benjamin3baa6e12016-10-07 21:10:38 -04001445 if len(data) < 8 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001446 return false
1447 }
1448 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin3baa6e12016-10-07 21:10:38 -04001449 extLen := int(data[6])<<8 | int(data[7])
1450 data = data[8:]
1451 if len(data) != extLen || len(data) == 0 {
Nick Harperdcfbc672016-07-16 17:47:31 +02001452 return false
1453 }
David Benjamin3baa6e12016-10-07 21:10:38 -04001454 for len(data) > 0 {
1455 if len(data) < 4 {
1456 return false
1457 }
1458 extension := uint16(data[0])<<8 | uint16(data[1])
1459 length := int(data[2])<<8 | int(data[3])
1460 data = data[4:]
1461 if len(data) < length {
1462 return false
1463 }
1464
1465 switch extension {
1466 case extensionKeyShare:
1467 if length != 2 {
1468 return false
1469 }
1470 m.hasSelectedGroup = true
1471 m.selectedGroup = CurveID(data[0])<<8 | CurveID(data[1])
1472 case extensionCookie:
1473 if length < 2 {
1474 return false
1475 }
1476 cookieLen := int(data[0])<<8 | int(data[1])
1477 if 2+cookieLen != length {
1478 return false
1479 }
1480 m.cookie = data[2 : 2+cookieLen]
1481 default:
1482 // Unknown extensions are illegal from the server.
1483 return false
1484 }
1485 data = data[length:]
1486 }
Nick Harperdcfbc672016-07-16 17:47:31 +02001487 return true
1488}
1489
Steven Valdeza833c352016-11-01 13:39:36 -04001490type certificateEntry struct {
1491 data []byte
1492 ocspResponse []byte
1493 sctList []byte
1494 duplicateExtensions bool
1495 extraExtension []byte
1496}
1497
Adam Langley95c29f32014-06-20 12:00:00 -07001498type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001499 raw []byte
1500 hasRequestContext bool
1501 requestContext []byte
Steven Valdeza833c352016-11-01 13:39:36 -04001502 certificates []certificateEntry
Adam Langley95c29f32014-06-20 12:00:00 -07001503}
1504
Adam Langley95c29f32014-06-20 12:00:00 -07001505func (m *certificateMsg) marshal() (x []byte) {
1506 if m.raw != nil {
1507 return m.raw
1508 }
1509
Nick Harper7e0442a2016-07-01 17:40:09 -04001510 certMsg := newByteBuilder()
1511 certMsg.addU8(typeCertificate)
1512 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001513 if m.hasRequestContext {
1514 context := certificate.addU8LengthPrefixed()
1515 context.addBytes(m.requestContext)
1516 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001517 certificateList := certificate.addU24LengthPrefixed()
1518 for _, cert := range m.certificates {
1519 certEntry := certificateList.addU24LengthPrefixed()
Steven Valdeza833c352016-11-01 13:39:36 -04001520 certEntry.addBytes(cert.data)
1521 if m.hasRequestContext {
1522 extensions := certificateList.addU16LengthPrefixed()
1523 count := 1
1524 if cert.duplicateExtensions {
1525 count = 2
1526 }
1527
1528 for i := 0; i < count; i++ {
1529 if cert.ocspResponse != nil {
1530 extensions.addU16(extensionStatusRequest)
1531 body := extensions.addU16LengthPrefixed()
1532 body.addU8(statusTypeOCSP)
1533 response := body.addU24LengthPrefixed()
1534 response.addBytes(cert.ocspResponse)
1535 }
1536
1537 if cert.sctList != nil {
1538 extensions.addU16(extensionSignedCertificateTimestamp)
1539 extension := extensions.addU16LengthPrefixed()
1540 extension.addBytes(cert.sctList)
1541 }
1542 }
1543 if cert.extraExtension != nil {
1544 extensions.addBytes(cert.extraExtension)
1545 }
1546 }
Adam Langley95c29f32014-06-20 12:00:00 -07001547 }
1548
Nick Harper7e0442a2016-07-01 17:40:09 -04001549 m.raw = certMsg.finish()
1550 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001551}
1552
1553func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001554 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001555 return false
1556 }
1557
1558 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001559 data = data[4:]
1560
1561 if m.hasRequestContext {
1562 if len(data) == 0 {
1563 return false
1564 }
1565 contextLen := int(data[0])
1566 if len(data) < 1+contextLen {
1567 return false
1568 }
1569 m.requestContext = make([]byte, contextLen)
1570 copy(m.requestContext, data[1:])
1571 data = data[1+contextLen:]
1572 }
1573
1574 if len(data) < 3 {
1575 return false
1576 }
1577 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1578 data = data[3:]
1579 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001580 return false
1581 }
1582
Steven Valdeza833c352016-11-01 13:39:36 -04001583 m.certificates = nil
1584 for len(data) != 0 {
1585 if len(data) < 3 {
Adam Langley95c29f32014-06-20 12:00:00 -07001586 return false
1587 }
Steven Valdeza833c352016-11-01 13:39:36 -04001588 certLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1589 if len(data) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001590 return false
1591 }
Steven Valdeza833c352016-11-01 13:39:36 -04001592 cert := certificateEntry{
1593 data: data[3 : 3+certLen],
1594 }
1595 data = data[3+certLen:]
1596 if m.hasRequestContext {
1597 if len(data) < 2 {
1598 return false
1599 }
1600 extensionsLen := int(data[0])<<8 | int(data[1])
1601 if len(data) < 2+extensionsLen {
1602 return false
1603 }
1604 extensions := data[2 : 2+extensionsLen]
1605 data = data[2+extensionsLen:]
1606 for len(extensions) != 0 {
1607 if len(extensions) < 4 {
1608 return false
1609 }
1610 extension := uint16(extensions[0])<<8 | uint16(extensions[1])
1611 length := int(extensions[2])<<8 | int(extensions[3])
1612 if len(extensions) < 4+length {
1613 return false
1614 }
1615 contents := extensions[4 : 4+length]
1616 extensions = extensions[4+length:]
Adam Langley95c29f32014-06-20 12:00:00 -07001617
Steven Valdeza833c352016-11-01 13:39:36 -04001618 switch extension {
1619 case extensionStatusRequest:
1620 if length < 4 {
1621 return false
1622 }
1623 if contents[0] != statusTypeOCSP {
1624 return false
1625 }
1626 respLen := int(contents[1])<<16 | int(contents[2])<<8 | int(contents[3])
1627 if respLen+4 != len(contents) || respLen == 0 {
1628 return false
1629 }
1630 cert.ocspResponse = contents[4:]
1631 case extensionSignedCertificateTimestamp:
1632 cert.sctList = contents
1633 default:
1634 return false
1635 }
1636 }
1637 }
1638 m.certificates = append(m.certificates, cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001639 }
1640
1641 return true
1642}
1643
1644type serverKeyExchangeMsg struct {
1645 raw []byte
1646 key []byte
1647}
1648
Adam Langley95c29f32014-06-20 12:00:00 -07001649func (m *serverKeyExchangeMsg) marshal() []byte {
1650 if m.raw != nil {
1651 return m.raw
1652 }
1653 length := len(m.key)
1654 x := make([]byte, length+4)
1655 x[0] = typeServerKeyExchange
1656 x[1] = uint8(length >> 16)
1657 x[2] = uint8(length >> 8)
1658 x[3] = uint8(length)
1659 copy(x[4:], m.key)
1660
1661 m.raw = x
1662 return x
1663}
1664
1665func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1666 m.raw = data
1667 if len(data) < 4 {
1668 return false
1669 }
1670 m.key = data[4:]
1671 return true
1672}
1673
1674type certificateStatusMsg struct {
1675 raw []byte
1676 statusType uint8
1677 response []byte
1678}
1679
Adam Langley95c29f32014-06-20 12:00:00 -07001680func (m *certificateStatusMsg) marshal() []byte {
1681 if m.raw != nil {
1682 return m.raw
1683 }
1684
1685 var x []byte
1686 if m.statusType == statusTypeOCSP {
1687 x = make([]byte, 4+4+len(m.response))
1688 x[0] = typeCertificateStatus
1689 l := len(m.response) + 4
1690 x[1] = byte(l >> 16)
1691 x[2] = byte(l >> 8)
1692 x[3] = byte(l)
1693 x[4] = statusTypeOCSP
1694
1695 l -= 4
1696 x[5] = byte(l >> 16)
1697 x[6] = byte(l >> 8)
1698 x[7] = byte(l)
1699 copy(x[8:], m.response)
1700 } else {
1701 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1702 }
1703
1704 m.raw = x
1705 return x
1706}
1707
1708func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1709 m.raw = data
1710 if len(data) < 5 {
1711 return false
1712 }
1713 m.statusType = data[4]
1714
1715 m.response = nil
1716 if m.statusType == statusTypeOCSP {
1717 if len(data) < 8 {
1718 return false
1719 }
1720 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1721 if uint32(len(data)) != 4+4+respLen {
1722 return false
1723 }
1724 m.response = data[8:]
1725 }
1726 return true
1727}
1728
1729type serverHelloDoneMsg struct{}
1730
Adam Langley95c29f32014-06-20 12:00:00 -07001731func (m *serverHelloDoneMsg) marshal() []byte {
1732 x := make([]byte, 4)
1733 x[0] = typeServerHelloDone
1734 return x
1735}
1736
1737func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1738 return len(data) == 4
1739}
1740
1741type clientKeyExchangeMsg struct {
1742 raw []byte
1743 ciphertext []byte
1744}
1745
Adam Langley95c29f32014-06-20 12:00:00 -07001746func (m *clientKeyExchangeMsg) marshal() []byte {
1747 if m.raw != nil {
1748 return m.raw
1749 }
1750 length := len(m.ciphertext)
1751 x := make([]byte, length+4)
1752 x[0] = typeClientKeyExchange
1753 x[1] = uint8(length >> 16)
1754 x[2] = uint8(length >> 8)
1755 x[3] = uint8(length)
1756 copy(x[4:], m.ciphertext)
1757
1758 m.raw = x
1759 return x
1760}
1761
1762func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1763 m.raw = data
1764 if len(data) < 4 {
1765 return false
1766 }
1767 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1768 if l != len(data)-4 {
1769 return false
1770 }
1771 m.ciphertext = data[4:]
1772 return true
1773}
1774
1775type finishedMsg struct {
1776 raw []byte
1777 verifyData []byte
1778}
1779
Adam Langley95c29f32014-06-20 12:00:00 -07001780func (m *finishedMsg) marshal() (x []byte) {
1781 if m.raw != nil {
1782 return m.raw
1783 }
1784
1785 x = make([]byte, 4+len(m.verifyData))
1786 x[0] = typeFinished
1787 x[3] = byte(len(m.verifyData))
1788 copy(x[4:], m.verifyData)
1789 m.raw = x
1790 return
1791}
1792
1793func (m *finishedMsg) unmarshal(data []byte) bool {
1794 m.raw = data
1795 if len(data) < 4 {
1796 return false
1797 }
1798 m.verifyData = data[4:]
1799 return true
1800}
1801
1802type nextProtoMsg struct {
1803 raw []byte
1804 proto string
1805}
1806
Adam Langley95c29f32014-06-20 12:00:00 -07001807func (m *nextProtoMsg) marshal() []byte {
1808 if m.raw != nil {
1809 return m.raw
1810 }
1811 l := len(m.proto)
1812 if l > 255 {
1813 l = 255
1814 }
1815
1816 padding := 32 - (l+2)%32
1817 length := l + padding + 2
1818 x := make([]byte, length+4)
1819 x[0] = typeNextProtocol
1820 x[1] = uint8(length >> 16)
1821 x[2] = uint8(length >> 8)
1822 x[3] = uint8(length)
1823
1824 y := x[4:]
1825 y[0] = byte(l)
1826 copy(y[1:], []byte(m.proto[0:l]))
1827 y = y[1+l:]
1828 y[0] = byte(padding)
1829
1830 m.raw = x
1831
1832 return x
1833}
1834
1835func (m *nextProtoMsg) unmarshal(data []byte) bool {
1836 m.raw = data
1837
1838 if len(data) < 5 {
1839 return false
1840 }
1841 data = data[4:]
1842 protoLen := int(data[0])
1843 data = data[1:]
1844 if len(data) < protoLen {
1845 return false
1846 }
1847 m.proto = string(data[0:protoLen])
1848 data = data[protoLen:]
1849
1850 if len(data) < 1 {
1851 return false
1852 }
1853 paddingLen := int(data[0])
1854 data = data[1:]
1855 if len(data) != paddingLen {
1856 return false
1857 }
1858
1859 return true
1860}
1861
1862type certificateRequestMsg struct {
1863 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001864 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001865 // of signature and hash functions. This change was introduced with TLS
1866 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001867 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001868 // hasRequestContext indicates whether this message includes a context
1869 // field instead of certificateTypes. This change was introduced with
1870 // TLS 1.3.
1871 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001872
1873 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001874 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001875 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001876 certificateAuthorities [][]byte
1877}
1878
Nick Harper7e0442a2016-07-01 17:40:09 -04001879func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001880 if m.raw != nil {
1881 return m.raw
1882 }
1883
1884 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001885 builder := newByteBuilder()
1886 builder.addU8(typeCertificateRequest)
1887 body := builder.addU24LengthPrefixed()
1888
Nick Harperb41d2e42016-07-01 17:50:32 -04001889 if m.hasRequestContext {
1890 requestContext := body.addU8LengthPrefixed()
1891 requestContext.addBytes(m.requestContext)
1892 } else {
1893 certificateTypes := body.addU8LengthPrefixed()
1894 certificateTypes.addBytes(m.certificateTypes)
1895 }
Adam Langley95c29f32014-06-20 12:00:00 -07001896
Nick Harper60edffd2016-06-21 15:19:24 -07001897 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001898 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001899 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001900 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001901 }
1902 }
1903
Nick Harper7e0442a2016-07-01 17:40:09 -04001904 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001905 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001906 caEntry := certificateAuthorities.addU16LengthPrefixed()
1907 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001908 }
1909
David Benjamin8d343b42016-07-09 14:26:01 -07001910 if m.hasRequestContext {
1911 // Emit no certificate extensions.
1912 body.addU16(0)
1913 }
1914
Nick Harper7e0442a2016-07-01 17:40:09 -04001915 m.raw = builder.finish()
1916 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001917}
1918
1919func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1920 m.raw = data
1921
1922 if len(data) < 5 {
1923 return false
1924 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001925 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001926
Nick Harperb41d2e42016-07-01 17:50:32 -04001927 if m.hasRequestContext {
1928 contextLen := int(data[0])
1929 if len(data) < 1+contextLen {
1930 return false
1931 }
1932 m.requestContext = make([]byte, contextLen)
1933 copy(m.requestContext, data[1:])
1934 data = data[1+contextLen:]
1935 } else {
1936 numCertTypes := int(data[0])
1937 if len(data) < 1+numCertTypes {
1938 return false
1939 }
1940 m.certificateTypes = make([]byte, numCertTypes)
1941 copy(m.certificateTypes, data[1:])
1942 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001943 }
1944
Nick Harper60edffd2016-06-21 15:19:24 -07001945 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001946 if len(data) < 2 {
1947 return false
1948 }
Nick Harper60edffd2016-06-21 15:19:24 -07001949 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001950 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001951 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001952 return false
1953 }
Nick Harper60edffd2016-06-21 15:19:24 -07001954 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001955 return false
1956 }
Nick Harper60edffd2016-06-21 15:19:24 -07001957 numSigAlgs := sigAlgsLen / 2
1958 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1959 for i := range m.signatureAlgorithms {
1960 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001961 data = data[2:]
1962 }
1963 }
1964
1965 if len(data) < 2 {
1966 return false
1967 }
1968 casLength := uint16(data[0])<<8 | uint16(data[1])
1969 data = data[2:]
1970 if len(data) < int(casLength) {
1971 return false
1972 }
1973 cas := make([]byte, casLength)
1974 copy(cas, data)
1975 data = data[casLength:]
1976
1977 m.certificateAuthorities = nil
1978 for len(cas) > 0 {
1979 if len(cas) < 2 {
1980 return false
1981 }
1982 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1983 cas = cas[2:]
1984
1985 if len(cas) < int(caLen) {
1986 return false
1987 }
1988
1989 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1990 cas = cas[caLen:]
1991 }
David Benjamin8d343b42016-07-09 14:26:01 -07001992
1993 if m.hasRequestContext {
1994 // Ignore certificate extensions.
1995 if len(data) < 2 {
1996 return false
1997 }
1998 extsLength := int(data[0])<<8 | int(data[1])
1999 if len(data) < 2+extsLength {
2000 return false
2001 }
2002 data = data[2+extsLength:]
2003 }
2004
Adam Langley95c29f32014-06-20 12:00:00 -07002005 if len(data) > 0 {
2006 return false
2007 }
2008
2009 return true
2010}
2011
2012type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07002013 raw []byte
2014 hasSignatureAlgorithm bool
2015 signatureAlgorithm signatureAlgorithm
2016 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07002017}
2018
Adam Langley95c29f32014-06-20 12:00:00 -07002019func (m *certificateVerifyMsg) marshal() (x []byte) {
2020 if m.raw != nil {
2021 return m.raw
2022 }
2023
2024 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
2025 siglength := len(m.signature)
2026 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07002027 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07002028 length += 2
2029 }
2030 x = make([]byte, 4+length)
2031 x[0] = typeCertificateVerify
2032 x[1] = uint8(length >> 16)
2033 x[2] = uint8(length >> 8)
2034 x[3] = uint8(length)
2035 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07002036 if m.hasSignatureAlgorithm {
2037 y[0] = byte(m.signatureAlgorithm >> 8)
2038 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07002039 y = y[2:]
2040 }
2041 y[0] = uint8(siglength >> 8)
2042 y[1] = uint8(siglength)
2043 copy(y[2:], m.signature)
2044
2045 m.raw = x
2046
2047 return
2048}
2049
2050func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
2051 m.raw = data
2052
2053 if len(data) < 6 {
2054 return false
2055 }
2056
2057 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2058 if uint32(len(data))-4 != length {
2059 return false
2060 }
2061
2062 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07002063 if m.hasSignatureAlgorithm {
2064 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07002065 data = data[2:]
2066 }
2067
2068 if len(data) < 2 {
2069 return false
2070 }
2071 siglength := int(data[0])<<8 + int(data[1])
2072 data = data[2:]
2073 if len(data) != siglength {
2074 return false
2075 }
2076
2077 m.signature = data
2078
2079 return true
2080}
2081
2082type newSessionTicketMsg struct {
David Benjamin9c33ae82017-01-08 06:04:43 -05002083 raw []byte
2084 version uint16
2085 ticketLifetime uint32
2086 ticketAgeAdd uint32
2087 ticket []byte
Nick Harperf2511f12016-12-06 16:02:31 -08002088 maxEarlyDataSize uint32
David Benjamin9c33ae82017-01-08 06:04:43 -05002089 customExtension string
2090 duplicateEarlyDataInfo bool
2091 hasGREASEExtension bool
Adam Langley95c29f32014-06-20 12:00:00 -07002092}
2093
David Benjamin58104882016-07-18 01:25:41 +02002094func (m *newSessionTicketMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07002095 if m.raw != nil {
2096 return m.raw
2097 }
2098
2099 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjamin58104882016-07-18 01:25:41 +02002100 ticketMsg := newByteBuilder()
2101 ticketMsg.addU8(typeNewSessionTicket)
2102 body := ticketMsg.addU24LengthPrefixed()
2103 body.addU32(m.ticketLifetime)
2104 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002105 body.addU32(m.ticketAgeAdd)
Steven Valdez5b986082016-09-01 12:29:49 -04002106 }
2107
2108 ticket := body.addU16LengthPrefixed()
2109 ticket.addBytes(m.ticket)
2110
2111 if m.version >= VersionTLS13 {
David Benjamin1286bee2016-10-07 15:25:06 -04002112 extensions := body.addU16LengthPrefixed()
Nick Harperf2511f12016-12-06 16:02:31 -08002113 if m.maxEarlyDataSize > 0 {
Steven Valdez08b65f42016-12-07 15:29:45 -05002114 extensions.addU16(extensionTicketEarlyDataInfo)
Nick Harperf2511f12016-12-06 16:02:31 -08002115 extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
David Benjamin9c33ae82017-01-08 06:04:43 -05002116 if m.duplicateEarlyDataInfo {
2117 extensions.addU16(extensionTicketEarlyDataInfo)
Nick Harperf2511f12016-12-06 16:02:31 -08002118 extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
David Benjamin9c33ae82017-01-08 06:04:43 -05002119 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002120 }
David Benjamin1286bee2016-10-07 15:25:06 -04002121 if len(m.customExtension) > 0 {
Steven Valdez08b65f42016-12-07 15:29:45 -05002122 extensions.addU16(extensionCustom)
David Benjamin1286bee2016-10-07 15:25:06 -04002123 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
2124 }
David Benjamin58104882016-07-18 01:25:41 +02002125 }
Adam Langley95c29f32014-06-20 12:00:00 -07002126
David Benjamin58104882016-07-18 01:25:41 +02002127 m.raw = ticketMsg.finish()
2128 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07002129}
2130
2131func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
2132 m.raw = data
2133
David Benjamin58104882016-07-18 01:25:41 +02002134 if len(data) < 8 {
2135 return false
2136 }
2137 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
2138 data = data[8:]
2139
2140 if m.version >= VersionTLS13 {
Steven Valdeza833c352016-11-01 13:39:36 -04002141 if len(data) < 4 {
David Benjamin58104882016-07-18 01:25:41 +02002142 return false
2143 }
Steven Valdeza833c352016-11-01 13:39:36 -04002144 m.ticketAgeAdd = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2145 data = data[4:]
David Benjamin58104882016-07-18 01:25:41 +02002146 }
2147
2148 if len(data) < 2 {
2149 return false
2150 }
2151 ticketLen := int(data[0])<<8 + int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002152 data = data[2:]
2153 if len(data) < ticketLen {
David Benjamin58104882016-07-18 01:25:41 +02002154 return false
2155 }
Steven Valdez5b986082016-09-01 12:29:49 -04002156
David Benjamin58104882016-07-18 01:25:41 +02002157 if m.version >= VersionTLS13 && ticketLen == 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07002158 return false
2159 }
2160
Steven Valdez5b986082016-09-01 12:29:49 -04002161 m.ticket = data[:ticketLen]
2162 data = data[ticketLen:]
2163
2164 if m.version >= VersionTLS13 {
2165 if len(data) < 2 {
2166 return false
2167 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002168
2169 extensionsLength := int(data[0])<<8 | int(data[1])
Steven Valdez5b986082016-09-01 12:29:49 -04002170 data = data[2:]
Steven Valdez08b65f42016-12-07 15:29:45 -05002171 if extensionsLength != len(data) {
Steven Valdez5b986082016-09-01 12:29:49 -04002172 return false
2173 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002174
Steven Valdez08b65f42016-12-07 15:29:45 -05002175 for len(data) != 0 {
2176 if len(data) < 4 {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002177 return false
2178 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002179 extension := uint16(data[0])<<8 | uint16(data[1])
2180 length := int(data[2])<<8 | int(data[3])
2181 data = data[4:]
2182 if len(data) < length {
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002183 return false
2184 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002185
Steven Valdez08b65f42016-12-07 15:29:45 -05002186 switch extension {
2187 case extensionTicketEarlyDataInfo:
2188 if length != 4 {
2189 return false
2190 }
Nick Harperf2511f12016-12-06 16:02:31 -08002191 m.maxEarlyDataSize = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
Steven Valdez08b65f42016-12-07 15:29:45 -05002192 default:
2193 if isGREASEValue(extension) {
2194 m.hasGREASEExtension = true
2195 }
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002196 }
Steven Valdez08b65f42016-12-07 15:29:45 -05002197
2198 data = data[length:]
David Benjamin1a5e8ec2016-10-07 15:19:18 -04002199 }
Steven Valdez5b986082016-09-01 12:29:49 -04002200 }
2201
2202 if len(data) > 0 {
2203 return false
2204 }
Adam Langley95c29f32014-06-20 12:00:00 -07002205
2206 return true
2207}
2208
David Benjamind86c7672014-08-02 04:07:12 -04002209type v2ClientHelloMsg struct {
2210 raw []byte
2211 vers uint16
2212 cipherSuites []uint16
2213 sessionId []byte
2214 challenge []byte
2215}
2216
David Benjamind86c7672014-08-02 04:07:12 -04002217func (m *v2ClientHelloMsg) marshal() []byte {
2218 if m.raw != nil {
2219 return m.raw
2220 }
2221
2222 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
2223
2224 x := make([]byte, length)
2225 x[0] = 1
2226 x[1] = uint8(m.vers >> 8)
2227 x[2] = uint8(m.vers)
2228 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
2229 x[4] = uint8(len(m.cipherSuites) * 3)
2230 x[5] = uint8(len(m.sessionId) >> 8)
2231 x[6] = uint8(len(m.sessionId))
2232 x[7] = uint8(len(m.challenge) >> 8)
2233 x[8] = uint8(len(m.challenge))
2234 y := x[9:]
2235 for i, spec := range m.cipherSuites {
2236 y[i*3] = 0
2237 y[i*3+1] = uint8(spec >> 8)
2238 y[i*3+2] = uint8(spec)
2239 }
2240 y = y[len(m.cipherSuites)*3:]
2241 copy(y, m.sessionId)
2242 y = y[len(m.sessionId):]
2243 copy(y, m.challenge)
2244
2245 m.raw = x
2246
2247 return x
2248}
2249
David Benjamin83c0bc92014-08-04 01:23:53 -04002250type helloVerifyRequestMsg struct {
2251 raw []byte
2252 vers uint16
2253 cookie []byte
2254}
2255
David Benjamin83c0bc92014-08-04 01:23:53 -04002256func (m *helloVerifyRequestMsg) marshal() []byte {
2257 if m.raw != nil {
2258 return m.raw
2259 }
2260
2261 length := 2 + 1 + len(m.cookie)
2262
2263 x := make([]byte, 4+length)
2264 x[0] = typeHelloVerifyRequest
2265 x[1] = uint8(length >> 16)
2266 x[2] = uint8(length >> 8)
2267 x[3] = uint8(length)
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002268 vers := m.vers
David Benjamin83c0bc92014-08-04 01:23:53 -04002269 x[4] = uint8(vers >> 8)
2270 x[5] = uint8(vers)
2271 x[6] = uint8(len(m.cookie))
2272 copy(x[7:7+len(m.cookie)], m.cookie)
2273
2274 return x
2275}
2276
2277func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
2278 if len(data) < 4+2+1 {
2279 return false
2280 }
2281 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -04002282 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin83c0bc92014-08-04 01:23:53 -04002283 cookieLen := int(data[6])
2284 if cookieLen > 32 || len(data) != 7+cookieLen {
2285 return false
2286 }
2287 m.cookie = data[7 : 7+cookieLen]
2288
2289 return true
2290}
2291
David Benjamin24599a82016-06-30 18:56:53 -04002292type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04002293 raw []byte
2294 channelID []byte
2295}
2296
David Benjamin24599a82016-06-30 18:56:53 -04002297func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04002298 if m.raw != nil {
2299 return m.raw
2300 }
2301
2302 length := 2 + 2 + len(m.channelID)
2303
2304 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04002305 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04002306 x[1] = uint8(length >> 16)
2307 x[2] = uint8(length >> 8)
2308 x[3] = uint8(length)
2309 x[4] = uint8(extensionChannelID >> 8)
2310 x[5] = uint8(extensionChannelID & 0xff)
2311 x[6] = uint8(len(m.channelID) >> 8)
2312 x[7] = uint8(len(m.channelID) & 0xff)
2313 copy(x[8:], m.channelID)
2314
2315 return x
2316}
2317
David Benjamin24599a82016-06-30 18:56:53 -04002318func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04002319 if len(data) != 4+2+2+128 {
2320 return false
2321 }
2322 m.raw = data
2323 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
2324 return false
2325 }
2326 if int(data[6])<<8|int(data[7]) != 128 {
2327 return false
2328 }
2329 m.channelID = data[4+2+2:]
2330
2331 return true
2332}
2333
Adam Langley2ae77d22014-10-28 17:29:33 -07002334type helloRequestMsg struct {
2335}
2336
2337func (*helloRequestMsg) marshal() []byte {
2338 return []byte{typeHelloRequest, 0, 0, 0}
2339}
2340
2341func (*helloRequestMsg) unmarshal(data []byte) bool {
2342 return len(data) == 4
2343}
2344
David Benjamin21c00282016-07-18 21:56:23 +02002345type keyUpdateMsg struct {
Steven Valdezc4aa7272016-10-03 12:25:56 -04002346 raw []byte
2347 keyUpdateRequest byte
David Benjamin21c00282016-07-18 21:56:23 +02002348}
2349
Steven Valdezc4aa7272016-10-03 12:25:56 -04002350func (m *keyUpdateMsg) marshal() []byte {
2351 if m.raw != nil {
2352 return m.raw
2353 }
2354
2355 return []byte{typeKeyUpdate, 0, 0, 1, m.keyUpdateRequest}
David Benjamin21c00282016-07-18 21:56:23 +02002356}
2357
Steven Valdezc4aa7272016-10-03 12:25:56 -04002358func (m *keyUpdateMsg) unmarshal(data []byte) bool {
2359 m.raw = data
2360
2361 if len(data) != 5 {
2362 return false
2363 }
2364
2365 length := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
2366 if len(data)-4 != length {
2367 return false
2368 }
2369
2370 m.keyUpdateRequest = data[4]
2371 return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
David Benjamin21c00282016-07-18 21:56:23 +02002372}
2373
David Benjamin053fee92017-01-02 08:30:36 -05002374// ssl3NoCertificateMsg is a dummy message to handle SSL 3.0 using a warning
2375// alert in the handshake.
2376type ssl3NoCertificateMsg struct{}
2377
Adam Langley95c29f32014-06-20 12:00:00 -07002378func eqUint16s(x, y []uint16) bool {
2379 if len(x) != len(y) {
2380 return false
2381 }
2382 for i, v := range x {
2383 if y[i] != v {
2384 return false
2385 }
2386 }
2387 return true
2388}
2389
2390func eqCurveIDs(x, y []CurveID) bool {
2391 if len(x) != len(y) {
2392 return false
2393 }
2394 for i, v := range x {
2395 if y[i] != v {
2396 return false
2397 }
2398 }
2399 return true
2400}
2401
2402func eqStrings(x, y []string) bool {
2403 if len(x) != len(y) {
2404 return false
2405 }
2406 for i, v := range x {
2407 if y[i] != v {
2408 return false
2409 }
2410 }
2411 return true
2412}
2413
2414func eqByteSlices(x, y [][]byte) bool {
2415 if len(x) != len(y) {
2416 return false
2417 }
2418 for i, v := range x {
2419 if !bytes.Equal(v, y[i]) {
2420 return false
2421 }
2422 }
2423 return true
2424}
2425
Nick Harper60edffd2016-06-21 15:19:24 -07002426func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07002427 if len(x) != len(y) {
2428 return false
2429 }
2430 for i, v := range x {
2431 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07002432 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07002433 return false
2434 }
2435 }
2436 return true
2437}
Nick Harperf8b0e702016-06-30 19:59:01 -04002438
2439func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2440 if len(x) != len(y) {
2441 return false
2442 }
2443 for i, v := range x {
2444 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2445 return false
2446 }
2447 }
2448 return true
2449
2450}
Steven Valdez5b986082016-09-01 12:29:49 -04002451
2452func eqPSKIdentityLists(x, y []pskIdentity) bool {
2453 if len(x) != len(y) {
2454 return false
2455 }
2456 for i, v := range x {
Steven Valdeza833c352016-11-01 13:39:36 -04002457 if !bytes.Equal(y[i].ticket, v.ticket) || y[i].obfuscatedTicketAge != v.obfuscatedTicketAge {
Steven Valdez5b986082016-09-01 12:29:49 -04002458 return false
2459 }
2460 }
2461 return true
2462
2463}