blob: 5ede6745618f67e3658583d1017bcefdec650207 [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
7import "bytes"
8
Nick Harper8dda5cc2016-06-30 18:51:11 -04009func writeLen(buf []byte, v, size int) {
10 for i := 0; i < size; i++ {
11 buf[size-i-1] = byte(v)
12 v >>= 8
13 }
14 if v != 0 {
15 panic("length is too long")
16 }
17}
18
19type byteBuilder struct {
20 buf *[]byte
21 start int
22 prefixLen int
23 child *byteBuilder
24}
25
26func newByteBuilder() *byteBuilder {
27 buf := make([]byte, 0, 32)
28 return &byteBuilder{buf: &buf}
29}
30
31func (bb *byteBuilder) len() int {
32 return len(*bb.buf) - bb.start - bb.prefixLen
33}
34
35func (bb *byteBuilder) flush() {
36 if bb.child == nil {
37 return
38 }
39 bb.child.flush()
40 writeLen((*bb.buf)[bb.child.start:], bb.child.len(), bb.child.prefixLen)
41 bb.child = nil
42 return
43}
44
45func (bb *byteBuilder) finish() []byte {
46 bb.flush()
47 return *bb.buf
48}
49
50func (bb *byteBuilder) addU8(u uint8) {
51 bb.flush()
52 *bb.buf = append(*bb.buf, u)
53}
54
55func (bb *byteBuilder) addU16(u uint16) {
56 bb.flush()
57 *bb.buf = append(*bb.buf, byte(u>>8), byte(u))
58}
59
60func (bb *byteBuilder) addU24(u int) {
61 bb.flush()
62 *bb.buf = append(*bb.buf, byte(u>>16), byte(u>>8), byte(u))
63}
64
65func (bb *byteBuilder) addU32(u uint32) {
66 bb.flush()
67 *bb.buf = append(*bb.buf, byte(u>>24), byte(u>>16), byte(u>>8), byte(u))
68}
69
70func (bb *byteBuilder) addU8LengthPrefixed() *byteBuilder {
71 return bb.createChild(1)
72}
73
74func (bb *byteBuilder) addU16LengthPrefixed() *byteBuilder {
75 return bb.createChild(2)
76}
77
78func (bb *byteBuilder) addU24LengthPrefixed() *byteBuilder {
79 return bb.createChild(3)
80}
81
82func (bb *byteBuilder) addBytes(b []byte) {
83 bb.flush()
84 *bb.buf = append(*bb.buf, b...)
85}
86
87func (bb *byteBuilder) createChild(lengthPrefixSize int) *byteBuilder {
88 bb.flush()
89 bb.child = &byteBuilder{
90 buf: bb.buf,
91 start: len(*bb.buf),
92 prefixLen: lengthPrefixSize,
93 }
94 for i := 0; i < lengthPrefixSize; i++ {
95 *bb.buf = append(*bb.buf, 0)
96 }
97 return bb.child
98}
99
100func (bb *byteBuilder) discardChild() {
101 if bb.child != nil {
102 return
103 }
104 bb.child = nil
105 *bb.buf = (*bb.buf)[:bb.start]
106}
107
Nick Harperf8b0e702016-06-30 19:59:01 -0400108type keyShareEntry struct {
109 group CurveID
110 keyExchange []byte
111}
112
Adam Langley95c29f32014-06-20 12:00:00 -0700113type clientHelloMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -0400114 raw []byte
115 isDTLS bool
116 vers uint16
117 random []byte
118 sessionId []byte
119 // TODO(davidben): Add support for TLS 1.3 cookies which are larger and
120 // use an extension.
David Benjaminca6c8262014-11-15 19:06:08 -0500121 cookie []byte
122 cipherSuites []uint16
123 compressionMethods []uint8
124 nextProtoNeg bool
125 serverName string
126 ocspStapling bool
127 supportedCurves []CurveID
128 supportedPoints []uint8
Nick Harperdcfbc672016-07-16 17:47:31 +0200129 hasKeyShares bool
Nick Harperf8b0e702016-06-30 19:59:01 -0400130 keyShares []keyShareEntry
131 pskIdentities [][]uint8
132 hasEarlyData bool
133 earlyDataContext []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500134 ticketSupported bool
135 sessionTicket []uint8
Nick Harper60edffd2016-06-21 15:19:24 -0700136 signatureAlgorithms []signatureAlgorithm
David Benjaminca6c8262014-11-15 19:06:08 -0500137 secureRenegotiation []byte
138 alpnProtocols []string
139 duplicateExtension bool
140 channelIDSupported bool
141 npnLast bool
142 extendedMasterSecret bool
143 srtpProtectionProfiles []uint16
144 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -0500145 sctListSupported bool
Adam Langley09505632015-07-30 18:10:13 -0700146 customExtension string
Adam Langley95c29f32014-06-20 12:00:00 -0700147}
148
149func (m *clientHelloMsg) equal(i interface{}) bool {
150 m1, ok := i.(*clientHelloMsg)
151 if !ok {
152 return false
153 }
154
155 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400156 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700157 m.vers == m1.vers &&
158 bytes.Equal(m.random, m1.random) &&
159 bytes.Equal(m.sessionId, m1.sessionId) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400160 bytes.Equal(m.cookie, m1.cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700161 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
162 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
163 m.nextProtoNeg == m1.nextProtoNeg &&
164 m.serverName == m1.serverName &&
165 m.ocspStapling == m1.ocspStapling &&
166 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
167 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
Nick Harperdcfbc672016-07-16 17:47:31 +0200168 m.hasKeyShares == m1.hasKeyShares &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400169 eqKeyShareEntryLists(m.keyShares, m1.keyShares) &&
170 eqByteSlices(m.pskIdentities, m1.pskIdentities) &&
171 m.hasEarlyData == m1.hasEarlyData &&
172 bytes.Equal(m.earlyDataContext, m1.earlyDataContext) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700173 m.ticketSupported == m1.ticketSupported &&
174 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
Nick Harper60edffd2016-06-21 15:19:24 -0700175 eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700176 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
177 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400178 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -0400179 m.duplicateExtension == m1.duplicateExtension &&
David Benjaminfc7b0862014-09-06 13:21:53 -0400180 m.channelIDSupported == m1.channelIDSupported &&
Adam Langley75712922014-10-10 16:23:43 -0700181 m.npnLast == m1.npnLast &&
David Benjaminca6c8262014-11-15 19:06:08 -0500182 m.extendedMasterSecret == m1.extendedMasterSecret &&
183 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
David Benjamin61f95272014-11-25 01:55:35 -0500184 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
Adam Langley09505632015-07-30 18:10:13 -0700185 m.sctListSupported == m1.sctListSupported &&
186 m.customExtension == m1.customExtension
Adam Langley95c29f32014-06-20 12:00:00 -0700187}
188
189func (m *clientHelloMsg) marshal() []byte {
190 if m.raw != nil {
191 return m.raw
192 }
193
Nick Harper8dda5cc2016-06-30 18:51:11 -0400194 handshakeMsg := newByteBuilder()
195 handshakeMsg.addU8(typeClientHello)
196 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin83c0bc92014-08-04 01:23:53 -0400197 vers := versionToWire(m.vers, m.isDTLS)
Nick Harper8dda5cc2016-06-30 18:51:11 -0400198 hello.addU16(vers)
199 hello.addBytes(m.random)
200 sessionId := hello.addU8LengthPrefixed()
201 sessionId.addBytes(m.sessionId)
David Benjamin83c0bc92014-08-04 01:23:53 -0400202 if m.isDTLS {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400203 cookie := hello.addU8LengthPrefixed()
204 cookie.addBytes(m.cookie)
David Benjamin83c0bc92014-08-04 01:23:53 -0400205 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400206 cipherSuites := hello.addU16LengthPrefixed()
207 for _, suite := range m.cipherSuites {
208 cipherSuites.addU16(suite)
Adam Langley95c29f32014-06-20 12:00:00 -0700209 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400210 compressionMethods := hello.addU8LengthPrefixed()
211 compressionMethods.addBytes(m.compressionMethods)
Adam Langley95c29f32014-06-20 12:00:00 -0700212
Nick Harper8dda5cc2016-06-30 18:51:11 -0400213 extensions := hello.addU16LengthPrefixed()
David Benjamin35a7a442014-07-05 00:23:20 -0400214 if m.duplicateExtension {
215 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400216 extensions.addU16(0xffff)
217 extensions.addU16(0) // 0-length for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400218 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400219 if m.nextProtoNeg && !m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400220 extensions.addU16(extensionNextProtoNeg)
221 extensions.addU16(0) // The length is always 0
Adam Langley95c29f32014-06-20 12:00:00 -0700222 }
223 if len(m.serverName) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400224 extensions.addU16(extensionServerName)
225 serverNameList := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700226
227 // RFC 3546, section 3.1
228 //
229 // struct {
230 // NameType name_type;
231 // select (name_type) {
232 // case host_name: HostName;
233 // } name;
234 // } ServerName;
235 //
236 // enum {
237 // host_name(0), (255)
238 // } NameType;
239 //
240 // opaque HostName<1..2^16-1>;
241 //
242 // struct {
243 // ServerName server_name_list<1..2^16-1>
244 // } ServerNameList;
245
Nick Harper8dda5cc2016-06-30 18:51:11 -0400246 serverName := serverNameList.addU16LengthPrefixed()
247 serverName.addU8(0) // NameType host_name(0)
248 hostName := serverName.addU16LengthPrefixed()
249 hostName.addBytes([]byte(m.serverName))
Adam Langley95c29f32014-06-20 12:00:00 -0700250 }
251 if m.ocspStapling {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400252 extensions.addU16(extensionStatusRequest)
253 certificateStatusRequest := extensions.addU16LengthPrefixed()
254
Adam Langley95c29f32014-06-20 12:00:00 -0700255 // RFC 4366, section 3.6
Nick Harper8dda5cc2016-06-30 18:51:11 -0400256 certificateStatusRequest.addU8(1) // OCSP type
Adam Langley95c29f32014-06-20 12:00:00 -0700257 // Two zero valued uint16s for the two lengths.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400258 certificateStatusRequest.addU16(0) // ResponderID length
259 certificateStatusRequest.addU16(0) // Extensions length
Adam Langley95c29f32014-06-20 12:00:00 -0700260 }
261 if len(m.supportedCurves) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400262 // http://tools.ietf.org/html/rfc4492#section-5.1.1
263 extensions.addU16(extensionSupportedCurves)
264 supportedCurvesList := extensions.addU16LengthPrefixed()
265 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700266 for _, curve := range m.supportedCurves {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400267 supportedCurves.addU16(uint16(curve))
Adam Langley95c29f32014-06-20 12:00:00 -0700268 }
269 }
270 if len(m.supportedPoints) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400271 // http://tools.ietf.org/html/rfc4492#section-5.1.2
272 extensions.addU16(extensionSupportedPoints)
273 supportedPointsList := extensions.addU16LengthPrefixed()
274 supportedPoints := supportedPointsList.addU8LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700275 for _, pointFormat := range m.supportedPoints {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400276 supportedPoints.addU8(pointFormat)
Adam Langley95c29f32014-06-20 12:00:00 -0700277 }
278 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200279 if m.hasKeyShares {
Nick Harperf8b0e702016-06-30 19:59:01 -0400280 extensions.addU16(extensionKeyShare)
281 keyShareList := extensions.addU16LengthPrefixed()
282
283 keyShares := keyShareList.addU16LengthPrefixed()
284 for _, keyShare := range m.keyShares {
285 keyShares.addU16(uint16(keyShare.group))
286 keyExchange := keyShares.addU16LengthPrefixed()
287 keyExchange.addBytes(keyShare.keyExchange)
288 }
289 }
290 if len(m.pskIdentities) > 0 {
291 extensions.addU16(extensionPreSharedKey)
292 pskExtension := extensions.addU16LengthPrefixed()
293
294 pskIdentities := pskExtension.addU16LengthPrefixed()
295 for _, psk := range m.pskIdentities {
296 pskIdentity := pskIdentities.addU16LengthPrefixed()
297 pskIdentity.addBytes(psk)
298 }
299 }
300 if m.hasEarlyData {
301 extensions.addU16(extensionEarlyData)
302 earlyDataIndication := extensions.addU16LengthPrefixed()
303
304 context := earlyDataIndication.addU8LengthPrefixed()
305 context.addBytes(m.earlyDataContext)
306 }
Adam Langley95c29f32014-06-20 12:00:00 -0700307 if m.ticketSupported {
308 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400309 extensions.addU16(extensionSessionTicket)
310 sessionTicketExtension := extensions.addU16LengthPrefixed()
311 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700312 }
Nick Harper60edffd2016-06-21 15:19:24 -0700313 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700314 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400315 extensions.addU16(extensionSignatureAlgorithms)
316 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
317 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700318 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400319 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700320 }
321 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700322 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400323 extensions.addU16(extensionRenegotiationInfo)
324 secureRenegoExt := extensions.addU16LengthPrefixed()
325 secureRenego := secureRenegoExt.addU8LengthPrefixed()
326 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700327 }
David Benjaminfa055a22014-09-15 16:51:51 -0400328 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400329 // https://tools.ietf.org/html/rfc7301#section-3.1
330 extensions.addU16(extensionALPN)
331 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400332
Nick Harper8dda5cc2016-06-30 18:51:11 -0400333 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400334 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400335 protocolName := protocolNameList.addU8LengthPrefixed()
336 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400337 }
David Benjaminfa055a22014-09-15 16:51:51 -0400338 }
David Benjamind30a9902014-08-24 01:44:23 -0400339 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400340 extensions.addU16(extensionChannelID)
341 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400342 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400343 if m.nextProtoNeg && m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400344 extensions.addU16(extensionNextProtoNeg)
345 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400346 }
David Benjamin35a7a442014-07-05 00:23:20 -0400347 if m.duplicateExtension {
348 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400349 extensions.addU16(0xffff)
350 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400351 }
Adam Langley75712922014-10-10 16:23:43 -0700352 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500353 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400354 extensions.addU16(extensionExtendedMasterSecret)
355 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700356 }
David Benjaminca6c8262014-11-15 19:06:08 -0500357 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400358 // https://tools.ietf.org/html/rfc5764#section-4.1.1
359 extensions.addU16(extensionUseSRTP)
360 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500361
Nick Harper8dda5cc2016-06-30 18:51:11 -0400362 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500363 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400364 // An SRTPProtectionProfile is defined as uint8[2],
365 // not uint16. For some reason, we're storing it
366 // as a uint16.
367 srtpProtectionProfiles.addU8(byte(p >> 8))
368 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500369 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400370 srtpMki := useSrtpExt.addU8LengthPrefixed()
371 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500372 }
David Benjamin61f95272014-11-25 01:55:35 -0500373 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400374 extensions.addU16(extensionSignedCertificateTimestamp)
375 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500376 }
Adam Langley09505632015-07-30 18:10:13 -0700377 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400378 extensions.addU16(extensionCustom)
379 customExt := extensions.addU16LengthPrefixed()
380 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700381 }
Adam Langley95c29f32014-06-20 12:00:00 -0700382
Nick Harper8dda5cc2016-06-30 18:51:11 -0400383 if extensions.len() == 0 {
384 hello.discardChild()
385 }
Adam Langley95c29f32014-06-20 12:00:00 -0700386
Nick Harper8dda5cc2016-06-30 18:51:11 -0400387 m.raw = handshakeMsg.finish()
388 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700389}
390
391func (m *clientHelloMsg) unmarshal(data []byte) bool {
392 if len(data) < 42 {
393 return false
394 }
395 m.raw = data
David Benjamin83c0bc92014-08-04 01:23:53 -0400396 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
Adam Langley95c29f32014-06-20 12:00:00 -0700397 m.random = data[6:38]
398 sessionIdLen := int(data[38])
399 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
400 return false
401 }
402 m.sessionId = data[39 : 39+sessionIdLen]
403 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400404 if m.isDTLS {
405 if len(data) < 1 {
406 return false
407 }
408 cookieLen := int(data[0])
409 if cookieLen > 32 || len(data) < 1+cookieLen {
410 return false
411 }
412 m.cookie = data[1 : 1+cookieLen]
413 data = data[1+cookieLen:]
414 }
Adam Langley95c29f32014-06-20 12:00:00 -0700415 if len(data) < 2 {
416 return false
417 }
418 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
419 // they are uint16s, the number must be even.
420 cipherSuiteLen := int(data[0])<<8 | int(data[1])
421 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
422 return false
423 }
424 numCipherSuites := cipherSuiteLen / 2
425 m.cipherSuites = make([]uint16, numCipherSuites)
426 for i := 0; i < numCipherSuites; i++ {
427 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
428 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700429 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700430 }
431 }
432 data = data[2+cipherSuiteLen:]
433 if len(data) < 1 {
434 return false
435 }
436 compressionMethodsLen := int(data[0])
437 if len(data) < 1+compressionMethodsLen {
438 return false
439 }
440 m.compressionMethods = data[1 : 1+compressionMethodsLen]
441
442 data = data[1+compressionMethodsLen:]
443
444 m.nextProtoNeg = false
445 m.serverName = ""
446 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400447 m.keyShares = nil
448 m.pskIdentities = nil
449 m.hasEarlyData = false
450 m.earlyDataContext = nil
Adam Langley95c29f32014-06-20 12:00:00 -0700451 m.ticketSupported = false
452 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700453 m.signatureAlgorithms = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400454 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700455 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700456 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700457
458 if len(data) == 0 {
459 // ClientHello is optionally followed by extension data
460 return true
461 }
462 if len(data) < 2 {
463 return false
464 }
465
466 extensionsLength := int(data[0])<<8 | int(data[1])
467 data = data[2:]
468 if extensionsLength != len(data) {
469 return false
470 }
471
472 for len(data) != 0 {
473 if len(data) < 4 {
474 return false
475 }
476 extension := uint16(data[0])<<8 | uint16(data[1])
477 length := int(data[2])<<8 | int(data[3])
478 data = data[4:]
479 if len(data) < length {
480 return false
481 }
482
483 switch extension {
484 case extensionServerName:
485 if length < 2 {
486 return false
487 }
488 numNames := int(data[0])<<8 | int(data[1])
489 d := data[2:]
490 for i := 0; i < numNames; i++ {
491 if len(d) < 3 {
492 return false
493 }
494 nameType := d[0]
495 nameLen := int(d[1])<<8 | int(d[2])
496 d = d[3:]
497 if len(d) < nameLen {
498 return false
499 }
500 if nameType == 0 {
501 m.serverName = string(d[0:nameLen])
502 break
503 }
504 d = d[nameLen:]
505 }
506 case extensionNextProtoNeg:
507 if length > 0 {
508 return false
509 }
510 m.nextProtoNeg = true
511 case extensionStatusRequest:
512 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
513 case extensionSupportedCurves:
514 // http://tools.ietf.org/html/rfc4492#section-5.5.1
515 if length < 2 {
516 return false
517 }
518 l := int(data[0])<<8 | int(data[1])
519 if l%2 == 1 || length != l+2 {
520 return false
521 }
522 numCurves := l / 2
523 m.supportedCurves = make([]CurveID, numCurves)
524 d := data[2:]
525 for i := 0; i < numCurves; i++ {
526 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
527 d = d[2:]
528 }
529 case extensionSupportedPoints:
530 // http://tools.ietf.org/html/rfc4492#section-5.5.2
531 if length < 1 {
532 return false
533 }
534 l := int(data[0])
535 if length != l+1 {
536 return false
537 }
538 m.supportedPoints = make([]uint8, l)
539 copy(m.supportedPoints, data[1:])
540 case extensionSessionTicket:
541 // http://tools.ietf.org/html/rfc5077#section-3.2
542 m.ticketSupported = true
543 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400544 case extensionKeyShare:
545 // draft-ietf-tls-tls13 section 6.3.2.3
546 if length < 2 {
547 return false
548 }
549 l := int(data[0])<<8 | int(data[1])
550 if l != length-2 {
551 return false
552 }
553 d := data[2:length]
Nick Harperdcfbc672016-07-16 17:47:31 +0200554 m.hasKeyShares = true
Nick Harperf8b0e702016-06-30 19:59:01 -0400555 for len(d) > 0 {
556 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
557 // key_exchange (2-byte length prefix with at least 1 byte of content).
558 if len(d) < 5 {
559 return false
560 }
561 entry := keyShareEntry{}
562 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
563 keyExchLen := int(d[2])<<8 | int(d[3])
564 d = d[4:]
565 if len(d) < keyExchLen {
566 return false
567 }
568 entry.keyExchange = d[:keyExchLen]
569 d = d[keyExchLen:]
570 m.keyShares = append(m.keyShares, entry)
571 }
572 case extensionPreSharedKey:
573 // draft-ietf-tls-tls13 section 6.3.2.4
574 if length < 2 {
575 return false
576 }
577 l := int(data[0])<<8 | int(data[1])
578 if l != length-2 {
579 return false
580 }
581 d := data[2:length]
582 for len(d) > 0 {
583 if len(d) < 2 {
584 return false
585 }
586 pskLen := int(d[0])<<8 | int(d[1])
587 d = d[2:]
588 if len(d) < pskLen {
589 return false
590 }
591 psk := d[:pskLen]
592 m.pskIdentities = append(m.pskIdentities, psk)
593 d = d[pskLen:]
594 }
595 case extensionEarlyData:
596 // draft-ietf-tls-tls13 section 6.3.2.5
597 if length < 1 {
598 return false
599 }
600 l := int(data[0])
601 if length != l+1 {
602 return false
603 }
604 m.hasEarlyData = true
605 m.earlyDataContext = data[1:length]
Adam Langley95c29f32014-06-20 12:00:00 -0700606 case extensionSignatureAlgorithms:
607 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
608 if length < 2 || length&1 != 0 {
609 return false
610 }
611 l := int(data[0])<<8 | int(data[1])
612 if l != length-2 {
613 return false
614 }
615 n := l / 2
616 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700617 m.signatureAlgorithms = make([]signatureAlgorithm, n)
618 for i := range m.signatureAlgorithms {
619 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700620 d = d[2:]
621 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700622 case extensionRenegotiationInfo:
623 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700624 return false
625 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700626 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400627 case extensionALPN:
628 if length < 2 {
629 return false
630 }
631 l := int(data[0])<<8 | int(data[1])
632 if l != length-2 {
633 return false
634 }
635 d := data[2:length]
636 for len(d) != 0 {
637 stringLen := int(d[0])
638 d = d[1:]
639 if stringLen == 0 || stringLen > len(d) {
640 return false
641 }
642 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
643 d = d[stringLen:]
644 }
David Benjamind30a9902014-08-24 01:44:23 -0400645 case extensionChannelID:
646 if length > 0 {
647 return false
648 }
649 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700650 case extensionExtendedMasterSecret:
651 if length != 0 {
652 return false
653 }
654 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500655 case extensionUseSRTP:
656 if length < 2 {
657 return false
658 }
659 l := int(data[0])<<8 | int(data[1])
660 if l > length-2 || l%2 != 0 {
661 return false
662 }
663 n := l / 2
664 m.srtpProtectionProfiles = make([]uint16, n)
665 d := data[2:length]
666 for i := 0; i < n; i++ {
667 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
668 d = d[2:]
669 }
670 if len(d) < 1 || int(d[0]) != len(d)-1 {
671 return false
672 }
673 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500674 case extensionSignedCertificateTimestamp:
675 if length != 0 {
676 return false
677 }
678 m.sctListSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700679 case extensionCustom:
680 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700681 }
682 data = data[length:]
683 }
684
685 return true
686}
687
688type serverHelloMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -0400689 raw []byte
690 isDTLS bool
691 vers uint16
692 random []byte
693 sessionId []byte
694 cipherSuite uint16
695 hasKeyShare bool
696 keyShare keyShareEntry
697 hasPSKIdentity bool
698 pskIdentity uint16
699 earlyDataIndication bool
700 compressionMethod uint8
701 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700702}
703
Adam Langley95c29f32014-06-20 12:00:00 -0700704func (m *serverHelloMsg) marshal() []byte {
705 if m.raw != nil {
706 return m.raw
707 }
708
Nick Harper5212ef82016-06-30 19:26:07 -0400709 handshakeMsg := newByteBuilder()
710 handshakeMsg.addU8(typeServerHello)
711 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin83c0bc92014-08-04 01:23:53 -0400712 vers := versionToWire(m.vers, m.isDTLS)
Nick Harper5212ef82016-06-30 19:26:07 -0400713 hello.addU16(vers)
714 hello.addBytes(m.random)
David Benjamin8d315d72016-07-18 01:03:18 +0200715 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400716 sessionId := hello.addU8LengthPrefixed()
717 sessionId.addBytes(m.sessionId)
718 }
Nick Harper5212ef82016-06-30 19:26:07 -0400719 hello.addU16(m.cipherSuite)
David Benjamin8d315d72016-07-18 01:03:18 +0200720 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400721 hello.addU8(m.compressionMethod)
722 }
Adam Langley95c29f32014-06-20 12:00:00 -0700723
Nick Harper5212ef82016-06-30 19:26:07 -0400724 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400725
David Benjamin8d315d72016-07-18 01:03:18 +0200726 if m.vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400727 if m.hasKeyShare {
728 extensions.addU16(extensionKeyShare)
729 keyShare := extensions.addU16LengthPrefixed()
730 keyShare.addU16(uint16(m.keyShare.group))
731 keyExchange := keyShare.addU16LengthPrefixed()
732 keyExchange.addBytes(m.keyShare.keyExchange)
733 }
734 if m.hasPSKIdentity {
735 extensions.addU16(extensionPreSharedKey)
736 extensions.addU16(2) // Length
737 extensions.addU16(m.pskIdentity)
738 }
739 if m.earlyDataIndication {
740 extensions.addU16(extensionEarlyData)
741 extensions.addU16(0) // Length
742 }
743 } else {
David Benjamin44b33bc2016-07-01 22:40:23 -0400744 m.extensions.marshal(extensions, m.vers)
Nick Harperb41d2e42016-07-01 17:50:32 -0400745 if extensions.len() == 0 {
746 hello.discardChild()
747 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400748 }
749
750 m.raw = handshakeMsg.finish()
751 return m.raw
752}
753
754func (m *serverHelloMsg) unmarshal(data []byte) bool {
755 if len(data) < 42 {
756 return false
757 }
758 m.raw = data
759 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
760 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400761 data = data[38:]
David Benjamin8d315d72016-07-18 01:03:18 +0200762 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400763 sessionIdLen := int(data[0])
764 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
765 return false
766 }
767 m.sessionId = data[1 : 1+sessionIdLen]
768 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400769 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400770 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400771 return false
772 }
773 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400774 data = data[2:]
David Benjamin8d315d72016-07-18 01:03:18 +0200775 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400776 if len(data) < 1 {
777 return false
778 }
779 m.compressionMethod = data[0]
780 data = data[1:]
781 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400782
David Benjamin8d315d72016-07-18 01:03:18 +0200783 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400784 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400785 m.extensions = serverExtensions{}
786 return true
787 }
788 if len(data) < 2 {
789 return false
790 }
791
792 extensionsLength := int(data[0])<<8 | int(data[1])
793 data = data[2:]
794 if len(data) != extensionsLength {
795 return false
796 }
797
David Benjamin8d315d72016-07-18 01:03:18 +0200798 if m.vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400799 for len(data) != 0 {
800 if len(data) < 4 {
801 return false
802 }
803 extension := uint16(data[0])<<8 | uint16(data[1])
804 length := int(data[2])<<8 | int(data[3])
805 data = data[4:]
806
807 if len(data) < length {
808 return false
809 }
810 d := data[:length]
811 data = data[length:]
812
813 switch extension {
814 case extensionKeyShare:
815 m.hasKeyShare = true
816 if len(d) < 4 {
817 return false
818 }
819 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
820 keyExchLen := int(d[2])<<8 | int(d[3])
821 if keyExchLen != len(d)-4 {
822 return false
823 }
824 m.keyShare.keyExchange = make([]byte, keyExchLen)
825 copy(m.keyShare.keyExchange, d[4:])
826 case extensionPreSharedKey:
827 if len(d) != 2 {
828 return false
829 }
830 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
831 m.hasPSKIdentity = true
832 case extensionEarlyData:
833 if len(d) != 0 {
834 return false
835 }
836 m.earlyDataIndication = true
837 default:
838 // Only allow the 3 extensions that are sent in
839 // the clear in TLS 1.3.
840 return false
841 }
842 }
David Benjamin44b33bc2016-07-01 22:40:23 -0400843 } else if !m.extensions.unmarshal(data, m.vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -0400844 return false
845 }
846
847 return true
848}
849
Nick Harperb41d2e42016-07-01 17:50:32 -0400850type encryptedExtensionsMsg struct {
851 raw []byte
852 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -0400853 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -0400854}
855
856func (m *encryptedExtensionsMsg) marshal() []byte {
857 if m.raw != nil {
858 return m.raw
859 }
860
861 encryptedExtensionsMsg := newByteBuilder()
862 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
863 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -0400864 if !m.empty {
865 extensions := encryptedExtensions.addU16LengthPrefixed()
866 m.extensions.marshal(extensions, VersionTLS13)
867 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400868
869 m.raw = encryptedExtensionsMsg.finish()
870 return m.raw
871}
872
873func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -0400874 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -0400875 if len(data) < 6 {
876 return false
877 }
878 if data[0] != typeEncryptedExtensions {
879 return false
880 }
881 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
882 data = data[4:]
883 if len(data) != msgLen {
884 return false
885 }
886 extLen := int(data[0])<<8 | int(data[1])
887 data = data[2:]
888 if extLen != len(data) {
889 return false
890 }
David Benjamin44b33bc2016-07-01 22:40:23 -0400891 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -0400892}
893
Nick Harperb3d51be2016-07-01 11:43:18 -0400894type serverExtensions struct {
895 nextProtoNeg bool
896 nextProtos []string
897 ocspStapling bool
David Benjamin44b33bc2016-07-01 22:40:23 -0400898 ocspResponse []byte
Nick Harperb3d51be2016-07-01 11:43:18 -0400899 ticketSupported bool
900 secureRenegotiation []byte
901 alpnProtocol string
902 alpnProtocolEmpty bool
903 duplicateExtension bool
904 channelIDRequested bool
905 extendedMasterSecret bool
906 srtpProtectionProfile uint16
907 srtpMasterKeyIdentifier string
908 sctList []byte
909 customExtension string
910 npnLast bool
Steven Valdez143e8b32016-07-11 13:19:03 -0400911 hasKeyShare bool
912 keyShare keyShareEntry
Nick Harperb3d51be2016-07-01 11:43:18 -0400913}
914
David Benjamin44b33bc2016-07-01 22:40:23 -0400915func (m *serverExtensions) marshal(extensions *byteBuilder, version uint16) {
David Benjamin35a7a442014-07-05 00:23:20 -0400916 if m.duplicateExtension {
917 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -0400918 extensions.addU16(0xffff)
919 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400920 }
David Benjamin76c2efc2015-08-31 14:24:29 -0400921 if m.nextProtoNeg && !m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -0400922 extensions.addU16(extensionNextProtoNeg)
923 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700924
925 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -0400926 if len(v) > 255 {
927 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -0700928 }
Nick Harper5212ef82016-06-30 19:26:07 -0400929 npn := extension.addU8LengthPrefixed()
930 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -0700931 }
932 }
David Benjamin8d315d72016-07-18 01:03:18 +0200933 if version >= VersionTLS13 {
David Benjamin44b33bc2016-07-01 22:40:23 -0400934 if m.ocspResponse != nil {
935 extensions.addU16(extensionStatusRequest)
936 body := extensions.addU16LengthPrefixed()
937 body.addU8(statusTypeOCSP)
938 response := body.addU24LengthPrefixed()
939 response.addBytes(m.ocspResponse)
940 }
941 } else {
942 if m.ocspStapling {
943 extensions.addU16(extensionStatusRequest)
944 extensions.addU16(0)
945 }
Adam Langley95c29f32014-06-20 12:00:00 -0700946 }
947 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -0400948 extensions.addU16(extensionSessionTicket)
949 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -0700950 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700951 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -0400952 extensions.addU16(extensionRenegotiationInfo)
953 extension := extensions.addU16LengthPrefixed()
954 secureRenego := extension.addU8LengthPrefixed()
955 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700956 }
Nick Harper5212ef82016-06-30 19:26:07 -0400957 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
958 extensions.addU16(extensionALPN)
959 extension := extensions.addU16LengthPrefixed()
960
961 protocolNameList := extension.addU16LengthPrefixed()
962 protocolName := protocolNameList.addU8LengthPrefixed()
963 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -0400964 }
David Benjamind30a9902014-08-24 01:44:23 -0400965 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -0400966 extensions.addU16(extensionChannelID)
967 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -0400968 }
David Benjamin35a7a442014-07-05 00:23:20 -0400969 if m.duplicateExtension {
970 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -0400971 extensions.addU16(0xffff)
972 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400973 }
Adam Langley75712922014-10-10 16:23:43 -0700974 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -0400975 extensions.addU16(extensionExtendedMasterSecret)
976 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -0700977 }
David Benjaminca6c8262014-11-15 19:06:08 -0500978 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -0400979 extensions.addU16(extensionUseSRTP)
980 extension := extensions.addU16LengthPrefixed()
981
982 srtpProtectionProfiles := extension.addU16LengthPrefixed()
983 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
984 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
985 srtpMki := extension.addU8LengthPrefixed()
986 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500987 }
David Benjamin61f95272014-11-25 01:55:35 -0500988 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -0400989 extensions.addU16(extensionSignedCertificateTimestamp)
990 extension := extensions.addU16LengthPrefixed()
991 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -0500992 }
Adam Langley09505632015-07-30 18:10:13 -0700993 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -0400994 extensions.addU16(extensionCustom)
995 customExt := extensions.addU16LengthPrefixed()
996 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700997 }
David Benjamin76c2efc2015-08-31 14:24:29 -0400998 if m.nextProtoNeg && m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -0400999 extensions.addU16(extensionNextProtoNeg)
1000 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -04001001
1002 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001003 if len(v) > 255 {
1004 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -04001005 }
Nick Harper5212ef82016-06-30 19:26:07 -04001006 npn := extension.addU8LengthPrefixed()
1007 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001008 }
1009 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001010 if m.hasKeyShare {
1011 extensions.addU16(extensionKeyShare)
1012 keyShare := extensions.addU16LengthPrefixed()
1013 keyShare.addU16(uint16(m.keyShare.group))
1014 keyExchange := keyShare.addU16LengthPrefixed()
1015 keyExchange.addBytes(m.keyShare.keyExchange)
1016 }
Adam Langley95c29f32014-06-20 12:00:00 -07001017}
1018
David Benjamin44b33bc2016-07-01 22:40:23 -04001019func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001020 // Reset all fields.
1021 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001022
1023 for len(data) != 0 {
1024 if len(data) < 4 {
1025 return false
1026 }
1027 extension := uint16(data[0])<<8 | uint16(data[1])
1028 length := int(data[2])<<8 | int(data[3])
1029 data = data[4:]
1030 if len(data) < length {
1031 return false
1032 }
1033
1034 switch extension {
1035 case extensionNextProtoNeg:
1036 m.nextProtoNeg = true
1037 d := data[:length]
1038 for len(d) > 0 {
1039 l := int(d[0])
1040 d = d[1:]
1041 if l == 0 || l > len(d) {
1042 return false
1043 }
1044 m.nextProtos = append(m.nextProtos, string(d[:l]))
1045 d = d[l:]
1046 }
1047 case extensionStatusRequest:
David Benjamin8d315d72016-07-18 01:03:18 +02001048 if version >= VersionTLS13 {
David Benjamin44b33bc2016-07-01 22:40:23 -04001049 if length < 4 {
1050 return false
1051 }
1052 d := data[:length]
1053 if d[0] != statusTypeOCSP {
1054 return false
1055 }
1056 respLen := int(d[1])<<16 | int(d[2])<<8 | int(d[3])
1057 if respLen+4 != len(d) || respLen == 0 {
1058 return false
1059 }
1060 m.ocspResponse = d[4:]
1061 } else {
1062 if length > 0 {
1063 return false
1064 }
1065 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001066 }
Adam Langley95c29f32014-06-20 12:00:00 -07001067 case extensionSessionTicket:
1068 if length > 0 {
1069 return false
1070 }
1071 m.ticketSupported = true
1072 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001073 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001074 return false
1075 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001076 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001077 case extensionALPN:
1078 d := data[:length]
1079 if len(d) < 3 {
1080 return false
1081 }
1082 l := int(d[0])<<8 | int(d[1])
1083 if l != len(d)-2 {
1084 return false
1085 }
1086 d = d[2:]
1087 l = int(d[0])
1088 if l != len(d)-1 {
1089 return false
1090 }
1091 d = d[1:]
1092 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001093 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001094 case extensionChannelID:
1095 if length > 0 {
1096 return false
1097 }
1098 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001099 case extensionExtendedMasterSecret:
1100 if length != 0 {
1101 return false
1102 }
1103 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001104 case extensionUseSRTP:
1105 if length < 2+2+1 {
1106 return false
1107 }
1108 if data[0] != 0 || data[1] != 2 {
1109 return false
1110 }
1111 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1112 d := data[4:length]
1113 l := int(d[0])
1114 if l != len(d)-1 {
1115 return false
1116 }
1117 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001118 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001119 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001120 case extensionCustom:
1121 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001122 case extensionServerName:
1123 if length != 0 {
1124 return false
1125 }
1126 // Ignore this extension from the server.
1127 case extensionSupportedPoints:
1128 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001129 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001130 return false
1131 }
1132 // Ignore this extension from the server.
David Benjamin4ee027f2016-07-17 12:34:41 +02001133 case extensionSupportedCurves:
1134 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001135 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001136 return false
1137 }
David Benjamin46f94bd2016-07-14 16:43:37 -04001138 default:
1139 // Unknown extensions are illegal from the server.
1140 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001141 }
1142 data = data[length:]
1143 }
1144
1145 return true
1146}
1147
Nick Harperdcfbc672016-07-16 17:47:31 +02001148type helloRetryRequestMsg struct {
1149 raw []byte
1150 vers uint16
1151 cipherSuite uint16
1152 selectedGroup CurveID
1153}
1154
1155func (m *helloRetryRequestMsg) marshal() []byte {
1156 if m.raw != nil {
1157 return m.raw
1158 }
1159
1160 retryRequestMsg := newByteBuilder()
1161 retryRequestMsg.addU8(typeHelloRetryRequest)
1162 retryRequest := retryRequestMsg.addU24LengthPrefixed()
1163 retryRequest.addU16(m.vers)
1164 retryRequest.addU16(m.cipherSuite)
1165 retryRequest.addU16(uint16(m.selectedGroup))
1166 // Extensions field. We have none to send.
1167 retryRequest.addU16(0)
1168
1169 m.raw = retryRequestMsg.finish()
1170 return m.raw
1171}
1172
1173func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1174 m.raw = data
1175 if len(data) < 12 {
1176 return false
1177 }
1178 m.vers = uint16(data[4])<<8 | uint16(data[5])
1179 m.cipherSuite = uint16(data[6])<<8 | uint16(data[7])
1180 m.selectedGroup = CurveID(data[8])<<8 | CurveID(data[9])
1181 extLen := int(data[10])<<8 | int(data[11])
1182 data = data[12:]
1183 if len(data) != extLen {
1184 return false
1185 }
1186 return true
1187}
1188
Adam Langley95c29f32014-06-20 12:00:00 -07001189type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001190 raw []byte
1191 hasRequestContext bool
1192 requestContext []byte
1193 certificates [][]byte
Adam Langley95c29f32014-06-20 12:00:00 -07001194}
1195
Adam Langley95c29f32014-06-20 12:00:00 -07001196func (m *certificateMsg) marshal() (x []byte) {
1197 if m.raw != nil {
1198 return m.raw
1199 }
1200
Nick Harper7e0442a2016-07-01 17:40:09 -04001201 certMsg := newByteBuilder()
1202 certMsg.addU8(typeCertificate)
1203 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001204 if m.hasRequestContext {
1205 context := certificate.addU8LengthPrefixed()
1206 context.addBytes(m.requestContext)
1207 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001208 certificateList := certificate.addU24LengthPrefixed()
1209 for _, cert := range m.certificates {
1210 certEntry := certificateList.addU24LengthPrefixed()
1211 certEntry.addBytes(cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001212 }
1213
Nick Harper7e0442a2016-07-01 17:40:09 -04001214 m.raw = certMsg.finish()
1215 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001216}
1217
1218func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001219 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001220 return false
1221 }
1222
1223 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001224 data = data[4:]
1225
1226 if m.hasRequestContext {
1227 if len(data) == 0 {
1228 return false
1229 }
1230 contextLen := int(data[0])
1231 if len(data) < 1+contextLen {
1232 return false
1233 }
1234 m.requestContext = make([]byte, contextLen)
1235 copy(m.requestContext, data[1:])
1236 data = data[1+contextLen:]
1237 }
1238
1239 if len(data) < 3 {
1240 return false
1241 }
1242 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1243 data = data[3:]
1244 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001245 return false
1246 }
1247
1248 numCerts := 0
Nick Harperb41d2e42016-07-01 17:50:32 -04001249 d := data
Adam Langley95c29f32014-06-20 12:00:00 -07001250 for certsLen > 0 {
1251 if len(d) < 4 {
1252 return false
1253 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001254 certLen := int(d[0])<<16 | int(d[1])<<8 | int(d[2])
1255 if len(d) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001256 return false
1257 }
1258 d = d[3+certLen:]
1259 certsLen -= 3 + certLen
1260 numCerts++
1261 }
1262
1263 m.certificates = make([][]byte, numCerts)
Nick Harperb41d2e42016-07-01 17:50:32 -04001264 d = data
Adam Langley95c29f32014-06-20 12:00:00 -07001265 for i := 0; i < numCerts; i++ {
1266 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
1267 m.certificates[i] = d[3 : 3+certLen]
1268 d = d[3+certLen:]
1269 }
1270
1271 return true
1272}
1273
1274type serverKeyExchangeMsg struct {
1275 raw []byte
1276 key []byte
1277}
1278
Adam Langley95c29f32014-06-20 12:00:00 -07001279func (m *serverKeyExchangeMsg) marshal() []byte {
1280 if m.raw != nil {
1281 return m.raw
1282 }
1283 length := len(m.key)
1284 x := make([]byte, length+4)
1285 x[0] = typeServerKeyExchange
1286 x[1] = uint8(length >> 16)
1287 x[2] = uint8(length >> 8)
1288 x[3] = uint8(length)
1289 copy(x[4:], m.key)
1290
1291 m.raw = x
1292 return x
1293}
1294
1295func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1296 m.raw = data
1297 if len(data) < 4 {
1298 return false
1299 }
1300 m.key = data[4:]
1301 return true
1302}
1303
1304type certificateStatusMsg struct {
1305 raw []byte
1306 statusType uint8
1307 response []byte
1308}
1309
Adam Langley95c29f32014-06-20 12:00:00 -07001310func (m *certificateStatusMsg) marshal() []byte {
1311 if m.raw != nil {
1312 return m.raw
1313 }
1314
1315 var x []byte
1316 if m.statusType == statusTypeOCSP {
1317 x = make([]byte, 4+4+len(m.response))
1318 x[0] = typeCertificateStatus
1319 l := len(m.response) + 4
1320 x[1] = byte(l >> 16)
1321 x[2] = byte(l >> 8)
1322 x[3] = byte(l)
1323 x[4] = statusTypeOCSP
1324
1325 l -= 4
1326 x[5] = byte(l >> 16)
1327 x[6] = byte(l >> 8)
1328 x[7] = byte(l)
1329 copy(x[8:], m.response)
1330 } else {
1331 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1332 }
1333
1334 m.raw = x
1335 return x
1336}
1337
1338func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1339 m.raw = data
1340 if len(data) < 5 {
1341 return false
1342 }
1343 m.statusType = data[4]
1344
1345 m.response = nil
1346 if m.statusType == statusTypeOCSP {
1347 if len(data) < 8 {
1348 return false
1349 }
1350 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1351 if uint32(len(data)) != 4+4+respLen {
1352 return false
1353 }
1354 m.response = data[8:]
1355 }
1356 return true
1357}
1358
1359type serverHelloDoneMsg struct{}
1360
Adam Langley95c29f32014-06-20 12:00:00 -07001361func (m *serverHelloDoneMsg) marshal() []byte {
1362 x := make([]byte, 4)
1363 x[0] = typeServerHelloDone
1364 return x
1365}
1366
1367func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1368 return len(data) == 4
1369}
1370
1371type clientKeyExchangeMsg struct {
1372 raw []byte
1373 ciphertext []byte
1374}
1375
Adam Langley95c29f32014-06-20 12:00:00 -07001376func (m *clientKeyExchangeMsg) marshal() []byte {
1377 if m.raw != nil {
1378 return m.raw
1379 }
1380 length := len(m.ciphertext)
1381 x := make([]byte, length+4)
1382 x[0] = typeClientKeyExchange
1383 x[1] = uint8(length >> 16)
1384 x[2] = uint8(length >> 8)
1385 x[3] = uint8(length)
1386 copy(x[4:], m.ciphertext)
1387
1388 m.raw = x
1389 return x
1390}
1391
1392func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1393 m.raw = data
1394 if len(data) < 4 {
1395 return false
1396 }
1397 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1398 if l != len(data)-4 {
1399 return false
1400 }
1401 m.ciphertext = data[4:]
1402 return true
1403}
1404
1405type finishedMsg struct {
1406 raw []byte
1407 verifyData []byte
1408}
1409
Adam Langley95c29f32014-06-20 12:00:00 -07001410func (m *finishedMsg) marshal() (x []byte) {
1411 if m.raw != nil {
1412 return m.raw
1413 }
1414
1415 x = make([]byte, 4+len(m.verifyData))
1416 x[0] = typeFinished
1417 x[3] = byte(len(m.verifyData))
1418 copy(x[4:], m.verifyData)
1419 m.raw = x
1420 return
1421}
1422
1423func (m *finishedMsg) unmarshal(data []byte) bool {
1424 m.raw = data
1425 if len(data) < 4 {
1426 return false
1427 }
1428 m.verifyData = data[4:]
1429 return true
1430}
1431
1432type nextProtoMsg struct {
1433 raw []byte
1434 proto string
1435}
1436
Adam Langley95c29f32014-06-20 12:00:00 -07001437func (m *nextProtoMsg) marshal() []byte {
1438 if m.raw != nil {
1439 return m.raw
1440 }
1441 l := len(m.proto)
1442 if l > 255 {
1443 l = 255
1444 }
1445
1446 padding := 32 - (l+2)%32
1447 length := l + padding + 2
1448 x := make([]byte, length+4)
1449 x[0] = typeNextProtocol
1450 x[1] = uint8(length >> 16)
1451 x[2] = uint8(length >> 8)
1452 x[3] = uint8(length)
1453
1454 y := x[4:]
1455 y[0] = byte(l)
1456 copy(y[1:], []byte(m.proto[0:l]))
1457 y = y[1+l:]
1458 y[0] = byte(padding)
1459
1460 m.raw = x
1461
1462 return x
1463}
1464
1465func (m *nextProtoMsg) unmarshal(data []byte) bool {
1466 m.raw = data
1467
1468 if len(data) < 5 {
1469 return false
1470 }
1471 data = data[4:]
1472 protoLen := int(data[0])
1473 data = data[1:]
1474 if len(data) < protoLen {
1475 return false
1476 }
1477 m.proto = string(data[0:protoLen])
1478 data = data[protoLen:]
1479
1480 if len(data) < 1 {
1481 return false
1482 }
1483 paddingLen := int(data[0])
1484 data = data[1:]
1485 if len(data) != paddingLen {
1486 return false
1487 }
1488
1489 return true
1490}
1491
1492type certificateRequestMsg struct {
1493 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001494 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001495 // of signature and hash functions. This change was introduced with TLS
1496 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001497 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001498 // hasRequestContext indicates whether this message includes a context
1499 // field instead of certificateTypes. This change was introduced with
1500 // TLS 1.3.
1501 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001502
1503 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001504 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001505 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001506 certificateAuthorities [][]byte
1507}
1508
Nick Harper7e0442a2016-07-01 17:40:09 -04001509func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001510 if m.raw != nil {
1511 return m.raw
1512 }
1513
1514 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001515 builder := newByteBuilder()
1516 builder.addU8(typeCertificateRequest)
1517 body := builder.addU24LengthPrefixed()
1518
Nick Harperb41d2e42016-07-01 17:50:32 -04001519 if m.hasRequestContext {
1520 requestContext := body.addU8LengthPrefixed()
1521 requestContext.addBytes(m.requestContext)
1522 } else {
1523 certificateTypes := body.addU8LengthPrefixed()
1524 certificateTypes.addBytes(m.certificateTypes)
1525 }
Adam Langley95c29f32014-06-20 12:00:00 -07001526
Nick Harper60edffd2016-06-21 15:19:24 -07001527 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001528 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001529 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001530 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001531 }
1532 }
1533
Nick Harper7e0442a2016-07-01 17:40:09 -04001534 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001535 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001536 caEntry := certificateAuthorities.addU16LengthPrefixed()
1537 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001538 }
1539
David Benjamin8d343b42016-07-09 14:26:01 -07001540 if m.hasRequestContext {
1541 // Emit no certificate extensions.
1542 body.addU16(0)
1543 }
1544
Nick Harper7e0442a2016-07-01 17:40:09 -04001545 m.raw = builder.finish()
1546 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001547}
1548
1549func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1550 m.raw = data
1551
1552 if len(data) < 5 {
1553 return false
1554 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001555 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001556
Nick Harperb41d2e42016-07-01 17:50:32 -04001557 if m.hasRequestContext {
1558 contextLen := int(data[0])
1559 if len(data) < 1+contextLen {
1560 return false
1561 }
1562 m.requestContext = make([]byte, contextLen)
1563 copy(m.requestContext, data[1:])
1564 data = data[1+contextLen:]
1565 } else {
1566 numCertTypes := int(data[0])
1567 if len(data) < 1+numCertTypes {
1568 return false
1569 }
1570 m.certificateTypes = make([]byte, numCertTypes)
1571 copy(m.certificateTypes, data[1:])
1572 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001573 }
1574
Nick Harper60edffd2016-06-21 15:19:24 -07001575 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001576 if len(data) < 2 {
1577 return false
1578 }
Nick Harper60edffd2016-06-21 15:19:24 -07001579 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001580 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001581 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001582 return false
1583 }
Nick Harper60edffd2016-06-21 15:19:24 -07001584 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001585 return false
1586 }
Nick Harper60edffd2016-06-21 15:19:24 -07001587 numSigAlgs := sigAlgsLen / 2
1588 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1589 for i := range m.signatureAlgorithms {
1590 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001591 data = data[2:]
1592 }
1593 }
1594
1595 if len(data) < 2 {
1596 return false
1597 }
1598 casLength := uint16(data[0])<<8 | uint16(data[1])
1599 data = data[2:]
1600 if len(data) < int(casLength) {
1601 return false
1602 }
1603 cas := make([]byte, casLength)
1604 copy(cas, data)
1605 data = data[casLength:]
1606
1607 m.certificateAuthorities = nil
1608 for len(cas) > 0 {
1609 if len(cas) < 2 {
1610 return false
1611 }
1612 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1613 cas = cas[2:]
1614
1615 if len(cas) < int(caLen) {
1616 return false
1617 }
1618
1619 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1620 cas = cas[caLen:]
1621 }
David Benjamin8d343b42016-07-09 14:26:01 -07001622
1623 if m.hasRequestContext {
1624 // Ignore certificate extensions.
1625 if len(data) < 2 {
1626 return false
1627 }
1628 extsLength := int(data[0])<<8 | int(data[1])
1629 if len(data) < 2+extsLength {
1630 return false
1631 }
1632 data = data[2+extsLength:]
1633 }
1634
Adam Langley95c29f32014-06-20 12:00:00 -07001635 if len(data) > 0 {
1636 return false
1637 }
1638
1639 return true
1640}
1641
1642type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07001643 raw []byte
1644 hasSignatureAlgorithm bool
1645 signatureAlgorithm signatureAlgorithm
1646 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001647}
1648
Adam Langley95c29f32014-06-20 12:00:00 -07001649func (m *certificateVerifyMsg) marshal() (x []byte) {
1650 if m.raw != nil {
1651 return m.raw
1652 }
1653
1654 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1655 siglength := len(m.signature)
1656 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07001657 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001658 length += 2
1659 }
1660 x = make([]byte, 4+length)
1661 x[0] = typeCertificateVerify
1662 x[1] = uint8(length >> 16)
1663 x[2] = uint8(length >> 8)
1664 x[3] = uint8(length)
1665 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001666 if m.hasSignatureAlgorithm {
1667 y[0] = byte(m.signatureAlgorithm >> 8)
1668 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07001669 y = y[2:]
1670 }
1671 y[0] = uint8(siglength >> 8)
1672 y[1] = uint8(siglength)
1673 copy(y[2:], m.signature)
1674
1675 m.raw = x
1676
1677 return
1678}
1679
1680func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1681 m.raw = data
1682
1683 if len(data) < 6 {
1684 return false
1685 }
1686
1687 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1688 if uint32(len(data))-4 != length {
1689 return false
1690 }
1691
1692 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001693 if m.hasSignatureAlgorithm {
1694 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001695 data = data[2:]
1696 }
1697
1698 if len(data) < 2 {
1699 return false
1700 }
1701 siglength := int(data[0])<<8 + int(data[1])
1702 data = data[2:]
1703 if len(data) != siglength {
1704 return false
1705 }
1706
1707 m.signature = data
1708
1709 return true
1710}
1711
1712type newSessionTicketMsg struct {
1713 raw []byte
1714 ticket []byte
1715}
1716
Adam Langley95c29f32014-06-20 12:00:00 -07001717func (m *newSessionTicketMsg) marshal() (x []byte) {
1718 if m.raw != nil {
1719 return m.raw
1720 }
1721
1722 // See http://tools.ietf.org/html/rfc5077#section-3.3
1723 ticketLen := len(m.ticket)
1724 length := 2 + 4 + ticketLen
1725 x = make([]byte, 4+length)
1726 x[0] = typeNewSessionTicket
1727 x[1] = uint8(length >> 16)
1728 x[2] = uint8(length >> 8)
1729 x[3] = uint8(length)
1730 x[8] = uint8(ticketLen >> 8)
1731 x[9] = uint8(ticketLen)
1732 copy(x[10:], m.ticket)
1733
1734 m.raw = x
1735
1736 return
1737}
1738
1739func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
1740 m.raw = data
1741
1742 if len(data) < 10 {
1743 return false
1744 }
1745
1746 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1747 if uint32(len(data))-4 != length {
1748 return false
1749 }
1750
1751 ticketLen := int(data[8])<<8 + int(data[9])
1752 if len(data)-10 != ticketLen {
1753 return false
1754 }
1755
1756 m.ticket = data[10:]
1757
1758 return true
1759}
1760
David Benjamind86c7672014-08-02 04:07:12 -04001761type v2ClientHelloMsg struct {
1762 raw []byte
1763 vers uint16
1764 cipherSuites []uint16
1765 sessionId []byte
1766 challenge []byte
1767}
1768
David Benjamind86c7672014-08-02 04:07:12 -04001769func (m *v2ClientHelloMsg) marshal() []byte {
1770 if m.raw != nil {
1771 return m.raw
1772 }
1773
1774 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
1775
1776 x := make([]byte, length)
1777 x[0] = 1
1778 x[1] = uint8(m.vers >> 8)
1779 x[2] = uint8(m.vers)
1780 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
1781 x[4] = uint8(len(m.cipherSuites) * 3)
1782 x[5] = uint8(len(m.sessionId) >> 8)
1783 x[6] = uint8(len(m.sessionId))
1784 x[7] = uint8(len(m.challenge) >> 8)
1785 x[8] = uint8(len(m.challenge))
1786 y := x[9:]
1787 for i, spec := range m.cipherSuites {
1788 y[i*3] = 0
1789 y[i*3+1] = uint8(spec >> 8)
1790 y[i*3+2] = uint8(spec)
1791 }
1792 y = y[len(m.cipherSuites)*3:]
1793 copy(y, m.sessionId)
1794 y = y[len(m.sessionId):]
1795 copy(y, m.challenge)
1796
1797 m.raw = x
1798
1799 return x
1800}
1801
David Benjamin83c0bc92014-08-04 01:23:53 -04001802type helloVerifyRequestMsg struct {
1803 raw []byte
1804 vers uint16
1805 cookie []byte
1806}
1807
David Benjamin83c0bc92014-08-04 01:23:53 -04001808func (m *helloVerifyRequestMsg) marshal() []byte {
1809 if m.raw != nil {
1810 return m.raw
1811 }
1812
1813 length := 2 + 1 + len(m.cookie)
1814
1815 x := make([]byte, 4+length)
1816 x[0] = typeHelloVerifyRequest
1817 x[1] = uint8(length >> 16)
1818 x[2] = uint8(length >> 8)
1819 x[3] = uint8(length)
1820 vers := versionToWire(m.vers, true)
1821 x[4] = uint8(vers >> 8)
1822 x[5] = uint8(vers)
1823 x[6] = uint8(len(m.cookie))
1824 copy(x[7:7+len(m.cookie)], m.cookie)
1825
1826 return x
1827}
1828
1829func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
1830 if len(data) < 4+2+1 {
1831 return false
1832 }
1833 m.raw = data
1834 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), true)
1835 cookieLen := int(data[6])
1836 if cookieLen > 32 || len(data) != 7+cookieLen {
1837 return false
1838 }
1839 m.cookie = data[7 : 7+cookieLen]
1840
1841 return true
1842}
1843
David Benjamin24599a82016-06-30 18:56:53 -04001844type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04001845 raw []byte
1846 channelID []byte
1847}
1848
David Benjamin24599a82016-06-30 18:56:53 -04001849func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04001850 if m.raw != nil {
1851 return m.raw
1852 }
1853
1854 length := 2 + 2 + len(m.channelID)
1855
1856 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04001857 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04001858 x[1] = uint8(length >> 16)
1859 x[2] = uint8(length >> 8)
1860 x[3] = uint8(length)
1861 x[4] = uint8(extensionChannelID >> 8)
1862 x[5] = uint8(extensionChannelID & 0xff)
1863 x[6] = uint8(len(m.channelID) >> 8)
1864 x[7] = uint8(len(m.channelID) & 0xff)
1865 copy(x[8:], m.channelID)
1866
1867 return x
1868}
1869
David Benjamin24599a82016-06-30 18:56:53 -04001870func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04001871 if len(data) != 4+2+2+128 {
1872 return false
1873 }
1874 m.raw = data
1875 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
1876 return false
1877 }
1878 if int(data[6])<<8|int(data[7]) != 128 {
1879 return false
1880 }
1881 m.channelID = data[4+2+2:]
1882
1883 return true
1884}
1885
Adam Langley2ae77d22014-10-28 17:29:33 -07001886type helloRequestMsg struct {
1887}
1888
1889func (*helloRequestMsg) marshal() []byte {
1890 return []byte{typeHelloRequest, 0, 0, 0}
1891}
1892
1893func (*helloRequestMsg) unmarshal(data []byte) bool {
1894 return len(data) == 4
1895}
1896
Adam Langley95c29f32014-06-20 12:00:00 -07001897func eqUint16s(x, y []uint16) bool {
1898 if len(x) != len(y) {
1899 return false
1900 }
1901 for i, v := range x {
1902 if y[i] != v {
1903 return false
1904 }
1905 }
1906 return true
1907}
1908
1909func eqCurveIDs(x, y []CurveID) bool {
1910 if len(x) != len(y) {
1911 return false
1912 }
1913 for i, v := range x {
1914 if y[i] != v {
1915 return false
1916 }
1917 }
1918 return true
1919}
1920
1921func eqStrings(x, y []string) bool {
1922 if len(x) != len(y) {
1923 return false
1924 }
1925 for i, v := range x {
1926 if y[i] != v {
1927 return false
1928 }
1929 }
1930 return true
1931}
1932
1933func eqByteSlices(x, y [][]byte) bool {
1934 if len(x) != len(y) {
1935 return false
1936 }
1937 for i, v := range x {
1938 if !bytes.Equal(v, y[i]) {
1939 return false
1940 }
1941 }
1942 return true
1943}
1944
Nick Harper60edffd2016-06-21 15:19:24 -07001945func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07001946 if len(x) != len(y) {
1947 return false
1948 }
1949 for i, v := range x {
1950 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07001951 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07001952 return false
1953 }
1954 }
1955 return true
1956}
Nick Harperf8b0e702016-06-30 19:59:01 -04001957
1958func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
1959 if len(x) != len(y) {
1960 return false
1961 }
1962 for i, v := range x {
1963 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
1964 return false
1965 }
1966 }
1967 return true
1968
1969}