blob: 6538dc62ab4efa8649585e0e12502ca72499ff43 [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
Adam Langley95c29f32014-06-20 12:00:00 -0700127type clientHelloMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -0400128 raw []byte
129 isDTLS bool
130 vers uint16
131 random []byte
132 sessionId []byte
133 // TODO(davidben): Add support for TLS 1.3 cookies which are larger and
134 // use an extension.
David Benjaminca6c8262014-11-15 19:06:08 -0500135 cookie []byte
136 cipherSuites []uint16
137 compressionMethods []uint8
138 nextProtoNeg bool
139 serverName string
140 ocspStapling bool
141 supportedCurves []CurveID
142 supportedPoints []uint8
Nick Harperdcfbc672016-07-16 17:47:31 +0200143 hasKeyShares bool
Nick Harperf8b0e702016-06-30 19:59:01 -0400144 keyShares []keyShareEntry
David Benjamin7e1f9842016-09-20 19:24:40 -0400145 trailingKeyShareData bool
Nick Harperf8b0e702016-06-30 19:59:01 -0400146 pskIdentities [][]uint8
147 hasEarlyData bool
148 earlyDataContext []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500149 ticketSupported bool
150 sessionTicket []uint8
Nick Harper60edffd2016-06-21 15:19:24 -0700151 signatureAlgorithms []signatureAlgorithm
David Benjaminca6c8262014-11-15 19:06:08 -0500152 secureRenegotiation []byte
153 alpnProtocols []string
154 duplicateExtension bool
155 channelIDSupported bool
156 npnLast bool
157 extendedMasterSecret bool
158 srtpProtectionProfiles []uint16
159 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -0500160 sctListSupported bool
Adam Langley09505632015-07-30 18:10:13 -0700161 customExtension string
David Benjamin65ac9972016-09-02 21:35:25 -0400162 hasGREASEExtension bool
Adam Langley95c29f32014-06-20 12:00:00 -0700163}
164
165func (m *clientHelloMsg) equal(i interface{}) bool {
166 m1, ok := i.(*clientHelloMsg)
167 if !ok {
168 return false
169 }
170
171 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400172 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700173 m.vers == m1.vers &&
174 bytes.Equal(m.random, m1.random) &&
175 bytes.Equal(m.sessionId, m1.sessionId) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400176 bytes.Equal(m.cookie, m1.cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700177 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
178 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
179 m.nextProtoNeg == m1.nextProtoNeg &&
180 m.serverName == m1.serverName &&
181 m.ocspStapling == m1.ocspStapling &&
182 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
183 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
Nick Harperdcfbc672016-07-16 17:47:31 +0200184 m.hasKeyShares == m1.hasKeyShares &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400185 eqKeyShareEntryLists(m.keyShares, m1.keyShares) &&
David Benjamin7e1f9842016-09-20 19:24:40 -0400186 m.trailingKeyShareData == m1.trailingKeyShareData &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400187 eqByteSlices(m.pskIdentities, m1.pskIdentities) &&
188 m.hasEarlyData == m1.hasEarlyData &&
189 bytes.Equal(m.earlyDataContext, m1.earlyDataContext) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700190 m.ticketSupported == m1.ticketSupported &&
191 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
Nick Harper60edffd2016-06-21 15:19:24 -0700192 eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700193 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
194 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400195 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -0400196 m.duplicateExtension == m1.duplicateExtension &&
David Benjaminfc7b0862014-09-06 13:21:53 -0400197 m.channelIDSupported == m1.channelIDSupported &&
Adam Langley75712922014-10-10 16:23:43 -0700198 m.npnLast == m1.npnLast &&
David Benjaminca6c8262014-11-15 19:06:08 -0500199 m.extendedMasterSecret == m1.extendedMasterSecret &&
200 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
David Benjamin61f95272014-11-25 01:55:35 -0500201 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
Adam Langley09505632015-07-30 18:10:13 -0700202 m.sctListSupported == m1.sctListSupported &&
David Benjamin65ac9972016-09-02 21:35:25 -0400203 m.customExtension == m1.customExtension &&
204 m.hasGREASEExtension == m1.hasGREASEExtension
Adam Langley95c29f32014-06-20 12:00:00 -0700205}
206
207func (m *clientHelloMsg) marshal() []byte {
208 if m.raw != nil {
209 return m.raw
210 }
211
Nick Harper8dda5cc2016-06-30 18:51:11 -0400212 handshakeMsg := newByteBuilder()
213 handshakeMsg.addU8(typeClientHello)
214 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400215 hello.addU16(m.vers)
Nick Harper8dda5cc2016-06-30 18:51:11 -0400216 hello.addBytes(m.random)
217 sessionId := hello.addU8LengthPrefixed()
218 sessionId.addBytes(m.sessionId)
David Benjamin83c0bc92014-08-04 01:23:53 -0400219 if m.isDTLS {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400220 cookie := hello.addU8LengthPrefixed()
221 cookie.addBytes(m.cookie)
David Benjamin83c0bc92014-08-04 01:23:53 -0400222 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400223 cipherSuites := hello.addU16LengthPrefixed()
224 for _, suite := range m.cipherSuites {
225 cipherSuites.addU16(suite)
Adam Langley95c29f32014-06-20 12:00:00 -0700226 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400227 compressionMethods := hello.addU8LengthPrefixed()
228 compressionMethods.addBytes(m.compressionMethods)
Adam Langley95c29f32014-06-20 12:00:00 -0700229
Nick Harper8dda5cc2016-06-30 18:51:11 -0400230 extensions := hello.addU16LengthPrefixed()
David Benjamin35a7a442014-07-05 00:23:20 -0400231 if m.duplicateExtension {
232 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400233 extensions.addU16(0xffff)
234 extensions.addU16(0) // 0-length for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400235 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400236 if m.nextProtoNeg && !m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400237 extensions.addU16(extensionNextProtoNeg)
238 extensions.addU16(0) // The length is always 0
Adam Langley95c29f32014-06-20 12:00:00 -0700239 }
240 if len(m.serverName) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400241 extensions.addU16(extensionServerName)
242 serverNameList := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700243
244 // RFC 3546, section 3.1
245 //
246 // struct {
247 // NameType name_type;
248 // select (name_type) {
249 // case host_name: HostName;
250 // } name;
251 // } ServerName;
252 //
253 // enum {
254 // host_name(0), (255)
255 // } NameType;
256 //
257 // opaque HostName<1..2^16-1>;
258 //
259 // struct {
260 // ServerName server_name_list<1..2^16-1>
261 // } ServerNameList;
262
Nick Harper8dda5cc2016-06-30 18:51:11 -0400263 serverName := serverNameList.addU16LengthPrefixed()
264 serverName.addU8(0) // NameType host_name(0)
265 hostName := serverName.addU16LengthPrefixed()
266 hostName.addBytes([]byte(m.serverName))
Adam Langley95c29f32014-06-20 12:00:00 -0700267 }
268 if m.ocspStapling {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400269 extensions.addU16(extensionStatusRequest)
270 certificateStatusRequest := extensions.addU16LengthPrefixed()
271
Adam Langley95c29f32014-06-20 12:00:00 -0700272 // RFC 4366, section 3.6
Nick Harper8dda5cc2016-06-30 18:51:11 -0400273 certificateStatusRequest.addU8(1) // OCSP type
Adam Langley95c29f32014-06-20 12:00:00 -0700274 // Two zero valued uint16s for the two lengths.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400275 certificateStatusRequest.addU16(0) // ResponderID length
276 certificateStatusRequest.addU16(0) // Extensions length
Adam Langley95c29f32014-06-20 12:00:00 -0700277 }
278 if len(m.supportedCurves) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400279 // http://tools.ietf.org/html/rfc4492#section-5.1.1
280 extensions.addU16(extensionSupportedCurves)
281 supportedCurvesList := extensions.addU16LengthPrefixed()
282 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700283 for _, curve := range m.supportedCurves {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400284 supportedCurves.addU16(uint16(curve))
Adam Langley95c29f32014-06-20 12:00:00 -0700285 }
286 }
287 if len(m.supportedPoints) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400288 // http://tools.ietf.org/html/rfc4492#section-5.1.2
289 extensions.addU16(extensionSupportedPoints)
290 supportedPointsList := extensions.addU16LengthPrefixed()
291 supportedPoints := supportedPointsList.addU8LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700292 for _, pointFormat := range m.supportedPoints {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400293 supportedPoints.addU8(pointFormat)
Adam Langley95c29f32014-06-20 12:00:00 -0700294 }
295 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200296 if m.hasKeyShares {
Nick Harperf8b0e702016-06-30 19:59:01 -0400297 extensions.addU16(extensionKeyShare)
298 keyShareList := extensions.addU16LengthPrefixed()
299
300 keyShares := keyShareList.addU16LengthPrefixed()
301 for _, keyShare := range m.keyShares {
302 keyShares.addU16(uint16(keyShare.group))
303 keyExchange := keyShares.addU16LengthPrefixed()
304 keyExchange.addBytes(keyShare.keyExchange)
305 }
David Benjamin7e1f9842016-09-20 19:24:40 -0400306
307 if m.trailingKeyShareData {
308 keyShares.addU8(0)
309 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400310 }
311 if len(m.pskIdentities) > 0 {
312 extensions.addU16(extensionPreSharedKey)
313 pskExtension := extensions.addU16LengthPrefixed()
314
315 pskIdentities := pskExtension.addU16LengthPrefixed()
316 for _, psk := range m.pskIdentities {
317 pskIdentity := pskIdentities.addU16LengthPrefixed()
318 pskIdentity.addBytes(psk)
319 }
320 }
321 if m.hasEarlyData {
322 extensions.addU16(extensionEarlyData)
323 earlyDataIndication := extensions.addU16LengthPrefixed()
324
325 context := earlyDataIndication.addU8LengthPrefixed()
326 context.addBytes(m.earlyDataContext)
327 }
Adam Langley95c29f32014-06-20 12:00:00 -0700328 if m.ticketSupported {
329 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400330 extensions.addU16(extensionSessionTicket)
331 sessionTicketExtension := extensions.addU16LengthPrefixed()
332 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700333 }
Nick Harper60edffd2016-06-21 15:19:24 -0700334 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700335 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400336 extensions.addU16(extensionSignatureAlgorithms)
337 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
338 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700339 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400340 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700341 }
342 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700343 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400344 extensions.addU16(extensionRenegotiationInfo)
345 secureRenegoExt := extensions.addU16LengthPrefixed()
346 secureRenego := secureRenegoExt.addU8LengthPrefixed()
347 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700348 }
David Benjaminfa055a22014-09-15 16:51:51 -0400349 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400350 // https://tools.ietf.org/html/rfc7301#section-3.1
351 extensions.addU16(extensionALPN)
352 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400353
Nick Harper8dda5cc2016-06-30 18:51:11 -0400354 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400355 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400356 protocolName := protocolNameList.addU8LengthPrefixed()
357 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400358 }
David Benjaminfa055a22014-09-15 16:51:51 -0400359 }
David Benjamind30a9902014-08-24 01:44:23 -0400360 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400361 extensions.addU16(extensionChannelID)
362 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400363 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400364 if m.nextProtoNeg && m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400365 extensions.addU16(extensionNextProtoNeg)
366 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400367 }
David Benjamin35a7a442014-07-05 00:23:20 -0400368 if m.duplicateExtension {
369 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400370 extensions.addU16(0xffff)
371 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400372 }
Adam Langley75712922014-10-10 16:23:43 -0700373 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500374 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400375 extensions.addU16(extensionExtendedMasterSecret)
376 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700377 }
David Benjaminca6c8262014-11-15 19:06:08 -0500378 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400379 // https://tools.ietf.org/html/rfc5764#section-4.1.1
380 extensions.addU16(extensionUseSRTP)
381 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500382
Nick Harper8dda5cc2016-06-30 18:51:11 -0400383 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500384 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400385 // An SRTPProtectionProfile is defined as uint8[2],
386 // not uint16. For some reason, we're storing it
387 // as a uint16.
388 srtpProtectionProfiles.addU8(byte(p >> 8))
389 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500390 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400391 srtpMki := useSrtpExt.addU8LengthPrefixed()
392 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500393 }
David Benjamin61f95272014-11-25 01:55:35 -0500394 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400395 extensions.addU16(extensionSignedCertificateTimestamp)
396 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500397 }
Adam Langley09505632015-07-30 18:10:13 -0700398 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400399 extensions.addU16(extensionCustom)
400 customExt := extensions.addU16LengthPrefixed()
401 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700402 }
Nick Harper4d90c102016-07-17 10:53:26 +0200403 if m.vers == VersionTLS13 {
404 extensions.addU16(extensionTLS13Draft)
405 extValue := extensions.addU16LengthPrefixed()
406 extValue.addU16(tls13DraftVersion)
407 }
Adam Langley95c29f32014-06-20 12:00:00 -0700408
Nick Harper8dda5cc2016-06-30 18:51:11 -0400409 if extensions.len() == 0 {
410 hello.discardChild()
411 }
Adam Langley95c29f32014-06-20 12:00:00 -0700412
Nick Harper8dda5cc2016-06-30 18:51:11 -0400413 m.raw = handshakeMsg.finish()
414 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700415}
416
417func (m *clientHelloMsg) unmarshal(data []byte) bool {
418 if len(data) < 42 {
419 return false
420 }
421 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400422 m.vers = uint16(data[4])<<8 | uint16(data[5])
Adam Langley95c29f32014-06-20 12:00:00 -0700423 m.random = data[6:38]
424 sessionIdLen := int(data[38])
425 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
426 return false
427 }
428 m.sessionId = data[39 : 39+sessionIdLen]
429 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400430 if m.isDTLS {
431 if len(data) < 1 {
432 return false
433 }
434 cookieLen := int(data[0])
435 if cookieLen > 32 || len(data) < 1+cookieLen {
436 return false
437 }
438 m.cookie = data[1 : 1+cookieLen]
439 data = data[1+cookieLen:]
440 }
Adam Langley95c29f32014-06-20 12:00:00 -0700441 if len(data) < 2 {
442 return false
443 }
444 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
445 // they are uint16s, the number must be even.
446 cipherSuiteLen := int(data[0])<<8 | int(data[1])
447 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
448 return false
449 }
450 numCipherSuites := cipherSuiteLen / 2
451 m.cipherSuites = make([]uint16, numCipherSuites)
452 for i := 0; i < numCipherSuites; i++ {
453 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
454 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700455 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700456 }
457 }
458 data = data[2+cipherSuiteLen:]
459 if len(data) < 1 {
460 return false
461 }
462 compressionMethodsLen := int(data[0])
463 if len(data) < 1+compressionMethodsLen {
464 return false
465 }
466 m.compressionMethods = data[1 : 1+compressionMethodsLen]
467
468 data = data[1+compressionMethodsLen:]
469
470 m.nextProtoNeg = false
471 m.serverName = ""
472 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400473 m.keyShares = nil
474 m.pskIdentities = nil
475 m.hasEarlyData = false
476 m.earlyDataContext = nil
Adam Langley95c29f32014-06-20 12:00:00 -0700477 m.ticketSupported = false
478 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700479 m.signatureAlgorithms = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400480 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700481 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700482 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700483
484 if len(data) == 0 {
485 // ClientHello is optionally followed by extension data
486 return true
487 }
488 if len(data) < 2 {
489 return false
490 }
491
492 extensionsLength := int(data[0])<<8 | int(data[1])
493 data = data[2:]
494 if extensionsLength != len(data) {
495 return false
496 }
497
498 for len(data) != 0 {
499 if len(data) < 4 {
500 return false
501 }
502 extension := uint16(data[0])<<8 | uint16(data[1])
503 length := int(data[2])<<8 | int(data[3])
504 data = data[4:]
505 if len(data) < length {
506 return false
507 }
508
509 switch extension {
510 case extensionServerName:
511 if length < 2 {
512 return false
513 }
514 numNames := int(data[0])<<8 | int(data[1])
515 d := data[2:]
516 for i := 0; i < numNames; i++ {
517 if len(d) < 3 {
518 return false
519 }
520 nameType := d[0]
521 nameLen := int(d[1])<<8 | int(d[2])
522 d = d[3:]
523 if len(d) < nameLen {
524 return false
525 }
526 if nameType == 0 {
527 m.serverName = string(d[0:nameLen])
528 break
529 }
530 d = d[nameLen:]
531 }
532 case extensionNextProtoNeg:
533 if length > 0 {
534 return false
535 }
536 m.nextProtoNeg = true
537 case extensionStatusRequest:
538 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
539 case extensionSupportedCurves:
540 // http://tools.ietf.org/html/rfc4492#section-5.5.1
541 if length < 2 {
542 return false
543 }
544 l := int(data[0])<<8 | int(data[1])
545 if l%2 == 1 || length != l+2 {
546 return false
547 }
548 numCurves := l / 2
549 m.supportedCurves = make([]CurveID, numCurves)
550 d := data[2:]
551 for i := 0; i < numCurves; i++ {
552 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
553 d = d[2:]
554 }
555 case extensionSupportedPoints:
556 // http://tools.ietf.org/html/rfc4492#section-5.5.2
557 if length < 1 {
558 return false
559 }
560 l := int(data[0])
561 if length != l+1 {
562 return false
563 }
564 m.supportedPoints = make([]uint8, l)
565 copy(m.supportedPoints, data[1:])
566 case extensionSessionTicket:
567 // http://tools.ietf.org/html/rfc5077#section-3.2
568 m.ticketSupported = true
569 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400570 case extensionKeyShare:
571 // draft-ietf-tls-tls13 section 6.3.2.3
572 if length < 2 {
573 return false
574 }
575 l := int(data[0])<<8 | int(data[1])
576 if l != length-2 {
577 return false
578 }
579 d := data[2:length]
Nick Harperdcfbc672016-07-16 17:47:31 +0200580 m.hasKeyShares = true
Nick Harperf8b0e702016-06-30 19:59:01 -0400581 for len(d) > 0 {
582 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
583 // key_exchange (2-byte length prefix with at least 1 byte of content).
584 if len(d) < 5 {
585 return false
586 }
587 entry := keyShareEntry{}
588 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
589 keyExchLen := int(d[2])<<8 | int(d[3])
590 d = d[4:]
591 if len(d) < keyExchLen {
592 return false
593 }
594 entry.keyExchange = d[:keyExchLen]
595 d = d[keyExchLen:]
596 m.keyShares = append(m.keyShares, entry)
597 }
598 case extensionPreSharedKey:
599 // draft-ietf-tls-tls13 section 6.3.2.4
600 if length < 2 {
601 return false
602 }
603 l := int(data[0])<<8 | int(data[1])
604 if l != length-2 {
605 return false
606 }
607 d := data[2:length]
608 for len(d) > 0 {
609 if len(d) < 2 {
610 return false
611 }
612 pskLen := int(d[0])<<8 | int(d[1])
613 d = d[2:]
614 if len(d) < pskLen {
615 return false
616 }
617 psk := d[:pskLen]
618 m.pskIdentities = append(m.pskIdentities, psk)
619 d = d[pskLen:]
620 }
621 case extensionEarlyData:
622 // draft-ietf-tls-tls13 section 6.3.2.5
623 if length < 1 {
624 return false
625 }
626 l := int(data[0])
627 if length != l+1 {
628 return false
629 }
630 m.hasEarlyData = true
631 m.earlyDataContext = data[1:length]
Adam Langley95c29f32014-06-20 12:00:00 -0700632 case extensionSignatureAlgorithms:
633 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
634 if length < 2 || length&1 != 0 {
635 return false
636 }
637 l := int(data[0])<<8 | int(data[1])
638 if l != length-2 {
639 return false
640 }
641 n := l / 2
642 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700643 m.signatureAlgorithms = make([]signatureAlgorithm, n)
644 for i := range m.signatureAlgorithms {
645 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700646 d = d[2:]
647 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700648 case extensionRenegotiationInfo:
649 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700650 return false
651 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700652 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400653 case extensionALPN:
654 if length < 2 {
655 return false
656 }
657 l := int(data[0])<<8 | int(data[1])
658 if l != length-2 {
659 return false
660 }
661 d := data[2:length]
662 for len(d) != 0 {
663 stringLen := int(d[0])
664 d = d[1:]
665 if stringLen == 0 || stringLen > len(d) {
666 return false
667 }
668 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
669 d = d[stringLen:]
670 }
David Benjamind30a9902014-08-24 01:44:23 -0400671 case extensionChannelID:
672 if length > 0 {
673 return false
674 }
675 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700676 case extensionExtendedMasterSecret:
677 if length != 0 {
678 return false
679 }
680 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500681 case extensionUseSRTP:
682 if length < 2 {
683 return false
684 }
685 l := int(data[0])<<8 | int(data[1])
686 if l > length-2 || l%2 != 0 {
687 return false
688 }
689 n := l / 2
690 m.srtpProtectionProfiles = make([]uint16, n)
691 d := data[2:length]
692 for i := 0; i < n; i++ {
693 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
694 d = d[2:]
695 }
696 if len(d) < 1 || int(d[0]) != len(d)-1 {
697 return false
698 }
699 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500700 case extensionSignedCertificateTimestamp:
701 if length != 0 {
702 return false
703 }
704 m.sctListSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700705 case extensionCustom:
706 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700707 }
708 data = data[length:]
David Benjamin65ac9972016-09-02 21:35:25 -0400709
710 if isGREASEValue(extension) {
711 m.hasGREASEExtension = true
712 }
Adam Langley95c29f32014-06-20 12:00:00 -0700713 }
714
715 return true
716}
717
718type serverHelloMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -0400719 raw []byte
720 isDTLS bool
721 vers uint16
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400722 versOverride uint16
Nick Harperb41d2e42016-07-01 17:50:32 -0400723 random []byte
724 sessionId []byte
725 cipherSuite uint16
726 hasKeyShare bool
727 keyShare keyShareEntry
728 hasPSKIdentity bool
729 pskIdentity uint16
730 earlyDataIndication bool
731 compressionMethod uint8
732 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700733}
734
Adam Langley95c29f32014-06-20 12:00:00 -0700735func (m *serverHelloMsg) marshal() []byte {
736 if m.raw != nil {
737 return m.raw
738 }
739
Nick Harper5212ef82016-06-30 19:26:07 -0400740 handshakeMsg := newByteBuilder()
741 handshakeMsg.addU8(typeServerHello)
742 hello := handshakeMsg.addU24LengthPrefixed()
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400743
744 // m.vers is used both to determine the format of the rest of the
745 // ServerHello and to override the value, so include a second version
746 // field.
747 vers, ok := wireToVersion(m.vers, m.isDTLS)
748 if !ok {
749 panic("unknown version")
750 }
751 if m.versOverride != 0 {
752 hello.addU16(m.versOverride)
753 } else {
754 hello.addU16(m.vers)
755 }
756
Nick Harper5212ef82016-06-30 19:26:07 -0400757 hello.addBytes(m.random)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400758 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400759 sessionId := hello.addU8LengthPrefixed()
760 sessionId.addBytes(m.sessionId)
761 }
Nick Harper5212ef82016-06-30 19:26:07 -0400762 hello.addU16(m.cipherSuite)
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400763 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400764 hello.addU8(m.compressionMethod)
765 }
Adam Langley95c29f32014-06-20 12:00:00 -0700766
Nick Harper5212ef82016-06-30 19:26:07 -0400767 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400768
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400769 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400770 if m.hasKeyShare {
771 extensions.addU16(extensionKeyShare)
772 keyShare := extensions.addU16LengthPrefixed()
773 keyShare.addU16(uint16(m.keyShare.group))
774 keyExchange := keyShare.addU16LengthPrefixed()
775 keyExchange.addBytes(m.keyShare.keyExchange)
776 }
777 if m.hasPSKIdentity {
778 extensions.addU16(extensionPreSharedKey)
779 extensions.addU16(2) // Length
780 extensions.addU16(m.pskIdentity)
781 }
782 if m.earlyDataIndication {
783 extensions.addU16(extensionEarlyData)
784 extensions.addU16(0) // Length
785 }
786 } else {
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400787 m.extensions.marshal(extensions, vers)
Nick Harperb41d2e42016-07-01 17:50:32 -0400788 if extensions.len() == 0 {
789 hello.discardChild()
790 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400791 }
792
793 m.raw = handshakeMsg.finish()
794 return m.raw
795}
796
797func (m *serverHelloMsg) unmarshal(data []byte) bool {
798 if len(data) < 42 {
799 return false
800 }
801 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400802 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjaminb1dd8cd2016-09-26 19:20:48 -0400803 vers, ok := wireToVersion(m.vers, m.isDTLS)
804 if !ok {
805 return false
806 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400807 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400808 data = data[38:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400809 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400810 sessionIdLen := int(data[0])
811 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
812 return false
813 }
814 m.sessionId = data[1 : 1+sessionIdLen]
815 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400816 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400817 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400818 return false
819 }
820 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400821 data = data[2:]
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400822 if vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400823 if len(data) < 1 {
824 return false
825 }
826 m.compressionMethod = data[0]
827 data = data[1:]
828 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400829
David Benjamin8d315d72016-07-18 01:03:18 +0200830 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400831 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400832 m.extensions = serverExtensions{}
833 return true
834 }
835 if len(data) < 2 {
836 return false
837 }
838
839 extensionsLength := int(data[0])<<8 | int(data[1])
840 data = data[2:]
841 if len(data) != extensionsLength {
842 return false
843 }
844
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400845 if vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400846 for len(data) != 0 {
847 if len(data) < 4 {
848 return false
849 }
850 extension := uint16(data[0])<<8 | uint16(data[1])
851 length := int(data[2])<<8 | int(data[3])
852 data = data[4:]
853
854 if len(data) < length {
855 return false
856 }
857 d := data[:length]
858 data = data[length:]
859
860 switch extension {
861 case extensionKeyShare:
862 m.hasKeyShare = true
863 if len(d) < 4 {
864 return false
865 }
866 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
867 keyExchLen := int(d[2])<<8 | int(d[3])
868 if keyExchLen != len(d)-4 {
869 return false
870 }
871 m.keyShare.keyExchange = make([]byte, keyExchLen)
872 copy(m.keyShare.keyExchange, d[4:])
873 case extensionPreSharedKey:
874 if len(d) != 2 {
875 return false
876 }
877 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
878 m.hasPSKIdentity = true
879 case extensionEarlyData:
880 if len(d) != 0 {
881 return false
882 }
883 m.earlyDataIndication = true
884 default:
885 // Only allow the 3 extensions that are sent in
886 // the clear in TLS 1.3.
887 return false
888 }
889 }
David Benjamin3c6a1ea2016-09-26 18:30:05 -0400890 } else if !m.extensions.unmarshal(data, vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -0400891 return false
892 }
893
894 return true
895}
896
Nick Harperb41d2e42016-07-01 17:50:32 -0400897type encryptedExtensionsMsg struct {
898 raw []byte
899 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -0400900 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -0400901}
902
903func (m *encryptedExtensionsMsg) marshal() []byte {
904 if m.raw != nil {
905 return m.raw
906 }
907
908 encryptedExtensionsMsg := newByteBuilder()
909 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
910 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -0400911 if !m.empty {
912 extensions := encryptedExtensions.addU16LengthPrefixed()
913 m.extensions.marshal(extensions, VersionTLS13)
914 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400915
916 m.raw = encryptedExtensionsMsg.finish()
917 return m.raw
918}
919
920func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -0400921 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -0400922 if len(data) < 6 {
923 return false
924 }
925 if data[0] != typeEncryptedExtensions {
926 return false
927 }
928 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
929 data = data[4:]
930 if len(data) != msgLen {
931 return false
932 }
933 extLen := int(data[0])<<8 | int(data[1])
934 data = data[2:]
935 if extLen != len(data) {
936 return false
937 }
David Benjamin44b33bc2016-07-01 22:40:23 -0400938 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -0400939}
940
Nick Harperb3d51be2016-07-01 11:43:18 -0400941type serverExtensions struct {
942 nextProtoNeg bool
943 nextProtos []string
944 ocspStapling bool
David Benjamin44b33bc2016-07-01 22:40:23 -0400945 ocspResponse []byte
Nick Harperb3d51be2016-07-01 11:43:18 -0400946 ticketSupported bool
947 secureRenegotiation []byte
948 alpnProtocol string
949 alpnProtocolEmpty bool
950 duplicateExtension bool
951 channelIDRequested bool
952 extendedMasterSecret bool
953 srtpProtectionProfile uint16
954 srtpMasterKeyIdentifier string
955 sctList []byte
956 customExtension string
957 npnLast bool
Steven Valdez143e8b32016-07-11 13:19:03 -0400958 hasKeyShare bool
959 keyShare keyShareEntry
Nick Harperb3d51be2016-07-01 11:43:18 -0400960}
961
David Benjamin44b33bc2016-07-01 22:40:23 -0400962func (m *serverExtensions) marshal(extensions *byteBuilder, version uint16) {
David Benjamin35a7a442014-07-05 00:23:20 -0400963 if m.duplicateExtension {
964 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -0400965 extensions.addU16(0xffff)
966 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400967 }
David Benjamin76c2efc2015-08-31 14:24:29 -0400968 if m.nextProtoNeg && !m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -0400969 extensions.addU16(extensionNextProtoNeg)
970 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700971
972 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -0400973 if len(v) > 255 {
974 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -0700975 }
Nick Harper5212ef82016-06-30 19:26:07 -0400976 npn := extension.addU8LengthPrefixed()
977 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -0700978 }
979 }
David Benjamin8d315d72016-07-18 01:03:18 +0200980 if version >= VersionTLS13 {
David Benjamin44b33bc2016-07-01 22:40:23 -0400981 if m.ocspResponse != nil {
982 extensions.addU16(extensionStatusRequest)
983 body := extensions.addU16LengthPrefixed()
984 body.addU8(statusTypeOCSP)
985 response := body.addU24LengthPrefixed()
986 response.addBytes(m.ocspResponse)
987 }
988 } else {
989 if m.ocspStapling {
990 extensions.addU16(extensionStatusRequest)
991 extensions.addU16(0)
992 }
Adam Langley95c29f32014-06-20 12:00:00 -0700993 }
994 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -0400995 extensions.addU16(extensionSessionTicket)
996 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -0700997 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700998 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -0400999 extensions.addU16(extensionRenegotiationInfo)
1000 extension := extensions.addU16LengthPrefixed()
1001 secureRenego := extension.addU8LengthPrefixed()
1002 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -07001003 }
Nick Harper5212ef82016-06-30 19:26:07 -04001004 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
1005 extensions.addU16(extensionALPN)
1006 extension := extensions.addU16LengthPrefixed()
1007
1008 protocolNameList := extension.addU16LengthPrefixed()
1009 protocolName := protocolNameList.addU8LengthPrefixed()
1010 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -04001011 }
David Benjamind30a9902014-08-24 01:44:23 -04001012 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -04001013 extensions.addU16(extensionChannelID)
1014 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -04001015 }
David Benjamin35a7a442014-07-05 00:23:20 -04001016 if m.duplicateExtension {
1017 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001018 extensions.addU16(0xffff)
1019 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -04001020 }
Adam Langley75712922014-10-10 16:23:43 -07001021 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -04001022 extensions.addU16(extensionExtendedMasterSecret)
1023 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -07001024 }
David Benjaminca6c8262014-11-15 19:06:08 -05001025 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001026 extensions.addU16(extensionUseSRTP)
1027 extension := extensions.addU16LengthPrefixed()
1028
1029 srtpProtectionProfiles := extension.addU16LengthPrefixed()
1030 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
1031 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
1032 srtpMki := extension.addU8LengthPrefixed()
1033 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -05001034 }
David Benjamin61f95272014-11-25 01:55:35 -05001035 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001036 extensions.addU16(extensionSignedCertificateTimestamp)
1037 extension := extensions.addU16LengthPrefixed()
1038 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -05001039 }
Adam Langley09505632015-07-30 18:10:13 -07001040 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001041 extensions.addU16(extensionCustom)
1042 customExt := extensions.addU16LengthPrefixed()
1043 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -07001044 }
David Benjamin76c2efc2015-08-31 14:24:29 -04001045 if m.nextProtoNeg && m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -04001046 extensions.addU16(extensionNextProtoNeg)
1047 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -04001048
1049 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001050 if len(v) > 255 {
1051 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -04001052 }
Nick Harper5212ef82016-06-30 19:26:07 -04001053 npn := extension.addU8LengthPrefixed()
1054 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001055 }
1056 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001057 if m.hasKeyShare {
1058 extensions.addU16(extensionKeyShare)
1059 keyShare := extensions.addU16LengthPrefixed()
1060 keyShare.addU16(uint16(m.keyShare.group))
1061 keyExchange := keyShare.addU16LengthPrefixed()
1062 keyExchange.addBytes(m.keyShare.keyExchange)
1063 }
Adam Langley95c29f32014-06-20 12:00:00 -07001064}
1065
David Benjamin44b33bc2016-07-01 22:40:23 -04001066func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001067 // Reset all fields.
1068 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001069
1070 for len(data) != 0 {
1071 if len(data) < 4 {
1072 return false
1073 }
1074 extension := uint16(data[0])<<8 | uint16(data[1])
1075 length := int(data[2])<<8 | int(data[3])
1076 data = data[4:]
1077 if len(data) < length {
1078 return false
1079 }
1080
1081 switch extension {
1082 case extensionNextProtoNeg:
1083 m.nextProtoNeg = true
1084 d := data[:length]
1085 for len(d) > 0 {
1086 l := int(d[0])
1087 d = d[1:]
1088 if l == 0 || l > len(d) {
1089 return false
1090 }
1091 m.nextProtos = append(m.nextProtos, string(d[:l]))
1092 d = d[l:]
1093 }
1094 case extensionStatusRequest:
David Benjamin8d315d72016-07-18 01:03:18 +02001095 if version >= VersionTLS13 {
David Benjamin44b33bc2016-07-01 22:40:23 -04001096 if length < 4 {
1097 return false
1098 }
1099 d := data[:length]
1100 if d[0] != statusTypeOCSP {
1101 return false
1102 }
1103 respLen := int(d[1])<<16 | int(d[2])<<8 | int(d[3])
1104 if respLen+4 != len(d) || respLen == 0 {
1105 return false
1106 }
1107 m.ocspResponse = d[4:]
1108 } else {
1109 if length > 0 {
1110 return false
1111 }
1112 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001113 }
Adam Langley95c29f32014-06-20 12:00:00 -07001114 case extensionSessionTicket:
1115 if length > 0 {
1116 return false
1117 }
1118 m.ticketSupported = true
1119 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001120 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001121 return false
1122 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001123 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001124 case extensionALPN:
1125 d := data[:length]
1126 if len(d) < 3 {
1127 return false
1128 }
1129 l := int(d[0])<<8 | int(d[1])
1130 if l != len(d)-2 {
1131 return false
1132 }
1133 d = d[2:]
1134 l = int(d[0])
1135 if l != len(d)-1 {
1136 return false
1137 }
1138 d = d[1:]
1139 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001140 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001141 case extensionChannelID:
1142 if length > 0 {
1143 return false
1144 }
1145 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001146 case extensionExtendedMasterSecret:
1147 if length != 0 {
1148 return false
1149 }
1150 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001151 case extensionUseSRTP:
1152 if length < 2+2+1 {
1153 return false
1154 }
1155 if data[0] != 0 || data[1] != 2 {
1156 return false
1157 }
1158 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1159 d := data[4:length]
1160 l := int(d[0])
1161 if l != len(d)-1 {
1162 return false
1163 }
1164 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001165 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001166 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001167 case extensionCustom:
1168 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001169 case extensionServerName:
1170 if length != 0 {
1171 return false
1172 }
1173 // Ignore this extension from the server.
1174 case extensionSupportedPoints:
1175 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001176 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001177 return false
1178 }
1179 // Ignore this extension from the server.
David Benjamin4ee027f2016-07-17 12:34:41 +02001180 case extensionSupportedCurves:
1181 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001182 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001183 return false
1184 }
David Benjamin46f94bd2016-07-14 16:43:37 -04001185 default:
1186 // Unknown extensions are illegal from the server.
1187 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001188 }
1189 data = data[length:]
1190 }
1191
1192 return true
1193}
1194
Nick Harperdcfbc672016-07-16 17:47:31 +02001195type helloRetryRequestMsg struct {
1196 raw []byte
1197 vers uint16
1198 cipherSuite uint16
1199 selectedGroup CurveID
1200}
1201
1202func (m *helloRetryRequestMsg) marshal() []byte {
1203 if m.raw != nil {
1204 return m.raw
1205 }
1206
1207 retryRequestMsg := newByteBuilder()
1208 retryRequestMsg.addU8(typeHelloRetryRequest)
1209 retryRequest := retryRequestMsg.addU24LengthPrefixed()
1210 retryRequest.addU16(m.vers)
1211 retryRequest.addU16(m.cipherSuite)
1212 retryRequest.addU16(uint16(m.selectedGroup))
1213 // Extensions field. We have none to send.
1214 retryRequest.addU16(0)
1215
1216 m.raw = retryRequestMsg.finish()
1217 return m.raw
1218}
1219
1220func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1221 m.raw = data
1222 if len(data) < 12 {
1223 return false
1224 }
1225 m.vers = uint16(data[4])<<8 | uint16(data[5])
1226 m.cipherSuite = uint16(data[6])<<8 | uint16(data[7])
1227 m.selectedGroup = CurveID(data[8])<<8 | CurveID(data[9])
1228 extLen := int(data[10])<<8 | int(data[11])
1229 data = data[12:]
1230 if len(data) != extLen {
1231 return false
1232 }
1233 return true
1234}
1235
Adam Langley95c29f32014-06-20 12:00:00 -07001236type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001237 raw []byte
1238 hasRequestContext bool
1239 requestContext []byte
1240 certificates [][]byte
Adam Langley95c29f32014-06-20 12:00:00 -07001241}
1242
Adam Langley95c29f32014-06-20 12:00:00 -07001243func (m *certificateMsg) marshal() (x []byte) {
1244 if m.raw != nil {
1245 return m.raw
1246 }
1247
Nick Harper7e0442a2016-07-01 17:40:09 -04001248 certMsg := newByteBuilder()
1249 certMsg.addU8(typeCertificate)
1250 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001251 if m.hasRequestContext {
1252 context := certificate.addU8LengthPrefixed()
1253 context.addBytes(m.requestContext)
1254 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001255 certificateList := certificate.addU24LengthPrefixed()
1256 for _, cert := range m.certificates {
1257 certEntry := certificateList.addU24LengthPrefixed()
1258 certEntry.addBytes(cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001259 }
1260
Nick Harper7e0442a2016-07-01 17:40:09 -04001261 m.raw = certMsg.finish()
1262 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001263}
1264
1265func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001266 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001267 return false
1268 }
1269
1270 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001271 data = data[4:]
1272
1273 if m.hasRequestContext {
1274 if len(data) == 0 {
1275 return false
1276 }
1277 contextLen := int(data[0])
1278 if len(data) < 1+contextLen {
1279 return false
1280 }
1281 m.requestContext = make([]byte, contextLen)
1282 copy(m.requestContext, data[1:])
1283 data = data[1+contextLen:]
1284 }
1285
1286 if len(data) < 3 {
1287 return false
1288 }
1289 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1290 data = data[3:]
1291 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001292 return false
1293 }
1294
1295 numCerts := 0
Nick Harperb41d2e42016-07-01 17:50:32 -04001296 d := data
Adam Langley95c29f32014-06-20 12:00:00 -07001297 for certsLen > 0 {
1298 if len(d) < 4 {
1299 return false
1300 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001301 certLen := int(d[0])<<16 | int(d[1])<<8 | int(d[2])
1302 if len(d) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001303 return false
1304 }
1305 d = d[3+certLen:]
1306 certsLen -= 3 + certLen
1307 numCerts++
1308 }
1309
1310 m.certificates = make([][]byte, numCerts)
Nick Harperb41d2e42016-07-01 17:50:32 -04001311 d = data
Adam Langley95c29f32014-06-20 12:00:00 -07001312 for i := 0; i < numCerts; i++ {
1313 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
1314 m.certificates[i] = d[3 : 3+certLen]
1315 d = d[3+certLen:]
1316 }
1317
1318 return true
1319}
1320
1321type serverKeyExchangeMsg struct {
1322 raw []byte
1323 key []byte
1324}
1325
Adam Langley95c29f32014-06-20 12:00:00 -07001326func (m *serverKeyExchangeMsg) marshal() []byte {
1327 if m.raw != nil {
1328 return m.raw
1329 }
1330 length := len(m.key)
1331 x := make([]byte, length+4)
1332 x[0] = typeServerKeyExchange
1333 x[1] = uint8(length >> 16)
1334 x[2] = uint8(length >> 8)
1335 x[3] = uint8(length)
1336 copy(x[4:], m.key)
1337
1338 m.raw = x
1339 return x
1340}
1341
1342func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1343 m.raw = data
1344 if len(data) < 4 {
1345 return false
1346 }
1347 m.key = data[4:]
1348 return true
1349}
1350
1351type certificateStatusMsg struct {
1352 raw []byte
1353 statusType uint8
1354 response []byte
1355}
1356
Adam Langley95c29f32014-06-20 12:00:00 -07001357func (m *certificateStatusMsg) marshal() []byte {
1358 if m.raw != nil {
1359 return m.raw
1360 }
1361
1362 var x []byte
1363 if m.statusType == statusTypeOCSP {
1364 x = make([]byte, 4+4+len(m.response))
1365 x[0] = typeCertificateStatus
1366 l := len(m.response) + 4
1367 x[1] = byte(l >> 16)
1368 x[2] = byte(l >> 8)
1369 x[3] = byte(l)
1370 x[4] = statusTypeOCSP
1371
1372 l -= 4
1373 x[5] = byte(l >> 16)
1374 x[6] = byte(l >> 8)
1375 x[7] = byte(l)
1376 copy(x[8:], m.response)
1377 } else {
1378 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1379 }
1380
1381 m.raw = x
1382 return x
1383}
1384
1385func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1386 m.raw = data
1387 if len(data) < 5 {
1388 return false
1389 }
1390 m.statusType = data[4]
1391
1392 m.response = nil
1393 if m.statusType == statusTypeOCSP {
1394 if len(data) < 8 {
1395 return false
1396 }
1397 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1398 if uint32(len(data)) != 4+4+respLen {
1399 return false
1400 }
1401 m.response = data[8:]
1402 }
1403 return true
1404}
1405
1406type serverHelloDoneMsg struct{}
1407
Adam Langley95c29f32014-06-20 12:00:00 -07001408func (m *serverHelloDoneMsg) marshal() []byte {
1409 x := make([]byte, 4)
1410 x[0] = typeServerHelloDone
1411 return x
1412}
1413
1414func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1415 return len(data) == 4
1416}
1417
1418type clientKeyExchangeMsg struct {
1419 raw []byte
1420 ciphertext []byte
1421}
1422
Adam Langley95c29f32014-06-20 12:00:00 -07001423func (m *clientKeyExchangeMsg) marshal() []byte {
1424 if m.raw != nil {
1425 return m.raw
1426 }
1427 length := len(m.ciphertext)
1428 x := make([]byte, length+4)
1429 x[0] = typeClientKeyExchange
1430 x[1] = uint8(length >> 16)
1431 x[2] = uint8(length >> 8)
1432 x[3] = uint8(length)
1433 copy(x[4:], m.ciphertext)
1434
1435 m.raw = x
1436 return x
1437}
1438
1439func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1440 m.raw = data
1441 if len(data) < 4 {
1442 return false
1443 }
1444 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1445 if l != len(data)-4 {
1446 return false
1447 }
1448 m.ciphertext = data[4:]
1449 return true
1450}
1451
1452type finishedMsg struct {
1453 raw []byte
1454 verifyData []byte
1455}
1456
Adam Langley95c29f32014-06-20 12:00:00 -07001457func (m *finishedMsg) marshal() (x []byte) {
1458 if m.raw != nil {
1459 return m.raw
1460 }
1461
1462 x = make([]byte, 4+len(m.verifyData))
1463 x[0] = typeFinished
1464 x[3] = byte(len(m.verifyData))
1465 copy(x[4:], m.verifyData)
1466 m.raw = x
1467 return
1468}
1469
1470func (m *finishedMsg) unmarshal(data []byte) bool {
1471 m.raw = data
1472 if len(data) < 4 {
1473 return false
1474 }
1475 m.verifyData = data[4:]
1476 return true
1477}
1478
1479type nextProtoMsg struct {
1480 raw []byte
1481 proto string
1482}
1483
Adam Langley95c29f32014-06-20 12:00:00 -07001484func (m *nextProtoMsg) marshal() []byte {
1485 if m.raw != nil {
1486 return m.raw
1487 }
1488 l := len(m.proto)
1489 if l > 255 {
1490 l = 255
1491 }
1492
1493 padding := 32 - (l+2)%32
1494 length := l + padding + 2
1495 x := make([]byte, length+4)
1496 x[0] = typeNextProtocol
1497 x[1] = uint8(length >> 16)
1498 x[2] = uint8(length >> 8)
1499 x[3] = uint8(length)
1500
1501 y := x[4:]
1502 y[0] = byte(l)
1503 copy(y[1:], []byte(m.proto[0:l]))
1504 y = y[1+l:]
1505 y[0] = byte(padding)
1506
1507 m.raw = x
1508
1509 return x
1510}
1511
1512func (m *nextProtoMsg) unmarshal(data []byte) bool {
1513 m.raw = data
1514
1515 if len(data) < 5 {
1516 return false
1517 }
1518 data = data[4:]
1519 protoLen := int(data[0])
1520 data = data[1:]
1521 if len(data) < protoLen {
1522 return false
1523 }
1524 m.proto = string(data[0:protoLen])
1525 data = data[protoLen:]
1526
1527 if len(data) < 1 {
1528 return false
1529 }
1530 paddingLen := int(data[0])
1531 data = data[1:]
1532 if len(data) != paddingLen {
1533 return false
1534 }
1535
1536 return true
1537}
1538
1539type certificateRequestMsg struct {
1540 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001541 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001542 // of signature and hash functions. This change was introduced with TLS
1543 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001544 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001545 // hasRequestContext indicates whether this message includes a context
1546 // field instead of certificateTypes. This change was introduced with
1547 // TLS 1.3.
1548 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001549
1550 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001551 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001552 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001553 certificateAuthorities [][]byte
1554}
1555
Nick Harper7e0442a2016-07-01 17:40:09 -04001556func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001557 if m.raw != nil {
1558 return m.raw
1559 }
1560
1561 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001562 builder := newByteBuilder()
1563 builder.addU8(typeCertificateRequest)
1564 body := builder.addU24LengthPrefixed()
1565
Nick Harperb41d2e42016-07-01 17:50:32 -04001566 if m.hasRequestContext {
1567 requestContext := body.addU8LengthPrefixed()
1568 requestContext.addBytes(m.requestContext)
1569 } else {
1570 certificateTypes := body.addU8LengthPrefixed()
1571 certificateTypes.addBytes(m.certificateTypes)
1572 }
Adam Langley95c29f32014-06-20 12:00:00 -07001573
Nick Harper60edffd2016-06-21 15:19:24 -07001574 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001575 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001576 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001577 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001578 }
1579 }
1580
Nick Harper7e0442a2016-07-01 17:40:09 -04001581 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001582 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001583 caEntry := certificateAuthorities.addU16LengthPrefixed()
1584 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001585 }
1586
David Benjamin8d343b42016-07-09 14:26:01 -07001587 if m.hasRequestContext {
1588 // Emit no certificate extensions.
1589 body.addU16(0)
1590 }
1591
Nick Harper7e0442a2016-07-01 17:40:09 -04001592 m.raw = builder.finish()
1593 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001594}
1595
1596func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1597 m.raw = data
1598
1599 if len(data) < 5 {
1600 return false
1601 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001602 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001603
Nick Harperb41d2e42016-07-01 17:50:32 -04001604 if m.hasRequestContext {
1605 contextLen := int(data[0])
1606 if len(data) < 1+contextLen {
1607 return false
1608 }
1609 m.requestContext = make([]byte, contextLen)
1610 copy(m.requestContext, data[1:])
1611 data = data[1+contextLen:]
1612 } else {
1613 numCertTypes := int(data[0])
1614 if len(data) < 1+numCertTypes {
1615 return false
1616 }
1617 m.certificateTypes = make([]byte, numCertTypes)
1618 copy(m.certificateTypes, data[1:])
1619 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001620 }
1621
Nick Harper60edffd2016-06-21 15:19:24 -07001622 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001623 if len(data) < 2 {
1624 return false
1625 }
Nick Harper60edffd2016-06-21 15:19:24 -07001626 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001627 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001628 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001629 return false
1630 }
Nick Harper60edffd2016-06-21 15:19:24 -07001631 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001632 return false
1633 }
Nick Harper60edffd2016-06-21 15:19:24 -07001634 numSigAlgs := sigAlgsLen / 2
1635 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1636 for i := range m.signatureAlgorithms {
1637 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001638 data = data[2:]
1639 }
1640 }
1641
1642 if len(data) < 2 {
1643 return false
1644 }
1645 casLength := uint16(data[0])<<8 | uint16(data[1])
1646 data = data[2:]
1647 if len(data) < int(casLength) {
1648 return false
1649 }
1650 cas := make([]byte, casLength)
1651 copy(cas, data)
1652 data = data[casLength:]
1653
1654 m.certificateAuthorities = nil
1655 for len(cas) > 0 {
1656 if len(cas) < 2 {
1657 return false
1658 }
1659 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1660 cas = cas[2:]
1661
1662 if len(cas) < int(caLen) {
1663 return false
1664 }
1665
1666 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1667 cas = cas[caLen:]
1668 }
David Benjamin8d343b42016-07-09 14:26:01 -07001669
1670 if m.hasRequestContext {
1671 // Ignore certificate extensions.
1672 if len(data) < 2 {
1673 return false
1674 }
1675 extsLength := int(data[0])<<8 | int(data[1])
1676 if len(data) < 2+extsLength {
1677 return false
1678 }
1679 data = data[2+extsLength:]
1680 }
1681
Adam Langley95c29f32014-06-20 12:00:00 -07001682 if len(data) > 0 {
1683 return false
1684 }
1685
1686 return true
1687}
1688
1689type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07001690 raw []byte
1691 hasSignatureAlgorithm bool
1692 signatureAlgorithm signatureAlgorithm
1693 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001694}
1695
Adam Langley95c29f32014-06-20 12:00:00 -07001696func (m *certificateVerifyMsg) marshal() (x []byte) {
1697 if m.raw != nil {
1698 return m.raw
1699 }
1700
1701 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1702 siglength := len(m.signature)
1703 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07001704 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001705 length += 2
1706 }
1707 x = make([]byte, 4+length)
1708 x[0] = typeCertificateVerify
1709 x[1] = uint8(length >> 16)
1710 x[2] = uint8(length >> 8)
1711 x[3] = uint8(length)
1712 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001713 if m.hasSignatureAlgorithm {
1714 y[0] = byte(m.signatureAlgorithm >> 8)
1715 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07001716 y = y[2:]
1717 }
1718 y[0] = uint8(siglength >> 8)
1719 y[1] = uint8(siglength)
1720 copy(y[2:], m.signature)
1721
1722 m.raw = x
1723
1724 return
1725}
1726
1727func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1728 m.raw = data
1729
1730 if len(data) < 6 {
1731 return false
1732 }
1733
1734 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1735 if uint32(len(data))-4 != length {
1736 return false
1737 }
1738
1739 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001740 if m.hasSignatureAlgorithm {
1741 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001742 data = data[2:]
1743 }
1744
1745 if len(data) < 2 {
1746 return false
1747 }
1748 siglength := int(data[0])<<8 + int(data[1])
1749 data = data[2:]
1750 if len(data) != siglength {
1751 return false
1752 }
1753
1754 m.signature = data
1755
1756 return true
1757}
1758
1759type newSessionTicketMsg struct {
David Benjamin58104882016-07-18 01:25:41 +02001760 raw []byte
1761 version uint16
1762 ticketLifetime uint32
1763 ticketFlags uint32
1764 ticketAgeAdd uint32
1765 ticket []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001766}
1767
David Benjamin58104882016-07-18 01:25:41 +02001768func (m *newSessionTicketMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001769 if m.raw != nil {
1770 return m.raw
1771 }
1772
1773 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjamin58104882016-07-18 01:25:41 +02001774 ticketMsg := newByteBuilder()
1775 ticketMsg.addU8(typeNewSessionTicket)
1776 body := ticketMsg.addU24LengthPrefixed()
1777 body.addU32(m.ticketLifetime)
1778 if m.version >= VersionTLS13 {
1779 body.addU32(m.ticketFlags)
1780 body.addU32(m.ticketAgeAdd)
1781 // Send no extensions.
1782 //
1783 // TODO(davidben): Add an option to send a custom extension to
1784 // test we correctly ignore unknown ones.
1785 body.addU16(0)
1786 }
1787 ticket := body.addU16LengthPrefixed()
1788 ticket.addBytes(m.ticket)
Adam Langley95c29f32014-06-20 12:00:00 -07001789
David Benjamin58104882016-07-18 01:25:41 +02001790 m.raw = ticketMsg.finish()
1791 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001792}
1793
1794func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
1795 m.raw = data
1796
David Benjamin58104882016-07-18 01:25:41 +02001797 if len(data) < 8 {
1798 return false
1799 }
1800 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1801 data = data[8:]
1802
1803 if m.version >= VersionTLS13 {
1804 if len(data) < 10 {
1805 return false
1806 }
1807 m.ticketFlags = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1808 m.ticketAgeAdd = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1809 extsLength := int(data[8])<<8 + int(data[9])
1810 data = data[10:]
1811 if len(data) < extsLength {
1812 return false
1813 }
1814 data = data[extsLength:]
1815 }
1816
1817 if len(data) < 2 {
1818 return false
1819 }
1820 ticketLen := int(data[0])<<8 + int(data[1])
1821 if len(data)-2 != ticketLen {
1822 return false
1823 }
1824 if m.version >= VersionTLS13 && ticketLen == 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001825 return false
1826 }
1827
David Benjamin58104882016-07-18 01:25:41 +02001828 m.ticket = data[2:]
Adam Langley95c29f32014-06-20 12:00:00 -07001829
1830 return true
1831}
1832
David Benjamind86c7672014-08-02 04:07:12 -04001833type v2ClientHelloMsg struct {
1834 raw []byte
1835 vers uint16
1836 cipherSuites []uint16
1837 sessionId []byte
1838 challenge []byte
1839}
1840
David Benjamind86c7672014-08-02 04:07:12 -04001841func (m *v2ClientHelloMsg) marshal() []byte {
1842 if m.raw != nil {
1843 return m.raw
1844 }
1845
1846 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
1847
1848 x := make([]byte, length)
1849 x[0] = 1
1850 x[1] = uint8(m.vers >> 8)
1851 x[2] = uint8(m.vers)
1852 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
1853 x[4] = uint8(len(m.cipherSuites) * 3)
1854 x[5] = uint8(len(m.sessionId) >> 8)
1855 x[6] = uint8(len(m.sessionId))
1856 x[7] = uint8(len(m.challenge) >> 8)
1857 x[8] = uint8(len(m.challenge))
1858 y := x[9:]
1859 for i, spec := range m.cipherSuites {
1860 y[i*3] = 0
1861 y[i*3+1] = uint8(spec >> 8)
1862 y[i*3+2] = uint8(spec)
1863 }
1864 y = y[len(m.cipherSuites)*3:]
1865 copy(y, m.sessionId)
1866 y = y[len(m.sessionId):]
1867 copy(y, m.challenge)
1868
1869 m.raw = x
1870
1871 return x
1872}
1873
David Benjamin83c0bc92014-08-04 01:23:53 -04001874type helloVerifyRequestMsg struct {
1875 raw []byte
1876 vers uint16
1877 cookie []byte
1878}
1879
David Benjamin83c0bc92014-08-04 01:23:53 -04001880func (m *helloVerifyRequestMsg) marshal() []byte {
1881 if m.raw != nil {
1882 return m.raw
1883 }
1884
1885 length := 2 + 1 + len(m.cookie)
1886
1887 x := make([]byte, 4+length)
1888 x[0] = typeHelloVerifyRequest
1889 x[1] = uint8(length >> 16)
1890 x[2] = uint8(length >> 8)
1891 x[3] = uint8(length)
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001892 vers := m.vers
David Benjamin83c0bc92014-08-04 01:23:53 -04001893 x[4] = uint8(vers >> 8)
1894 x[5] = uint8(vers)
1895 x[6] = uint8(len(m.cookie))
1896 copy(x[7:7+len(m.cookie)], m.cookie)
1897
1898 return x
1899}
1900
1901func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
1902 if len(data) < 4+2+1 {
1903 return false
1904 }
1905 m.raw = data
David Benjamin3c6a1ea2016-09-26 18:30:05 -04001906 m.vers = uint16(data[4])<<8 | uint16(data[5])
David Benjamin83c0bc92014-08-04 01:23:53 -04001907 cookieLen := int(data[6])
1908 if cookieLen > 32 || len(data) != 7+cookieLen {
1909 return false
1910 }
1911 m.cookie = data[7 : 7+cookieLen]
1912
1913 return true
1914}
1915
David Benjamin24599a82016-06-30 18:56:53 -04001916type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04001917 raw []byte
1918 channelID []byte
1919}
1920
David Benjamin24599a82016-06-30 18:56:53 -04001921func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04001922 if m.raw != nil {
1923 return m.raw
1924 }
1925
1926 length := 2 + 2 + len(m.channelID)
1927
1928 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04001929 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04001930 x[1] = uint8(length >> 16)
1931 x[2] = uint8(length >> 8)
1932 x[3] = uint8(length)
1933 x[4] = uint8(extensionChannelID >> 8)
1934 x[5] = uint8(extensionChannelID & 0xff)
1935 x[6] = uint8(len(m.channelID) >> 8)
1936 x[7] = uint8(len(m.channelID) & 0xff)
1937 copy(x[8:], m.channelID)
1938
1939 return x
1940}
1941
David Benjamin24599a82016-06-30 18:56:53 -04001942func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04001943 if len(data) != 4+2+2+128 {
1944 return false
1945 }
1946 m.raw = data
1947 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
1948 return false
1949 }
1950 if int(data[6])<<8|int(data[7]) != 128 {
1951 return false
1952 }
1953 m.channelID = data[4+2+2:]
1954
1955 return true
1956}
1957
Adam Langley2ae77d22014-10-28 17:29:33 -07001958type helloRequestMsg struct {
1959}
1960
1961func (*helloRequestMsg) marshal() []byte {
1962 return []byte{typeHelloRequest, 0, 0, 0}
1963}
1964
1965func (*helloRequestMsg) unmarshal(data []byte) bool {
1966 return len(data) == 4
1967}
1968
David Benjamin21c00282016-07-18 21:56:23 +02001969type keyUpdateMsg struct {
1970}
1971
1972func (*keyUpdateMsg) marshal() []byte {
1973 return []byte{typeKeyUpdate, 0, 0, 0}
1974}
1975
1976func (*keyUpdateMsg) unmarshal(data []byte) bool {
1977 return len(data) == 4
1978}
1979
Adam Langley95c29f32014-06-20 12:00:00 -07001980func eqUint16s(x, y []uint16) bool {
1981 if len(x) != len(y) {
1982 return false
1983 }
1984 for i, v := range x {
1985 if y[i] != v {
1986 return false
1987 }
1988 }
1989 return true
1990}
1991
1992func eqCurveIDs(x, y []CurveID) bool {
1993 if len(x) != len(y) {
1994 return false
1995 }
1996 for i, v := range x {
1997 if y[i] != v {
1998 return false
1999 }
2000 }
2001 return true
2002}
2003
2004func eqStrings(x, y []string) bool {
2005 if len(x) != len(y) {
2006 return false
2007 }
2008 for i, v := range x {
2009 if y[i] != v {
2010 return false
2011 }
2012 }
2013 return true
2014}
2015
2016func eqByteSlices(x, y [][]byte) bool {
2017 if len(x) != len(y) {
2018 return false
2019 }
2020 for i, v := range x {
2021 if !bytes.Equal(v, y[i]) {
2022 return false
2023 }
2024 }
2025 return true
2026}
2027
Nick Harper60edffd2016-06-21 15:19:24 -07002028func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07002029 if len(x) != len(y) {
2030 return false
2031 }
2032 for i, v := range x {
2033 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07002034 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07002035 return false
2036 }
2037 }
2038 return true
2039}
Nick Harperf8b0e702016-06-30 19:59:01 -04002040
2041func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2042 if len(x) != len(y) {
2043 return false
2044 }
2045 for i, v := range x {
2046 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2047 return false
2048 }
2049 }
2050 return true
2051
2052}