blob: f0a1493053e17b6a5bca48fd9c827bb947a0b0f4 [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
5package main
6
7import "bytes"
8
9type clientHelloMsg struct {
10 raw []byte
David Benjamin83c0bc92014-08-04 01:23:53 -040011 isDTLS bool
Adam Langley95c29f32014-06-20 12:00:00 -070012 vers uint16
13 random []byte
14 sessionId []byte
David Benjamin83c0bc92014-08-04 01:23:53 -040015 cookie []byte
Adam Langley95c29f32014-06-20 12:00:00 -070016 cipherSuites []uint16
17 compressionMethods []uint8
18 nextProtoNeg bool
19 serverName string
20 ocspStapling bool
21 supportedCurves []CurveID
22 supportedPoints []uint8
23 ticketSupported bool
24 sessionTicket []uint8
25 signatureAndHashes []signatureAndHash
26 secureRenegotiation bool
David Benjaminfa055a22014-09-15 16:51:51 -040027 alpnProtocols []string
David Benjamin35a7a442014-07-05 00:23:20 -040028 duplicateExtension bool
David Benjamind30a9902014-08-24 01:44:23 -040029 channelIDSupported bool
Adam Langley95c29f32014-06-20 12:00:00 -070030}
31
32func (m *clientHelloMsg) equal(i interface{}) bool {
33 m1, ok := i.(*clientHelloMsg)
34 if !ok {
35 return false
36 }
37
38 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -040039 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -070040 m.vers == m1.vers &&
41 bytes.Equal(m.random, m1.random) &&
42 bytes.Equal(m.sessionId, m1.sessionId) &&
David Benjamin83c0bc92014-08-04 01:23:53 -040043 bytes.Equal(m.cookie, m1.cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -070044 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
45 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
46 m.nextProtoNeg == m1.nextProtoNeg &&
47 m.serverName == m1.serverName &&
48 m.ocspStapling == m1.ocspStapling &&
49 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
50 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
51 m.ticketSupported == m1.ticketSupported &&
52 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
53 eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) &&
David Benjamind30a9902014-08-24 01:44:23 -040054 m.secureRenegotiation == m1.secureRenegotiation &&
David Benjaminfa055a22014-09-15 16:51:51 -040055 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -040056 m.duplicateExtension == m1.duplicateExtension &&
57 m.channelIDSupported == m1.channelIDSupported
Adam Langley95c29f32014-06-20 12:00:00 -070058}
59
60func (m *clientHelloMsg) marshal() []byte {
61 if m.raw != nil {
62 return m.raw
63 }
64
65 length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods)
David Benjamin83c0bc92014-08-04 01:23:53 -040066 if m.isDTLS {
67 length += 1 + len(m.cookie)
68 }
Adam Langley95c29f32014-06-20 12:00:00 -070069 numExtensions := 0
70 extensionsLength := 0
71 if m.nextProtoNeg {
72 numExtensions++
73 }
74 if m.ocspStapling {
75 extensionsLength += 1 + 2 + 2
76 numExtensions++
77 }
78 if len(m.serverName) > 0 {
79 extensionsLength += 5 + len(m.serverName)
80 numExtensions++
81 }
82 if len(m.supportedCurves) > 0 {
83 extensionsLength += 2 + 2*len(m.supportedCurves)
84 numExtensions++
85 }
86 if len(m.supportedPoints) > 0 {
87 extensionsLength += 1 + len(m.supportedPoints)
88 numExtensions++
89 }
90 if m.ticketSupported {
91 extensionsLength += len(m.sessionTicket)
92 numExtensions++
93 }
94 if len(m.signatureAndHashes) > 0 {
95 extensionsLength += 2 + 2*len(m.signatureAndHashes)
96 numExtensions++
97 }
98 if m.secureRenegotiation {
99 extensionsLength += 1
100 numExtensions++
101 }
David Benjamin35a7a442014-07-05 00:23:20 -0400102 if m.duplicateExtension {
103 numExtensions += 2
104 }
David Benjamind30a9902014-08-24 01:44:23 -0400105 if m.channelIDSupported {
106 numExtensions++
107 }
David Benjaminfa055a22014-09-15 16:51:51 -0400108 if len(m.alpnProtocols) > 0 {
109 extensionsLength += 2
110 for _, s := range m.alpnProtocols {
111 if l := len(s); l == 0 || l > 255 {
112 panic("invalid ALPN protocol")
113 }
114 extensionsLength++
115 extensionsLength += len(s)
116 }
117 numExtensions++
118 }
Adam Langley95c29f32014-06-20 12:00:00 -0700119 if numExtensions > 0 {
120 extensionsLength += 4 * numExtensions
121 length += 2 + extensionsLength
122 }
123
124 x := make([]byte, 4+length)
125 x[0] = typeClientHello
126 x[1] = uint8(length >> 16)
127 x[2] = uint8(length >> 8)
128 x[3] = uint8(length)
David Benjamin83c0bc92014-08-04 01:23:53 -0400129 vers := versionToWire(m.vers, m.isDTLS)
130 x[4] = uint8(vers >> 8)
131 x[5] = uint8(vers)
Adam Langley95c29f32014-06-20 12:00:00 -0700132 copy(x[6:38], m.random)
133 x[38] = uint8(len(m.sessionId))
134 copy(x[39:39+len(m.sessionId)], m.sessionId)
135 y := x[39+len(m.sessionId):]
David Benjamin83c0bc92014-08-04 01:23:53 -0400136 if m.isDTLS {
137 y[0] = uint8(len(m.cookie))
138 copy(y[1:], m.cookie)
139 y = y[1+len(m.cookie):]
140 }
Adam Langley95c29f32014-06-20 12:00:00 -0700141 y[0] = uint8(len(m.cipherSuites) >> 7)
142 y[1] = uint8(len(m.cipherSuites) << 1)
143 for i, suite := range m.cipherSuites {
144 y[2+i*2] = uint8(suite >> 8)
145 y[3+i*2] = uint8(suite)
146 }
147 z := y[2+len(m.cipherSuites)*2:]
148 z[0] = uint8(len(m.compressionMethods))
149 copy(z[1:], m.compressionMethods)
150
151 z = z[1+len(m.compressionMethods):]
152 if numExtensions > 0 {
153 z[0] = byte(extensionsLength >> 8)
154 z[1] = byte(extensionsLength)
155 z = z[2:]
156 }
David Benjamin35a7a442014-07-05 00:23:20 -0400157 if m.duplicateExtension {
158 // Add a duplicate bogus extension at the beginning and end.
159 z[0] = 0xff
160 z[1] = 0xff
161 z = z[4:]
162 }
Adam Langley95c29f32014-06-20 12:00:00 -0700163 if m.nextProtoNeg {
164 z[0] = byte(extensionNextProtoNeg >> 8)
165 z[1] = byte(extensionNextProtoNeg & 0xff)
166 // The length is always 0
167 z = z[4:]
168 }
169 if len(m.serverName) > 0 {
170 z[0] = byte(extensionServerName >> 8)
171 z[1] = byte(extensionServerName & 0xff)
172 l := len(m.serverName) + 5
173 z[2] = byte(l >> 8)
174 z[3] = byte(l)
175 z = z[4:]
176
177 // RFC 3546, section 3.1
178 //
179 // struct {
180 // NameType name_type;
181 // select (name_type) {
182 // case host_name: HostName;
183 // } name;
184 // } ServerName;
185 //
186 // enum {
187 // host_name(0), (255)
188 // } NameType;
189 //
190 // opaque HostName<1..2^16-1>;
191 //
192 // struct {
193 // ServerName server_name_list<1..2^16-1>
194 // } ServerNameList;
195
196 z[0] = byte((len(m.serverName) + 3) >> 8)
197 z[1] = byte(len(m.serverName) + 3)
198 z[3] = byte(len(m.serverName) >> 8)
199 z[4] = byte(len(m.serverName))
200 copy(z[5:], []byte(m.serverName))
201 z = z[l:]
202 }
203 if m.ocspStapling {
204 // RFC 4366, section 3.6
205 z[0] = byte(extensionStatusRequest >> 8)
206 z[1] = byte(extensionStatusRequest)
207 z[2] = 0
208 z[3] = 5
209 z[4] = 1 // OCSP type
210 // Two zero valued uint16s for the two lengths.
211 z = z[9:]
212 }
213 if len(m.supportedCurves) > 0 {
214 // http://tools.ietf.org/html/rfc4492#section-5.5.1
215 z[0] = byte(extensionSupportedCurves >> 8)
216 z[1] = byte(extensionSupportedCurves)
217 l := 2 + 2*len(m.supportedCurves)
218 z[2] = byte(l >> 8)
219 z[3] = byte(l)
220 l -= 2
221 z[4] = byte(l >> 8)
222 z[5] = byte(l)
223 z = z[6:]
224 for _, curve := range m.supportedCurves {
225 z[0] = byte(curve >> 8)
226 z[1] = byte(curve)
227 z = z[2:]
228 }
229 }
230 if len(m.supportedPoints) > 0 {
231 // http://tools.ietf.org/html/rfc4492#section-5.5.2
232 z[0] = byte(extensionSupportedPoints >> 8)
233 z[1] = byte(extensionSupportedPoints)
234 l := 1 + len(m.supportedPoints)
235 z[2] = byte(l >> 8)
236 z[3] = byte(l)
237 l--
238 z[4] = byte(l)
239 z = z[5:]
240 for _, pointFormat := range m.supportedPoints {
241 z[0] = byte(pointFormat)
242 z = z[1:]
243 }
244 }
245 if m.ticketSupported {
246 // http://tools.ietf.org/html/rfc5077#section-3.2
247 z[0] = byte(extensionSessionTicket >> 8)
248 z[1] = byte(extensionSessionTicket)
249 l := len(m.sessionTicket)
250 z[2] = byte(l >> 8)
251 z[3] = byte(l)
252 z = z[4:]
253 copy(z, m.sessionTicket)
254 z = z[len(m.sessionTicket):]
255 }
256 if len(m.signatureAndHashes) > 0 {
257 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
258 z[0] = byte(extensionSignatureAlgorithms >> 8)
259 z[1] = byte(extensionSignatureAlgorithms)
260 l := 2 + 2*len(m.signatureAndHashes)
261 z[2] = byte(l >> 8)
262 z[3] = byte(l)
263 z = z[4:]
264
265 l -= 2
266 z[0] = byte(l >> 8)
267 z[1] = byte(l)
268 z = z[2:]
269 for _, sigAndHash := range m.signatureAndHashes {
270 z[0] = sigAndHash.hash
271 z[1] = sigAndHash.signature
272 z = z[2:]
273 }
274 }
275 if m.secureRenegotiation {
276 z[0] = byte(extensionRenegotiationInfo >> 8)
277 z[1] = byte(extensionRenegotiationInfo & 0xff)
278 z[2] = 0
279 z[3] = 1
280 z = z[5:]
281 }
David Benjaminfa055a22014-09-15 16:51:51 -0400282 if len(m.alpnProtocols) > 0 {
283 z[0] = byte(extensionALPN >> 8)
284 z[1] = byte(extensionALPN & 0xff)
285 lengths := z[2:]
286 z = z[6:]
287
288 stringsLength := 0
289 for _, s := range m.alpnProtocols {
290 l := len(s)
291 z[0] = byte(l)
292 copy(z[1:], s)
293 z = z[1+l:]
294 stringsLength += 1 + l
295 }
296
297 lengths[2] = byte(stringsLength >> 8)
298 lengths[3] = byte(stringsLength)
299 stringsLength += 2
300 lengths[0] = byte(stringsLength >> 8)
301 lengths[1] = byte(stringsLength)
302 }
David Benjamind30a9902014-08-24 01:44:23 -0400303 if m.channelIDSupported {
304 z[0] = byte(extensionChannelID >> 8)
305 z[1] = byte(extensionChannelID & 0xff)
306 z = z[4:]
307 }
David Benjamin35a7a442014-07-05 00:23:20 -0400308 if m.duplicateExtension {
309 // Add a duplicate bogus extension at the beginning and end.
310 z[0] = 0xff
311 z[1] = 0xff
312 z = z[4:]
313 }
Adam Langley95c29f32014-06-20 12:00:00 -0700314
315 m.raw = x
316
317 return x
318}
319
320func (m *clientHelloMsg) unmarshal(data []byte) bool {
321 if len(data) < 42 {
322 return false
323 }
324 m.raw = data
David Benjamin83c0bc92014-08-04 01:23:53 -0400325 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
Adam Langley95c29f32014-06-20 12:00:00 -0700326 m.random = data[6:38]
327 sessionIdLen := int(data[38])
328 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
329 return false
330 }
331 m.sessionId = data[39 : 39+sessionIdLen]
332 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400333 if m.isDTLS {
334 if len(data) < 1 {
335 return false
336 }
337 cookieLen := int(data[0])
338 if cookieLen > 32 || len(data) < 1+cookieLen {
339 return false
340 }
341 m.cookie = data[1 : 1+cookieLen]
342 data = data[1+cookieLen:]
343 }
Adam Langley95c29f32014-06-20 12:00:00 -0700344 if len(data) < 2 {
345 return false
346 }
347 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
348 // they are uint16s, the number must be even.
349 cipherSuiteLen := int(data[0])<<8 | int(data[1])
350 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
351 return false
352 }
353 numCipherSuites := cipherSuiteLen / 2
354 m.cipherSuites = make([]uint16, numCipherSuites)
355 for i := 0; i < numCipherSuites; i++ {
356 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
357 if m.cipherSuites[i] == scsvRenegotiation {
358 m.secureRenegotiation = true
359 }
360 }
361 data = data[2+cipherSuiteLen:]
362 if len(data) < 1 {
363 return false
364 }
365 compressionMethodsLen := int(data[0])
366 if len(data) < 1+compressionMethodsLen {
367 return false
368 }
369 m.compressionMethods = data[1 : 1+compressionMethodsLen]
370
371 data = data[1+compressionMethodsLen:]
372
373 m.nextProtoNeg = false
374 m.serverName = ""
375 m.ocspStapling = false
376 m.ticketSupported = false
377 m.sessionTicket = nil
378 m.signatureAndHashes = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400379 m.alpnProtocols = nil
Adam Langley95c29f32014-06-20 12:00:00 -0700380
381 if len(data) == 0 {
382 // ClientHello is optionally followed by extension data
383 return true
384 }
385 if len(data) < 2 {
386 return false
387 }
388
389 extensionsLength := int(data[0])<<8 | int(data[1])
390 data = data[2:]
391 if extensionsLength != len(data) {
392 return false
393 }
394
395 for len(data) != 0 {
396 if len(data) < 4 {
397 return false
398 }
399 extension := uint16(data[0])<<8 | uint16(data[1])
400 length := int(data[2])<<8 | int(data[3])
401 data = data[4:]
402 if len(data) < length {
403 return false
404 }
405
406 switch extension {
407 case extensionServerName:
408 if length < 2 {
409 return false
410 }
411 numNames := int(data[0])<<8 | int(data[1])
412 d := data[2:]
413 for i := 0; i < numNames; i++ {
414 if len(d) < 3 {
415 return false
416 }
417 nameType := d[0]
418 nameLen := int(d[1])<<8 | int(d[2])
419 d = d[3:]
420 if len(d) < nameLen {
421 return false
422 }
423 if nameType == 0 {
424 m.serverName = string(d[0:nameLen])
425 break
426 }
427 d = d[nameLen:]
428 }
429 case extensionNextProtoNeg:
430 if length > 0 {
431 return false
432 }
433 m.nextProtoNeg = true
434 case extensionStatusRequest:
435 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
436 case extensionSupportedCurves:
437 // http://tools.ietf.org/html/rfc4492#section-5.5.1
438 if length < 2 {
439 return false
440 }
441 l := int(data[0])<<8 | int(data[1])
442 if l%2 == 1 || length != l+2 {
443 return false
444 }
445 numCurves := l / 2
446 m.supportedCurves = make([]CurveID, numCurves)
447 d := data[2:]
448 for i := 0; i < numCurves; i++ {
449 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
450 d = d[2:]
451 }
452 case extensionSupportedPoints:
453 // http://tools.ietf.org/html/rfc4492#section-5.5.2
454 if length < 1 {
455 return false
456 }
457 l := int(data[0])
458 if length != l+1 {
459 return false
460 }
461 m.supportedPoints = make([]uint8, l)
462 copy(m.supportedPoints, data[1:])
463 case extensionSessionTicket:
464 // http://tools.ietf.org/html/rfc5077#section-3.2
465 m.ticketSupported = true
466 m.sessionTicket = data[:length]
467 case extensionSignatureAlgorithms:
468 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
469 if length < 2 || length&1 != 0 {
470 return false
471 }
472 l := int(data[0])<<8 | int(data[1])
473 if l != length-2 {
474 return false
475 }
476 n := l / 2
477 d := data[2:]
478 m.signatureAndHashes = make([]signatureAndHash, n)
479 for i := range m.signatureAndHashes {
480 m.signatureAndHashes[i].hash = d[0]
481 m.signatureAndHashes[i].signature = d[1]
482 d = d[2:]
483 }
484 case extensionRenegotiationInfo + 1:
485 if length != 1 || data[0] != 0 {
486 return false
487 }
488 m.secureRenegotiation = true
David Benjaminfa055a22014-09-15 16:51:51 -0400489 case extensionALPN:
490 if length < 2 {
491 return false
492 }
493 l := int(data[0])<<8 | int(data[1])
494 if l != length-2 {
495 return false
496 }
497 d := data[2:length]
498 for len(d) != 0 {
499 stringLen := int(d[0])
500 d = d[1:]
501 if stringLen == 0 || stringLen > len(d) {
502 return false
503 }
504 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
505 d = d[stringLen:]
506 }
David Benjamind30a9902014-08-24 01:44:23 -0400507 case extensionChannelID:
508 if length > 0 {
509 return false
510 }
511 m.channelIDSupported = true
Adam Langley95c29f32014-06-20 12:00:00 -0700512 }
513 data = data[length:]
514 }
515
516 return true
517}
518
519type serverHelloMsg struct {
520 raw []byte
David Benjamin83c0bc92014-08-04 01:23:53 -0400521 isDTLS bool
Adam Langley95c29f32014-06-20 12:00:00 -0700522 vers uint16
523 random []byte
524 sessionId []byte
525 cipherSuite uint16
526 compressionMethod uint8
527 nextProtoNeg bool
528 nextProtos []string
529 ocspStapling bool
530 ticketSupported bool
531 secureRenegotiation bool
David Benjaminfa055a22014-09-15 16:51:51 -0400532 alpnProtocol string
David Benjamin35a7a442014-07-05 00:23:20 -0400533 duplicateExtension bool
David Benjamind30a9902014-08-24 01:44:23 -0400534 channelIDRequested bool
Adam Langley95c29f32014-06-20 12:00:00 -0700535}
536
537func (m *serverHelloMsg) equal(i interface{}) bool {
538 m1, ok := i.(*serverHelloMsg)
539 if !ok {
540 return false
541 }
542
543 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400544 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700545 m.vers == m1.vers &&
546 bytes.Equal(m.random, m1.random) &&
547 bytes.Equal(m.sessionId, m1.sessionId) &&
548 m.cipherSuite == m1.cipherSuite &&
549 m.compressionMethod == m1.compressionMethod &&
550 m.nextProtoNeg == m1.nextProtoNeg &&
551 eqStrings(m.nextProtos, m1.nextProtos) &&
552 m.ocspStapling == m1.ocspStapling &&
553 m.ticketSupported == m1.ticketSupported &&
David Benjamind30a9902014-08-24 01:44:23 -0400554 m.secureRenegotiation == m1.secureRenegotiation &&
David Benjaminfa055a22014-09-15 16:51:51 -0400555 m.alpnProtocol == m1.alpnProtocol &&
David Benjamind30a9902014-08-24 01:44:23 -0400556 m.duplicateExtension == m1.duplicateExtension &&
557 m.channelIDRequested == m1.channelIDRequested
Adam Langley95c29f32014-06-20 12:00:00 -0700558}
559
560func (m *serverHelloMsg) marshal() []byte {
561 if m.raw != nil {
562 return m.raw
563 }
564
565 length := 38 + len(m.sessionId)
566 numExtensions := 0
567 extensionsLength := 0
568
569 nextProtoLen := 0
570 if m.nextProtoNeg {
571 numExtensions++
572 for _, v := range m.nextProtos {
573 nextProtoLen += len(v)
574 }
575 nextProtoLen += len(m.nextProtos)
576 extensionsLength += nextProtoLen
577 }
578 if m.ocspStapling {
579 numExtensions++
580 }
581 if m.ticketSupported {
582 numExtensions++
583 }
584 if m.secureRenegotiation {
585 extensionsLength += 1
586 numExtensions++
587 }
David Benjamin35a7a442014-07-05 00:23:20 -0400588 if m.duplicateExtension {
589 numExtensions += 2
590 }
David Benjamind30a9902014-08-24 01:44:23 -0400591 if m.channelIDRequested {
592 numExtensions++
593 }
David Benjaminfa055a22014-09-15 16:51:51 -0400594 if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
595 if alpnLen >= 256 {
596 panic("invalid ALPN protocol")
597 }
598 extensionsLength += 2 + 1 + alpnLen
599 numExtensions++
600 }
601
Adam Langley95c29f32014-06-20 12:00:00 -0700602 if numExtensions > 0 {
603 extensionsLength += 4 * numExtensions
604 length += 2 + extensionsLength
605 }
606
607 x := make([]byte, 4+length)
608 x[0] = typeServerHello
609 x[1] = uint8(length >> 16)
610 x[2] = uint8(length >> 8)
611 x[3] = uint8(length)
David Benjamin83c0bc92014-08-04 01:23:53 -0400612 vers := versionToWire(m.vers, m.isDTLS)
613 x[4] = uint8(vers >> 8)
614 x[5] = uint8(vers)
Adam Langley95c29f32014-06-20 12:00:00 -0700615 copy(x[6:38], m.random)
616 x[38] = uint8(len(m.sessionId))
617 copy(x[39:39+len(m.sessionId)], m.sessionId)
618 z := x[39+len(m.sessionId):]
619 z[0] = uint8(m.cipherSuite >> 8)
620 z[1] = uint8(m.cipherSuite)
621 z[2] = uint8(m.compressionMethod)
622
623 z = z[3:]
624 if numExtensions > 0 {
625 z[0] = byte(extensionsLength >> 8)
626 z[1] = byte(extensionsLength)
627 z = z[2:]
628 }
David Benjamin35a7a442014-07-05 00:23:20 -0400629 if m.duplicateExtension {
630 // Add a duplicate bogus extension at the beginning and end.
631 z[0] = 0xff
632 z[1] = 0xff
633 z = z[4:]
634 }
Adam Langley95c29f32014-06-20 12:00:00 -0700635 if m.nextProtoNeg {
636 z[0] = byte(extensionNextProtoNeg >> 8)
637 z[1] = byte(extensionNextProtoNeg & 0xff)
638 z[2] = byte(nextProtoLen >> 8)
639 z[3] = byte(nextProtoLen)
640 z = z[4:]
641
642 for _, v := range m.nextProtos {
643 l := len(v)
644 if l > 255 {
645 l = 255
646 }
647 z[0] = byte(l)
648 copy(z[1:], []byte(v[0:l]))
649 z = z[1+l:]
650 }
651 }
652 if m.ocspStapling {
653 z[0] = byte(extensionStatusRequest >> 8)
654 z[1] = byte(extensionStatusRequest)
655 z = z[4:]
656 }
657 if m.ticketSupported {
658 z[0] = byte(extensionSessionTicket >> 8)
659 z[1] = byte(extensionSessionTicket)
660 z = z[4:]
661 }
662 if m.secureRenegotiation {
663 z[0] = byte(extensionRenegotiationInfo >> 8)
664 z[1] = byte(extensionRenegotiationInfo & 0xff)
665 z[2] = 0
666 z[3] = 1
667 z = z[5:]
668 }
David Benjaminfa055a22014-09-15 16:51:51 -0400669 if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
670 z[0] = byte(extensionALPN >> 8)
671 z[1] = byte(extensionALPN & 0xff)
672 l := 2 + 1 + alpnLen
673 z[2] = byte(l >> 8)
674 z[3] = byte(l)
675 l -= 2
676 z[4] = byte(l >> 8)
677 z[5] = byte(l)
678 l -= 1
679 z[6] = byte(l)
680 copy(z[7:], []byte(m.alpnProtocol))
681 z = z[7+alpnLen:]
682 }
David Benjamind30a9902014-08-24 01:44:23 -0400683 if m.channelIDRequested {
684 z[0] = byte(extensionChannelID >> 8)
685 z[1] = byte(extensionChannelID & 0xff)
686 z = z[4:]
687 }
David Benjamin35a7a442014-07-05 00:23:20 -0400688 if m.duplicateExtension {
689 // Add a duplicate bogus extension at the beginning and end.
690 z[0] = 0xff
691 z[1] = 0xff
692 z = z[4:]
693 }
Adam Langley95c29f32014-06-20 12:00:00 -0700694
695 m.raw = x
696
697 return x
698}
699
700func (m *serverHelloMsg) unmarshal(data []byte) bool {
701 if len(data) < 42 {
702 return false
703 }
704 m.raw = data
David Benjamin83c0bc92014-08-04 01:23:53 -0400705 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
Adam Langley95c29f32014-06-20 12:00:00 -0700706 m.random = data[6:38]
707 sessionIdLen := int(data[38])
708 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
709 return false
710 }
711 m.sessionId = data[39 : 39+sessionIdLen]
712 data = data[39+sessionIdLen:]
713 if len(data) < 3 {
714 return false
715 }
716 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
717 m.compressionMethod = data[2]
718 data = data[3:]
719
720 m.nextProtoNeg = false
721 m.nextProtos = nil
722 m.ocspStapling = false
723 m.ticketSupported = false
David Benjaminfa055a22014-09-15 16:51:51 -0400724 m.alpnProtocol = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700725
726 if len(data) == 0 {
727 // ServerHello is optionally followed by extension data
728 return true
729 }
730 if len(data) < 2 {
731 return false
732 }
733
734 extensionsLength := int(data[0])<<8 | int(data[1])
735 data = data[2:]
736 if len(data) != extensionsLength {
737 return false
738 }
739
740 for len(data) != 0 {
741 if len(data) < 4 {
742 return false
743 }
744 extension := uint16(data[0])<<8 | uint16(data[1])
745 length := int(data[2])<<8 | int(data[3])
746 data = data[4:]
747 if len(data) < length {
748 return false
749 }
750
751 switch extension {
752 case extensionNextProtoNeg:
753 m.nextProtoNeg = true
754 d := data[:length]
755 for len(d) > 0 {
756 l := int(d[0])
757 d = d[1:]
758 if l == 0 || l > len(d) {
759 return false
760 }
761 m.nextProtos = append(m.nextProtos, string(d[:l]))
762 d = d[l:]
763 }
764 case extensionStatusRequest:
765 if length > 0 {
766 return false
767 }
768 m.ocspStapling = true
769 case extensionSessionTicket:
770 if length > 0 {
771 return false
772 }
773 m.ticketSupported = true
774 case extensionRenegotiationInfo:
775 if length != 1 || data[0] != 0 {
776 return false
777 }
778 m.secureRenegotiation = true
David Benjaminfa055a22014-09-15 16:51:51 -0400779 case extensionALPN:
780 d := data[:length]
781 if len(d) < 3 {
782 return false
783 }
784 l := int(d[0])<<8 | int(d[1])
785 if l != len(d)-2 {
786 return false
787 }
788 d = d[2:]
789 l = int(d[0])
790 if l != len(d)-1 {
791 return false
792 }
793 d = d[1:]
794 m.alpnProtocol = string(d)
David Benjamind30a9902014-08-24 01:44:23 -0400795 case extensionChannelID:
796 if length > 0 {
797 return false
798 }
799 m.channelIDRequested = true
Adam Langley95c29f32014-06-20 12:00:00 -0700800 }
801 data = data[length:]
802 }
803
804 return true
805}
806
807type certificateMsg struct {
808 raw []byte
809 certificates [][]byte
810}
811
812func (m *certificateMsg) equal(i interface{}) bool {
813 m1, ok := i.(*certificateMsg)
814 if !ok {
815 return false
816 }
817
818 return bytes.Equal(m.raw, m1.raw) &&
819 eqByteSlices(m.certificates, m1.certificates)
820}
821
822func (m *certificateMsg) marshal() (x []byte) {
823 if m.raw != nil {
824 return m.raw
825 }
826
827 var i int
828 for _, slice := range m.certificates {
829 i += len(slice)
830 }
831
832 length := 3 + 3*len(m.certificates) + i
833 x = make([]byte, 4+length)
834 x[0] = typeCertificate
835 x[1] = uint8(length >> 16)
836 x[2] = uint8(length >> 8)
837 x[3] = uint8(length)
838
839 certificateOctets := length - 3
840 x[4] = uint8(certificateOctets >> 16)
841 x[5] = uint8(certificateOctets >> 8)
842 x[6] = uint8(certificateOctets)
843
844 y := x[7:]
845 for _, slice := range m.certificates {
846 y[0] = uint8(len(slice) >> 16)
847 y[1] = uint8(len(slice) >> 8)
848 y[2] = uint8(len(slice))
849 copy(y[3:], slice)
850 y = y[3+len(slice):]
851 }
852
853 m.raw = x
854 return
855}
856
857func (m *certificateMsg) unmarshal(data []byte) bool {
858 if len(data) < 7 {
859 return false
860 }
861
862 m.raw = data
863 certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
864 if uint32(len(data)) != certsLen+7 {
865 return false
866 }
867
868 numCerts := 0
869 d := data[7:]
870 for certsLen > 0 {
871 if len(d) < 4 {
872 return false
873 }
874 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
875 if uint32(len(d)) < 3+certLen {
876 return false
877 }
878 d = d[3+certLen:]
879 certsLen -= 3 + certLen
880 numCerts++
881 }
882
883 m.certificates = make([][]byte, numCerts)
884 d = data[7:]
885 for i := 0; i < numCerts; i++ {
886 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
887 m.certificates[i] = d[3 : 3+certLen]
888 d = d[3+certLen:]
889 }
890
891 return true
892}
893
894type serverKeyExchangeMsg struct {
895 raw []byte
896 key []byte
897}
898
899func (m *serverKeyExchangeMsg) equal(i interface{}) bool {
900 m1, ok := i.(*serverKeyExchangeMsg)
901 if !ok {
902 return false
903 }
904
905 return bytes.Equal(m.raw, m1.raw) &&
906 bytes.Equal(m.key, m1.key)
907}
908
909func (m *serverKeyExchangeMsg) marshal() []byte {
910 if m.raw != nil {
911 return m.raw
912 }
913 length := len(m.key)
914 x := make([]byte, length+4)
915 x[0] = typeServerKeyExchange
916 x[1] = uint8(length >> 16)
917 x[2] = uint8(length >> 8)
918 x[3] = uint8(length)
919 copy(x[4:], m.key)
920
921 m.raw = x
922 return x
923}
924
925func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
926 m.raw = data
927 if len(data) < 4 {
928 return false
929 }
930 m.key = data[4:]
931 return true
932}
933
934type certificateStatusMsg struct {
935 raw []byte
936 statusType uint8
937 response []byte
938}
939
940func (m *certificateStatusMsg) equal(i interface{}) bool {
941 m1, ok := i.(*certificateStatusMsg)
942 if !ok {
943 return false
944 }
945
946 return bytes.Equal(m.raw, m1.raw) &&
947 m.statusType == m1.statusType &&
948 bytes.Equal(m.response, m1.response)
949}
950
951func (m *certificateStatusMsg) marshal() []byte {
952 if m.raw != nil {
953 return m.raw
954 }
955
956 var x []byte
957 if m.statusType == statusTypeOCSP {
958 x = make([]byte, 4+4+len(m.response))
959 x[0] = typeCertificateStatus
960 l := len(m.response) + 4
961 x[1] = byte(l >> 16)
962 x[2] = byte(l >> 8)
963 x[3] = byte(l)
964 x[4] = statusTypeOCSP
965
966 l -= 4
967 x[5] = byte(l >> 16)
968 x[6] = byte(l >> 8)
969 x[7] = byte(l)
970 copy(x[8:], m.response)
971 } else {
972 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
973 }
974
975 m.raw = x
976 return x
977}
978
979func (m *certificateStatusMsg) unmarshal(data []byte) bool {
980 m.raw = data
981 if len(data) < 5 {
982 return false
983 }
984 m.statusType = data[4]
985
986 m.response = nil
987 if m.statusType == statusTypeOCSP {
988 if len(data) < 8 {
989 return false
990 }
991 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
992 if uint32(len(data)) != 4+4+respLen {
993 return false
994 }
995 m.response = data[8:]
996 }
997 return true
998}
999
1000type serverHelloDoneMsg struct{}
1001
1002func (m *serverHelloDoneMsg) equal(i interface{}) bool {
1003 _, ok := i.(*serverHelloDoneMsg)
1004 return ok
1005}
1006
1007func (m *serverHelloDoneMsg) marshal() []byte {
1008 x := make([]byte, 4)
1009 x[0] = typeServerHelloDone
1010 return x
1011}
1012
1013func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1014 return len(data) == 4
1015}
1016
1017type clientKeyExchangeMsg struct {
1018 raw []byte
1019 ciphertext []byte
1020}
1021
1022func (m *clientKeyExchangeMsg) equal(i interface{}) bool {
1023 m1, ok := i.(*clientKeyExchangeMsg)
1024 if !ok {
1025 return false
1026 }
1027
1028 return bytes.Equal(m.raw, m1.raw) &&
1029 bytes.Equal(m.ciphertext, m1.ciphertext)
1030}
1031
1032func (m *clientKeyExchangeMsg) marshal() []byte {
1033 if m.raw != nil {
1034 return m.raw
1035 }
1036 length := len(m.ciphertext)
1037 x := make([]byte, length+4)
1038 x[0] = typeClientKeyExchange
1039 x[1] = uint8(length >> 16)
1040 x[2] = uint8(length >> 8)
1041 x[3] = uint8(length)
1042 copy(x[4:], m.ciphertext)
1043
1044 m.raw = x
1045 return x
1046}
1047
1048func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1049 m.raw = data
1050 if len(data) < 4 {
1051 return false
1052 }
1053 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1054 if l != len(data)-4 {
1055 return false
1056 }
1057 m.ciphertext = data[4:]
1058 return true
1059}
1060
1061type finishedMsg struct {
1062 raw []byte
1063 verifyData []byte
1064}
1065
1066func (m *finishedMsg) equal(i interface{}) bool {
1067 m1, ok := i.(*finishedMsg)
1068 if !ok {
1069 return false
1070 }
1071
1072 return bytes.Equal(m.raw, m1.raw) &&
1073 bytes.Equal(m.verifyData, m1.verifyData)
1074}
1075
1076func (m *finishedMsg) marshal() (x []byte) {
1077 if m.raw != nil {
1078 return m.raw
1079 }
1080
1081 x = make([]byte, 4+len(m.verifyData))
1082 x[0] = typeFinished
1083 x[3] = byte(len(m.verifyData))
1084 copy(x[4:], m.verifyData)
1085 m.raw = x
1086 return
1087}
1088
1089func (m *finishedMsg) unmarshal(data []byte) bool {
1090 m.raw = data
1091 if len(data) < 4 {
1092 return false
1093 }
1094 m.verifyData = data[4:]
1095 return true
1096}
1097
1098type nextProtoMsg struct {
1099 raw []byte
1100 proto string
1101}
1102
1103func (m *nextProtoMsg) equal(i interface{}) bool {
1104 m1, ok := i.(*nextProtoMsg)
1105 if !ok {
1106 return false
1107 }
1108
1109 return bytes.Equal(m.raw, m1.raw) &&
1110 m.proto == m1.proto
1111}
1112
1113func (m *nextProtoMsg) marshal() []byte {
1114 if m.raw != nil {
1115 return m.raw
1116 }
1117 l := len(m.proto)
1118 if l > 255 {
1119 l = 255
1120 }
1121
1122 padding := 32 - (l+2)%32
1123 length := l + padding + 2
1124 x := make([]byte, length+4)
1125 x[0] = typeNextProtocol
1126 x[1] = uint8(length >> 16)
1127 x[2] = uint8(length >> 8)
1128 x[3] = uint8(length)
1129
1130 y := x[4:]
1131 y[0] = byte(l)
1132 copy(y[1:], []byte(m.proto[0:l]))
1133 y = y[1+l:]
1134 y[0] = byte(padding)
1135
1136 m.raw = x
1137
1138 return x
1139}
1140
1141func (m *nextProtoMsg) unmarshal(data []byte) bool {
1142 m.raw = data
1143
1144 if len(data) < 5 {
1145 return false
1146 }
1147 data = data[4:]
1148 protoLen := int(data[0])
1149 data = data[1:]
1150 if len(data) < protoLen {
1151 return false
1152 }
1153 m.proto = string(data[0:protoLen])
1154 data = data[protoLen:]
1155
1156 if len(data) < 1 {
1157 return false
1158 }
1159 paddingLen := int(data[0])
1160 data = data[1:]
1161 if len(data) != paddingLen {
1162 return false
1163 }
1164
1165 return true
1166}
1167
1168type certificateRequestMsg struct {
1169 raw []byte
1170 // hasSignatureAndHash indicates whether this message includes a list
1171 // of signature and hash functions. This change was introduced with TLS
1172 // 1.2.
1173 hasSignatureAndHash bool
1174
1175 certificateTypes []byte
1176 signatureAndHashes []signatureAndHash
1177 certificateAuthorities [][]byte
1178}
1179
1180func (m *certificateRequestMsg) equal(i interface{}) bool {
1181 m1, ok := i.(*certificateRequestMsg)
1182 if !ok {
1183 return false
1184 }
1185
1186 return bytes.Equal(m.raw, m1.raw) &&
1187 bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
1188 eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
1189 eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes)
1190}
1191
1192func (m *certificateRequestMsg) marshal() (x []byte) {
1193 if m.raw != nil {
1194 return m.raw
1195 }
1196
1197 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
1198 length := 1 + len(m.certificateTypes) + 2
1199 casLength := 0
1200 for _, ca := range m.certificateAuthorities {
1201 casLength += 2 + len(ca)
1202 }
1203 length += casLength
1204
1205 if m.hasSignatureAndHash {
1206 length += 2 + 2*len(m.signatureAndHashes)
1207 }
1208
1209 x = make([]byte, 4+length)
1210 x[0] = typeCertificateRequest
1211 x[1] = uint8(length >> 16)
1212 x[2] = uint8(length >> 8)
1213 x[3] = uint8(length)
1214
1215 x[4] = uint8(len(m.certificateTypes))
1216
1217 copy(x[5:], m.certificateTypes)
1218 y := x[5+len(m.certificateTypes):]
1219
1220 if m.hasSignatureAndHash {
1221 n := len(m.signatureAndHashes) * 2
1222 y[0] = uint8(n >> 8)
1223 y[1] = uint8(n)
1224 y = y[2:]
1225 for _, sigAndHash := range m.signatureAndHashes {
1226 y[0] = sigAndHash.hash
1227 y[1] = sigAndHash.signature
1228 y = y[2:]
1229 }
1230 }
1231
1232 y[0] = uint8(casLength >> 8)
1233 y[1] = uint8(casLength)
1234 y = y[2:]
1235 for _, ca := range m.certificateAuthorities {
1236 y[0] = uint8(len(ca) >> 8)
1237 y[1] = uint8(len(ca))
1238 y = y[2:]
1239 copy(y, ca)
1240 y = y[len(ca):]
1241 }
1242
1243 m.raw = x
1244 return
1245}
1246
1247func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1248 m.raw = data
1249
1250 if len(data) < 5 {
1251 return false
1252 }
1253
1254 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1255 if uint32(len(data))-4 != length {
1256 return false
1257 }
1258
1259 numCertTypes := int(data[4])
1260 data = data[5:]
1261 if numCertTypes == 0 || len(data) <= numCertTypes {
1262 return false
1263 }
1264
1265 m.certificateTypes = make([]byte, numCertTypes)
1266 if copy(m.certificateTypes, data) != numCertTypes {
1267 return false
1268 }
1269
1270 data = data[numCertTypes:]
1271
1272 if m.hasSignatureAndHash {
1273 if len(data) < 2 {
1274 return false
1275 }
1276 sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
1277 data = data[2:]
1278 if sigAndHashLen&1 != 0 {
1279 return false
1280 }
1281 if len(data) < int(sigAndHashLen) {
1282 return false
1283 }
1284 numSigAndHash := sigAndHashLen / 2
1285 m.signatureAndHashes = make([]signatureAndHash, numSigAndHash)
1286 for i := range m.signatureAndHashes {
1287 m.signatureAndHashes[i].hash = data[0]
1288 m.signatureAndHashes[i].signature = data[1]
1289 data = data[2:]
1290 }
1291 }
1292
1293 if len(data) < 2 {
1294 return false
1295 }
1296 casLength := uint16(data[0])<<8 | uint16(data[1])
1297 data = data[2:]
1298 if len(data) < int(casLength) {
1299 return false
1300 }
1301 cas := make([]byte, casLength)
1302 copy(cas, data)
1303 data = data[casLength:]
1304
1305 m.certificateAuthorities = nil
1306 for len(cas) > 0 {
1307 if len(cas) < 2 {
1308 return false
1309 }
1310 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1311 cas = cas[2:]
1312
1313 if len(cas) < int(caLen) {
1314 return false
1315 }
1316
1317 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1318 cas = cas[caLen:]
1319 }
1320 if len(data) > 0 {
1321 return false
1322 }
1323
1324 return true
1325}
1326
1327type certificateVerifyMsg struct {
1328 raw []byte
1329 hasSignatureAndHash bool
1330 signatureAndHash signatureAndHash
1331 signature []byte
1332}
1333
1334func (m *certificateVerifyMsg) equal(i interface{}) bool {
1335 m1, ok := i.(*certificateVerifyMsg)
1336 if !ok {
1337 return false
1338 }
1339
1340 return bytes.Equal(m.raw, m1.raw) &&
1341 m.hasSignatureAndHash == m1.hasSignatureAndHash &&
1342 m.signatureAndHash.hash == m1.signatureAndHash.hash &&
1343 m.signatureAndHash.signature == m1.signatureAndHash.signature &&
1344 bytes.Equal(m.signature, m1.signature)
1345}
1346
1347func (m *certificateVerifyMsg) marshal() (x []byte) {
1348 if m.raw != nil {
1349 return m.raw
1350 }
1351
1352 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1353 siglength := len(m.signature)
1354 length := 2 + siglength
1355 if m.hasSignatureAndHash {
1356 length += 2
1357 }
1358 x = make([]byte, 4+length)
1359 x[0] = typeCertificateVerify
1360 x[1] = uint8(length >> 16)
1361 x[2] = uint8(length >> 8)
1362 x[3] = uint8(length)
1363 y := x[4:]
1364 if m.hasSignatureAndHash {
1365 y[0] = m.signatureAndHash.hash
1366 y[1] = m.signatureAndHash.signature
1367 y = y[2:]
1368 }
1369 y[0] = uint8(siglength >> 8)
1370 y[1] = uint8(siglength)
1371 copy(y[2:], m.signature)
1372
1373 m.raw = x
1374
1375 return
1376}
1377
1378func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1379 m.raw = data
1380
1381 if len(data) < 6 {
1382 return false
1383 }
1384
1385 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1386 if uint32(len(data))-4 != length {
1387 return false
1388 }
1389
1390 data = data[4:]
1391 if m.hasSignatureAndHash {
1392 m.signatureAndHash.hash = data[0]
1393 m.signatureAndHash.signature = data[1]
1394 data = data[2:]
1395 }
1396
1397 if len(data) < 2 {
1398 return false
1399 }
1400 siglength := int(data[0])<<8 + int(data[1])
1401 data = data[2:]
1402 if len(data) != siglength {
1403 return false
1404 }
1405
1406 m.signature = data
1407
1408 return true
1409}
1410
1411type newSessionTicketMsg struct {
1412 raw []byte
1413 ticket []byte
1414}
1415
1416func (m *newSessionTicketMsg) equal(i interface{}) bool {
1417 m1, ok := i.(*newSessionTicketMsg)
1418 if !ok {
1419 return false
1420 }
1421
1422 return bytes.Equal(m.raw, m1.raw) &&
1423 bytes.Equal(m.ticket, m1.ticket)
1424}
1425
1426func (m *newSessionTicketMsg) marshal() (x []byte) {
1427 if m.raw != nil {
1428 return m.raw
1429 }
1430
1431 // See http://tools.ietf.org/html/rfc5077#section-3.3
1432 ticketLen := len(m.ticket)
1433 length := 2 + 4 + ticketLen
1434 x = make([]byte, 4+length)
1435 x[0] = typeNewSessionTicket
1436 x[1] = uint8(length >> 16)
1437 x[2] = uint8(length >> 8)
1438 x[3] = uint8(length)
1439 x[8] = uint8(ticketLen >> 8)
1440 x[9] = uint8(ticketLen)
1441 copy(x[10:], m.ticket)
1442
1443 m.raw = x
1444
1445 return
1446}
1447
1448func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
1449 m.raw = data
1450
1451 if len(data) < 10 {
1452 return false
1453 }
1454
1455 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1456 if uint32(len(data))-4 != length {
1457 return false
1458 }
1459
1460 ticketLen := int(data[8])<<8 + int(data[9])
1461 if len(data)-10 != ticketLen {
1462 return false
1463 }
1464
1465 m.ticket = data[10:]
1466
1467 return true
1468}
1469
David Benjamind86c7672014-08-02 04:07:12 -04001470type v2ClientHelloMsg struct {
1471 raw []byte
1472 vers uint16
1473 cipherSuites []uint16
1474 sessionId []byte
1475 challenge []byte
1476}
1477
1478func (m *v2ClientHelloMsg) equal(i interface{}) bool {
1479 m1, ok := i.(*v2ClientHelloMsg)
1480 if !ok {
1481 return false
1482 }
1483
1484 return bytes.Equal(m.raw, m1.raw) &&
1485 m.vers == m1.vers &&
1486 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
1487 bytes.Equal(m.sessionId, m1.sessionId) &&
1488 bytes.Equal(m.challenge, m1.challenge)
1489}
1490
1491func (m *v2ClientHelloMsg) marshal() []byte {
1492 if m.raw != nil {
1493 return m.raw
1494 }
1495
1496 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
1497
1498 x := make([]byte, length)
1499 x[0] = 1
1500 x[1] = uint8(m.vers >> 8)
1501 x[2] = uint8(m.vers)
1502 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
1503 x[4] = uint8(len(m.cipherSuites) * 3)
1504 x[5] = uint8(len(m.sessionId) >> 8)
1505 x[6] = uint8(len(m.sessionId))
1506 x[7] = uint8(len(m.challenge) >> 8)
1507 x[8] = uint8(len(m.challenge))
1508 y := x[9:]
1509 for i, spec := range m.cipherSuites {
1510 y[i*3] = 0
1511 y[i*3+1] = uint8(spec >> 8)
1512 y[i*3+2] = uint8(spec)
1513 }
1514 y = y[len(m.cipherSuites)*3:]
1515 copy(y, m.sessionId)
1516 y = y[len(m.sessionId):]
1517 copy(y, m.challenge)
1518
1519 m.raw = x
1520
1521 return x
1522}
1523
David Benjamin83c0bc92014-08-04 01:23:53 -04001524type helloVerifyRequestMsg struct {
1525 raw []byte
1526 vers uint16
1527 cookie []byte
1528}
1529
1530func (m *helloVerifyRequestMsg) equal(i interface{}) bool {
1531 m1, ok := i.(*helloVerifyRequestMsg)
1532 if !ok {
1533 return false
1534 }
1535
David Benjamind30a9902014-08-24 01:44:23 -04001536 return bytes.Equal(m.raw, m1.raw) &&
1537 m.vers == m1.vers &&
David Benjamin83c0bc92014-08-04 01:23:53 -04001538 bytes.Equal(m.cookie, m1.cookie)
1539}
1540
1541func (m *helloVerifyRequestMsg) marshal() []byte {
1542 if m.raw != nil {
1543 return m.raw
1544 }
1545
1546 length := 2 + 1 + len(m.cookie)
1547
1548 x := make([]byte, 4+length)
1549 x[0] = typeHelloVerifyRequest
1550 x[1] = uint8(length >> 16)
1551 x[2] = uint8(length >> 8)
1552 x[3] = uint8(length)
1553 vers := versionToWire(m.vers, true)
1554 x[4] = uint8(vers >> 8)
1555 x[5] = uint8(vers)
1556 x[6] = uint8(len(m.cookie))
1557 copy(x[7:7+len(m.cookie)], m.cookie)
1558
1559 return x
1560}
1561
1562func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
1563 if len(data) < 4+2+1 {
1564 return false
1565 }
1566 m.raw = data
1567 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), true)
1568 cookieLen := int(data[6])
1569 if cookieLen > 32 || len(data) != 7+cookieLen {
1570 return false
1571 }
1572 m.cookie = data[7 : 7+cookieLen]
1573
1574 return true
1575}
1576
David Benjamind30a9902014-08-24 01:44:23 -04001577type encryptedExtensionsMsg struct {
1578 raw []byte
1579 channelID []byte
1580}
1581
1582func (m *encryptedExtensionsMsg) equal(i interface{}) bool {
1583 m1, ok := i.(*encryptedExtensionsMsg)
1584 if !ok {
1585 return false
1586 }
1587
1588 return bytes.Equal(m.raw, m1.raw) &&
1589 bytes.Equal(m.channelID, m1.channelID)
1590}
1591
1592func (m *encryptedExtensionsMsg) marshal() []byte {
1593 if m.raw != nil {
1594 return m.raw
1595 }
1596
1597 length := 2 + 2 + len(m.channelID)
1598
1599 x := make([]byte, 4+length)
1600 x[0] = typeEncryptedExtensions
1601 x[1] = uint8(length >> 16)
1602 x[2] = uint8(length >> 8)
1603 x[3] = uint8(length)
1604 x[4] = uint8(extensionChannelID >> 8)
1605 x[5] = uint8(extensionChannelID & 0xff)
1606 x[6] = uint8(len(m.channelID) >> 8)
1607 x[7] = uint8(len(m.channelID) & 0xff)
1608 copy(x[8:], m.channelID)
1609
1610 return x
1611}
1612
1613func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
1614 if len(data) != 4+2+2+128 {
1615 return false
1616 }
1617 m.raw = data
1618 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
1619 return false
1620 }
1621 if int(data[6])<<8|int(data[7]) != 128 {
1622 return false
1623 }
1624 m.channelID = data[4+2+2:]
1625
1626 return true
1627}
1628
Adam Langley95c29f32014-06-20 12:00:00 -07001629func eqUint16s(x, y []uint16) bool {
1630 if len(x) != len(y) {
1631 return false
1632 }
1633 for i, v := range x {
1634 if y[i] != v {
1635 return false
1636 }
1637 }
1638 return true
1639}
1640
1641func eqCurveIDs(x, y []CurveID) bool {
1642 if len(x) != len(y) {
1643 return false
1644 }
1645 for i, v := range x {
1646 if y[i] != v {
1647 return false
1648 }
1649 }
1650 return true
1651}
1652
1653func eqStrings(x, y []string) bool {
1654 if len(x) != len(y) {
1655 return false
1656 }
1657 for i, v := range x {
1658 if y[i] != v {
1659 return false
1660 }
1661 }
1662 return true
1663}
1664
1665func eqByteSlices(x, y [][]byte) bool {
1666 if len(x) != len(y) {
1667 return false
1668 }
1669 for i, v := range x {
1670 if !bytes.Equal(v, y[i]) {
1671 return false
1672 }
1673 }
1674 return true
1675}
1676
1677func eqSignatureAndHashes(x, y []signatureAndHash) bool {
1678 if len(x) != len(y) {
1679 return false
1680 }
1681 for i, v := range x {
1682 v2 := y[i]
1683 if v.hash != v2.hash || v.signature != v2.signature {
1684 return false
1685 }
1686 }
1687 return true
1688}