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