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