blob: 8cec98b1157907d3af1aede6c2eed858ebc46759 [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 Benjamin83c0bc92014-08-04 01:23:53 -0400215 vers := versionToWire(m.vers, m.isDTLS)
Nick Harper8dda5cc2016-06-30 18:51:11 -0400216 hello.addU16(vers)
217 hello.addBytes(m.random)
218 sessionId := hello.addU8LengthPrefixed()
219 sessionId.addBytes(m.sessionId)
David Benjamin83c0bc92014-08-04 01:23:53 -0400220 if m.isDTLS {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400221 cookie := hello.addU8LengthPrefixed()
222 cookie.addBytes(m.cookie)
David Benjamin83c0bc92014-08-04 01:23:53 -0400223 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400224 cipherSuites := hello.addU16LengthPrefixed()
225 for _, suite := range m.cipherSuites {
226 cipherSuites.addU16(suite)
Adam Langley95c29f32014-06-20 12:00:00 -0700227 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400228 compressionMethods := hello.addU8LengthPrefixed()
229 compressionMethods.addBytes(m.compressionMethods)
Adam Langley95c29f32014-06-20 12:00:00 -0700230
Nick Harper8dda5cc2016-06-30 18:51:11 -0400231 extensions := hello.addU16LengthPrefixed()
David Benjamin35a7a442014-07-05 00:23:20 -0400232 if m.duplicateExtension {
233 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400234 extensions.addU16(0xffff)
235 extensions.addU16(0) // 0-length for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400236 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400237 if m.nextProtoNeg && !m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400238 extensions.addU16(extensionNextProtoNeg)
239 extensions.addU16(0) // The length is always 0
Adam Langley95c29f32014-06-20 12:00:00 -0700240 }
241 if len(m.serverName) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400242 extensions.addU16(extensionServerName)
243 serverNameList := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700244
245 // RFC 3546, section 3.1
246 //
247 // struct {
248 // NameType name_type;
249 // select (name_type) {
250 // case host_name: HostName;
251 // } name;
252 // } ServerName;
253 //
254 // enum {
255 // host_name(0), (255)
256 // } NameType;
257 //
258 // opaque HostName<1..2^16-1>;
259 //
260 // struct {
261 // ServerName server_name_list<1..2^16-1>
262 // } ServerNameList;
263
Nick Harper8dda5cc2016-06-30 18:51:11 -0400264 serverName := serverNameList.addU16LengthPrefixed()
265 serverName.addU8(0) // NameType host_name(0)
266 hostName := serverName.addU16LengthPrefixed()
267 hostName.addBytes([]byte(m.serverName))
Adam Langley95c29f32014-06-20 12:00:00 -0700268 }
269 if m.ocspStapling {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400270 extensions.addU16(extensionStatusRequest)
271 certificateStatusRequest := extensions.addU16LengthPrefixed()
272
Adam Langley95c29f32014-06-20 12:00:00 -0700273 // RFC 4366, section 3.6
Nick Harper8dda5cc2016-06-30 18:51:11 -0400274 certificateStatusRequest.addU8(1) // OCSP type
Adam Langley95c29f32014-06-20 12:00:00 -0700275 // Two zero valued uint16s for the two lengths.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400276 certificateStatusRequest.addU16(0) // ResponderID length
277 certificateStatusRequest.addU16(0) // Extensions length
Adam Langley95c29f32014-06-20 12:00:00 -0700278 }
279 if len(m.supportedCurves) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400280 // http://tools.ietf.org/html/rfc4492#section-5.1.1
281 extensions.addU16(extensionSupportedCurves)
282 supportedCurvesList := extensions.addU16LengthPrefixed()
283 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700284 for _, curve := range m.supportedCurves {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400285 supportedCurves.addU16(uint16(curve))
Adam Langley95c29f32014-06-20 12:00:00 -0700286 }
287 }
288 if len(m.supportedPoints) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400289 // http://tools.ietf.org/html/rfc4492#section-5.1.2
290 extensions.addU16(extensionSupportedPoints)
291 supportedPointsList := extensions.addU16LengthPrefixed()
292 supportedPoints := supportedPointsList.addU8LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700293 for _, pointFormat := range m.supportedPoints {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400294 supportedPoints.addU8(pointFormat)
Adam Langley95c29f32014-06-20 12:00:00 -0700295 }
296 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200297 if m.hasKeyShares {
Nick Harperf8b0e702016-06-30 19:59:01 -0400298 extensions.addU16(extensionKeyShare)
299 keyShareList := extensions.addU16LengthPrefixed()
300
301 keyShares := keyShareList.addU16LengthPrefixed()
302 for _, keyShare := range m.keyShares {
303 keyShares.addU16(uint16(keyShare.group))
304 keyExchange := keyShares.addU16LengthPrefixed()
305 keyExchange.addBytes(keyShare.keyExchange)
306 }
David Benjamin7e1f9842016-09-20 19:24:40 -0400307
308 if m.trailingKeyShareData {
309 keyShares.addU8(0)
310 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400311 }
312 if len(m.pskIdentities) > 0 {
313 extensions.addU16(extensionPreSharedKey)
314 pskExtension := extensions.addU16LengthPrefixed()
315
316 pskIdentities := pskExtension.addU16LengthPrefixed()
317 for _, psk := range m.pskIdentities {
318 pskIdentity := pskIdentities.addU16LengthPrefixed()
319 pskIdentity.addBytes(psk)
320 }
321 }
322 if m.hasEarlyData {
323 extensions.addU16(extensionEarlyData)
324 earlyDataIndication := extensions.addU16LengthPrefixed()
325
326 context := earlyDataIndication.addU8LengthPrefixed()
327 context.addBytes(m.earlyDataContext)
328 }
Adam Langley95c29f32014-06-20 12:00:00 -0700329 if m.ticketSupported {
330 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400331 extensions.addU16(extensionSessionTicket)
332 sessionTicketExtension := extensions.addU16LengthPrefixed()
333 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700334 }
Nick Harper60edffd2016-06-21 15:19:24 -0700335 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700336 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400337 extensions.addU16(extensionSignatureAlgorithms)
338 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
339 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700340 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400341 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700342 }
343 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700344 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400345 extensions.addU16(extensionRenegotiationInfo)
346 secureRenegoExt := extensions.addU16LengthPrefixed()
347 secureRenego := secureRenegoExt.addU8LengthPrefixed()
348 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700349 }
David Benjaminfa055a22014-09-15 16:51:51 -0400350 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400351 // https://tools.ietf.org/html/rfc7301#section-3.1
352 extensions.addU16(extensionALPN)
353 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400354
Nick Harper8dda5cc2016-06-30 18:51:11 -0400355 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400356 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400357 protocolName := protocolNameList.addU8LengthPrefixed()
358 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400359 }
David Benjaminfa055a22014-09-15 16:51:51 -0400360 }
David Benjamind30a9902014-08-24 01:44:23 -0400361 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400362 extensions.addU16(extensionChannelID)
363 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400364 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400365 if m.nextProtoNeg && m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400366 extensions.addU16(extensionNextProtoNeg)
367 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400368 }
David Benjamin35a7a442014-07-05 00:23:20 -0400369 if m.duplicateExtension {
370 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400371 extensions.addU16(0xffff)
372 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400373 }
Adam Langley75712922014-10-10 16:23:43 -0700374 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500375 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400376 extensions.addU16(extensionExtendedMasterSecret)
377 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700378 }
David Benjaminca6c8262014-11-15 19:06:08 -0500379 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400380 // https://tools.ietf.org/html/rfc5764#section-4.1.1
381 extensions.addU16(extensionUseSRTP)
382 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500383
Nick Harper8dda5cc2016-06-30 18:51:11 -0400384 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500385 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400386 // An SRTPProtectionProfile is defined as uint8[2],
387 // not uint16. For some reason, we're storing it
388 // as a uint16.
389 srtpProtectionProfiles.addU8(byte(p >> 8))
390 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500391 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400392 srtpMki := useSrtpExt.addU8LengthPrefixed()
393 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500394 }
David Benjamin61f95272014-11-25 01:55:35 -0500395 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400396 extensions.addU16(extensionSignedCertificateTimestamp)
397 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500398 }
Adam Langley09505632015-07-30 18:10:13 -0700399 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400400 extensions.addU16(extensionCustom)
401 customExt := extensions.addU16LengthPrefixed()
402 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700403 }
Nick Harper4d90c102016-07-17 10:53:26 +0200404 if m.vers == VersionTLS13 {
405 extensions.addU16(extensionTLS13Draft)
406 extValue := extensions.addU16LengthPrefixed()
407 extValue.addU16(tls13DraftVersion)
408 }
Adam Langley95c29f32014-06-20 12:00:00 -0700409
Nick Harper8dda5cc2016-06-30 18:51:11 -0400410 if extensions.len() == 0 {
411 hello.discardChild()
412 }
Adam Langley95c29f32014-06-20 12:00:00 -0700413
Nick Harper8dda5cc2016-06-30 18:51:11 -0400414 m.raw = handshakeMsg.finish()
415 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700416}
417
418func (m *clientHelloMsg) unmarshal(data []byte) bool {
419 if len(data) < 42 {
420 return false
421 }
422 m.raw = data
David Benjamin83c0bc92014-08-04 01:23:53 -0400423 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
Adam Langley95c29f32014-06-20 12:00:00 -0700424 m.random = data[6:38]
425 sessionIdLen := int(data[38])
426 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
427 return false
428 }
429 m.sessionId = data[39 : 39+sessionIdLen]
430 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400431 if m.isDTLS {
432 if len(data) < 1 {
433 return false
434 }
435 cookieLen := int(data[0])
436 if cookieLen > 32 || len(data) < 1+cookieLen {
437 return false
438 }
439 m.cookie = data[1 : 1+cookieLen]
440 data = data[1+cookieLen:]
441 }
Adam Langley95c29f32014-06-20 12:00:00 -0700442 if len(data) < 2 {
443 return false
444 }
445 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
446 // they are uint16s, the number must be even.
447 cipherSuiteLen := int(data[0])<<8 | int(data[1])
448 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
449 return false
450 }
451 numCipherSuites := cipherSuiteLen / 2
452 m.cipherSuites = make([]uint16, numCipherSuites)
453 for i := 0; i < numCipherSuites; i++ {
454 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
455 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700456 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700457 }
458 }
459 data = data[2+cipherSuiteLen:]
460 if len(data) < 1 {
461 return false
462 }
463 compressionMethodsLen := int(data[0])
464 if len(data) < 1+compressionMethodsLen {
465 return false
466 }
467 m.compressionMethods = data[1 : 1+compressionMethodsLen]
468
469 data = data[1+compressionMethodsLen:]
470
471 m.nextProtoNeg = false
472 m.serverName = ""
473 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400474 m.keyShares = nil
475 m.pskIdentities = nil
476 m.hasEarlyData = false
477 m.earlyDataContext = nil
Adam Langley95c29f32014-06-20 12:00:00 -0700478 m.ticketSupported = false
479 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700480 m.signatureAlgorithms = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400481 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700482 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700483 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700484
485 if len(data) == 0 {
486 // ClientHello is optionally followed by extension data
487 return true
488 }
489 if len(data) < 2 {
490 return false
491 }
492
493 extensionsLength := int(data[0])<<8 | int(data[1])
494 data = data[2:]
495 if extensionsLength != len(data) {
496 return false
497 }
498
499 for len(data) != 0 {
500 if len(data) < 4 {
501 return false
502 }
503 extension := uint16(data[0])<<8 | uint16(data[1])
504 length := int(data[2])<<8 | int(data[3])
505 data = data[4:]
506 if len(data) < length {
507 return false
508 }
509
510 switch extension {
511 case extensionServerName:
512 if length < 2 {
513 return false
514 }
515 numNames := int(data[0])<<8 | int(data[1])
516 d := data[2:]
517 for i := 0; i < numNames; i++ {
518 if len(d) < 3 {
519 return false
520 }
521 nameType := d[0]
522 nameLen := int(d[1])<<8 | int(d[2])
523 d = d[3:]
524 if len(d) < nameLen {
525 return false
526 }
527 if nameType == 0 {
528 m.serverName = string(d[0:nameLen])
529 break
530 }
531 d = d[nameLen:]
532 }
533 case extensionNextProtoNeg:
534 if length > 0 {
535 return false
536 }
537 m.nextProtoNeg = true
538 case extensionStatusRequest:
539 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
540 case extensionSupportedCurves:
541 // http://tools.ietf.org/html/rfc4492#section-5.5.1
542 if length < 2 {
543 return false
544 }
545 l := int(data[0])<<8 | int(data[1])
546 if l%2 == 1 || length != l+2 {
547 return false
548 }
549 numCurves := l / 2
550 m.supportedCurves = make([]CurveID, numCurves)
551 d := data[2:]
552 for i := 0; i < numCurves; i++ {
553 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
554 d = d[2:]
555 }
556 case extensionSupportedPoints:
557 // http://tools.ietf.org/html/rfc4492#section-5.5.2
558 if length < 1 {
559 return false
560 }
561 l := int(data[0])
562 if length != l+1 {
563 return false
564 }
565 m.supportedPoints = make([]uint8, l)
566 copy(m.supportedPoints, data[1:])
567 case extensionSessionTicket:
568 // http://tools.ietf.org/html/rfc5077#section-3.2
569 m.ticketSupported = true
570 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400571 case extensionKeyShare:
572 // draft-ietf-tls-tls13 section 6.3.2.3
573 if length < 2 {
574 return false
575 }
576 l := int(data[0])<<8 | int(data[1])
577 if l != length-2 {
578 return false
579 }
580 d := data[2:length]
Nick Harperdcfbc672016-07-16 17:47:31 +0200581 m.hasKeyShares = true
Nick Harperf8b0e702016-06-30 19:59:01 -0400582 for len(d) > 0 {
583 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
584 // key_exchange (2-byte length prefix with at least 1 byte of content).
585 if len(d) < 5 {
586 return false
587 }
588 entry := keyShareEntry{}
589 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
590 keyExchLen := int(d[2])<<8 | int(d[3])
591 d = d[4:]
592 if len(d) < keyExchLen {
593 return false
594 }
595 entry.keyExchange = d[:keyExchLen]
596 d = d[keyExchLen:]
597 m.keyShares = append(m.keyShares, entry)
598 }
599 case extensionPreSharedKey:
600 // draft-ietf-tls-tls13 section 6.3.2.4
601 if length < 2 {
602 return false
603 }
604 l := int(data[0])<<8 | int(data[1])
605 if l != length-2 {
606 return false
607 }
608 d := data[2:length]
609 for len(d) > 0 {
610 if len(d) < 2 {
611 return false
612 }
613 pskLen := int(d[0])<<8 | int(d[1])
614 d = d[2:]
615 if len(d) < pskLen {
616 return false
617 }
618 psk := d[:pskLen]
619 m.pskIdentities = append(m.pskIdentities, psk)
620 d = d[pskLen:]
621 }
622 case extensionEarlyData:
623 // draft-ietf-tls-tls13 section 6.3.2.5
624 if length < 1 {
625 return false
626 }
627 l := int(data[0])
628 if length != l+1 {
629 return false
630 }
631 m.hasEarlyData = true
632 m.earlyDataContext = data[1:length]
Adam Langley95c29f32014-06-20 12:00:00 -0700633 case extensionSignatureAlgorithms:
634 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
635 if length < 2 || length&1 != 0 {
636 return false
637 }
638 l := int(data[0])<<8 | int(data[1])
639 if l != length-2 {
640 return false
641 }
642 n := l / 2
643 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700644 m.signatureAlgorithms = make([]signatureAlgorithm, n)
645 for i := range m.signatureAlgorithms {
646 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700647 d = d[2:]
648 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700649 case extensionRenegotiationInfo:
650 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700651 return false
652 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700653 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400654 case extensionALPN:
655 if length < 2 {
656 return false
657 }
658 l := int(data[0])<<8 | int(data[1])
659 if l != length-2 {
660 return false
661 }
662 d := data[2:length]
663 for len(d) != 0 {
664 stringLen := int(d[0])
665 d = d[1:]
666 if stringLen == 0 || stringLen > len(d) {
667 return false
668 }
669 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
670 d = d[stringLen:]
671 }
David Benjamind30a9902014-08-24 01:44:23 -0400672 case extensionChannelID:
673 if length > 0 {
674 return false
675 }
676 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700677 case extensionExtendedMasterSecret:
678 if length != 0 {
679 return false
680 }
681 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500682 case extensionUseSRTP:
683 if length < 2 {
684 return false
685 }
686 l := int(data[0])<<8 | int(data[1])
687 if l > length-2 || l%2 != 0 {
688 return false
689 }
690 n := l / 2
691 m.srtpProtectionProfiles = make([]uint16, n)
692 d := data[2:length]
693 for i := 0; i < n; i++ {
694 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
695 d = d[2:]
696 }
697 if len(d) < 1 || int(d[0]) != len(d)-1 {
698 return false
699 }
700 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500701 case extensionSignedCertificateTimestamp:
702 if length != 0 {
703 return false
704 }
705 m.sctListSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700706 case extensionCustom:
707 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700708 }
709 data = data[length:]
David Benjamin65ac9972016-09-02 21:35:25 -0400710
711 if isGREASEValue(extension) {
712 m.hasGREASEExtension = true
713 }
Adam Langley95c29f32014-06-20 12:00:00 -0700714 }
715
716 return true
717}
718
719type serverHelloMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -0400720 raw []byte
721 isDTLS bool
722 vers uint16
723 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 Benjamin83c0bc92014-08-04 01:23:53 -0400743 vers := versionToWire(m.vers, m.isDTLS)
Nick Harper5212ef82016-06-30 19:26:07 -0400744 hello.addU16(vers)
745 hello.addBytes(m.random)
David Benjamin8d315d72016-07-18 01:03:18 +0200746 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400747 sessionId := hello.addU8LengthPrefixed()
748 sessionId.addBytes(m.sessionId)
749 }
Nick Harper5212ef82016-06-30 19:26:07 -0400750 hello.addU16(m.cipherSuite)
David Benjamin8d315d72016-07-18 01:03:18 +0200751 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400752 hello.addU8(m.compressionMethod)
753 }
Adam Langley95c29f32014-06-20 12:00:00 -0700754
Nick Harper5212ef82016-06-30 19:26:07 -0400755 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400756
David Benjamin8d315d72016-07-18 01:03:18 +0200757 if m.vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400758 if m.hasKeyShare {
759 extensions.addU16(extensionKeyShare)
760 keyShare := extensions.addU16LengthPrefixed()
761 keyShare.addU16(uint16(m.keyShare.group))
762 keyExchange := keyShare.addU16LengthPrefixed()
763 keyExchange.addBytes(m.keyShare.keyExchange)
764 }
765 if m.hasPSKIdentity {
766 extensions.addU16(extensionPreSharedKey)
767 extensions.addU16(2) // Length
768 extensions.addU16(m.pskIdentity)
769 }
770 if m.earlyDataIndication {
771 extensions.addU16(extensionEarlyData)
772 extensions.addU16(0) // Length
773 }
774 } else {
David Benjamin44b33bc2016-07-01 22:40:23 -0400775 m.extensions.marshal(extensions, m.vers)
Nick Harperb41d2e42016-07-01 17:50:32 -0400776 if extensions.len() == 0 {
777 hello.discardChild()
778 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400779 }
780
781 m.raw = handshakeMsg.finish()
782 return m.raw
783}
784
785func (m *serverHelloMsg) unmarshal(data []byte) bool {
786 if len(data) < 42 {
787 return false
788 }
789 m.raw = data
790 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
791 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400792 data = data[38:]
David Benjamin8d315d72016-07-18 01:03:18 +0200793 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400794 sessionIdLen := int(data[0])
795 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
796 return false
797 }
798 m.sessionId = data[1 : 1+sessionIdLen]
799 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400800 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400801 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400802 return false
803 }
804 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400805 data = data[2:]
David Benjamin8d315d72016-07-18 01:03:18 +0200806 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400807 if len(data) < 1 {
808 return false
809 }
810 m.compressionMethod = data[0]
811 data = data[1:]
812 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400813
David Benjamin8d315d72016-07-18 01:03:18 +0200814 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400815 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400816 m.extensions = serverExtensions{}
817 return true
818 }
819 if len(data) < 2 {
820 return false
821 }
822
823 extensionsLength := int(data[0])<<8 | int(data[1])
824 data = data[2:]
825 if len(data) != extensionsLength {
826 return false
827 }
828
David Benjamin8d315d72016-07-18 01:03:18 +0200829 if m.vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400830 for len(data) != 0 {
831 if len(data) < 4 {
832 return false
833 }
834 extension := uint16(data[0])<<8 | uint16(data[1])
835 length := int(data[2])<<8 | int(data[3])
836 data = data[4:]
837
838 if len(data) < length {
839 return false
840 }
841 d := data[:length]
842 data = data[length:]
843
844 switch extension {
845 case extensionKeyShare:
846 m.hasKeyShare = true
847 if len(d) < 4 {
848 return false
849 }
850 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
851 keyExchLen := int(d[2])<<8 | int(d[3])
852 if keyExchLen != len(d)-4 {
853 return false
854 }
855 m.keyShare.keyExchange = make([]byte, keyExchLen)
856 copy(m.keyShare.keyExchange, d[4:])
857 case extensionPreSharedKey:
858 if len(d) != 2 {
859 return false
860 }
861 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
862 m.hasPSKIdentity = true
863 case extensionEarlyData:
864 if len(d) != 0 {
865 return false
866 }
867 m.earlyDataIndication = true
868 default:
869 // Only allow the 3 extensions that are sent in
870 // the clear in TLS 1.3.
871 return false
872 }
873 }
David Benjamin44b33bc2016-07-01 22:40:23 -0400874 } else if !m.extensions.unmarshal(data, m.vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -0400875 return false
876 }
877
878 return true
879}
880
Nick Harperb41d2e42016-07-01 17:50:32 -0400881type encryptedExtensionsMsg struct {
882 raw []byte
883 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -0400884 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -0400885}
886
887func (m *encryptedExtensionsMsg) marshal() []byte {
888 if m.raw != nil {
889 return m.raw
890 }
891
892 encryptedExtensionsMsg := newByteBuilder()
893 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
894 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -0400895 if !m.empty {
896 extensions := encryptedExtensions.addU16LengthPrefixed()
897 m.extensions.marshal(extensions, VersionTLS13)
898 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400899
900 m.raw = encryptedExtensionsMsg.finish()
901 return m.raw
902}
903
904func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -0400905 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -0400906 if len(data) < 6 {
907 return false
908 }
909 if data[0] != typeEncryptedExtensions {
910 return false
911 }
912 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
913 data = data[4:]
914 if len(data) != msgLen {
915 return false
916 }
917 extLen := int(data[0])<<8 | int(data[1])
918 data = data[2:]
919 if extLen != len(data) {
920 return false
921 }
David Benjamin44b33bc2016-07-01 22:40:23 -0400922 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -0400923}
924
Nick Harperb3d51be2016-07-01 11:43:18 -0400925type serverExtensions struct {
926 nextProtoNeg bool
927 nextProtos []string
928 ocspStapling bool
David Benjamin44b33bc2016-07-01 22:40:23 -0400929 ocspResponse []byte
Nick Harperb3d51be2016-07-01 11:43:18 -0400930 ticketSupported bool
931 secureRenegotiation []byte
932 alpnProtocol string
933 alpnProtocolEmpty bool
934 duplicateExtension bool
935 channelIDRequested bool
936 extendedMasterSecret bool
937 srtpProtectionProfile uint16
938 srtpMasterKeyIdentifier string
939 sctList []byte
940 customExtension string
941 npnLast bool
Steven Valdez143e8b32016-07-11 13:19:03 -0400942 hasKeyShare bool
943 keyShare keyShareEntry
Nick Harperb3d51be2016-07-01 11:43:18 -0400944}
945
David Benjamin44b33bc2016-07-01 22:40:23 -0400946func (m *serverExtensions) marshal(extensions *byteBuilder, version uint16) {
David Benjamin35a7a442014-07-05 00:23:20 -0400947 if m.duplicateExtension {
948 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -0400949 extensions.addU16(0xffff)
950 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400951 }
David Benjamin76c2efc2015-08-31 14:24:29 -0400952 if m.nextProtoNeg && !m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -0400953 extensions.addU16(extensionNextProtoNeg)
954 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700955
956 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -0400957 if len(v) > 255 {
958 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -0700959 }
Nick Harper5212ef82016-06-30 19:26:07 -0400960 npn := extension.addU8LengthPrefixed()
961 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -0700962 }
963 }
David Benjamin8d315d72016-07-18 01:03:18 +0200964 if version >= VersionTLS13 {
David Benjamin44b33bc2016-07-01 22:40:23 -0400965 if m.ocspResponse != nil {
966 extensions.addU16(extensionStatusRequest)
967 body := extensions.addU16LengthPrefixed()
968 body.addU8(statusTypeOCSP)
969 response := body.addU24LengthPrefixed()
970 response.addBytes(m.ocspResponse)
971 }
972 } else {
973 if m.ocspStapling {
974 extensions.addU16(extensionStatusRequest)
975 extensions.addU16(0)
976 }
Adam Langley95c29f32014-06-20 12:00:00 -0700977 }
978 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -0400979 extensions.addU16(extensionSessionTicket)
980 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -0700981 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700982 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -0400983 extensions.addU16(extensionRenegotiationInfo)
984 extension := extensions.addU16LengthPrefixed()
985 secureRenego := extension.addU8LengthPrefixed()
986 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700987 }
Nick Harper5212ef82016-06-30 19:26:07 -0400988 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
989 extensions.addU16(extensionALPN)
990 extension := extensions.addU16LengthPrefixed()
991
992 protocolNameList := extension.addU16LengthPrefixed()
993 protocolName := protocolNameList.addU8LengthPrefixed()
994 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -0400995 }
David Benjamind30a9902014-08-24 01:44:23 -0400996 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -0400997 extensions.addU16(extensionChannelID)
998 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -0400999 }
David Benjamin35a7a442014-07-05 00:23:20 -04001000 if m.duplicateExtension {
1001 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -04001002 extensions.addU16(0xffff)
1003 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -04001004 }
Adam Langley75712922014-10-10 16:23:43 -07001005 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -04001006 extensions.addU16(extensionExtendedMasterSecret)
1007 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -07001008 }
David Benjaminca6c8262014-11-15 19:06:08 -05001009 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001010 extensions.addU16(extensionUseSRTP)
1011 extension := extensions.addU16LengthPrefixed()
1012
1013 srtpProtectionProfiles := extension.addU16LengthPrefixed()
1014 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
1015 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
1016 srtpMki := extension.addU8LengthPrefixed()
1017 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -05001018 }
David Benjamin61f95272014-11-25 01:55:35 -05001019 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -04001020 extensions.addU16(extensionSignedCertificateTimestamp)
1021 extension := extensions.addU16LengthPrefixed()
1022 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -05001023 }
Adam Langley09505632015-07-30 18:10:13 -07001024 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -04001025 extensions.addU16(extensionCustom)
1026 customExt := extensions.addU16LengthPrefixed()
1027 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -07001028 }
David Benjamin76c2efc2015-08-31 14:24:29 -04001029 if m.nextProtoNeg && m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -04001030 extensions.addU16(extensionNextProtoNeg)
1031 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -04001032
1033 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001034 if len(v) > 255 {
1035 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -04001036 }
Nick Harper5212ef82016-06-30 19:26:07 -04001037 npn := extension.addU8LengthPrefixed()
1038 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001039 }
1040 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001041 if m.hasKeyShare {
1042 extensions.addU16(extensionKeyShare)
1043 keyShare := extensions.addU16LengthPrefixed()
1044 keyShare.addU16(uint16(m.keyShare.group))
1045 keyExchange := keyShare.addU16LengthPrefixed()
1046 keyExchange.addBytes(m.keyShare.keyExchange)
1047 }
Adam Langley95c29f32014-06-20 12:00:00 -07001048}
1049
David Benjamin44b33bc2016-07-01 22:40:23 -04001050func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001051 // Reset all fields.
1052 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001053
1054 for len(data) != 0 {
1055 if len(data) < 4 {
1056 return false
1057 }
1058 extension := uint16(data[0])<<8 | uint16(data[1])
1059 length := int(data[2])<<8 | int(data[3])
1060 data = data[4:]
1061 if len(data) < length {
1062 return false
1063 }
1064
1065 switch extension {
1066 case extensionNextProtoNeg:
1067 m.nextProtoNeg = true
1068 d := data[:length]
1069 for len(d) > 0 {
1070 l := int(d[0])
1071 d = d[1:]
1072 if l == 0 || l > len(d) {
1073 return false
1074 }
1075 m.nextProtos = append(m.nextProtos, string(d[:l]))
1076 d = d[l:]
1077 }
1078 case extensionStatusRequest:
David Benjamin8d315d72016-07-18 01:03:18 +02001079 if version >= VersionTLS13 {
David Benjamin44b33bc2016-07-01 22:40:23 -04001080 if length < 4 {
1081 return false
1082 }
1083 d := data[:length]
1084 if d[0] != statusTypeOCSP {
1085 return false
1086 }
1087 respLen := int(d[1])<<16 | int(d[2])<<8 | int(d[3])
1088 if respLen+4 != len(d) || respLen == 0 {
1089 return false
1090 }
1091 m.ocspResponse = d[4:]
1092 } else {
1093 if length > 0 {
1094 return false
1095 }
1096 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001097 }
Adam Langley95c29f32014-06-20 12:00:00 -07001098 case extensionSessionTicket:
1099 if length > 0 {
1100 return false
1101 }
1102 m.ticketSupported = true
1103 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001104 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001105 return false
1106 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001107 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001108 case extensionALPN:
1109 d := data[:length]
1110 if len(d) < 3 {
1111 return false
1112 }
1113 l := int(d[0])<<8 | int(d[1])
1114 if l != len(d)-2 {
1115 return false
1116 }
1117 d = d[2:]
1118 l = int(d[0])
1119 if l != len(d)-1 {
1120 return false
1121 }
1122 d = d[1:]
1123 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001124 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001125 case extensionChannelID:
1126 if length > 0 {
1127 return false
1128 }
1129 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001130 case extensionExtendedMasterSecret:
1131 if length != 0 {
1132 return false
1133 }
1134 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001135 case extensionUseSRTP:
1136 if length < 2+2+1 {
1137 return false
1138 }
1139 if data[0] != 0 || data[1] != 2 {
1140 return false
1141 }
1142 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1143 d := data[4:length]
1144 l := int(d[0])
1145 if l != len(d)-1 {
1146 return false
1147 }
1148 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001149 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001150 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001151 case extensionCustom:
1152 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001153 case extensionServerName:
1154 if length != 0 {
1155 return false
1156 }
1157 // Ignore this extension from the server.
1158 case extensionSupportedPoints:
1159 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001160 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001161 return false
1162 }
1163 // Ignore this extension from the server.
David Benjamin4ee027f2016-07-17 12:34:41 +02001164 case extensionSupportedCurves:
1165 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001166 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001167 return false
1168 }
David Benjamin46f94bd2016-07-14 16:43:37 -04001169 default:
1170 // Unknown extensions are illegal from the server.
1171 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001172 }
1173 data = data[length:]
1174 }
1175
1176 return true
1177}
1178
Nick Harperdcfbc672016-07-16 17:47:31 +02001179type helloRetryRequestMsg struct {
1180 raw []byte
1181 vers uint16
1182 cipherSuite uint16
1183 selectedGroup CurveID
1184}
1185
1186func (m *helloRetryRequestMsg) marshal() []byte {
1187 if m.raw != nil {
1188 return m.raw
1189 }
1190
1191 retryRequestMsg := newByteBuilder()
1192 retryRequestMsg.addU8(typeHelloRetryRequest)
1193 retryRequest := retryRequestMsg.addU24LengthPrefixed()
1194 retryRequest.addU16(m.vers)
1195 retryRequest.addU16(m.cipherSuite)
1196 retryRequest.addU16(uint16(m.selectedGroup))
1197 // Extensions field. We have none to send.
1198 retryRequest.addU16(0)
1199
1200 m.raw = retryRequestMsg.finish()
1201 return m.raw
1202}
1203
1204func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1205 m.raw = data
1206 if len(data) < 12 {
1207 return false
1208 }
1209 m.vers = uint16(data[4])<<8 | uint16(data[5])
1210 m.cipherSuite = uint16(data[6])<<8 | uint16(data[7])
1211 m.selectedGroup = CurveID(data[8])<<8 | CurveID(data[9])
1212 extLen := int(data[10])<<8 | int(data[11])
1213 data = data[12:]
1214 if len(data) != extLen {
1215 return false
1216 }
1217 return true
1218}
1219
Adam Langley95c29f32014-06-20 12:00:00 -07001220type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001221 raw []byte
1222 hasRequestContext bool
1223 requestContext []byte
1224 certificates [][]byte
Adam Langley95c29f32014-06-20 12:00:00 -07001225}
1226
Adam Langley95c29f32014-06-20 12:00:00 -07001227func (m *certificateMsg) marshal() (x []byte) {
1228 if m.raw != nil {
1229 return m.raw
1230 }
1231
Nick Harper7e0442a2016-07-01 17:40:09 -04001232 certMsg := newByteBuilder()
1233 certMsg.addU8(typeCertificate)
1234 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001235 if m.hasRequestContext {
1236 context := certificate.addU8LengthPrefixed()
1237 context.addBytes(m.requestContext)
1238 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001239 certificateList := certificate.addU24LengthPrefixed()
1240 for _, cert := range m.certificates {
1241 certEntry := certificateList.addU24LengthPrefixed()
1242 certEntry.addBytes(cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001243 }
1244
Nick Harper7e0442a2016-07-01 17:40:09 -04001245 m.raw = certMsg.finish()
1246 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001247}
1248
1249func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001250 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001251 return false
1252 }
1253
1254 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001255 data = data[4:]
1256
1257 if m.hasRequestContext {
1258 if len(data) == 0 {
1259 return false
1260 }
1261 contextLen := int(data[0])
1262 if len(data) < 1+contextLen {
1263 return false
1264 }
1265 m.requestContext = make([]byte, contextLen)
1266 copy(m.requestContext, data[1:])
1267 data = data[1+contextLen:]
1268 }
1269
1270 if len(data) < 3 {
1271 return false
1272 }
1273 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1274 data = data[3:]
1275 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001276 return false
1277 }
1278
1279 numCerts := 0
Nick Harperb41d2e42016-07-01 17:50:32 -04001280 d := data
Adam Langley95c29f32014-06-20 12:00:00 -07001281 for certsLen > 0 {
1282 if len(d) < 4 {
1283 return false
1284 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001285 certLen := int(d[0])<<16 | int(d[1])<<8 | int(d[2])
1286 if len(d) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001287 return false
1288 }
1289 d = d[3+certLen:]
1290 certsLen -= 3 + certLen
1291 numCerts++
1292 }
1293
1294 m.certificates = make([][]byte, numCerts)
Nick Harperb41d2e42016-07-01 17:50:32 -04001295 d = data
Adam Langley95c29f32014-06-20 12:00:00 -07001296 for i := 0; i < numCerts; i++ {
1297 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
1298 m.certificates[i] = d[3 : 3+certLen]
1299 d = d[3+certLen:]
1300 }
1301
1302 return true
1303}
1304
1305type serverKeyExchangeMsg struct {
1306 raw []byte
1307 key []byte
1308}
1309
Adam Langley95c29f32014-06-20 12:00:00 -07001310func (m *serverKeyExchangeMsg) marshal() []byte {
1311 if m.raw != nil {
1312 return m.raw
1313 }
1314 length := len(m.key)
1315 x := make([]byte, length+4)
1316 x[0] = typeServerKeyExchange
1317 x[1] = uint8(length >> 16)
1318 x[2] = uint8(length >> 8)
1319 x[3] = uint8(length)
1320 copy(x[4:], m.key)
1321
1322 m.raw = x
1323 return x
1324}
1325
1326func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1327 m.raw = data
1328 if len(data) < 4 {
1329 return false
1330 }
1331 m.key = data[4:]
1332 return true
1333}
1334
1335type certificateStatusMsg struct {
1336 raw []byte
1337 statusType uint8
1338 response []byte
1339}
1340
Adam Langley95c29f32014-06-20 12:00:00 -07001341func (m *certificateStatusMsg) marshal() []byte {
1342 if m.raw != nil {
1343 return m.raw
1344 }
1345
1346 var x []byte
1347 if m.statusType == statusTypeOCSP {
1348 x = make([]byte, 4+4+len(m.response))
1349 x[0] = typeCertificateStatus
1350 l := len(m.response) + 4
1351 x[1] = byte(l >> 16)
1352 x[2] = byte(l >> 8)
1353 x[3] = byte(l)
1354 x[4] = statusTypeOCSP
1355
1356 l -= 4
1357 x[5] = byte(l >> 16)
1358 x[6] = byte(l >> 8)
1359 x[7] = byte(l)
1360 copy(x[8:], m.response)
1361 } else {
1362 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1363 }
1364
1365 m.raw = x
1366 return x
1367}
1368
1369func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1370 m.raw = data
1371 if len(data) < 5 {
1372 return false
1373 }
1374 m.statusType = data[4]
1375
1376 m.response = nil
1377 if m.statusType == statusTypeOCSP {
1378 if len(data) < 8 {
1379 return false
1380 }
1381 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1382 if uint32(len(data)) != 4+4+respLen {
1383 return false
1384 }
1385 m.response = data[8:]
1386 }
1387 return true
1388}
1389
1390type serverHelloDoneMsg struct{}
1391
Adam Langley95c29f32014-06-20 12:00:00 -07001392func (m *serverHelloDoneMsg) marshal() []byte {
1393 x := make([]byte, 4)
1394 x[0] = typeServerHelloDone
1395 return x
1396}
1397
1398func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1399 return len(data) == 4
1400}
1401
1402type clientKeyExchangeMsg struct {
1403 raw []byte
1404 ciphertext []byte
1405}
1406
Adam Langley95c29f32014-06-20 12:00:00 -07001407func (m *clientKeyExchangeMsg) marshal() []byte {
1408 if m.raw != nil {
1409 return m.raw
1410 }
1411 length := len(m.ciphertext)
1412 x := make([]byte, length+4)
1413 x[0] = typeClientKeyExchange
1414 x[1] = uint8(length >> 16)
1415 x[2] = uint8(length >> 8)
1416 x[3] = uint8(length)
1417 copy(x[4:], m.ciphertext)
1418
1419 m.raw = x
1420 return x
1421}
1422
1423func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1424 m.raw = data
1425 if len(data) < 4 {
1426 return false
1427 }
1428 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1429 if l != len(data)-4 {
1430 return false
1431 }
1432 m.ciphertext = data[4:]
1433 return true
1434}
1435
1436type finishedMsg struct {
1437 raw []byte
1438 verifyData []byte
1439}
1440
Adam Langley95c29f32014-06-20 12:00:00 -07001441func (m *finishedMsg) marshal() (x []byte) {
1442 if m.raw != nil {
1443 return m.raw
1444 }
1445
1446 x = make([]byte, 4+len(m.verifyData))
1447 x[0] = typeFinished
1448 x[3] = byte(len(m.verifyData))
1449 copy(x[4:], m.verifyData)
1450 m.raw = x
1451 return
1452}
1453
1454func (m *finishedMsg) unmarshal(data []byte) bool {
1455 m.raw = data
1456 if len(data) < 4 {
1457 return false
1458 }
1459 m.verifyData = data[4:]
1460 return true
1461}
1462
1463type nextProtoMsg struct {
1464 raw []byte
1465 proto string
1466}
1467
Adam Langley95c29f32014-06-20 12:00:00 -07001468func (m *nextProtoMsg) marshal() []byte {
1469 if m.raw != nil {
1470 return m.raw
1471 }
1472 l := len(m.proto)
1473 if l > 255 {
1474 l = 255
1475 }
1476
1477 padding := 32 - (l+2)%32
1478 length := l + padding + 2
1479 x := make([]byte, length+4)
1480 x[0] = typeNextProtocol
1481 x[1] = uint8(length >> 16)
1482 x[2] = uint8(length >> 8)
1483 x[3] = uint8(length)
1484
1485 y := x[4:]
1486 y[0] = byte(l)
1487 copy(y[1:], []byte(m.proto[0:l]))
1488 y = y[1+l:]
1489 y[0] = byte(padding)
1490
1491 m.raw = x
1492
1493 return x
1494}
1495
1496func (m *nextProtoMsg) unmarshal(data []byte) bool {
1497 m.raw = data
1498
1499 if len(data) < 5 {
1500 return false
1501 }
1502 data = data[4:]
1503 protoLen := int(data[0])
1504 data = data[1:]
1505 if len(data) < protoLen {
1506 return false
1507 }
1508 m.proto = string(data[0:protoLen])
1509 data = data[protoLen:]
1510
1511 if len(data) < 1 {
1512 return false
1513 }
1514 paddingLen := int(data[0])
1515 data = data[1:]
1516 if len(data) != paddingLen {
1517 return false
1518 }
1519
1520 return true
1521}
1522
1523type certificateRequestMsg struct {
1524 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001525 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001526 // of signature and hash functions. This change was introduced with TLS
1527 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001528 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001529 // hasRequestContext indicates whether this message includes a context
1530 // field instead of certificateTypes. This change was introduced with
1531 // TLS 1.3.
1532 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001533
1534 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001535 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001536 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001537 certificateAuthorities [][]byte
1538}
1539
Nick Harper7e0442a2016-07-01 17:40:09 -04001540func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001541 if m.raw != nil {
1542 return m.raw
1543 }
1544
1545 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001546 builder := newByteBuilder()
1547 builder.addU8(typeCertificateRequest)
1548 body := builder.addU24LengthPrefixed()
1549
Nick Harperb41d2e42016-07-01 17:50:32 -04001550 if m.hasRequestContext {
1551 requestContext := body.addU8LengthPrefixed()
1552 requestContext.addBytes(m.requestContext)
1553 } else {
1554 certificateTypes := body.addU8LengthPrefixed()
1555 certificateTypes.addBytes(m.certificateTypes)
1556 }
Adam Langley95c29f32014-06-20 12:00:00 -07001557
Nick Harper60edffd2016-06-21 15:19:24 -07001558 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001559 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001560 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001561 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001562 }
1563 }
1564
Nick Harper7e0442a2016-07-01 17:40:09 -04001565 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001566 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001567 caEntry := certificateAuthorities.addU16LengthPrefixed()
1568 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001569 }
1570
David Benjamin8d343b42016-07-09 14:26:01 -07001571 if m.hasRequestContext {
1572 // Emit no certificate extensions.
1573 body.addU16(0)
1574 }
1575
Nick Harper7e0442a2016-07-01 17:40:09 -04001576 m.raw = builder.finish()
1577 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001578}
1579
1580func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1581 m.raw = data
1582
1583 if len(data) < 5 {
1584 return false
1585 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001586 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001587
Nick Harperb41d2e42016-07-01 17:50:32 -04001588 if m.hasRequestContext {
1589 contextLen := int(data[0])
1590 if len(data) < 1+contextLen {
1591 return false
1592 }
1593 m.requestContext = make([]byte, contextLen)
1594 copy(m.requestContext, data[1:])
1595 data = data[1+contextLen:]
1596 } else {
1597 numCertTypes := int(data[0])
1598 if len(data) < 1+numCertTypes {
1599 return false
1600 }
1601 m.certificateTypes = make([]byte, numCertTypes)
1602 copy(m.certificateTypes, data[1:])
1603 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001604 }
1605
Nick Harper60edffd2016-06-21 15:19:24 -07001606 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001607 if len(data) < 2 {
1608 return false
1609 }
Nick Harper60edffd2016-06-21 15:19:24 -07001610 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001611 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001612 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001613 return false
1614 }
Nick Harper60edffd2016-06-21 15:19:24 -07001615 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001616 return false
1617 }
Nick Harper60edffd2016-06-21 15:19:24 -07001618 numSigAlgs := sigAlgsLen / 2
1619 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1620 for i := range m.signatureAlgorithms {
1621 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001622 data = data[2:]
1623 }
1624 }
1625
1626 if len(data) < 2 {
1627 return false
1628 }
1629 casLength := uint16(data[0])<<8 | uint16(data[1])
1630 data = data[2:]
1631 if len(data) < int(casLength) {
1632 return false
1633 }
1634 cas := make([]byte, casLength)
1635 copy(cas, data)
1636 data = data[casLength:]
1637
1638 m.certificateAuthorities = nil
1639 for len(cas) > 0 {
1640 if len(cas) < 2 {
1641 return false
1642 }
1643 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1644 cas = cas[2:]
1645
1646 if len(cas) < int(caLen) {
1647 return false
1648 }
1649
1650 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1651 cas = cas[caLen:]
1652 }
David Benjamin8d343b42016-07-09 14:26:01 -07001653
1654 if m.hasRequestContext {
1655 // Ignore certificate extensions.
1656 if len(data) < 2 {
1657 return false
1658 }
1659 extsLength := int(data[0])<<8 | int(data[1])
1660 if len(data) < 2+extsLength {
1661 return false
1662 }
1663 data = data[2+extsLength:]
1664 }
1665
Adam Langley95c29f32014-06-20 12:00:00 -07001666 if len(data) > 0 {
1667 return false
1668 }
1669
1670 return true
1671}
1672
1673type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07001674 raw []byte
1675 hasSignatureAlgorithm bool
1676 signatureAlgorithm signatureAlgorithm
1677 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001678}
1679
Adam Langley95c29f32014-06-20 12:00:00 -07001680func (m *certificateVerifyMsg) marshal() (x []byte) {
1681 if m.raw != nil {
1682 return m.raw
1683 }
1684
1685 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1686 siglength := len(m.signature)
1687 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07001688 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001689 length += 2
1690 }
1691 x = make([]byte, 4+length)
1692 x[0] = typeCertificateVerify
1693 x[1] = uint8(length >> 16)
1694 x[2] = uint8(length >> 8)
1695 x[3] = uint8(length)
1696 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001697 if m.hasSignatureAlgorithm {
1698 y[0] = byte(m.signatureAlgorithm >> 8)
1699 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07001700 y = y[2:]
1701 }
1702 y[0] = uint8(siglength >> 8)
1703 y[1] = uint8(siglength)
1704 copy(y[2:], m.signature)
1705
1706 m.raw = x
1707
1708 return
1709}
1710
1711func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1712 m.raw = data
1713
1714 if len(data) < 6 {
1715 return false
1716 }
1717
1718 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1719 if uint32(len(data))-4 != length {
1720 return false
1721 }
1722
1723 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001724 if m.hasSignatureAlgorithm {
1725 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001726 data = data[2:]
1727 }
1728
1729 if len(data) < 2 {
1730 return false
1731 }
1732 siglength := int(data[0])<<8 + int(data[1])
1733 data = data[2:]
1734 if len(data) != siglength {
1735 return false
1736 }
1737
1738 m.signature = data
1739
1740 return true
1741}
1742
1743type newSessionTicketMsg struct {
David Benjamin58104882016-07-18 01:25:41 +02001744 raw []byte
1745 version uint16
1746 ticketLifetime uint32
1747 ticketFlags uint32
1748 ticketAgeAdd uint32
1749 ticket []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001750}
1751
David Benjamin58104882016-07-18 01:25:41 +02001752func (m *newSessionTicketMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001753 if m.raw != nil {
1754 return m.raw
1755 }
1756
1757 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjamin58104882016-07-18 01:25:41 +02001758 ticketMsg := newByteBuilder()
1759 ticketMsg.addU8(typeNewSessionTicket)
1760 body := ticketMsg.addU24LengthPrefixed()
1761 body.addU32(m.ticketLifetime)
1762 if m.version >= VersionTLS13 {
1763 body.addU32(m.ticketFlags)
1764 body.addU32(m.ticketAgeAdd)
1765 // Send no extensions.
1766 //
1767 // TODO(davidben): Add an option to send a custom extension to
1768 // test we correctly ignore unknown ones.
1769 body.addU16(0)
1770 }
1771 ticket := body.addU16LengthPrefixed()
1772 ticket.addBytes(m.ticket)
Adam Langley95c29f32014-06-20 12:00:00 -07001773
David Benjamin58104882016-07-18 01:25:41 +02001774 m.raw = ticketMsg.finish()
1775 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001776}
1777
1778func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
1779 m.raw = data
1780
David Benjamin58104882016-07-18 01:25:41 +02001781 if len(data) < 8 {
1782 return false
1783 }
1784 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1785 data = data[8:]
1786
1787 if m.version >= VersionTLS13 {
1788 if len(data) < 10 {
1789 return false
1790 }
1791 m.ticketFlags = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1792 m.ticketAgeAdd = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1793 extsLength := int(data[8])<<8 + int(data[9])
1794 data = data[10:]
1795 if len(data) < extsLength {
1796 return false
1797 }
1798 data = data[extsLength:]
1799 }
1800
1801 if len(data) < 2 {
1802 return false
1803 }
1804 ticketLen := int(data[0])<<8 + int(data[1])
1805 if len(data)-2 != ticketLen {
1806 return false
1807 }
1808 if m.version >= VersionTLS13 && ticketLen == 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001809 return false
1810 }
1811
David Benjamin58104882016-07-18 01:25:41 +02001812 m.ticket = data[2:]
Adam Langley95c29f32014-06-20 12:00:00 -07001813
1814 return true
1815}
1816
David Benjamind86c7672014-08-02 04:07:12 -04001817type v2ClientHelloMsg struct {
1818 raw []byte
1819 vers uint16
1820 cipherSuites []uint16
1821 sessionId []byte
1822 challenge []byte
1823}
1824
David Benjamind86c7672014-08-02 04:07:12 -04001825func (m *v2ClientHelloMsg) marshal() []byte {
1826 if m.raw != nil {
1827 return m.raw
1828 }
1829
1830 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
1831
1832 x := make([]byte, length)
1833 x[0] = 1
1834 x[1] = uint8(m.vers >> 8)
1835 x[2] = uint8(m.vers)
1836 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
1837 x[4] = uint8(len(m.cipherSuites) * 3)
1838 x[5] = uint8(len(m.sessionId) >> 8)
1839 x[6] = uint8(len(m.sessionId))
1840 x[7] = uint8(len(m.challenge) >> 8)
1841 x[8] = uint8(len(m.challenge))
1842 y := x[9:]
1843 for i, spec := range m.cipherSuites {
1844 y[i*3] = 0
1845 y[i*3+1] = uint8(spec >> 8)
1846 y[i*3+2] = uint8(spec)
1847 }
1848 y = y[len(m.cipherSuites)*3:]
1849 copy(y, m.sessionId)
1850 y = y[len(m.sessionId):]
1851 copy(y, m.challenge)
1852
1853 m.raw = x
1854
1855 return x
1856}
1857
David Benjamin83c0bc92014-08-04 01:23:53 -04001858type helloVerifyRequestMsg struct {
1859 raw []byte
1860 vers uint16
1861 cookie []byte
1862}
1863
David Benjamin83c0bc92014-08-04 01:23:53 -04001864func (m *helloVerifyRequestMsg) marshal() []byte {
1865 if m.raw != nil {
1866 return m.raw
1867 }
1868
1869 length := 2 + 1 + len(m.cookie)
1870
1871 x := make([]byte, 4+length)
1872 x[0] = typeHelloVerifyRequest
1873 x[1] = uint8(length >> 16)
1874 x[2] = uint8(length >> 8)
1875 x[3] = uint8(length)
1876 vers := versionToWire(m.vers, true)
1877 x[4] = uint8(vers >> 8)
1878 x[5] = uint8(vers)
1879 x[6] = uint8(len(m.cookie))
1880 copy(x[7:7+len(m.cookie)], m.cookie)
1881
1882 return x
1883}
1884
1885func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
1886 if len(data) < 4+2+1 {
1887 return false
1888 }
1889 m.raw = data
1890 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), true)
1891 cookieLen := int(data[6])
1892 if cookieLen > 32 || len(data) != 7+cookieLen {
1893 return false
1894 }
1895 m.cookie = data[7 : 7+cookieLen]
1896
1897 return true
1898}
1899
David Benjamin24599a82016-06-30 18:56:53 -04001900type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04001901 raw []byte
1902 channelID []byte
1903}
1904
David Benjamin24599a82016-06-30 18:56:53 -04001905func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04001906 if m.raw != nil {
1907 return m.raw
1908 }
1909
1910 length := 2 + 2 + len(m.channelID)
1911
1912 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04001913 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04001914 x[1] = uint8(length >> 16)
1915 x[2] = uint8(length >> 8)
1916 x[3] = uint8(length)
1917 x[4] = uint8(extensionChannelID >> 8)
1918 x[5] = uint8(extensionChannelID & 0xff)
1919 x[6] = uint8(len(m.channelID) >> 8)
1920 x[7] = uint8(len(m.channelID) & 0xff)
1921 copy(x[8:], m.channelID)
1922
1923 return x
1924}
1925
David Benjamin24599a82016-06-30 18:56:53 -04001926func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04001927 if len(data) != 4+2+2+128 {
1928 return false
1929 }
1930 m.raw = data
1931 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
1932 return false
1933 }
1934 if int(data[6])<<8|int(data[7]) != 128 {
1935 return false
1936 }
1937 m.channelID = data[4+2+2:]
1938
1939 return true
1940}
1941
Adam Langley2ae77d22014-10-28 17:29:33 -07001942type helloRequestMsg struct {
1943}
1944
1945func (*helloRequestMsg) marshal() []byte {
1946 return []byte{typeHelloRequest, 0, 0, 0}
1947}
1948
1949func (*helloRequestMsg) unmarshal(data []byte) bool {
1950 return len(data) == 4
1951}
1952
David Benjamin21c00282016-07-18 21:56:23 +02001953type keyUpdateMsg struct {
1954}
1955
1956func (*keyUpdateMsg) marshal() []byte {
1957 return []byte{typeKeyUpdate, 0, 0, 0}
1958}
1959
1960func (*keyUpdateMsg) unmarshal(data []byte) bool {
1961 return len(data) == 4
1962}
1963
Adam Langley95c29f32014-06-20 12:00:00 -07001964func eqUint16s(x, y []uint16) bool {
1965 if len(x) != len(y) {
1966 return false
1967 }
1968 for i, v := range x {
1969 if y[i] != v {
1970 return false
1971 }
1972 }
1973 return true
1974}
1975
1976func eqCurveIDs(x, y []CurveID) bool {
1977 if len(x) != len(y) {
1978 return false
1979 }
1980 for i, v := range x {
1981 if y[i] != v {
1982 return false
1983 }
1984 }
1985 return true
1986}
1987
1988func eqStrings(x, y []string) bool {
1989 if len(x) != len(y) {
1990 return false
1991 }
1992 for i, v := range x {
1993 if y[i] != v {
1994 return false
1995 }
1996 }
1997 return true
1998}
1999
2000func eqByteSlices(x, y [][]byte) bool {
2001 if len(x) != len(y) {
2002 return false
2003 }
2004 for i, v := range x {
2005 if !bytes.Equal(v, y[i]) {
2006 return false
2007 }
2008 }
2009 return true
2010}
2011
Nick Harper60edffd2016-06-21 15:19:24 -07002012func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07002013 if len(x) != len(y) {
2014 return false
2015 }
2016 for i, v := range x {
2017 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07002018 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07002019 return false
2020 }
2021 }
2022 return true
2023}
Nick Harperf8b0e702016-06-30 19:59:01 -04002024
2025func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2026 if len(x) != len(y) {
2027 return false
2028 }
2029 for i, v := range x {
2030 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2031 return false
2032 }
2033 }
2034 return true
2035
2036}