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