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