blob: 4fee9d4624acbae16de3046734503629e9afe773 [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 {
Adam Langleyefb0e162015-07-09 11:35:04 -0700122 if l := len(s); l > 255 {
David Benjaminfa055a22014-09-15 16:51:51 -0400123 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
Adam Langleyefb0e162015-07-09 11:35:04 -0700628 alpnProtocolEmpty bool
David Benjaminca6c8262014-11-15 19:06:08 -0500629 duplicateExtension bool
630 channelIDRequested bool
631 extendedMasterSecret bool
632 srtpProtectionProfile uint16
633 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -0500634 sctList []byte
Adam Langley95c29f32014-06-20 12:00:00 -0700635}
636
637func (m *serverHelloMsg) equal(i interface{}) bool {
638 m1, ok := i.(*serverHelloMsg)
639 if !ok {
640 return false
641 }
642
643 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400644 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700645 m.vers == m1.vers &&
646 bytes.Equal(m.random, m1.random) &&
647 bytes.Equal(m.sessionId, m1.sessionId) &&
648 m.cipherSuite == m1.cipherSuite &&
649 m.compressionMethod == m1.compressionMethod &&
650 m.nextProtoNeg == m1.nextProtoNeg &&
651 eqStrings(m.nextProtos, m1.nextProtos) &&
652 m.ocspStapling == m1.ocspStapling &&
653 m.ticketSupported == m1.ticketSupported &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700654 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
655 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400656 m.alpnProtocol == m1.alpnProtocol &&
Adam Langleyefb0e162015-07-09 11:35:04 -0700657 m.alpnProtocolEmpty == m1.alpnProtocolEmpty &&
David Benjamind30a9902014-08-24 01:44:23 -0400658 m.duplicateExtension == m1.duplicateExtension &&
Adam Langley75712922014-10-10 16:23:43 -0700659 m.channelIDRequested == m1.channelIDRequested &&
David Benjaminca6c8262014-11-15 19:06:08 -0500660 m.extendedMasterSecret == m1.extendedMasterSecret &&
661 m.srtpProtectionProfile == m1.srtpProtectionProfile &&
David Benjamin61f95272014-11-25 01:55:35 -0500662 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
663 bytes.Equal(m.sctList, m1.sctList)
Adam Langley95c29f32014-06-20 12:00:00 -0700664}
665
666func (m *serverHelloMsg) marshal() []byte {
667 if m.raw != nil {
668 return m.raw
669 }
670
671 length := 38 + len(m.sessionId)
672 numExtensions := 0
673 extensionsLength := 0
674
675 nextProtoLen := 0
676 if m.nextProtoNeg {
677 numExtensions++
678 for _, v := range m.nextProtos {
679 nextProtoLen += len(v)
680 }
681 nextProtoLen += len(m.nextProtos)
682 extensionsLength += nextProtoLen
683 }
684 if m.ocspStapling {
685 numExtensions++
686 }
687 if m.ticketSupported {
688 numExtensions++
689 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700690 if m.secureRenegotiation != nil {
691 extensionsLength += 1 + len(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700692 numExtensions++
693 }
David Benjamin35a7a442014-07-05 00:23:20 -0400694 if m.duplicateExtension {
695 numExtensions += 2
696 }
David Benjamind30a9902014-08-24 01:44:23 -0400697 if m.channelIDRequested {
698 numExtensions++
699 }
Adam Langleyefb0e162015-07-09 11:35:04 -0700700 if alpnLen := len(m.alpnProtocol); alpnLen > 0 || m.alpnProtocolEmpty {
David Benjaminfa055a22014-09-15 16:51:51 -0400701 if alpnLen >= 256 {
702 panic("invalid ALPN protocol")
703 }
704 extensionsLength += 2 + 1 + alpnLen
705 numExtensions++
706 }
Adam Langley75712922014-10-10 16:23:43 -0700707 if m.extendedMasterSecret {
708 numExtensions++
709 }
David Benjaminca6c8262014-11-15 19:06:08 -0500710 if m.srtpProtectionProfile != 0 {
711 extensionsLength += 2 + 2 + 1 + len(m.srtpMasterKeyIdentifier)
712 numExtensions++
713 }
David Benjamin61f95272014-11-25 01:55:35 -0500714 if m.sctList != nil {
715 extensionsLength += len(m.sctList)
716 numExtensions++
717 }
David Benjaminfa055a22014-09-15 16:51:51 -0400718
Adam Langley95c29f32014-06-20 12:00:00 -0700719 if numExtensions > 0 {
720 extensionsLength += 4 * numExtensions
721 length += 2 + extensionsLength
722 }
723
724 x := make([]byte, 4+length)
725 x[0] = typeServerHello
726 x[1] = uint8(length >> 16)
727 x[2] = uint8(length >> 8)
728 x[3] = uint8(length)
David Benjamin83c0bc92014-08-04 01:23:53 -0400729 vers := versionToWire(m.vers, m.isDTLS)
730 x[4] = uint8(vers >> 8)
731 x[5] = uint8(vers)
Adam Langley95c29f32014-06-20 12:00:00 -0700732 copy(x[6:38], m.random)
733 x[38] = uint8(len(m.sessionId))
734 copy(x[39:39+len(m.sessionId)], m.sessionId)
735 z := x[39+len(m.sessionId):]
736 z[0] = uint8(m.cipherSuite >> 8)
737 z[1] = uint8(m.cipherSuite)
738 z[2] = uint8(m.compressionMethod)
739
740 z = z[3:]
741 if numExtensions > 0 {
742 z[0] = byte(extensionsLength >> 8)
743 z[1] = byte(extensionsLength)
744 z = z[2:]
745 }
David Benjamin35a7a442014-07-05 00:23:20 -0400746 if m.duplicateExtension {
747 // Add a duplicate bogus extension at the beginning and end.
748 z[0] = 0xff
749 z[1] = 0xff
750 z = z[4:]
751 }
Adam Langley95c29f32014-06-20 12:00:00 -0700752 if m.nextProtoNeg {
753 z[0] = byte(extensionNextProtoNeg >> 8)
754 z[1] = byte(extensionNextProtoNeg & 0xff)
755 z[2] = byte(nextProtoLen >> 8)
756 z[3] = byte(nextProtoLen)
757 z = z[4:]
758
759 for _, v := range m.nextProtos {
760 l := len(v)
761 if l > 255 {
762 l = 255
763 }
764 z[0] = byte(l)
765 copy(z[1:], []byte(v[0:l]))
766 z = z[1+l:]
767 }
768 }
769 if m.ocspStapling {
770 z[0] = byte(extensionStatusRequest >> 8)
771 z[1] = byte(extensionStatusRequest)
772 z = z[4:]
773 }
774 if m.ticketSupported {
775 z[0] = byte(extensionSessionTicket >> 8)
776 z[1] = byte(extensionSessionTicket)
777 z = z[4:]
778 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700779 if m.secureRenegotiation != nil {
Adam Langley95c29f32014-06-20 12:00:00 -0700780 z[0] = byte(extensionRenegotiationInfo >> 8)
781 z[1] = byte(extensionRenegotiationInfo & 0xff)
782 z[2] = 0
Adam Langley2ae77d22014-10-28 17:29:33 -0700783 z[3] = byte(1 + len(m.secureRenegotiation))
784 z[4] = byte(len(m.secureRenegotiation))
Adam Langley95c29f32014-06-20 12:00:00 -0700785 z = z[5:]
Adam Langley2ae77d22014-10-28 17:29:33 -0700786 copy(z, m.secureRenegotiation)
787 z = z[len(m.secureRenegotiation):]
Adam Langley95c29f32014-06-20 12:00:00 -0700788 }
Adam Langleyefb0e162015-07-09 11:35:04 -0700789 if alpnLen := len(m.alpnProtocol); alpnLen > 0 || m.alpnProtocolEmpty {
David Benjaminfa055a22014-09-15 16:51:51 -0400790 z[0] = byte(extensionALPN >> 8)
791 z[1] = byte(extensionALPN & 0xff)
792 l := 2 + 1 + alpnLen
793 z[2] = byte(l >> 8)
794 z[3] = byte(l)
795 l -= 2
796 z[4] = byte(l >> 8)
797 z[5] = byte(l)
798 l -= 1
799 z[6] = byte(l)
800 copy(z[7:], []byte(m.alpnProtocol))
801 z = z[7+alpnLen:]
802 }
David Benjamind30a9902014-08-24 01:44:23 -0400803 if m.channelIDRequested {
804 z[0] = byte(extensionChannelID >> 8)
805 z[1] = byte(extensionChannelID & 0xff)
806 z = z[4:]
807 }
David Benjamin35a7a442014-07-05 00:23:20 -0400808 if m.duplicateExtension {
809 // Add a duplicate bogus extension at the beginning and end.
810 z[0] = 0xff
811 z[1] = 0xff
812 z = z[4:]
813 }
Adam Langley75712922014-10-10 16:23:43 -0700814 if m.extendedMasterSecret {
815 z[0] = byte(extensionExtendedMasterSecret >> 8)
816 z[1] = byte(extensionExtendedMasterSecret & 0xff)
817 z = z[4:]
818 }
David Benjaminca6c8262014-11-15 19:06:08 -0500819 if m.srtpProtectionProfile != 0 {
820 z[0] = byte(extensionUseSRTP >> 8)
821 z[1] = byte(extensionUseSRTP & 0xff)
822 l := 2 + 2 + 1 + len(m.srtpMasterKeyIdentifier)
823 z[2] = byte(l >> 8)
824 z[3] = byte(l & 0xff)
825 z[4] = 0
826 z[5] = 2
827 z[6] = byte(m.srtpProtectionProfile >> 8)
828 z[7] = byte(m.srtpProtectionProfile & 0xff)
829 l = len(m.srtpMasterKeyIdentifier)
830 z[8] = byte(l)
831 copy(z[9:], []byte(m.srtpMasterKeyIdentifier))
832 z = z[9+l:]
833 }
David Benjamin61f95272014-11-25 01:55:35 -0500834 if m.sctList != nil {
835 z[0] = byte(extensionSignedCertificateTimestamp >> 8)
836 z[1] = byte(extensionSignedCertificateTimestamp & 0xff)
837 l := len(m.sctList)
838 z[2] = byte(l >> 8)
839 z[3] = byte(l & 0xff)
840 copy(z[4:], m.sctList)
841 z = z[4+l:]
842 }
Adam Langley95c29f32014-06-20 12:00:00 -0700843
844 m.raw = x
845
846 return x
847}
848
849func (m *serverHelloMsg) unmarshal(data []byte) bool {
850 if len(data) < 42 {
851 return false
852 }
853 m.raw = data
David Benjamin83c0bc92014-08-04 01:23:53 -0400854 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
Adam Langley95c29f32014-06-20 12:00:00 -0700855 m.random = data[6:38]
856 sessionIdLen := int(data[38])
857 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
858 return false
859 }
860 m.sessionId = data[39 : 39+sessionIdLen]
861 data = data[39+sessionIdLen:]
862 if len(data) < 3 {
863 return false
864 }
865 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
866 m.compressionMethod = data[2]
867 data = data[3:]
868
869 m.nextProtoNeg = false
870 m.nextProtos = nil
871 m.ocspStapling = false
872 m.ticketSupported = false
David Benjaminfa055a22014-09-15 16:51:51 -0400873 m.alpnProtocol = ""
Adam Langleyefb0e162015-07-09 11:35:04 -0700874 m.alpnProtocolEmpty = false
Adam Langley75712922014-10-10 16:23:43 -0700875 m.extendedMasterSecret = false
Adam Langley95c29f32014-06-20 12:00:00 -0700876
877 if len(data) == 0 {
878 // ServerHello is optionally followed by extension data
879 return true
880 }
881 if len(data) < 2 {
882 return false
883 }
884
885 extensionsLength := int(data[0])<<8 | int(data[1])
886 data = data[2:]
887 if len(data) != extensionsLength {
888 return false
889 }
890
891 for len(data) != 0 {
892 if len(data) < 4 {
893 return false
894 }
895 extension := uint16(data[0])<<8 | uint16(data[1])
896 length := int(data[2])<<8 | int(data[3])
897 data = data[4:]
898 if len(data) < length {
899 return false
900 }
901
902 switch extension {
903 case extensionNextProtoNeg:
904 m.nextProtoNeg = true
905 d := data[:length]
906 for len(d) > 0 {
907 l := int(d[0])
908 d = d[1:]
909 if l == 0 || l > len(d) {
910 return false
911 }
912 m.nextProtos = append(m.nextProtos, string(d[:l]))
913 d = d[l:]
914 }
915 case extensionStatusRequest:
916 if length > 0 {
917 return false
918 }
919 m.ocspStapling = true
920 case extensionSessionTicket:
921 if length > 0 {
922 return false
923 }
924 m.ticketSupported = true
925 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -0700926 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700927 return false
928 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700929 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400930 case extensionALPN:
931 d := data[:length]
932 if len(d) < 3 {
933 return false
934 }
935 l := int(d[0])<<8 | int(d[1])
936 if l != len(d)-2 {
937 return false
938 }
939 d = d[2:]
940 l = int(d[0])
941 if l != len(d)-1 {
942 return false
943 }
944 d = d[1:]
945 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -0700946 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -0400947 case extensionChannelID:
948 if length > 0 {
949 return false
950 }
951 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -0700952 case extensionExtendedMasterSecret:
953 if length != 0 {
954 return false
955 }
956 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500957 case extensionUseSRTP:
958 if length < 2+2+1 {
959 return false
960 }
961 if data[0] != 0 || data[1] != 2 {
962 return false
963 }
964 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
965 d := data[4:length]
966 l := int(d[0])
967 if l != len(d)-1 {
968 return false
969 }
970 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500971 case extensionSignedCertificateTimestamp:
972 if length < 2 {
973 return false
974 }
975 l := int(data[0])<<8 | int(data[1])
976 if l != len(data)-2 {
977 return false
978 }
979 m.sctList = data[2:length]
Adam Langley95c29f32014-06-20 12:00:00 -0700980 }
981 data = data[length:]
982 }
983
984 return true
985}
986
987type certificateMsg struct {
988 raw []byte
989 certificates [][]byte
990}
991
992func (m *certificateMsg) equal(i interface{}) bool {
993 m1, ok := i.(*certificateMsg)
994 if !ok {
995 return false
996 }
997
998 return bytes.Equal(m.raw, m1.raw) &&
999 eqByteSlices(m.certificates, m1.certificates)
1000}
1001
1002func (m *certificateMsg) marshal() (x []byte) {
1003 if m.raw != nil {
1004 return m.raw
1005 }
1006
1007 var i int
1008 for _, slice := range m.certificates {
1009 i += len(slice)
1010 }
1011
1012 length := 3 + 3*len(m.certificates) + i
1013 x = make([]byte, 4+length)
1014 x[0] = typeCertificate
1015 x[1] = uint8(length >> 16)
1016 x[2] = uint8(length >> 8)
1017 x[3] = uint8(length)
1018
1019 certificateOctets := length - 3
1020 x[4] = uint8(certificateOctets >> 16)
1021 x[5] = uint8(certificateOctets >> 8)
1022 x[6] = uint8(certificateOctets)
1023
1024 y := x[7:]
1025 for _, slice := range m.certificates {
1026 y[0] = uint8(len(slice) >> 16)
1027 y[1] = uint8(len(slice) >> 8)
1028 y[2] = uint8(len(slice))
1029 copy(y[3:], slice)
1030 y = y[3+len(slice):]
1031 }
1032
1033 m.raw = x
1034 return
1035}
1036
1037func (m *certificateMsg) unmarshal(data []byte) bool {
1038 if len(data) < 7 {
1039 return false
1040 }
1041
1042 m.raw = data
1043 certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
1044 if uint32(len(data)) != certsLen+7 {
1045 return false
1046 }
1047
1048 numCerts := 0
1049 d := data[7:]
1050 for certsLen > 0 {
1051 if len(d) < 4 {
1052 return false
1053 }
1054 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
1055 if uint32(len(d)) < 3+certLen {
1056 return false
1057 }
1058 d = d[3+certLen:]
1059 certsLen -= 3 + certLen
1060 numCerts++
1061 }
1062
1063 m.certificates = make([][]byte, numCerts)
1064 d = data[7:]
1065 for i := 0; i < numCerts; i++ {
1066 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
1067 m.certificates[i] = d[3 : 3+certLen]
1068 d = d[3+certLen:]
1069 }
1070
1071 return true
1072}
1073
1074type serverKeyExchangeMsg struct {
1075 raw []byte
1076 key []byte
1077}
1078
1079func (m *serverKeyExchangeMsg) equal(i interface{}) bool {
1080 m1, ok := i.(*serverKeyExchangeMsg)
1081 if !ok {
1082 return false
1083 }
1084
1085 return bytes.Equal(m.raw, m1.raw) &&
1086 bytes.Equal(m.key, m1.key)
1087}
1088
1089func (m *serverKeyExchangeMsg) marshal() []byte {
1090 if m.raw != nil {
1091 return m.raw
1092 }
1093 length := len(m.key)
1094 x := make([]byte, length+4)
1095 x[0] = typeServerKeyExchange
1096 x[1] = uint8(length >> 16)
1097 x[2] = uint8(length >> 8)
1098 x[3] = uint8(length)
1099 copy(x[4:], m.key)
1100
1101 m.raw = x
1102 return x
1103}
1104
1105func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1106 m.raw = data
1107 if len(data) < 4 {
1108 return false
1109 }
1110 m.key = data[4:]
1111 return true
1112}
1113
1114type certificateStatusMsg struct {
1115 raw []byte
1116 statusType uint8
1117 response []byte
1118}
1119
1120func (m *certificateStatusMsg) equal(i interface{}) bool {
1121 m1, ok := i.(*certificateStatusMsg)
1122 if !ok {
1123 return false
1124 }
1125
1126 return bytes.Equal(m.raw, m1.raw) &&
1127 m.statusType == m1.statusType &&
1128 bytes.Equal(m.response, m1.response)
1129}
1130
1131func (m *certificateStatusMsg) marshal() []byte {
1132 if m.raw != nil {
1133 return m.raw
1134 }
1135
1136 var x []byte
1137 if m.statusType == statusTypeOCSP {
1138 x = make([]byte, 4+4+len(m.response))
1139 x[0] = typeCertificateStatus
1140 l := len(m.response) + 4
1141 x[1] = byte(l >> 16)
1142 x[2] = byte(l >> 8)
1143 x[3] = byte(l)
1144 x[4] = statusTypeOCSP
1145
1146 l -= 4
1147 x[5] = byte(l >> 16)
1148 x[6] = byte(l >> 8)
1149 x[7] = byte(l)
1150 copy(x[8:], m.response)
1151 } else {
1152 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1153 }
1154
1155 m.raw = x
1156 return x
1157}
1158
1159func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1160 m.raw = data
1161 if len(data) < 5 {
1162 return false
1163 }
1164 m.statusType = data[4]
1165
1166 m.response = nil
1167 if m.statusType == statusTypeOCSP {
1168 if len(data) < 8 {
1169 return false
1170 }
1171 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1172 if uint32(len(data)) != 4+4+respLen {
1173 return false
1174 }
1175 m.response = data[8:]
1176 }
1177 return true
1178}
1179
1180type serverHelloDoneMsg struct{}
1181
1182func (m *serverHelloDoneMsg) equal(i interface{}) bool {
1183 _, ok := i.(*serverHelloDoneMsg)
1184 return ok
1185}
1186
1187func (m *serverHelloDoneMsg) marshal() []byte {
1188 x := make([]byte, 4)
1189 x[0] = typeServerHelloDone
1190 return x
1191}
1192
1193func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1194 return len(data) == 4
1195}
1196
1197type clientKeyExchangeMsg struct {
1198 raw []byte
1199 ciphertext []byte
1200}
1201
1202func (m *clientKeyExchangeMsg) equal(i interface{}) bool {
1203 m1, ok := i.(*clientKeyExchangeMsg)
1204 if !ok {
1205 return false
1206 }
1207
1208 return bytes.Equal(m.raw, m1.raw) &&
1209 bytes.Equal(m.ciphertext, m1.ciphertext)
1210}
1211
1212func (m *clientKeyExchangeMsg) marshal() []byte {
1213 if m.raw != nil {
1214 return m.raw
1215 }
1216 length := len(m.ciphertext)
1217 x := make([]byte, length+4)
1218 x[0] = typeClientKeyExchange
1219 x[1] = uint8(length >> 16)
1220 x[2] = uint8(length >> 8)
1221 x[3] = uint8(length)
1222 copy(x[4:], m.ciphertext)
1223
1224 m.raw = x
1225 return x
1226}
1227
1228func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1229 m.raw = data
1230 if len(data) < 4 {
1231 return false
1232 }
1233 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1234 if l != len(data)-4 {
1235 return false
1236 }
1237 m.ciphertext = data[4:]
1238 return true
1239}
1240
1241type finishedMsg struct {
1242 raw []byte
1243 verifyData []byte
1244}
1245
1246func (m *finishedMsg) equal(i interface{}) bool {
1247 m1, ok := i.(*finishedMsg)
1248 if !ok {
1249 return false
1250 }
1251
1252 return bytes.Equal(m.raw, m1.raw) &&
1253 bytes.Equal(m.verifyData, m1.verifyData)
1254}
1255
1256func (m *finishedMsg) marshal() (x []byte) {
1257 if m.raw != nil {
1258 return m.raw
1259 }
1260
1261 x = make([]byte, 4+len(m.verifyData))
1262 x[0] = typeFinished
1263 x[3] = byte(len(m.verifyData))
1264 copy(x[4:], m.verifyData)
1265 m.raw = x
1266 return
1267}
1268
1269func (m *finishedMsg) unmarshal(data []byte) bool {
1270 m.raw = data
1271 if len(data) < 4 {
1272 return false
1273 }
1274 m.verifyData = data[4:]
1275 return true
1276}
1277
1278type nextProtoMsg struct {
1279 raw []byte
1280 proto string
1281}
1282
1283func (m *nextProtoMsg) equal(i interface{}) bool {
1284 m1, ok := i.(*nextProtoMsg)
1285 if !ok {
1286 return false
1287 }
1288
1289 return bytes.Equal(m.raw, m1.raw) &&
1290 m.proto == m1.proto
1291}
1292
1293func (m *nextProtoMsg) marshal() []byte {
1294 if m.raw != nil {
1295 return m.raw
1296 }
1297 l := len(m.proto)
1298 if l > 255 {
1299 l = 255
1300 }
1301
1302 padding := 32 - (l+2)%32
1303 length := l + padding + 2
1304 x := make([]byte, length+4)
1305 x[0] = typeNextProtocol
1306 x[1] = uint8(length >> 16)
1307 x[2] = uint8(length >> 8)
1308 x[3] = uint8(length)
1309
1310 y := x[4:]
1311 y[0] = byte(l)
1312 copy(y[1:], []byte(m.proto[0:l]))
1313 y = y[1+l:]
1314 y[0] = byte(padding)
1315
1316 m.raw = x
1317
1318 return x
1319}
1320
1321func (m *nextProtoMsg) unmarshal(data []byte) bool {
1322 m.raw = data
1323
1324 if len(data) < 5 {
1325 return false
1326 }
1327 data = data[4:]
1328 protoLen := int(data[0])
1329 data = data[1:]
1330 if len(data) < protoLen {
1331 return false
1332 }
1333 m.proto = string(data[0:protoLen])
1334 data = data[protoLen:]
1335
1336 if len(data) < 1 {
1337 return false
1338 }
1339 paddingLen := int(data[0])
1340 data = data[1:]
1341 if len(data) != paddingLen {
1342 return false
1343 }
1344
1345 return true
1346}
1347
1348type certificateRequestMsg struct {
1349 raw []byte
1350 // hasSignatureAndHash indicates whether this message includes a list
1351 // of signature and hash functions. This change was introduced with TLS
1352 // 1.2.
1353 hasSignatureAndHash bool
1354
1355 certificateTypes []byte
1356 signatureAndHashes []signatureAndHash
1357 certificateAuthorities [][]byte
1358}
1359
1360func (m *certificateRequestMsg) equal(i interface{}) bool {
1361 m1, ok := i.(*certificateRequestMsg)
1362 if !ok {
1363 return false
1364 }
1365
1366 return bytes.Equal(m.raw, m1.raw) &&
1367 bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
1368 eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
1369 eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes)
1370}
1371
1372func (m *certificateRequestMsg) marshal() (x []byte) {
1373 if m.raw != nil {
1374 return m.raw
1375 }
1376
1377 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
1378 length := 1 + len(m.certificateTypes) + 2
1379 casLength := 0
1380 for _, ca := range m.certificateAuthorities {
1381 casLength += 2 + len(ca)
1382 }
1383 length += casLength
1384
1385 if m.hasSignatureAndHash {
1386 length += 2 + 2*len(m.signatureAndHashes)
1387 }
1388
1389 x = make([]byte, 4+length)
1390 x[0] = typeCertificateRequest
1391 x[1] = uint8(length >> 16)
1392 x[2] = uint8(length >> 8)
1393 x[3] = uint8(length)
1394
1395 x[4] = uint8(len(m.certificateTypes))
1396
1397 copy(x[5:], m.certificateTypes)
1398 y := x[5+len(m.certificateTypes):]
1399
1400 if m.hasSignatureAndHash {
1401 n := len(m.signatureAndHashes) * 2
1402 y[0] = uint8(n >> 8)
1403 y[1] = uint8(n)
1404 y = y[2:]
1405 for _, sigAndHash := range m.signatureAndHashes {
1406 y[0] = sigAndHash.hash
1407 y[1] = sigAndHash.signature
1408 y = y[2:]
1409 }
1410 }
1411
1412 y[0] = uint8(casLength >> 8)
1413 y[1] = uint8(casLength)
1414 y = y[2:]
1415 for _, ca := range m.certificateAuthorities {
1416 y[0] = uint8(len(ca) >> 8)
1417 y[1] = uint8(len(ca))
1418 y = y[2:]
1419 copy(y, ca)
1420 y = y[len(ca):]
1421 }
1422
1423 m.raw = x
1424 return
1425}
1426
1427func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1428 m.raw = data
1429
1430 if len(data) < 5 {
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 numCertTypes := int(data[4])
1440 data = data[5:]
1441 if numCertTypes == 0 || len(data) <= numCertTypes {
1442 return false
1443 }
1444
1445 m.certificateTypes = make([]byte, numCertTypes)
1446 if copy(m.certificateTypes, data) != numCertTypes {
1447 return false
1448 }
1449
1450 data = data[numCertTypes:]
1451
1452 if m.hasSignatureAndHash {
1453 if len(data) < 2 {
1454 return false
1455 }
1456 sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
1457 data = data[2:]
1458 if sigAndHashLen&1 != 0 {
1459 return false
1460 }
1461 if len(data) < int(sigAndHashLen) {
1462 return false
1463 }
1464 numSigAndHash := sigAndHashLen / 2
1465 m.signatureAndHashes = make([]signatureAndHash, numSigAndHash)
1466 for i := range m.signatureAndHashes {
1467 m.signatureAndHashes[i].hash = data[0]
1468 m.signatureAndHashes[i].signature = data[1]
1469 data = data[2:]
1470 }
1471 }
1472
1473 if len(data) < 2 {
1474 return false
1475 }
1476 casLength := uint16(data[0])<<8 | uint16(data[1])
1477 data = data[2:]
1478 if len(data) < int(casLength) {
1479 return false
1480 }
1481 cas := make([]byte, casLength)
1482 copy(cas, data)
1483 data = data[casLength:]
1484
1485 m.certificateAuthorities = nil
1486 for len(cas) > 0 {
1487 if len(cas) < 2 {
1488 return false
1489 }
1490 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1491 cas = cas[2:]
1492
1493 if len(cas) < int(caLen) {
1494 return false
1495 }
1496
1497 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1498 cas = cas[caLen:]
1499 }
1500 if len(data) > 0 {
1501 return false
1502 }
1503
1504 return true
1505}
1506
1507type certificateVerifyMsg struct {
1508 raw []byte
1509 hasSignatureAndHash bool
1510 signatureAndHash signatureAndHash
1511 signature []byte
1512}
1513
1514func (m *certificateVerifyMsg) equal(i interface{}) bool {
1515 m1, ok := i.(*certificateVerifyMsg)
1516 if !ok {
1517 return false
1518 }
1519
1520 return bytes.Equal(m.raw, m1.raw) &&
1521 m.hasSignatureAndHash == m1.hasSignatureAndHash &&
1522 m.signatureAndHash.hash == m1.signatureAndHash.hash &&
1523 m.signatureAndHash.signature == m1.signatureAndHash.signature &&
1524 bytes.Equal(m.signature, m1.signature)
1525}
1526
1527func (m *certificateVerifyMsg) marshal() (x []byte) {
1528 if m.raw != nil {
1529 return m.raw
1530 }
1531
1532 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1533 siglength := len(m.signature)
1534 length := 2 + siglength
1535 if m.hasSignatureAndHash {
1536 length += 2
1537 }
1538 x = make([]byte, 4+length)
1539 x[0] = typeCertificateVerify
1540 x[1] = uint8(length >> 16)
1541 x[2] = uint8(length >> 8)
1542 x[3] = uint8(length)
1543 y := x[4:]
1544 if m.hasSignatureAndHash {
1545 y[0] = m.signatureAndHash.hash
1546 y[1] = m.signatureAndHash.signature
1547 y = y[2:]
1548 }
1549 y[0] = uint8(siglength >> 8)
1550 y[1] = uint8(siglength)
1551 copy(y[2:], m.signature)
1552
1553 m.raw = x
1554
1555 return
1556}
1557
1558func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1559 m.raw = data
1560
1561 if len(data) < 6 {
1562 return false
1563 }
1564
1565 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1566 if uint32(len(data))-4 != length {
1567 return false
1568 }
1569
1570 data = data[4:]
1571 if m.hasSignatureAndHash {
1572 m.signatureAndHash.hash = data[0]
1573 m.signatureAndHash.signature = data[1]
1574 data = data[2:]
1575 }
1576
1577 if len(data) < 2 {
1578 return false
1579 }
1580 siglength := int(data[0])<<8 + int(data[1])
1581 data = data[2:]
1582 if len(data) != siglength {
1583 return false
1584 }
1585
1586 m.signature = data
1587
1588 return true
1589}
1590
1591type newSessionTicketMsg struct {
1592 raw []byte
1593 ticket []byte
1594}
1595
1596func (m *newSessionTicketMsg) equal(i interface{}) bool {
1597 m1, ok := i.(*newSessionTicketMsg)
1598 if !ok {
1599 return false
1600 }
1601
1602 return bytes.Equal(m.raw, m1.raw) &&
1603 bytes.Equal(m.ticket, m1.ticket)
1604}
1605
1606func (m *newSessionTicketMsg) marshal() (x []byte) {
1607 if m.raw != nil {
1608 return m.raw
1609 }
1610
1611 // See http://tools.ietf.org/html/rfc5077#section-3.3
1612 ticketLen := len(m.ticket)
1613 length := 2 + 4 + ticketLen
1614 x = make([]byte, 4+length)
1615 x[0] = typeNewSessionTicket
1616 x[1] = uint8(length >> 16)
1617 x[2] = uint8(length >> 8)
1618 x[3] = uint8(length)
1619 x[8] = uint8(ticketLen >> 8)
1620 x[9] = uint8(ticketLen)
1621 copy(x[10:], m.ticket)
1622
1623 m.raw = x
1624
1625 return
1626}
1627
1628func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
1629 m.raw = data
1630
1631 if len(data) < 10 {
1632 return false
1633 }
1634
1635 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1636 if uint32(len(data))-4 != length {
1637 return false
1638 }
1639
1640 ticketLen := int(data[8])<<8 + int(data[9])
1641 if len(data)-10 != ticketLen {
1642 return false
1643 }
1644
1645 m.ticket = data[10:]
1646
1647 return true
1648}
1649
David Benjamind86c7672014-08-02 04:07:12 -04001650type v2ClientHelloMsg struct {
1651 raw []byte
1652 vers uint16
1653 cipherSuites []uint16
1654 sessionId []byte
1655 challenge []byte
1656}
1657
1658func (m *v2ClientHelloMsg) equal(i interface{}) bool {
1659 m1, ok := i.(*v2ClientHelloMsg)
1660 if !ok {
1661 return false
1662 }
1663
1664 return bytes.Equal(m.raw, m1.raw) &&
1665 m.vers == m1.vers &&
1666 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
1667 bytes.Equal(m.sessionId, m1.sessionId) &&
1668 bytes.Equal(m.challenge, m1.challenge)
1669}
1670
1671func (m *v2ClientHelloMsg) marshal() []byte {
1672 if m.raw != nil {
1673 return m.raw
1674 }
1675
1676 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
1677
1678 x := make([]byte, length)
1679 x[0] = 1
1680 x[1] = uint8(m.vers >> 8)
1681 x[2] = uint8(m.vers)
1682 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
1683 x[4] = uint8(len(m.cipherSuites) * 3)
1684 x[5] = uint8(len(m.sessionId) >> 8)
1685 x[6] = uint8(len(m.sessionId))
1686 x[7] = uint8(len(m.challenge) >> 8)
1687 x[8] = uint8(len(m.challenge))
1688 y := x[9:]
1689 for i, spec := range m.cipherSuites {
1690 y[i*3] = 0
1691 y[i*3+1] = uint8(spec >> 8)
1692 y[i*3+2] = uint8(spec)
1693 }
1694 y = y[len(m.cipherSuites)*3:]
1695 copy(y, m.sessionId)
1696 y = y[len(m.sessionId):]
1697 copy(y, m.challenge)
1698
1699 m.raw = x
1700
1701 return x
1702}
1703
David Benjamin83c0bc92014-08-04 01:23:53 -04001704type helloVerifyRequestMsg struct {
1705 raw []byte
1706 vers uint16
1707 cookie []byte
1708}
1709
1710func (m *helloVerifyRequestMsg) equal(i interface{}) bool {
1711 m1, ok := i.(*helloVerifyRequestMsg)
1712 if !ok {
1713 return false
1714 }
1715
David Benjamind30a9902014-08-24 01:44:23 -04001716 return bytes.Equal(m.raw, m1.raw) &&
1717 m.vers == m1.vers &&
David Benjamin83c0bc92014-08-04 01:23:53 -04001718 bytes.Equal(m.cookie, m1.cookie)
1719}
1720
1721func (m *helloVerifyRequestMsg) marshal() []byte {
1722 if m.raw != nil {
1723 return m.raw
1724 }
1725
1726 length := 2 + 1 + len(m.cookie)
1727
1728 x := make([]byte, 4+length)
1729 x[0] = typeHelloVerifyRequest
1730 x[1] = uint8(length >> 16)
1731 x[2] = uint8(length >> 8)
1732 x[3] = uint8(length)
1733 vers := versionToWire(m.vers, true)
1734 x[4] = uint8(vers >> 8)
1735 x[5] = uint8(vers)
1736 x[6] = uint8(len(m.cookie))
1737 copy(x[7:7+len(m.cookie)], m.cookie)
1738
1739 return x
1740}
1741
1742func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
1743 if len(data) < 4+2+1 {
1744 return false
1745 }
1746 m.raw = data
1747 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), true)
1748 cookieLen := int(data[6])
1749 if cookieLen > 32 || len(data) != 7+cookieLen {
1750 return false
1751 }
1752 m.cookie = data[7 : 7+cookieLen]
1753
1754 return true
1755}
1756
David Benjamind30a9902014-08-24 01:44:23 -04001757type encryptedExtensionsMsg struct {
1758 raw []byte
1759 channelID []byte
1760}
1761
1762func (m *encryptedExtensionsMsg) equal(i interface{}) bool {
1763 m1, ok := i.(*encryptedExtensionsMsg)
1764 if !ok {
1765 return false
1766 }
1767
1768 return bytes.Equal(m.raw, m1.raw) &&
1769 bytes.Equal(m.channelID, m1.channelID)
1770}
1771
1772func (m *encryptedExtensionsMsg) marshal() []byte {
1773 if m.raw != nil {
1774 return m.raw
1775 }
1776
1777 length := 2 + 2 + len(m.channelID)
1778
1779 x := make([]byte, 4+length)
1780 x[0] = typeEncryptedExtensions
1781 x[1] = uint8(length >> 16)
1782 x[2] = uint8(length >> 8)
1783 x[3] = uint8(length)
1784 x[4] = uint8(extensionChannelID >> 8)
1785 x[5] = uint8(extensionChannelID & 0xff)
1786 x[6] = uint8(len(m.channelID) >> 8)
1787 x[7] = uint8(len(m.channelID) & 0xff)
1788 copy(x[8:], m.channelID)
1789
1790 return x
1791}
1792
1793func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
1794 if len(data) != 4+2+2+128 {
1795 return false
1796 }
1797 m.raw = data
1798 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
1799 return false
1800 }
1801 if int(data[6])<<8|int(data[7]) != 128 {
1802 return false
1803 }
1804 m.channelID = data[4+2+2:]
1805
1806 return true
1807}
1808
Adam Langley2ae77d22014-10-28 17:29:33 -07001809type helloRequestMsg struct {
1810}
1811
1812func (*helloRequestMsg) marshal() []byte {
1813 return []byte{typeHelloRequest, 0, 0, 0}
1814}
1815
1816func (*helloRequestMsg) unmarshal(data []byte) bool {
1817 return len(data) == 4
1818}
1819
Adam Langley95c29f32014-06-20 12:00:00 -07001820func eqUint16s(x, y []uint16) bool {
1821 if len(x) != len(y) {
1822 return false
1823 }
1824 for i, v := range x {
1825 if y[i] != v {
1826 return false
1827 }
1828 }
1829 return true
1830}
1831
1832func eqCurveIDs(x, y []CurveID) bool {
1833 if len(x) != len(y) {
1834 return false
1835 }
1836 for i, v := range x {
1837 if y[i] != v {
1838 return false
1839 }
1840 }
1841 return true
1842}
1843
1844func eqStrings(x, y []string) bool {
1845 if len(x) != len(y) {
1846 return false
1847 }
1848 for i, v := range x {
1849 if y[i] != v {
1850 return false
1851 }
1852 }
1853 return true
1854}
1855
1856func eqByteSlices(x, y [][]byte) bool {
1857 if len(x) != len(y) {
1858 return false
1859 }
1860 for i, v := range x {
1861 if !bytes.Equal(v, y[i]) {
1862 return false
1863 }
1864 }
1865 return true
1866}
1867
1868func eqSignatureAndHashes(x, y []signatureAndHash) bool {
1869 if len(x) != len(y) {
1870 return false
1871 }
1872 for i, v := range x {
1873 v2 := y[i]
1874 if v.hash != v2.hash || v.signature != v2.signature {
1875 return false
1876 }
1877 }
1878 return true
1879}