blob: ce214fde3cb4b2d50c7a66effed695c8b99f08bd [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 {
David Benjaminca6c8262014-11-15 19:06:08 -050010 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
26 secureRenegotiation []byte
27 alpnProtocols []string
28 duplicateExtension bool
29 channelIDSupported bool
30 npnLast bool
31 extendedMasterSecret bool
32 srtpProtectionProfiles []uint16
33 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -050034 sctListSupported bool
Adam Langley95c29f32014-06-20 12:00:00 -070035}
36
37func (m *clientHelloMsg) equal(i interface{}) bool {
38 m1, ok := i.(*clientHelloMsg)
39 if !ok {
40 return false
41 }
42
43 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -040044 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -070045 m.vers == m1.vers &&
46 bytes.Equal(m.random, m1.random) &&
47 bytes.Equal(m.sessionId, m1.sessionId) &&
David Benjamin83c0bc92014-08-04 01:23:53 -040048 bytes.Equal(m.cookie, m1.cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -070049 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
50 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
51 m.nextProtoNeg == m1.nextProtoNeg &&
52 m.serverName == m1.serverName &&
53 m.ocspStapling == m1.ocspStapling &&
54 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
55 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
56 m.ticketSupported == m1.ticketSupported &&
57 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
58 eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) &&
Adam Langley2ae77d22014-10-28 17:29:33 -070059 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
60 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -040061 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -040062 m.duplicateExtension == m1.duplicateExtension &&
David Benjaminfc7b0862014-09-06 13:21:53 -040063 m.channelIDSupported == m1.channelIDSupported &&
Adam Langley75712922014-10-10 16:23:43 -070064 m.npnLast == m1.npnLast &&
David Benjaminca6c8262014-11-15 19:06:08 -050065 m.extendedMasterSecret == m1.extendedMasterSecret &&
66 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
David Benjamin61f95272014-11-25 01:55:35 -050067 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
68 m.sctListSupported == m1.sctListSupported
Adam Langley95c29f32014-06-20 12:00:00 -070069}
70
71func (m *clientHelloMsg) marshal() []byte {
72 if m.raw != nil {
73 return m.raw
74 }
75
76 length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods)
David Benjamin83c0bc92014-08-04 01:23:53 -040077 if m.isDTLS {
78 length += 1 + len(m.cookie)
79 }
Adam Langley95c29f32014-06-20 12:00:00 -070080 numExtensions := 0
81 extensionsLength := 0
82 if m.nextProtoNeg {
83 numExtensions++
84 }
85 if m.ocspStapling {
86 extensionsLength += 1 + 2 + 2
87 numExtensions++
88 }
89 if len(m.serverName) > 0 {
90 extensionsLength += 5 + len(m.serverName)
91 numExtensions++
92 }
93 if len(m.supportedCurves) > 0 {
94 extensionsLength += 2 + 2*len(m.supportedCurves)
95 numExtensions++
96 }
97 if len(m.supportedPoints) > 0 {
98 extensionsLength += 1 + len(m.supportedPoints)
99 numExtensions++
100 }
101 if m.ticketSupported {
102 extensionsLength += len(m.sessionTicket)
103 numExtensions++
104 }
105 if len(m.signatureAndHashes) > 0 {
106 extensionsLength += 2 + 2*len(m.signatureAndHashes)
107 numExtensions++
108 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700109 if m.secureRenegotiation != nil {
110 extensionsLength += 1 + len(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700111 numExtensions++
112 }
David Benjamin35a7a442014-07-05 00:23:20 -0400113 if m.duplicateExtension {
114 numExtensions += 2
115 }
David Benjamind30a9902014-08-24 01:44:23 -0400116 if m.channelIDSupported {
117 numExtensions++
118 }
David Benjaminfa055a22014-09-15 16:51:51 -0400119 if len(m.alpnProtocols) > 0 {
120 extensionsLength += 2
121 for _, s := range m.alpnProtocols {
122 if l := len(s); l == 0 || l > 255 {
123 panic("invalid ALPN protocol")
124 }
125 extensionsLength++
126 extensionsLength += len(s)
127 }
128 numExtensions++
129 }
Adam Langley75712922014-10-10 16:23:43 -0700130 if m.extendedMasterSecret {
131 numExtensions++
132 }
David Benjaminca6c8262014-11-15 19:06:08 -0500133 if len(m.srtpProtectionProfiles) > 0 {
134 extensionsLength += 2 + 2*len(m.srtpProtectionProfiles)
135 extensionsLength += 1 + len(m.srtpMasterKeyIdentifier)
136 numExtensions++
137 }
David Benjamin61f95272014-11-25 01:55:35 -0500138 if m.sctListSupported {
139 numExtensions++
140 }
Adam Langley95c29f32014-06-20 12:00:00 -0700141 if numExtensions > 0 {
142 extensionsLength += 4 * numExtensions
143 length += 2 + extensionsLength
144 }
145
146 x := make([]byte, 4+length)
147 x[0] = typeClientHello
148 x[1] = uint8(length >> 16)
149 x[2] = uint8(length >> 8)
150 x[3] = uint8(length)
David Benjamin83c0bc92014-08-04 01:23:53 -0400151 vers := versionToWire(m.vers, m.isDTLS)
152 x[4] = uint8(vers >> 8)
153 x[5] = uint8(vers)
Adam Langley95c29f32014-06-20 12:00:00 -0700154 copy(x[6:38], m.random)
155 x[38] = uint8(len(m.sessionId))
156 copy(x[39:39+len(m.sessionId)], m.sessionId)
157 y := x[39+len(m.sessionId):]
David Benjamin83c0bc92014-08-04 01:23:53 -0400158 if m.isDTLS {
159 y[0] = uint8(len(m.cookie))
160 copy(y[1:], m.cookie)
161 y = y[1+len(m.cookie):]
162 }
Adam Langley95c29f32014-06-20 12:00:00 -0700163 y[0] = uint8(len(m.cipherSuites) >> 7)
164 y[1] = uint8(len(m.cipherSuites) << 1)
165 for i, suite := range m.cipherSuites {
166 y[2+i*2] = uint8(suite >> 8)
167 y[3+i*2] = uint8(suite)
168 }
169 z := y[2+len(m.cipherSuites)*2:]
170 z[0] = uint8(len(m.compressionMethods))
171 copy(z[1:], m.compressionMethods)
172
173 z = z[1+len(m.compressionMethods):]
174 if numExtensions > 0 {
175 z[0] = byte(extensionsLength >> 8)
176 z[1] = byte(extensionsLength)
177 z = z[2:]
178 }
David Benjamin35a7a442014-07-05 00:23:20 -0400179 if m.duplicateExtension {
180 // Add a duplicate bogus extension at the beginning and end.
181 z[0] = 0xff
182 z[1] = 0xff
183 z = z[4:]
184 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400185 if m.nextProtoNeg && !m.npnLast {
Adam Langley95c29f32014-06-20 12:00:00 -0700186 z[0] = byte(extensionNextProtoNeg >> 8)
187 z[1] = byte(extensionNextProtoNeg & 0xff)
188 // The length is always 0
189 z = z[4:]
190 }
191 if len(m.serverName) > 0 {
192 z[0] = byte(extensionServerName >> 8)
193 z[1] = byte(extensionServerName & 0xff)
194 l := len(m.serverName) + 5
195 z[2] = byte(l >> 8)
196 z[3] = byte(l)
197 z = z[4:]
198
199 // RFC 3546, section 3.1
200 //
201 // struct {
202 // NameType name_type;
203 // select (name_type) {
204 // case host_name: HostName;
205 // } name;
206 // } ServerName;
207 //
208 // enum {
209 // host_name(0), (255)
210 // } NameType;
211 //
212 // opaque HostName<1..2^16-1>;
213 //
214 // struct {
215 // ServerName server_name_list<1..2^16-1>
216 // } ServerNameList;
217
218 z[0] = byte((len(m.serverName) + 3) >> 8)
219 z[1] = byte(len(m.serverName) + 3)
220 z[3] = byte(len(m.serverName) >> 8)
221 z[4] = byte(len(m.serverName))
222 copy(z[5:], []byte(m.serverName))
223 z = z[l:]
224 }
225 if m.ocspStapling {
226 // RFC 4366, section 3.6
227 z[0] = byte(extensionStatusRequest >> 8)
228 z[1] = byte(extensionStatusRequest)
229 z[2] = 0
230 z[3] = 5
231 z[4] = 1 // OCSP type
232 // Two zero valued uint16s for the two lengths.
233 z = z[9:]
234 }
235 if len(m.supportedCurves) > 0 {
236 // http://tools.ietf.org/html/rfc4492#section-5.5.1
237 z[0] = byte(extensionSupportedCurves >> 8)
238 z[1] = byte(extensionSupportedCurves)
239 l := 2 + 2*len(m.supportedCurves)
240 z[2] = byte(l >> 8)
241 z[3] = byte(l)
242 l -= 2
243 z[4] = byte(l >> 8)
244 z[5] = byte(l)
245 z = z[6:]
246 for _, curve := range m.supportedCurves {
247 z[0] = byte(curve >> 8)
248 z[1] = byte(curve)
249 z = z[2:]
250 }
251 }
252 if len(m.supportedPoints) > 0 {
253 // http://tools.ietf.org/html/rfc4492#section-5.5.2
254 z[0] = byte(extensionSupportedPoints >> 8)
255 z[1] = byte(extensionSupportedPoints)
256 l := 1 + len(m.supportedPoints)
257 z[2] = byte(l >> 8)
258 z[3] = byte(l)
259 l--
260 z[4] = byte(l)
261 z = z[5:]
262 for _, pointFormat := range m.supportedPoints {
263 z[0] = byte(pointFormat)
264 z = z[1:]
265 }
266 }
267 if m.ticketSupported {
268 // http://tools.ietf.org/html/rfc5077#section-3.2
269 z[0] = byte(extensionSessionTicket >> 8)
270 z[1] = byte(extensionSessionTicket)
271 l := len(m.sessionTicket)
272 z[2] = byte(l >> 8)
273 z[3] = byte(l)
274 z = z[4:]
275 copy(z, m.sessionTicket)
276 z = z[len(m.sessionTicket):]
277 }
278 if len(m.signatureAndHashes) > 0 {
279 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
280 z[0] = byte(extensionSignatureAlgorithms >> 8)
281 z[1] = byte(extensionSignatureAlgorithms)
282 l := 2 + 2*len(m.signatureAndHashes)
283 z[2] = byte(l >> 8)
284 z[3] = byte(l)
285 z = z[4:]
286
287 l -= 2
288 z[0] = byte(l >> 8)
289 z[1] = byte(l)
290 z = z[2:]
291 for _, sigAndHash := range m.signatureAndHashes {
292 z[0] = sigAndHash.hash
293 z[1] = sigAndHash.signature
294 z = z[2:]
295 }
296 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700297 if m.secureRenegotiation != nil {
Adam Langley95c29f32014-06-20 12:00:00 -0700298 z[0] = byte(extensionRenegotiationInfo >> 8)
299 z[1] = byte(extensionRenegotiationInfo & 0xff)
300 z[2] = 0
Adam Langley2ae77d22014-10-28 17:29:33 -0700301 z[3] = byte(1 + len(m.secureRenegotiation))
302 z[4] = byte(len(m.secureRenegotiation))
Adam Langley95c29f32014-06-20 12:00:00 -0700303 z = z[5:]
Adam Langley2ae77d22014-10-28 17:29:33 -0700304 copy(z, m.secureRenegotiation)
305 z = z[len(m.secureRenegotiation):]
Adam Langley95c29f32014-06-20 12:00:00 -0700306 }
David Benjaminfa055a22014-09-15 16:51:51 -0400307 if len(m.alpnProtocols) > 0 {
308 z[0] = byte(extensionALPN >> 8)
309 z[1] = byte(extensionALPN & 0xff)
310 lengths := z[2:]
311 z = z[6:]
312
313 stringsLength := 0
314 for _, s := range m.alpnProtocols {
315 l := len(s)
316 z[0] = byte(l)
317 copy(z[1:], s)
318 z = z[1+l:]
319 stringsLength += 1 + l
320 }
321
322 lengths[2] = byte(stringsLength >> 8)
323 lengths[3] = byte(stringsLength)
324 stringsLength += 2
325 lengths[0] = byte(stringsLength >> 8)
326 lengths[1] = byte(stringsLength)
327 }
David Benjamind30a9902014-08-24 01:44:23 -0400328 if m.channelIDSupported {
329 z[0] = byte(extensionChannelID >> 8)
330 z[1] = byte(extensionChannelID & 0xff)
331 z = z[4:]
332 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400333 if m.nextProtoNeg && m.npnLast {
334 z[0] = byte(extensionNextProtoNeg >> 8)
335 z[1] = byte(extensionNextProtoNeg & 0xff)
336 // The length is always 0
337 z = z[4:]
338 }
David Benjamin35a7a442014-07-05 00:23:20 -0400339 if m.duplicateExtension {
340 // Add a duplicate bogus extension at the beginning and end.
341 z[0] = 0xff
342 z[1] = 0xff
343 z = z[4:]
344 }
Adam Langley75712922014-10-10 16:23:43 -0700345 if m.extendedMasterSecret {
346 // https://tools.ietf.org/html/draft-ietf-tls-session-hash-01
347 z[0] = byte(extensionExtendedMasterSecret >> 8)
348 z[1] = byte(extensionExtendedMasterSecret & 0xff)
349 z = z[4:]
350 }
David Benjaminca6c8262014-11-15 19:06:08 -0500351 if len(m.srtpProtectionProfiles) > 0 {
352 z[0] = byte(extensionUseSRTP >> 8)
353 z[1] = byte(extensionUseSRTP & 0xff)
354
355 profilesLen := 2 * len(m.srtpProtectionProfiles)
356 mkiLen := len(m.srtpMasterKeyIdentifier)
357 l := 2 + profilesLen + 1 + mkiLen
358 z[2] = byte(l >> 8)
359 z[3] = byte(l & 0xff)
360
361 z[4] = byte(profilesLen >> 8)
362 z[5] = byte(profilesLen & 0xff)
363 z = z[6:]
364 for _, p := range m.srtpProtectionProfiles {
365 z[0] = byte(p >> 8)
366 z[1] = byte(p & 0xff)
367 z = z[2:]
368 }
369
370 z[0] = byte(mkiLen)
371 copy(z[1:], []byte(m.srtpMasterKeyIdentifier))
372 z = z[1+mkiLen:]
373 }
David Benjamin61f95272014-11-25 01:55:35 -0500374 if m.sctListSupported {
375 z[0] = byte(extensionSignedCertificateTimestamp >> 8)
376 z[1] = byte(extensionSignedCertificateTimestamp & 0xff)
377 z = z[4:]
378 }
Adam Langley95c29f32014-06-20 12:00:00 -0700379
380 m.raw = x
381
382 return x
383}
384
385func (m *clientHelloMsg) unmarshal(data []byte) bool {
386 if len(data) < 42 {
387 return false
388 }
389 m.raw = data
David Benjamin83c0bc92014-08-04 01:23:53 -0400390 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
Adam Langley95c29f32014-06-20 12:00:00 -0700391 m.random = data[6:38]
392 sessionIdLen := int(data[38])
393 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
394 return false
395 }
396 m.sessionId = data[39 : 39+sessionIdLen]
397 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400398 if m.isDTLS {
399 if len(data) < 1 {
400 return false
401 }
402 cookieLen := int(data[0])
403 if cookieLen > 32 || len(data) < 1+cookieLen {
404 return false
405 }
406 m.cookie = data[1 : 1+cookieLen]
407 data = data[1+cookieLen:]
408 }
Adam Langley95c29f32014-06-20 12:00:00 -0700409 if len(data) < 2 {
410 return false
411 }
412 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
413 // they are uint16s, the number must be even.
414 cipherSuiteLen := int(data[0])<<8 | int(data[1])
415 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
416 return false
417 }
418 numCipherSuites := cipherSuiteLen / 2
419 m.cipherSuites = make([]uint16, numCipherSuites)
420 for i := 0; i < numCipherSuites; i++ {
421 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
422 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700423 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700424 }
425 }
426 data = data[2+cipherSuiteLen:]
427 if len(data) < 1 {
428 return false
429 }
430 compressionMethodsLen := int(data[0])
431 if len(data) < 1+compressionMethodsLen {
432 return false
433 }
434 m.compressionMethods = data[1 : 1+compressionMethodsLen]
435
436 data = data[1+compressionMethodsLen:]
437
438 m.nextProtoNeg = false
439 m.serverName = ""
440 m.ocspStapling = false
441 m.ticketSupported = false
442 m.sessionTicket = nil
443 m.signatureAndHashes = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400444 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700445 m.extendedMasterSecret = false
Adam Langley95c29f32014-06-20 12:00:00 -0700446
447 if len(data) == 0 {
448 // ClientHello is optionally followed by extension data
449 return true
450 }
451 if len(data) < 2 {
452 return false
453 }
454
455 extensionsLength := int(data[0])<<8 | int(data[1])
456 data = data[2:]
457 if extensionsLength != len(data) {
458 return false
459 }
460
461 for len(data) != 0 {
462 if len(data) < 4 {
463 return false
464 }
465 extension := uint16(data[0])<<8 | uint16(data[1])
466 length := int(data[2])<<8 | int(data[3])
467 data = data[4:]
468 if len(data) < length {
469 return false
470 }
471
472 switch extension {
473 case extensionServerName:
474 if length < 2 {
475 return false
476 }
477 numNames := int(data[0])<<8 | int(data[1])
478 d := data[2:]
479 for i := 0; i < numNames; i++ {
480 if len(d) < 3 {
481 return false
482 }
483 nameType := d[0]
484 nameLen := int(d[1])<<8 | int(d[2])
485 d = d[3:]
486 if len(d) < nameLen {
487 return false
488 }
489 if nameType == 0 {
490 m.serverName = string(d[0:nameLen])
491 break
492 }
493 d = d[nameLen:]
494 }
495 case extensionNextProtoNeg:
496 if length > 0 {
497 return false
498 }
499 m.nextProtoNeg = true
500 case extensionStatusRequest:
501 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
502 case extensionSupportedCurves:
503 // http://tools.ietf.org/html/rfc4492#section-5.5.1
504 if length < 2 {
505 return false
506 }
507 l := int(data[0])<<8 | int(data[1])
508 if l%2 == 1 || length != l+2 {
509 return false
510 }
511 numCurves := l / 2
512 m.supportedCurves = make([]CurveID, numCurves)
513 d := data[2:]
514 for i := 0; i < numCurves; i++ {
515 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
516 d = d[2:]
517 }
518 case extensionSupportedPoints:
519 // http://tools.ietf.org/html/rfc4492#section-5.5.2
520 if length < 1 {
521 return false
522 }
523 l := int(data[0])
524 if length != l+1 {
525 return false
526 }
527 m.supportedPoints = make([]uint8, l)
528 copy(m.supportedPoints, data[1:])
529 case extensionSessionTicket:
530 // http://tools.ietf.org/html/rfc5077#section-3.2
531 m.ticketSupported = true
532 m.sessionTicket = data[:length]
533 case extensionSignatureAlgorithms:
534 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
535 if length < 2 || length&1 != 0 {
536 return false
537 }
538 l := int(data[0])<<8 | int(data[1])
539 if l != length-2 {
540 return false
541 }
542 n := l / 2
543 d := data[2:]
544 m.signatureAndHashes = make([]signatureAndHash, n)
545 for i := range m.signatureAndHashes {
546 m.signatureAndHashes[i].hash = d[0]
547 m.signatureAndHashes[i].signature = d[1]
548 d = d[2:]
549 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700550 case extensionRenegotiationInfo:
551 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700552 return false
553 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700554 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400555 case extensionALPN:
556 if length < 2 {
557 return false
558 }
559 l := int(data[0])<<8 | int(data[1])
560 if l != length-2 {
561 return false
562 }
563 d := data[2:length]
564 for len(d) != 0 {
565 stringLen := int(d[0])
566 d = d[1:]
567 if stringLen == 0 || stringLen > len(d) {
568 return false
569 }
570 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
571 d = d[stringLen:]
572 }
David Benjamind30a9902014-08-24 01:44:23 -0400573 case extensionChannelID:
574 if length > 0 {
575 return false
576 }
577 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700578 case extensionExtendedMasterSecret:
579 if length != 0 {
580 return false
581 }
582 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500583 case extensionUseSRTP:
584 if length < 2 {
585 return false
586 }
587 l := int(data[0])<<8 | int(data[1])
588 if l > length-2 || l%2 != 0 {
589 return false
590 }
591 n := l / 2
592 m.srtpProtectionProfiles = make([]uint16, n)
593 d := data[2:length]
594 for i := 0; i < n; i++ {
595 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
596 d = d[2:]
597 }
598 if len(d) < 1 || int(d[0]) != len(d)-1 {
599 return false
600 }
601 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500602 case extensionSignedCertificateTimestamp:
603 if length != 0 {
604 return false
605 }
606 m.sctListSupported = true
Adam Langley95c29f32014-06-20 12:00:00 -0700607 }
608 data = data[length:]
609 }
610
611 return true
612}
613
614type serverHelloMsg struct {
David Benjaminca6c8262014-11-15 19:06:08 -0500615 raw []byte
616 isDTLS bool
617 vers uint16
618 random []byte
619 sessionId []byte
620 cipherSuite uint16
621 compressionMethod uint8
622 nextProtoNeg bool
623 nextProtos []string
624 ocspStapling bool
625 ticketSupported bool
626 secureRenegotiation []byte
627 alpnProtocol string
628 duplicateExtension bool
629 channelIDRequested bool
630 extendedMasterSecret bool
631 srtpProtectionProfile uint16
632 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -0500633 sctList []byte
Adam Langley95c29f32014-06-20 12:00:00 -0700634}
635
636func (m *serverHelloMsg) equal(i interface{}) bool {
637 m1, ok := i.(*serverHelloMsg)
638 if !ok {
639 return false
640 }
641
642 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400643 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700644 m.vers == m1.vers &&
645 bytes.Equal(m.random, m1.random) &&
646 bytes.Equal(m.sessionId, m1.sessionId) &&
647 m.cipherSuite == m1.cipherSuite &&
648 m.compressionMethod == m1.compressionMethod &&
649 m.nextProtoNeg == m1.nextProtoNeg &&
650 eqStrings(m.nextProtos, m1.nextProtos) &&
651 m.ocspStapling == m1.ocspStapling &&
652 m.ticketSupported == m1.ticketSupported &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700653 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
654 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400655 m.alpnProtocol == m1.alpnProtocol &&
David Benjamind30a9902014-08-24 01:44:23 -0400656 m.duplicateExtension == m1.duplicateExtension &&
Adam Langley75712922014-10-10 16:23:43 -0700657 m.channelIDRequested == m1.channelIDRequested &&
David Benjaminca6c8262014-11-15 19:06:08 -0500658 m.extendedMasterSecret == m1.extendedMasterSecret &&
659 m.srtpProtectionProfile == m1.srtpProtectionProfile &&
David Benjamin61f95272014-11-25 01:55:35 -0500660 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
661 bytes.Equal(m.sctList, m1.sctList)
Adam Langley95c29f32014-06-20 12:00:00 -0700662}
663
664func (m *serverHelloMsg) marshal() []byte {
665 if m.raw != nil {
666 return m.raw
667 }
668
669 length := 38 + len(m.sessionId)
670 numExtensions := 0
671 extensionsLength := 0
672
673 nextProtoLen := 0
674 if m.nextProtoNeg {
675 numExtensions++
676 for _, v := range m.nextProtos {
677 nextProtoLen += len(v)
678 }
679 nextProtoLen += len(m.nextProtos)
680 extensionsLength += nextProtoLen
681 }
682 if m.ocspStapling {
683 numExtensions++
684 }
685 if m.ticketSupported {
686 numExtensions++
687 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700688 if m.secureRenegotiation != nil {
689 extensionsLength += 1 + len(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700690 numExtensions++
691 }
David Benjamin35a7a442014-07-05 00:23:20 -0400692 if m.duplicateExtension {
693 numExtensions += 2
694 }
David Benjamind30a9902014-08-24 01:44:23 -0400695 if m.channelIDRequested {
696 numExtensions++
697 }
David Benjaminfa055a22014-09-15 16:51:51 -0400698 if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
699 if alpnLen >= 256 {
700 panic("invalid ALPN protocol")
701 }
702 extensionsLength += 2 + 1 + alpnLen
703 numExtensions++
704 }
Adam Langley75712922014-10-10 16:23:43 -0700705 if m.extendedMasterSecret {
706 numExtensions++
707 }
David Benjaminca6c8262014-11-15 19:06:08 -0500708 if m.srtpProtectionProfile != 0 {
709 extensionsLength += 2 + 2 + 1 + len(m.srtpMasterKeyIdentifier)
710 numExtensions++
711 }
David Benjamin61f95272014-11-25 01:55:35 -0500712 if m.sctList != nil {
713 extensionsLength += len(m.sctList)
714 numExtensions++
715 }
David Benjaminfa055a22014-09-15 16:51:51 -0400716
Adam Langley95c29f32014-06-20 12:00:00 -0700717 if numExtensions > 0 {
718 extensionsLength += 4 * numExtensions
719 length += 2 + extensionsLength
720 }
721
722 x := make([]byte, 4+length)
723 x[0] = typeServerHello
724 x[1] = uint8(length >> 16)
725 x[2] = uint8(length >> 8)
726 x[3] = uint8(length)
David Benjamin83c0bc92014-08-04 01:23:53 -0400727 vers := versionToWire(m.vers, m.isDTLS)
728 x[4] = uint8(vers >> 8)
729 x[5] = uint8(vers)
Adam Langley95c29f32014-06-20 12:00:00 -0700730 copy(x[6:38], m.random)
731 x[38] = uint8(len(m.sessionId))
732 copy(x[39:39+len(m.sessionId)], m.sessionId)
733 z := x[39+len(m.sessionId):]
734 z[0] = uint8(m.cipherSuite >> 8)
735 z[1] = uint8(m.cipherSuite)
736 z[2] = uint8(m.compressionMethod)
737
738 z = z[3:]
739 if numExtensions > 0 {
740 z[0] = byte(extensionsLength >> 8)
741 z[1] = byte(extensionsLength)
742 z = z[2:]
743 }
David Benjamin35a7a442014-07-05 00:23:20 -0400744 if m.duplicateExtension {
745 // Add a duplicate bogus extension at the beginning and end.
746 z[0] = 0xff
747 z[1] = 0xff
748 z = z[4:]
749 }
Adam Langley95c29f32014-06-20 12:00:00 -0700750 if m.nextProtoNeg {
751 z[0] = byte(extensionNextProtoNeg >> 8)
752 z[1] = byte(extensionNextProtoNeg & 0xff)
753 z[2] = byte(nextProtoLen >> 8)
754 z[3] = byte(nextProtoLen)
755 z = z[4:]
756
757 for _, v := range m.nextProtos {
758 l := len(v)
759 if l > 255 {
760 l = 255
761 }
762 z[0] = byte(l)
763 copy(z[1:], []byte(v[0:l]))
764 z = z[1+l:]
765 }
766 }
767 if m.ocspStapling {
768 z[0] = byte(extensionStatusRequest >> 8)
769 z[1] = byte(extensionStatusRequest)
770 z = z[4:]
771 }
772 if m.ticketSupported {
773 z[0] = byte(extensionSessionTicket >> 8)
774 z[1] = byte(extensionSessionTicket)
775 z = z[4:]
776 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700777 if m.secureRenegotiation != nil {
Adam Langley95c29f32014-06-20 12:00:00 -0700778 z[0] = byte(extensionRenegotiationInfo >> 8)
779 z[1] = byte(extensionRenegotiationInfo & 0xff)
780 z[2] = 0
Adam Langley2ae77d22014-10-28 17:29:33 -0700781 z[3] = byte(1 + len(m.secureRenegotiation))
782 z[4] = byte(len(m.secureRenegotiation))
Adam Langley95c29f32014-06-20 12:00:00 -0700783 z = z[5:]
Adam Langley2ae77d22014-10-28 17:29:33 -0700784 copy(z, m.secureRenegotiation)
785 z = z[len(m.secureRenegotiation):]
Adam Langley95c29f32014-06-20 12:00:00 -0700786 }
David Benjaminfa055a22014-09-15 16:51:51 -0400787 if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
788 z[0] = byte(extensionALPN >> 8)
789 z[1] = byte(extensionALPN & 0xff)
790 l := 2 + 1 + alpnLen
791 z[2] = byte(l >> 8)
792 z[3] = byte(l)
793 l -= 2
794 z[4] = byte(l >> 8)
795 z[5] = byte(l)
796 l -= 1
797 z[6] = byte(l)
798 copy(z[7:], []byte(m.alpnProtocol))
799 z = z[7+alpnLen:]
800 }
David Benjamind30a9902014-08-24 01:44:23 -0400801 if m.channelIDRequested {
802 z[0] = byte(extensionChannelID >> 8)
803 z[1] = byte(extensionChannelID & 0xff)
804 z = z[4:]
805 }
David Benjamin35a7a442014-07-05 00:23:20 -0400806 if m.duplicateExtension {
807 // Add a duplicate bogus extension at the beginning and end.
808 z[0] = 0xff
809 z[1] = 0xff
810 z = z[4:]
811 }
Adam Langley75712922014-10-10 16:23:43 -0700812 if m.extendedMasterSecret {
813 z[0] = byte(extensionExtendedMasterSecret >> 8)
814 z[1] = byte(extensionExtendedMasterSecret & 0xff)
815 z = z[4:]
816 }
David Benjaminca6c8262014-11-15 19:06:08 -0500817 if m.srtpProtectionProfile != 0 {
818 z[0] = byte(extensionUseSRTP >> 8)
819 z[1] = byte(extensionUseSRTP & 0xff)
820 l := 2 + 2 + 1 + len(m.srtpMasterKeyIdentifier)
821 z[2] = byte(l >> 8)
822 z[3] = byte(l & 0xff)
823 z[4] = 0
824 z[5] = 2
825 z[6] = byte(m.srtpProtectionProfile >> 8)
826 z[7] = byte(m.srtpProtectionProfile & 0xff)
827 l = len(m.srtpMasterKeyIdentifier)
828 z[8] = byte(l)
829 copy(z[9:], []byte(m.srtpMasterKeyIdentifier))
830 z = z[9+l:]
831 }
David Benjamin61f95272014-11-25 01:55:35 -0500832 if m.sctList != nil {
833 z[0] = byte(extensionSignedCertificateTimestamp >> 8)
834 z[1] = byte(extensionSignedCertificateTimestamp & 0xff)
835 l := len(m.sctList)
836 z[2] = byte(l >> 8)
837 z[3] = byte(l & 0xff)
838 copy(z[4:], m.sctList)
839 z = z[4+l:]
840 }
Adam Langley95c29f32014-06-20 12:00:00 -0700841
842 m.raw = x
843
844 return x
845}
846
847func (m *serverHelloMsg) unmarshal(data []byte) bool {
848 if len(data) < 42 {
849 return false
850 }
851 m.raw = data
David Benjamin83c0bc92014-08-04 01:23:53 -0400852 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
Adam Langley95c29f32014-06-20 12:00:00 -0700853 m.random = data[6:38]
854 sessionIdLen := int(data[38])
855 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
856 return false
857 }
858 m.sessionId = data[39 : 39+sessionIdLen]
859 data = data[39+sessionIdLen:]
860 if len(data) < 3 {
861 return false
862 }
863 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
864 m.compressionMethod = data[2]
865 data = data[3:]
866
867 m.nextProtoNeg = false
868 m.nextProtos = nil
869 m.ocspStapling = false
870 m.ticketSupported = false
David Benjaminfa055a22014-09-15 16:51:51 -0400871 m.alpnProtocol = ""
Adam Langley75712922014-10-10 16:23:43 -0700872 m.extendedMasterSecret = false
Adam Langley95c29f32014-06-20 12:00:00 -0700873
874 if len(data) == 0 {
875 // ServerHello is optionally followed by extension data
876 return true
877 }
878 if len(data) < 2 {
879 return false
880 }
881
882 extensionsLength := int(data[0])<<8 | int(data[1])
883 data = data[2:]
884 if len(data) != extensionsLength {
885 return false
886 }
887
888 for len(data) != 0 {
889 if len(data) < 4 {
890 return false
891 }
892 extension := uint16(data[0])<<8 | uint16(data[1])
893 length := int(data[2])<<8 | int(data[3])
894 data = data[4:]
895 if len(data) < length {
896 return false
897 }
898
899 switch extension {
900 case extensionNextProtoNeg:
901 m.nextProtoNeg = true
902 d := data[:length]
903 for len(d) > 0 {
904 l := int(d[0])
905 d = d[1:]
906 if l == 0 || l > len(d) {
907 return false
908 }
909 m.nextProtos = append(m.nextProtos, string(d[:l]))
910 d = d[l:]
911 }
912 case extensionStatusRequest:
913 if length > 0 {
914 return false
915 }
916 m.ocspStapling = true
917 case extensionSessionTicket:
918 if length > 0 {
919 return false
920 }
921 m.ticketSupported = true
922 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -0700923 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700924 return false
925 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700926 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400927 case extensionALPN:
928 d := data[:length]
929 if len(d) < 3 {
930 return false
931 }
932 l := int(d[0])<<8 | int(d[1])
933 if l != len(d)-2 {
934 return false
935 }
936 d = d[2:]
937 l = int(d[0])
938 if l != len(d)-1 {
939 return false
940 }
941 d = d[1:]
942 m.alpnProtocol = string(d)
David Benjamind30a9902014-08-24 01:44:23 -0400943 case extensionChannelID:
944 if length > 0 {
945 return false
946 }
947 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -0700948 case extensionExtendedMasterSecret:
949 if length != 0 {
950 return false
951 }
952 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500953 case extensionUseSRTP:
954 if length < 2+2+1 {
955 return false
956 }
957 if data[0] != 0 || data[1] != 2 {
958 return false
959 }
960 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
961 d := data[4:length]
962 l := int(d[0])
963 if l != len(d)-1 {
964 return false
965 }
966 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500967 case extensionSignedCertificateTimestamp:
968 if length < 2 {
969 return false
970 }
971 l := int(data[0])<<8 | int(data[1])
972 if l != len(data)-2 {
973 return false
974 }
975 m.sctList = data[2:length]
Adam Langley95c29f32014-06-20 12:00:00 -0700976 }
977 data = data[length:]
978 }
979
980 return true
981}
982
983type certificateMsg struct {
984 raw []byte
985 certificates [][]byte
986}
987
988func (m *certificateMsg) equal(i interface{}) bool {
989 m1, ok := i.(*certificateMsg)
990 if !ok {
991 return false
992 }
993
994 return bytes.Equal(m.raw, m1.raw) &&
995 eqByteSlices(m.certificates, m1.certificates)
996}
997
998func (m *certificateMsg) marshal() (x []byte) {
999 if m.raw != nil {
1000 return m.raw
1001 }
1002
1003 var i int
1004 for _, slice := range m.certificates {
1005 i += len(slice)
1006 }
1007
1008 length := 3 + 3*len(m.certificates) + i
1009 x = make([]byte, 4+length)
1010 x[0] = typeCertificate
1011 x[1] = uint8(length >> 16)
1012 x[2] = uint8(length >> 8)
1013 x[3] = uint8(length)
1014
1015 certificateOctets := length - 3
1016 x[4] = uint8(certificateOctets >> 16)
1017 x[5] = uint8(certificateOctets >> 8)
1018 x[6] = uint8(certificateOctets)
1019
1020 y := x[7:]
1021 for _, slice := range m.certificates {
1022 y[0] = uint8(len(slice) >> 16)
1023 y[1] = uint8(len(slice) >> 8)
1024 y[2] = uint8(len(slice))
1025 copy(y[3:], slice)
1026 y = y[3+len(slice):]
1027 }
1028
1029 m.raw = x
1030 return
1031}
1032
1033func (m *certificateMsg) unmarshal(data []byte) bool {
1034 if len(data) < 7 {
1035 return false
1036 }
1037
1038 m.raw = data
1039 certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
1040 if uint32(len(data)) != certsLen+7 {
1041 return false
1042 }
1043
1044 numCerts := 0
1045 d := data[7:]
1046 for certsLen > 0 {
1047 if len(d) < 4 {
1048 return false
1049 }
1050 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
1051 if uint32(len(d)) < 3+certLen {
1052 return false
1053 }
1054 d = d[3+certLen:]
1055 certsLen -= 3 + certLen
1056 numCerts++
1057 }
1058
1059 m.certificates = make([][]byte, numCerts)
1060 d = data[7:]
1061 for i := 0; i < numCerts; i++ {
1062 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
1063 m.certificates[i] = d[3 : 3+certLen]
1064 d = d[3+certLen:]
1065 }
1066
1067 return true
1068}
1069
1070type serverKeyExchangeMsg struct {
1071 raw []byte
1072 key []byte
1073}
1074
1075func (m *serverKeyExchangeMsg) equal(i interface{}) bool {
1076 m1, ok := i.(*serverKeyExchangeMsg)
1077 if !ok {
1078 return false
1079 }
1080
1081 return bytes.Equal(m.raw, m1.raw) &&
1082 bytes.Equal(m.key, m1.key)
1083}
1084
1085func (m *serverKeyExchangeMsg) marshal() []byte {
1086 if m.raw != nil {
1087 return m.raw
1088 }
1089 length := len(m.key)
1090 x := make([]byte, length+4)
1091 x[0] = typeServerKeyExchange
1092 x[1] = uint8(length >> 16)
1093 x[2] = uint8(length >> 8)
1094 x[3] = uint8(length)
1095 copy(x[4:], m.key)
1096
1097 m.raw = x
1098 return x
1099}
1100
1101func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1102 m.raw = data
1103 if len(data) < 4 {
1104 return false
1105 }
1106 m.key = data[4:]
1107 return true
1108}
1109
1110type certificateStatusMsg struct {
1111 raw []byte
1112 statusType uint8
1113 response []byte
1114}
1115
1116func (m *certificateStatusMsg) equal(i interface{}) bool {
1117 m1, ok := i.(*certificateStatusMsg)
1118 if !ok {
1119 return false
1120 }
1121
1122 return bytes.Equal(m.raw, m1.raw) &&
1123 m.statusType == m1.statusType &&
1124 bytes.Equal(m.response, m1.response)
1125}
1126
1127func (m *certificateStatusMsg) marshal() []byte {
1128 if m.raw != nil {
1129 return m.raw
1130 }
1131
1132 var x []byte
1133 if m.statusType == statusTypeOCSP {
1134 x = make([]byte, 4+4+len(m.response))
1135 x[0] = typeCertificateStatus
1136 l := len(m.response) + 4
1137 x[1] = byte(l >> 16)
1138 x[2] = byte(l >> 8)
1139 x[3] = byte(l)
1140 x[4] = statusTypeOCSP
1141
1142 l -= 4
1143 x[5] = byte(l >> 16)
1144 x[6] = byte(l >> 8)
1145 x[7] = byte(l)
1146 copy(x[8:], m.response)
1147 } else {
1148 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1149 }
1150
1151 m.raw = x
1152 return x
1153}
1154
1155func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1156 m.raw = data
1157 if len(data) < 5 {
1158 return false
1159 }
1160 m.statusType = data[4]
1161
1162 m.response = nil
1163 if m.statusType == statusTypeOCSP {
1164 if len(data) < 8 {
1165 return false
1166 }
1167 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1168 if uint32(len(data)) != 4+4+respLen {
1169 return false
1170 }
1171 m.response = data[8:]
1172 }
1173 return true
1174}
1175
1176type serverHelloDoneMsg struct{}
1177
1178func (m *serverHelloDoneMsg) equal(i interface{}) bool {
1179 _, ok := i.(*serverHelloDoneMsg)
1180 return ok
1181}
1182
1183func (m *serverHelloDoneMsg) marshal() []byte {
1184 x := make([]byte, 4)
1185 x[0] = typeServerHelloDone
1186 return x
1187}
1188
1189func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1190 return len(data) == 4
1191}
1192
1193type clientKeyExchangeMsg struct {
1194 raw []byte
1195 ciphertext []byte
1196}
1197
1198func (m *clientKeyExchangeMsg) equal(i interface{}) bool {
1199 m1, ok := i.(*clientKeyExchangeMsg)
1200 if !ok {
1201 return false
1202 }
1203
1204 return bytes.Equal(m.raw, m1.raw) &&
1205 bytes.Equal(m.ciphertext, m1.ciphertext)
1206}
1207
1208func (m *clientKeyExchangeMsg) marshal() []byte {
1209 if m.raw != nil {
1210 return m.raw
1211 }
1212 length := len(m.ciphertext)
1213 x := make([]byte, length+4)
1214 x[0] = typeClientKeyExchange
1215 x[1] = uint8(length >> 16)
1216 x[2] = uint8(length >> 8)
1217 x[3] = uint8(length)
1218 copy(x[4:], m.ciphertext)
1219
1220 m.raw = x
1221 return x
1222}
1223
1224func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1225 m.raw = data
1226 if len(data) < 4 {
1227 return false
1228 }
1229 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1230 if l != len(data)-4 {
1231 return false
1232 }
1233 m.ciphertext = data[4:]
1234 return true
1235}
1236
1237type finishedMsg struct {
1238 raw []byte
1239 verifyData []byte
1240}
1241
1242func (m *finishedMsg) equal(i interface{}) bool {
1243 m1, ok := i.(*finishedMsg)
1244 if !ok {
1245 return false
1246 }
1247
1248 return bytes.Equal(m.raw, m1.raw) &&
1249 bytes.Equal(m.verifyData, m1.verifyData)
1250}
1251
1252func (m *finishedMsg) marshal() (x []byte) {
1253 if m.raw != nil {
1254 return m.raw
1255 }
1256
1257 x = make([]byte, 4+len(m.verifyData))
1258 x[0] = typeFinished
1259 x[3] = byte(len(m.verifyData))
1260 copy(x[4:], m.verifyData)
1261 m.raw = x
1262 return
1263}
1264
1265func (m *finishedMsg) unmarshal(data []byte) bool {
1266 m.raw = data
1267 if len(data) < 4 {
1268 return false
1269 }
1270 m.verifyData = data[4:]
1271 return true
1272}
1273
1274type nextProtoMsg struct {
1275 raw []byte
1276 proto string
1277}
1278
1279func (m *nextProtoMsg) equal(i interface{}) bool {
1280 m1, ok := i.(*nextProtoMsg)
1281 if !ok {
1282 return false
1283 }
1284
1285 return bytes.Equal(m.raw, m1.raw) &&
1286 m.proto == m1.proto
1287}
1288
1289func (m *nextProtoMsg) marshal() []byte {
1290 if m.raw != nil {
1291 return m.raw
1292 }
1293 l := len(m.proto)
1294 if l > 255 {
1295 l = 255
1296 }
1297
1298 padding := 32 - (l+2)%32
1299 length := l + padding + 2
1300 x := make([]byte, length+4)
1301 x[0] = typeNextProtocol
1302 x[1] = uint8(length >> 16)
1303 x[2] = uint8(length >> 8)
1304 x[3] = uint8(length)
1305
1306 y := x[4:]
1307 y[0] = byte(l)
1308 copy(y[1:], []byte(m.proto[0:l]))
1309 y = y[1+l:]
1310 y[0] = byte(padding)
1311
1312 m.raw = x
1313
1314 return x
1315}
1316
1317func (m *nextProtoMsg) unmarshal(data []byte) bool {
1318 m.raw = data
1319
1320 if len(data) < 5 {
1321 return false
1322 }
1323 data = data[4:]
1324 protoLen := int(data[0])
1325 data = data[1:]
1326 if len(data) < protoLen {
1327 return false
1328 }
1329 m.proto = string(data[0:protoLen])
1330 data = data[protoLen:]
1331
1332 if len(data) < 1 {
1333 return false
1334 }
1335 paddingLen := int(data[0])
1336 data = data[1:]
1337 if len(data) != paddingLen {
1338 return false
1339 }
1340
1341 return true
1342}
1343
1344type certificateRequestMsg struct {
1345 raw []byte
1346 // hasSignatureAndHash indicates whether this message includes a list
1347 // of signature and hash functions. This change was introduced with TLS
1348 // 1.2.
1349 hasSignatureAndHash bool
1350
1351 certificateTypes []byte
1352 signatureAndHashes []signatureAndHash
1353 certificateAuthorities [][]byte
1354}
1355
1356func (m *certificateRequestMsg) equal(i interface{}) bool {
1357 m1, ok := i.(*certificateRequestMsg)
1358 if !ok {
1359 return false
1360 }
1361
1362 return bytes.Equal(m.raw, m1.raw) &&
1363 bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
1364 eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
1365 eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes)
1366}
1367
1368func (m *certificateRequestMsg) marshal() (x []byte) {
1369 if m.raw != nil {
1370 return m.raw
1371 }
1372
1373 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
1374 length := 1 + len(m.certificateTypes) + 2
1375 casLength := 0
1376 for _, ca := range m.certificateAuthorities {
1377 casLength += 2 + len(ca)
1378 }
1379 length += casLength
1380
1381 if m.hasSignatureAndHash {
1382 length += 2 + 2*len(m.signatureAndHashes)
1383 }
1384
1385 x = make([]byte, 4+length)
1386 x[0] = typeCertificateRequest
1387 x[1] = uint8(length >> 16)
1388 x[2] = uint8(length >> 8)
1389 x[3] = uint8(length)
1390
1391 x[4] = uint8(len(m.certificateTypes))
1392
1393 copy(x[5:], m.certificateTypes)
1394 y := x[5+len(m.certificateTypes):]
1395
1396 if m.hasSignatureAndHash {
1397 n := len(m.signatureAndHashes) * 2
1398 y[0] = uint8(n >> 8)
1399 y[1] = uint8(n)
1400 y = y[2:]
1401 for _, sigAndHash := range m.signatureAndHashes {
1402 y[0] = sigAndHash.hash
1403 y[1] = sigAndHash.signature
1404 y = y[2:]
1405 }
1406 }
1407
1408 y[0] = uint8(casLength >> 8)
1409 y[1] = uint8(casLength)
1410 y = y[2:]
1411 for _, ca := range m.certificateAuthorities {
1412 y[0] = uint8(len(ca) >> 8)
1413 y[1] = uint8(len(ca))
1414 y = y[2:]
1415 copy(y, ca)
1416 y = y[len(ca):]
1417 }
1418
1419 m.raw = x
1420 return
1421}
1422
1423func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1424 m.raw = data
1425
1426 if len(data) < 5 {
1427 return false
1428 }
1429
1430 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1431 if uint32(len(data))-4 != length {
1432 return false
1433 }
1434
1435 numCertTypes := int(data[4])
1436 data = data[5:]
1437 if numCertTypes == 0 || len(data) <= numCertTypes {
1438 return false
1439 }
1440
1441 m.certificateTypes = make([]byte, numCertTypes)
1442 if copy(m.certificateTypes, data) != numCertTypes {
1443 return false
1444 }
1445
1446 data = data[numCertTypes:]
1447
1448 if m.hasSignatureAndHash {
1449 if len(data) < 2 {
1450 return false
1451 }
1452 sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
1453 data = data[2:]
1454 if sigAndHashLen&1 != 0 {
1455 return false
1456 }
1457 if len(data) < int(sigAndHashLen) {
1458 return false
1459 }
1460 numSigAndHash := sigAndHashLen / 2
1461 m.signatureAndHashes = make([]signatureAndHash, numSigAndHash)
1462 for i := range m.signatureAndHashes {
1463 m.signatureAndHashes[i].hash = data[0]
1464 m.signatureAndHashes[i].signature = data[1]
1465 data = data[2:]
1466 }
1467 }
1468
1469 if len(data) < 2 {
1470 return false
1471 }
1472 casLength := uint16(data[0])<<8 | uint16(data[1])
1473 data = data[2:]
1474 if len(data) < int(casLength) {
1475 return false
1476 }
1477 cas := make([]byte, casLength)
1478 copy(cas, data)
1479 data = data[casLength:]
1480
1481 m.certificateAuthorities = nil
1482 for len(cas) > 0 {
1483 if len(cas) < 2 {
1484 return false
1485 }
1486 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1487 cas = cas[2:]
1488
1489 if len(cas) < int(caLen) {
1490 return false
1491 }
1492
1493 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1494 cas = cas[caLen:]
1495 }
1496 if len(data) > 0 {
1497 return false
1498 }
1499
1500 return true
1501}
1502
1503type certificateVerifyMsg struct {
1504 raw []byte
1505 hasSignatureAndHash bool
1506 signatureAndHash signatureAndHash
1507 signature []byte
1508}
1509
1510func (m *certificateVerifyMsg) equal(i interface{}) bool {
1511 m1, ok := i.(*certificateVerifyMsg)
1512 if !ok {
1513 return false
1514 }
1515
1516 return bytes.Equal(m.raw, m1.raw) &&
1517 m.hasSignatureAndHash == m1.hasSignatureAndHash &&
1518 m.signatureAndHash.hash == m1.signatureAndHash.hash &&
1519 m.signatureAndHash.signature == m1.signatureAndHash.signature &&
1520 bytes.Equal(m.signature, m1.signature)
1521}
1522
1523func (m *certificateVerifyMsg) marshal() (x []byte) {
1524 if m.raw != nil {
1525 return m.raw
1526 }
1527
1528 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1529 siglength := len(m.signature)
1530 length := 2 + siglength
1531 if m.hasSignatureAndHash {
1532 length += 2
1533 }
1534 x = make([]byte, 4+length)
1535 x[0] = typeCertificateVerify
1536 x[1] = uint8(length >> 16)
1537 x[2] = uint8(length >> 8)
1538 x[3] = uint8(length)
1539 y := x[4:]
1540 if m.hasSignatureAndHash {
1541 y[0] = m.signatureAndHash.hash
1542 y[1] = m.signatureAndHash.signature
1543 y = y[2:]
1544 }
1545 y[0] = uint8(siglength >> 8)
1546 y[1] = uint8(siglength)
1547 copy(y[2:], m.signature)
1548
1549 m.raw = x
1550
1551 return
1552}
1553
1554func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1555 m.raw = data
1556
1557 if len(data) < 6 {
1558 return false
1559 }
1560
1561 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1562 if uint32(len(data))-4 != length {
1563 return false
1564 }
1565
1566 data = data[4:]
1567 if m.hasSignatureAndHash {
1568 m.signatureAndHash.hash = data[0]
1569 m.signatureAndHash.signature = data[1]
1570 data = data[2:]
1571 }
1572
1573 if len(data) < 2 {
1574 return false
1575 }
1576 siglength := int(data[0])<<8 + int(data[1])
1577 data = data[2:]
1578 if len(data) != siglength {
1579 return false
1580 }
1581
1582 m.signature = data
1583
1584 return true
1585}
1586
1587type newSessionTicketMsg struct {
1588 raw []byte
1589 ticket []byte
1590}
1591
1592func (m *newSessionTicketMsg) equal(i interface{}) bool {
1593 m1, ok := i.(*newSessionTicketMsg)
1594 if !ok {
1595 return false
1596 }
1597
1598 return bytes.Equal(m.raw, m1.raw) &&
1599 bytes.Equal(m.ticket, m1.ticket)
1600}
1601
1602func (m *newSessionTicketMsg) marshal() (x []byte) {
1603 if m.raw != nil {
1604 return m.raw
1605 }
1606
1607 // See http://tools.ietf.org/html/rfc5077#section-3.3
1608 ticketLen := len(m.ticket)
1609 length := 2 + 4 + ticketLen
1610 x = make([]byte, 4+length)
1611 x[0] = typeNewSessionTicket
1612 x[1] = uint8(length >> 16)
1613 x[2] = uint8(length >> 8)
1614 x[3] = uint8(length)
1615 x[8] = uint8(ticketLen >> 8)
1616 x[9] = uint8(ticketLen)
1617 copy(x[10:], m.ticket)
1618
1619 m.raw = x
1620
1621 return
1622}
1623
1624func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
1625 m.raw = data
1626
1627 if len(data) < 10 {
1628 return false
1629 }
1630
1631 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1632 if uint32(len(data))-4 != length {
1633 return false
1634 }
1635
1636 ticketLen := int(data[8])<<8 + int(data[9])
1637 if len(data)-10 != ticketLen {
1638 return false
1639 }
1640
1641 m.ticket = data[10:]
1642
1643 return true
1644}
1645
David Benjamind86c7672014-08-02 04:07:12 -04001646type v2ClientHelloMsg struct {
1647 raw []byte
1648 vers uint16
1649 cipherSuites []uint16
1650 sessionId []byte
1651 challenge []byte
1652}
1653
1654func (m *v2ClientHelloMsg) equal(i interface{}) bool {
1655 m1, ok := i.(*v2ClientHelloMsg)
1656 if !ok {
1657 return false
1658 }
1659
1660 return bytes.Equal(m.raw, m1.raw) &&
1661 m.vers == m1.vers &&
1662 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
1663 bytes.Equal(m.sessionId, m1.sessionId) &&
1664 bytes.Equal(m.challenge, m1.challenge)
1665}
1666
1667func (m *v2ClientHelloMsg) marshal() []byte {
1668 if m.raw != nil {
1669 return m.raw
1670 }
1671
1672 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
1673
1674 x := make([]byte, length)
1675 x[0] = 1
1676 x[1] = uint8(m.vers >> 8)
1677 x[2] = uint8(m.vers)
1678 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
1679 x[4] = uint8(len(m.cipherSuites) * 3)
1680 x[5] = uint8(len(m.sessionId) >> 8)
1681 x[6] = uint8(len(m.sessionId))
1682 x[7] = uint8(len(m.challenge) >> 8)
1683 x[8] = uint8(len(m.challenge))
1684 y := x[9:]
1685 for i, spec := range m.cipherSuites {
1686 y[i*3] = 0
1687 y[i*3+1] = uint8(spec >> 8)
1688 y[i*3+2] = uint8(spec)
1689 }
1690 y = y[len(m.cipherSuites)*3:]
1691 copy(y, m.sessionId)
1692 y = y[len(m.sessionId):]
1693 copy(y, m.challenge)
1694
1695 m.raw = x
1696
1697 return x
1698}
1699
David Benjamin83c0bc92014-08-04 01:23:53 -04001700type helloVerifyRequestMsg struct {
1701 raw []byte
1702 vers uint16
1703 cookie []byte
1704}
1705
1706func (m *helloVerifyRequestMsg) equal(i interface{}) bool {
1707 m1, ok := i.(*helloVerifyRequestMsg)
1708 if !ok {
1709 return false
1710 }
1711
David Benjamind30a9902014-08-24 01:44:23 -04001712 return bytes.Equal(m.raw, m1.raw) &&
1713 m.vers == m1.vers &&
David Benjamin83c0bc92014-08-04 01:23:53 -04001714 bytes.Equal(m.cookie, m1.cookie)
1715}
1716
1717func (m *helloVerifyRequestMsg) marshal() []byte {
1718 if m.raw != nil {
1719 return m.raw
1720 }
1721
1722 length := 2 + 1 + len(m.cookie)
1723
1724 x := make([]byte, 4+length)
1725 x[0] = typeHelloVerifyRequest
1726 x[1] = uint8(length >> 16)
1727 x[2] = uint8(length >> 8)
1728 x[3] = uint8(length)
1729 vers := versionToWire(m.vers, true)
1730 x[4] = uint8(vers >> 8)
1731 x[5] = uint8(vers)
1732 x[6] = uint8(len(m.cookie))
1733 copy(x[7:7+len(m.cookie)], m.cookie)
1734
1735 return x
1736}
1737
1738func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
1739 if len(data) < 4+2+1 {
1740 return false
1741 }
1742 m.raw = data
1743 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), true)
1744 cookieLen := int(data[6])
1745 if cookieLen > 32 || len(data) != 7+cookieLen {
1746 return false
1747 }
1748 m.cookie = data[7 : 7+cookieLen]
1749
1750 return true
1751}
1752
David Benjamind30a9902014-08-24 01:44:23 -04001753type encryptedExtensionsMsg struct {
1754 raw []byte
1755 channelID []byte
1756}
1757
1758func (m *encryptedExtensionsMsg) equal(i interface{}) bool {
1759 m1, ok := i.(*encryptedExtensionsMsg)
1760 if !ok {
1761 return false
1762 }
1763
1764 return bytes.Equal(m.raw, m1.raw) &&
1765 bytes.Equal(m.channelID, m1.channelID)
1766}
1767
1768func (m *encryptedExtensionsMsg) marshal() []byte {
1769 if m.raw != nil {
1770 return m.raw
1771 }
1772
1773 length := 2 + 2 + len(m.channelID)
1774
1775 x := make([]byte, 4+length)
1776 x[0] = typeEncryptedExtensions
1777 x[1] = uint8(length >> 16)
1778 x[2] = uint8(length >> 8)
1779 x[3] = uint8(length)
1780 x[4] = uint8(extensionChannelID >> 8)
1781 x[5] = uint8(extensionChannelID & 0xff)
1782 x[6] = uint8(len(m.channelID) >> 8)
1783 x[7] = uint8(len(m.channelID) & 0xff)
1784 copy(x[8:], m.channelID)
1785
1786 return x
1787}
1788
1789func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
1790 if len(data) != 4+2+2+128 {
1791 return false
1792 }
1793 m.raw = data
1794 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
1795 return false
1796 }
1797 if int(data[6])<<8|int(data[7]) != 128 {
1798 return false
1799 }
1800 m.channelID = data[4+2+2:]
1801
1802 return true
1803}
1804
Adam Langley2ae77d22014-10-28 17:29:33 -07001805type helloRequestMsg struct {
1806}
1807
1808func (*helloRequestMsg) marshal() []byte {
1809 return []byte{typeHelloRequest, 0, 0, 0}
1810}
1811
1812func (*helloRequestMsg) unmarshal(data []byte) bool {
1813 return len(data) == 4
1814}
1815
Adam Langley95c29f32014-06-20 12:00:00 -07001816func eqUint16s(x, y []uint16) bool {
1817 if len(x) != len(y) {
1818 return false
1819 }
1820 for i, v := range x {
1821 if y[i] != v {
1822 return false
1823 }
1824 }
1825 return true
1826}
1827
1828func eqCurveIDs(x, y []CurveID) bool {
1829 if len(x) != len(y) {
1830 return false
1831 }
1832 for i, v := range x {
1833 if y[i] != v {
1834 return false
1835 }
1836 }
1837 return true
1838}
1839
1840func eqStrings(x, y []string) bool {
1841 if len(x) != len(y) {
1842 return false
1843 }
1844 for i, v := range x {
1845 if y[i] != v {
1846 return false
1847 }
1848 }
1849 return true
1850}
1851
1852func eqByteSlices(x, y [][]byte) bool {
1853 if len(x) != len(y) {
1854 return false
1855 }
1856 for i, v := range x {
1857 if !bytes.Equal(v, y[i]) {
1858 return false
1859 }
1860 }
1861 return true
1862}
1863
1864func eqSignatureAndHashes(x, y []signatureAndHash) bool {
1865 if len(x) != len(y) {
1866 return false
1867 }
1868 for i, v := range x {
1869 v2 := y[i]
1870 if v.hash != v2.hash || v.signature != v2.signature {
1871 return false
1872 }
1873 }
1874 return true
1875}