blob: 17fb5cb99af882e3e783388b0996b104ba474b81 [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
Adam Langleydc7e9c42015-09-29 15:21:04 -07005package runner
Adam Langley95c29f32014-06-20 12:00:00 -07006
7import "bytes"
8
Nick Harper8dda5cc2016-06-30 18:51:11 -04009func writeLen(buf []byte, v, size int) {
10 for i := 0; i < size; i++ {
11 buf[size-i-1] = byte(v)
12 v >>= 8
13 }
14 if v != 0 {
15 panic("length is too long")
16 }
17}
18
19type byteBuilder struct {
20 buf *[]byte
21 start int
22 prefixLen int
23 child *byteBuilder
24}
25
26func newByteBuilder() *byteBuilder {
27 buf := make([]byte, 0, 32)
28 return &byteBuilder{buf: &buf}
29}
30
31func (bb *byteBuilder) len() int {
32 return len(*bb.buf) - bb.start - bb.prefixLen
33}
34
35func (bb *byteBuilder) flush() {
36 if bb.child == nil {
37 return
38 }
39 bb.child.flush()
40 writeLen((*bb.buf)[bb.child.start:], bb.child.len(), bb.child.prefixLen)
41 bb.child = nil
42 return
43}
44
45func (bb *byteBuilder) finish() []byte {
46 bb.flush()
47 return *bb.buf
48}
49
50func (bb *byteBuilder) addU8(u uint8) {
51 bb.flush()
52 *bb.buf = append(*bb.buf, u)
53}
54
55func (bb *byteBuilder) addU16(u uint16) {
56 bb.flush()
57 *bb.buf = append(*bb.buf, byte(u>>8), byte(u))
58}
59
60func (bb *byteBuilder) addU24(u int) {
61 bb.flush()
62 *bb.buf = append(*bb.buf, byte(u>>16), byte(u>>8), byte(u))
63}
64
65func (bb *byteBuilder) addU32(u uint32) {
66 bb.flush()
67 *bb.buf = append(*bb.buf, byte(u>>24), byte(u>>16), byte(u>>8), byte(u))
68}
69
70func (bb *byteBuilder) addU8LengthPrefixed() *byteBuilder {
71 return bb.createChild(1)
72}
73
74func (bb *byteBuilder) addU16LengthPrefixed() *byteBuilder {
75 return bb.createChild(2)
76}
77
78func (bb *byteBuilder) addU24LengthPrefixed() *byteBuilder {
79 return bb.createChild(3)
80}
81
82func (bb *byteBuilder) addBytes(b []byte) {
83 bb.flush()
84 *bb.buf = append(*bb.buf, b...)
85}
86
87func (bb *byteBuilder) createChild(lengthPrefixSize int) *byteBuilder {
88 bb.flush()
89 bb.child = &byteBuilder{
90 buf: bb.buf,
91 start: len(*bb.buf),
92 prefixLen: lengthPrefixSize,
93 }
94 for i := 0; i < lengthPrefixSize; i++ {
95 *bb.buf = append(*bb.buf, 0)
96 }
97 return bb.child
98}
99
100func (bb *byteBuilder) discardChild() {
101 if bb.child != nil {
102 return
103 }
104 bb.child = nil
105 *bb.buf = (*bb.buf)[:bb.start]
106}
107
Nick Harperf8b0e702016-06-30 19:59:01 -0400108type keyShareEntry struct {
109 group CurveID
110 keyExchange []byte
111}
112
Adam Langley95c29f32014-06-20 12:00:00 -0700113type clientHelloMsg struct {
David Benjaminca6c8262014-11-15 19:06:08 -0500114 raw []byte
115 isDTLS bool
116 vers uint16
117 random []byte
118 sessionId []byte
119 cookie []byte
120 cipherSuites []uint16
121 compressionMethods []uint8
122 nextProtoNeg bool
123 serverName string
124 ocspStapling bool
125 supportedCurves []CurveID
126 supportedPoints []uint8
Nick Harperf8b0e702016-06-30 19:59:01 -0400127 keyShares []keyShareEntry
128 pskIdentities [][]uint8
129 hasEarlyData bool
130 earlyDataContext []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500131 ticketSupported bool
132 sessionTicket []uint8
Nick Harper60edffd2016-06-21 15:19:24 -0700133 signatureAlgorithms []signatureAlgorithm
David Benjaminca6c8262014-11-15 19:06:08 -0500134 secureRenegotiation []byte
135 alpnProtocols []string
136 duplicateExtension bool
137 channelIDSupported bool
138 npnLast bool
139 extendedMasterSecret bool
140 srtpProtectionProfiles []uint16
141 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -0500142 sctListSupported bool
Adam Langley09505632015-07-30 18:10:13 -0700143 customExtension string
Adam Langley95c29f32014-06-20 12:00:00 -0700144}
145
146func (m *clientHelloMsg) equal(i interface{}) bool {
147 m1, ok := i.(*clientHelloMsg)
148 if !ok {
149 return false
150 }
151
152 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400153 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700154 m.vers == m1.vers &&
155 bytes.Equal(m.random, m1.random) &&
156 bytes.Equal(m.sessionId, m1.sessionId) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400157 bytes.Equal(m.cookie, m1.cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700158 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
159 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
160 m.nextProtoNeg == m1.nextProtoNeg &&
161 m.serverName == m1.serverName &&
162 m.ocspStapling == m1.ocspStapling &&
163 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
164 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400165 eqKeyShareEntryLists(m.keyShares, m1.keyShares) &&
166 eqByteSlices(m.pskIdentities, m1.pskIdentities) &&
167 m.hasEarlyData == m1.hasEarlyData &&
168 bytes.Equal(m.earlyDataContext, m1.earlyDataContext) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700169 m.ticketSupported == m1.ticketSupported &&
170 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
Nick Harper60edffd2016-06-21 15:19:24 -0700171 eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700172 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
173 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400174 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -0400175 m.duplicateExtension == m1.duplicateExtension &&
David Benjaminfc7b0862014-09-06 13:21:53 -0400176 m.channelIDSupported == m1.channelIDSupported &&
Adam Langley75712922014-10-10 16:23:43 -0700177 m.npnLast == m1.npnLast &&
David Benjaminca6c8262014-11-15 19:06:08 -0500178 m.extendedMasterSecret == m1.extendedMasterSecret &&
179 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
David Benjamin61f95272014-11-25 01:55:35 -0500180 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
Adam Langley09505632015-07-30 18:10:13 -0700181 m.sctListSupported == m1.sctListSupported &&
182 m.customExtension == m1.customExtension
Adam Langley95c29f32014-06-20 12:00:00 -0700183}
184
185func (m *clientHelloMsg) marshal() []byte {
186 if m.raw != nil {
187 return m.raw
188 }
189
Nick Harper8dda5cc2016-06-30 18:51:11 -0400190 handshakeMsg := newByteBuilder()
191 handshakeMsg.addU8(typeClientHello)
192 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin83c0bc92014-08-04 01:23:53 -0400193 vers := versionToWire(m.vers, m.isDTLS)
Nick Harper8dda5cc2016-06-30 18:51:11 -0400194 hello.addU16(vers)
195 hello.addBytes(m.random)
196 sessionId := hello.addU8LengthPrefixed()
197 sessionId.addBytes(m.sessionId)
David Benjamin83c0bc92014-08-04 01:23:53 -0400198 if m.isDTLS {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400199 cookie := hello.addU8LengthPrefixed()
200 cookie.addBytes(m.cookie)
David Benjamin83c0bc92014-08-04 01:23:53 -0400201 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400202 cipherSuites := hello.addU16LengthPrefixed()
203 for _, suite := range m.cipherSuites {
204 cipherSuites.addU16(suite)
Adam Langley95c29f32014-06-20 12:00:00 -0700205 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400206 compressionMethods := hello.addU8LengthPrefixed()
207 compressionMethods.addBytes(m.compressionMethods)
Adam Langley95c29f32014-06-20 12:00:00 -0700208
Nick Harper8dda5cc2016-06-30 18:51:11 -0400209 extensions := hello.addU16LengthPrefixed()
David Benjamin35a7a442014-07-05 00:23:20 -0400210 if m.duplicateExtension {
211 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400212 extensions.addU16(0xffff)
213 extensions.addU16(0) // 0-length for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400214 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400215 if m.nextProtoNeg && !m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400216 extensions.addU16(extensionNextProtoNeg)
217 extensions.addU16(0) // The length is always 0
Adam Langley95c29f32014-06-20 12:00:00 -0700218 }
219 if len(m.serverName) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400220 extensions.addU16(extensionServerName)
221 serverNameList := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700222
223 // RFC 3546, section 3.1
224 //
225 // struct {
226 // NameType name_type;
227 // select (name_type) {
228 // case host_name: HostName;
229 // } name;
230 // } ServerName;
231 //
232 // enum {
233 // host_name(0), (255)
234 // } NameType;
235 //
236 // opaque HostName<1..2^16-1>;
237 //
238 // struct {
239 // ServerName server_name_list<1..2^16-1>
240 // } ServerNameList;
241
Nick Harper8dda5cc2016-06-30 18:51:11 -0400242 serverName := serverNameList.addU16LengthPrefixed()
243 serverName.addU8(0) // NameType host_name(0)
244 hostName := serverName.addU16LengthPrefixed()
245 hostName.addBytes([]byte(m.serverName))
Adam Langley95c29f32014-06-20 12:00:00 -0700246 }
247 if m.ocspStapling {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400248 extensions.addU16(extensionStatusRequest)
249 certificateStatusRequest := extensions.addU16LengthPrefixed()
250
Adam Langley95c29f32014-06-20 12:00:00 -0700251 // RFC 4366, section 3.6
Nick Harper8dda5cc2016-06-30 18:51:11 -0400252 certificateStatusRequest.addU8(1) // OCSP type
Adam Langley95c29f32014-06-20 12:00:00 -0700253 // Two zero valued uint16s for the two lengths.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400254 certificateStatusRequest.addU16(0) // ResponderID length
255 certificateStatusRequest.addU16(0) // Extensions length
Adam Langley95c29f32014-06-20 12:00:00 -0700256 }
257 if len(m.supportedCurves) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400258 // http://tools.ietf.org/html/rfc4492#section-5.1.1
259 extensions.addU16(extensionSupportedCurves)
260 supportedCurvesList := extensions.addU16LengthPrefixed()
261 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700262 for _, curve := range m.supportedCurves {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400263 supportedCurves.addU16(uint16(curve))
Adam Langley95c29f32014-06-20 12:00:00 -0700264 }
265 }
266 if len(m.supportedPoints) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400267 // http://tools.ietf.org/html/rfc4492#section-5.1.2
268 extensions.addU16(extensionSupportedPoints)
269 supportedPointsList := extensions.addU16LengthPrefixed()
270 supportedPoints := supportedPointsList.addU8LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700271 for _, pointFormat := range m.supportedPoints {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400272 supportedPoints.addU8(pointFormat)
Adam Langley95c29f32014-06-20 12:00:00 -0700273 }
274 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400275 if len(m.keyShares) > 0 {
276 extensions.addU16(extensionKeyShare)
277 keyShareList := extensions.addU16LengthPrefixed()
278
279 keyShares := keyShareList.addU16LengthPrefixed()
280 for _, keyShare := range m.keyShares {
281 keyShares.addU16(uint16(keyShare.group))
282 keyExchange := keyShares.addU16LengthPrefixed()
283 keyExchange.addBytes(keyShare.keyExchange)
284 }
285 }
286 if len(m.pskIdentities) > 0 {
287 extensions.addU16(extensionPreSharedKey)
288 pskExtension := extensions.addU16LengthPrefixed()
289
290 pskIdentities := pskExtension.addU16LengthPrefixed()
291 for _, psk := range m.pskIdentities {
292 pskIdentity := pskIdentities.addU16LengthPrefixed()
293 pskIdentity.addBytes(psk)
294 }
295 }
296 if m.hasEarlyData {
297 extensions.addU16(extensionEarlyData)
298 earlyDataIndication := extensions.addU16LengthPrefixed()
299
300 context := earlyDataIndication.addU8LengthPrefixed()
301 context.addBytes(m.earlyDataContext)
302 }
Adam Langley95c29f32014-06-20 12:00:00 -0700303 if m.ticketSupported {
304 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400305 extensions.addU16(extensionSessionTicket)
306 sessionTicketExtension := extensions.addU16LengthPrefixed()
307 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700308 }
Nick Harper60edffd2016-06-21 15:19:24 -0700309 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700310 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400311 extensions.addU16(extensionSignatureAlgorithms)
312 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
313 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700314 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400315 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700316 }
317 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700318 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400319 extensions.addU16(extensionRenegotiationInfo)
320 secureRenegoExt := extensions.addU16LengthPrefixed()
321 secureRenego := secureRenegoExt.addU8LengthPrefixed()
322 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700323 }
David Benjaminfa055a22014-09-15 16:51:51 -0400324 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400325 // https://tools.ietf.org/html/rfc7301#section-3.1
326 extensions.addU16(extensionALPN)
327 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400328
Nick Harper8dda5cc2016-06-30 18:51:11 -0400329 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400330 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400331 protocolName := protocolNameList.addU8LengthPrefixed()
332 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400333 }
David Benjaminfa055a22014-09-15 16:51:51 -0400334 }
David Benjamind30a9902014-08-24 01:44:23 -0400335 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400336 extensions.addU16(extensionChannelID)
337 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400338 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400339 if m.nextProtoNeg && m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400340 extensions.addU16(extensionNextProtoNeg)
341 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400342 }
David Benjamin35a7a442014-07-05 00:23:20 -0400343 if m.duplicateExtension {
344 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400345 extensions.addU16(0xffff)
346 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400347 }
Adam Langley75712922014-10-10 16:23:43 -0700348 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500349 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400350 extensions.addU16(extensionExtendedMasterSecret)
351 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700352 }
David Benjaminca6c8262014-11-15 19:06:08 -0500353 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400354 // https://tools.ietf.org/html/rfc5764#section-4.1.1
355 extensions.addU16(extensionUseSRTP)
356 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500357
Nick Harper8dda5cc2016-06-30 18:51:11 -0400358 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500359 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400360 // An SRTPProtectionProfile is defined as uint8[2],
361 // not uint16. For some reason, we're storing it
362 // as a uint16.
363 srtpProtectionProfiles.addU8(byte(p >> 8))
364 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500365 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400366 srtpMki := useSrtpExt.addU8LengthPrefixed()
367 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500368 }
David Benjamin61f95272014-11-25 01:55:35 -0500369 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400370 extensions.addU16(extensionSignedCertificateTimestamp)
371 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500372 }
Adam Langley09505632015-07-30 18:10:13 -0700373 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400374 extensions.addU16(extensionCustom)
375 customExt := extensions.addU16LengthPrefixed()
376 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700377 }
Adam Langley95c29f32014-06-20 12:00:00 -0700378
Nick Harper8dda5cc2016-06-30 18:51:11 -0400379 if extensions.len() == 0 {
380 hello.discardChild()
381 }
Adam Langley95c29f32014-06-20 12:00:00 -0700382
Nick Harper8dda5cc2016-06-30 18:51:11 -0400383 m.raw = handshakeMsg.finish()
384 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700385}
386
387func (m *clientHelloMsg) unmarshal(data []byte) bool {
388 if len(data) < 42 {
389 return false
390 }
391 m.raw = data
David Benjamin83c0bc92014-08-04 01:23:53 -0400392 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
Adam Langley95c29f32014-06-20 12:00:00 -0700393 m.random = data[6:38]
394 sessionIdLen := int(data[38])
395 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
396 return false
397 }
398 m.sessionId = data[39 : 39+sessionIdLen]
399 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400400 if m.isDTLS {
401 if len(data) < 1 {
402 return false
403 }
404 cookieLen := int(data[0])
405 if cookieLen > 32 || len(data) < 1+cookieLen {
406 return false
407 }
408 m.cookie = data[1 : 1+cookieLen]
409 data = data[1+cookieLen:]
410 }
Adam Langley95c29f32014-06-20 12:00:00 -0700411 if len(data) < 2 {
412 return false
413 }
414 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
415 // they are uint16s, the number must be even.
416 cipherSuiteLen := int(data[0])<<8 | int(data[1])
417 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
418 return false
419 }
420 numCipherSuites := cipherSuiteLen / 2
421 m.cipherSuites = make([]uint16, numCipherSuites)
422 for i := 0; i < numCipherSuites; i++ {
423 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
424 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700425 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700426 }
427 }
428 data = data[2+cipherSuiteLen:]
429 if len(data) < 1 {
430 return false
431 }
432 compressionMethodsLen := int(data[0])
433 if len(data) < 1+compressionMethodsLen {
434 return false
435 }
436 m.compressionMethods = data[1 : 1+compressionMethodsLen]
437
438 data = data[1+compressionMethodsLen:]
439
440 m.nextProtoNeg = false
441 m.serverName = ""
442 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400443 m.keyShares = nil
444 m.pskIdentities = nil
445 m.hasEarlyData = false
446 m.earlyDataContext = nil
Adam Langley95c29f32014-06-20 12:00:00 -0700447 m.ticketSupported = false
448 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700449 m.signatureAlgorithms = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400450 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700451 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700452 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700453
454 if len(data) == 0 {
455 // ClientHello is optionally followed by extension data
456 return true
457 }
458 if len(data) < 2 {
459 return false
460 }
461
462 extensionsLength := int(data[0])<<8 | int(data[1])
463 data = data[2:]
464 if extensionsLength != len(data) {
465 return false
466 }
467
468 for len(data) != 0 {
469 if len(data) < 4 {
470 return false
471 }
472 extension := uint16(data[0])<<8 | uint16(data[1])
473 length := int(data[2])<<8 | int(data[3])
474 data = data[4:]
475 if len(data) < length {
476 return false
477 }
478
479 switch extension {
480 case extensionServerName:
481 if length < 2 {
482 return false
483 }
484 numNames := int(data[0])<<8 | int(data[1])
485 d := data[2:]
486 for i := 0; i < numNames; i++ {
487 if len(d) < 3 {
488 return false
489 }
490 nameType := d[0]
491 nameLen := int(d[1])<<8 | int(d[2])
492 d = d[3:]
493 if len(d) < nameLen {
494 return false
495 }
496 if nameType == 0 {
497 m.serverName = string(d[0:nameLen])
498 break
499 }
500 d = d[nameLen:]
501 }
502 case extensionNextProtoNeg:
503 if length > 0 {
504 return false
505 }
506 m.nextProtoNeg = true
507 case extensionStatusRequest:
508 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
509 case extensionSupportedCurves:
510 // http://tools.ietf.org/html/rfc4492#section-5.5.1
511 if length < 2 {
512 return false
513 }
514 l := int(data[0])<<8 | int(data[1])
515 if l%2 == 1 || length != l+2 {
516 return false
517 }
518 numCurves := l / 2
519 m.supportedCurves = make([]CurveID, numCurves)
520 d := data[2:]
521 for i := 0; i < numCurves; i++ {
522 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
523 d = d[2:]
524 }
525 case extensionSupportedPoints:
526 // http://tools.ietf.org/html/rfc4492#section-5.5.2
527 if length < 1 {
528 return false
529 }
530 l := int(data[0])
531 if length != l+1 {
532 return false
533 }
534 m.supportedPoints = make([]uint8, l)
535 copy(m.supportedPoints, data[1:])
536 case extensionSessionTicket:
537 // http://tools.ietf.org/html/rfc5077#section-3.2
538 m.ticketSupported = true
539 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400540 case extensionKeyShare:
541 // draft-ietf-tls-tls13 section 6.3.2.3
542 if length < 2 {
543 return false
544 }
545 l := int(data[0])<<8 | int(data[1])
546 if l != length-2 {
547 return false
548 }
549 d := data[2:length]
550 for len(d) > 0 {
551 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
552 // key_exchange (2-byte length prefix with at least 1 byte of content).
553 if len(d) < 5 {
554 return false
555 }
556 entry := keyShareEntry{}
557 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
558 keyExchLen := int(d[2])<<8 | int(d[3])
559 d = d[4:]
560 if len(d) < keyExchLen {
561 return false
562 }
563 entry.keyExchange = d[:keyExchLen]
564 d = d[keyExchLen:]
565 m.keyShares = append(m.keyShares, entry)
566 }
567 case extensionPreSharedKey:
568 // draft-ietf-tls-tls13 section 6.3.2.4
569 if length < 2 {
570 return false
571 }
572 l := int(data[0])<<8 | int(data[1])
573 if l != length-2 {
574 return false
575 }
576 d := data[2:length]
577 for len(d) > 0 {
578 if len(d) < 2 {
579 return false
580 }
581 pskLen := int(d[0])<<8 | int(d[1])
582 d = d[2:]
583 if len(d) < pskLen {
584 return false
585 }
586 psk := d[:pskLen]
587 m.pskIdentities = append(m.pskIdentities, psk)
588 d = d[pskLen:]
589 }
590 case extensionEarlyData:
591 // draft-ietf-tls-tls13 section 6.3.2.5
592 if length < 1 {
593 return false
594 }
595 l := int(data[0])
596 if length != l+1 {
597 return false
598 }
599 m.hasEarlyData = true
600 m.earlyDataContext = data[1:length]
Adam Langley95c29f32014-06-20 12:00:00 -0700601 case extensionSignatureAlgorithms:
602 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
603 if length < 2 || length&1 != 0 {
604 return false
605 }
606 l := int(data[0])<<8 | int(data[1])
607 if l != length-2 {
608 return false
609 }
610 n := l / 2
611 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700612 m.signatureAlgorithms = make([]signatureAlgorithm, n)
613 for i := range m.signatureAlgorithms {
614 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700615 d = d[2:]
616 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700617 case extensionRenegotiationInfo:
618 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700619 return false
620 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700621 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400622 case extensionALPN:
623 if length < 2 {
624 return false
625 }
626 l := int(data[0])<<8 | int(data[1])
627 if l != length-2 {
628 return false
629 }
630 d := data[2:length]
631 for len(d) != 0 {
632 stringLen := int(d[0])
633 d = d[1:]
634 if stringLen == 0 || stringLen > len(d) {
635 return false
636 }
637 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
638 d = d[stringLen:]
639 }
David Benjamind30a9902014-08-24 01:44:23 -0400640 case extensionChannelID:
641 if length > 0 {
642 return false
643 }
644 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700645 case extensionExtendedMasterSecret:
646 if length != 0 {
647 return false
648 }
649 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500650 case extensionUseSRTP:
651 if length < 2 {
652 return false
653 }
654 l := int(data[0])<<8 | int(data[1])
655 if l > length-2 || l%2 != 0 {
656 return false
657 }
658 n := l / 2
659 m.srtpProtectionProfiles = make([]uint16, n)
660 d := data[2:length]
661 for i := 0; i < n; i++ {
662 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
663 d = d[2:]
664 }
665 if len(d) < 1 || int(d[0]) != len(d)-1 {
666 return false
667 }
668 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500669 case extensionSignedCertificateTimestamp:
670 if length != 0 {
671 return false
672 }
673 m.sctListSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700674 case extensionCustom:
675 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700676 }
677 data = data[length:]
678 }
679
680 return true
681}
682
683type serverHelloMsg struct {
Nick Harperb3d51be2016-07-01 11:43:18 -0400684 raw []byte
685 isDTLS bool
686 vers uint16
687 random []byte
688 sessionId []byte
689 cipherSuite uint16
690 compressionMethod uint8
691 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700692}
693
Adam Langley95c29f32014-06-20 12:00:00 -0700694func (m *serverHelloMsg) marshal() []byte {
695 if m.raw != nil {
696 return m.raw
697 }
698
Nick Harper5212ef82016-06-30 19:26:07 -0400699 handshakeMsg := newByteBuilder()
700 handshakeMsg.addU8(typeServerHello)
701 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin83c0bc92014-08-04 01:23:53 -0400702 vers := versionToWire(m.vers, m.isDTLS)
Nick Harper5212ef82016-06-30 19:26:07 -0400703 hello.addU16(vers)
704 hello.addBytes(m.random)
705 sessionId := hello.addU8LengthPrefixed()
706 sessionId.addBytes(m.sessionId)
707 hello.addU16(m.cipherSuite)
708 hello.addU8(m.compressionMethod)
Adam Langley95c29f32014-06-20 12:00:00 -0700709
Nick Harper5212ef82016-06-30 19:26:07 -0400710 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400711
712 m.extensions.marshal(extensions)
713
714 if extensions.len() == 0 {
715 hello.discardChild()
716 }
717
718 m.raw = handshakeMsg.finish()
719 return m.raw
720}
721
722func (m *serverHelloMsg) unmarshal(data []byte) bool {
723 if len(data) < 42 {
724 return false
725 }
726 m.raw = data
727 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
728 m.random = data[6:38]
729 sessionIdLen := int(data[38])
730 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
731 return false
732 }
733 m.sessionId = data[39 : 39+sessionIdLen]
734 data = data[39+sessionIdLen:]
735 if len(data) < 3 {
736 return false
737 }
738 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
739 m.compressionMethod = data[2]
740 data = data[3:]
741
742 if len(data) == 0 {
743 // ServerHello is optionally followed by extension data
744 m.extensions = serverExtensions{}
745 return true
746 }
747 if len(data) < 2 {
748 return false
749 }
750
751 extensionsLength := int(data[0])<<8 | int(data[1])
752 data = data[2:]
753 if len(data) != extensionsLength {
754 return false
755 }
756
757 if !m.extensions.unmarshal(data) {
758 return false
759 }
760
761 return true
762}
763
764type serverExtensions struct {
765 nextProtoNeg bool
766 nextProtos []string
767 ocspStapling bool
768 ticketSupported bool
769 secureRenegotiation []byte
770 alpnProtocol string
771 alpnProtocolEmpty bool
772 duplicateExtension bool
773 channelIDRequested bool
774 extendedMasterSecret bool
775 srtpProtectionProfile uint16
776 srtpMasterKeyIdentifier string
777 sctList []byte
778 customExtension string
779 npnLast bool
780}
781
782func (m *serverExtensions) marshal(extensions *byteBuilder) {
David Benjamin35a7a442014-07-05 00:23:20 -0400783 if m.duplicateExtension {
784 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -0400785 extensions.addU16(0xffff)
786 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400787 }
David Benjamin76c2efc2015-08-31 14:24:29 -0400788 if m.nextProtoNeg && !m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -0400789 extensions.addU16(extensionNextProtoNeg)
790 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700791
792 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -0400793 if len(v) > 255 {
794 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -0700795 }
Nick Harper5212ef82016-06-30 19:26:07 -0400796 npn := extension.addU8LengthPrefixed()
797 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -0700798 }
799 }
800 if m.ocspStapling {
Nick Harper5212ef82016-06-30 19:26:07 -0400801 extensions.addU16(extensionStatusRequest)
802 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -0700803 }
804 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -0400805 extensions.addU16(extensionSessionTicket)
806 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -0700807 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700808 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -0400809 extensions.addU16(extensionRenegotiationInfo)
810 extension := extensions.addU16LengthPrefixed()
811 secureRenego := extension.addU8LengthPrefixed()
812 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700813 }
Nick Harper5212ef82016-06-30 19:26:07 -0400814 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
815 extensions.addU16(extensionALPN)
816 extension := extensions.addU16LengthPrefixed()
817
818 protocolNameList := extension.addU16LengthPrefixed()
819 protocolName := protocolNameList.addU8LengthPrefixed()
820 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -0400821 }
David Benjamind30a9902014-08-24 01:44:23 -0400822 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -0400823 extensions.addU16(extensionChannelID)
824 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -0400825 }
David Benjamin35a7a442014-07-05 00:23:20 -0400826 if m.duplicateExtension {
827 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -0400828 extensions.addU16(0xffff)
829 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400830 }
Adam Langley75712922014-10-10 16:23:43 -0700831 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -0400832 extensions.addU16(extensionExtendedMasterSecret)
833 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -0700834 }
David Benjaminca6c8262014-11-15 19:06:08 -0500835 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -0400836 extensions.addU16(extensionUseSRTP)
837 extension := extensions.addU16LengthPrefixed()
838
839 srtpProtectionProfiles := extension.addU16LengthPrefixed()
840 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
841 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
842 srtpMki := extension.addU8LengthPrefixed()
843 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500844 }
David Benjamin61f95272014-11-25 01:55:35 -0500845 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -0400846 extensions.addU16(extensionSignedCertificateTimestamp)
847 extension := extensions.addU16LengthPrefixed()
848 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -0500849 }
Adam Langley09505632015-07-30 18:10:13 -0700850 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -0400851 extensions.addU16(extensionCustom)
852 customExt := extensions.addU16LengthPrefixed()
853 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700854 }
David Benjamin76c2efc2015-08-31 14:24:29 -0400855 if m.nextProtoNeg && m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -0400856 extensions.addU16(extensionNextProtoNeg)
857 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -0400858
859 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -0400860 if len(v) > 255 {
861 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -0400862 }
Nick Harper5212ef82016-06-30 19:26:07 -0400863 npn := extension.addU8LengthPrefixed()
864 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -0400865 }
866 }
Adam Langley95c29f32014-06-20 12:00:00 -0700867}
868
Nick Harperb3d51be2016-07-01 11:43:18 -0400869func (m *serverExtensions) unmarshal(data []byte) bool {
870 // Reset all fields.
871 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -0700872
873 for len(data) != 0 {
874 if len(data) < 4 {
875 return false
876 }
877 extension := uint16(data[0])<<8 | uint16(data[1])
878 length := int(data[2])<<8 | int(data[3])
879 data = data[4:]
880 if len(data) < length {
881 return false
882 }
883
884 switch extension {
885 case extensionNextProtoNeg:
886 m.nextProtoNeg = true
887 d := data[:length]
888 for len(d) > 0 {
889 l := int(d[0])
890 d = d[1:]
891 if l == 0 || l > len(d) {
892 return false
893 }
894 m.nextProtos = append(m.nextProtos, string(d[:l]))
895 d = d[l:]
896 }
897 case extensionStatusRequest:
898 if length > 0 {
899 return false
900 }
901 m.ocspStapling = true
902 case extensionSessionTicket:
903 if length > 0 {
904 return false
905 }
906 m.ticketSupported = true
907 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -0700908 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700909 return false
910 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700911 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400912 case extensionALPN:
913 d := data[:length]
914 if len(d) < 3 {
915 return false
916 }
917 l := int(d[0])<<8 | int(d[1])
918 if l != len(d)-2 {
919 return false
920 }
921 d = d[2:]
922 l = int(d[0])
923 if l != len(d)-1 {
924 return false
925 }
926 d = d[1:]
927 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -0700928 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -0400929 case extensionChannelID:
930 if length > 0 {
931 return false
932 }
933 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -0700934 case extensionExtendedMasterSecret:
935 if length != 0 {
936 return false
937 }
938 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500939 case extensionUseSRTP:
940 if length < 2+2+1 {
941 return false
942 }
943 if data[0] != 0 || data[1] != 2 {
944 return false
945 }
946 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
947 d := data[4:length]
948 l := int(d[0])
949 if l != len(d)-1 {
950 return false
951 }
952 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500953 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +0100954 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -0700955 case extensionCustom:
956 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700957 }
958 data = data[length:]
959 }
960
961 return true
962}
963
964type certificateMsg struct {
965 raw []byte
966 certificates [][]byte
967}
968
Adam Langley95c29f32014-06-20 12:00:00 -0700969func (m *certificateMsg) marshal() (x []byte) {
970 if m.raw != nil {
971 return m.raw
972 }
973
Nick Harper7e0442a2016-07-01 17:40:09 -0400974 certMsg := newByteBuilder()
975 certMsg.addU8(typeCertificate)
976 certificate := certMsg.addU24LengthPrefixed()
977 certificateList := certificate.addU24LengthPrefixed()
978 for _, cert := range m.certificates {
979 certEntry := certificateList.addU24LengthPrefixed()
980 certEntry.addBytes(cert)
Adam Langley95c29f32014-06-20 12:00:00 -0700981 }
982
Nick Harper7e0442a2016-07-01 17:40:09 -0400983 m.raw = certMsg.finish()
984 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700985}
986
987func (m *certificateMsg) unmarshal(data []byte) bool {
988 if len(data) < 7 {
989 return false
990 }
991
992 m.raw = data
993 certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
994 if uint32(len(data)) != certsLen+7 {
995 return false
996 }
997
998 numCerts := 0
999 d := data[7:]
1000 for certsLen > 0 {
1001 if len(d) < 4 {
1002 return false
1003 }
1004 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
1005 if uint32(len(d)) < 3+certLen {
1006 return false
1007 }
1008 d = d[3+certLen:]
1009 certsLen -= 3 + certLen
1010 numCerts++
1011 }
1012
1013 m.certificates = make([][]byte, numCerts)
1014 d = data[7:]
1015 for i := 0; i < numCerts; i++ {
1016 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
1017 m.certificates[i] = d[3 : 3+certLen]
1018 d = d[3+certLen:]
1019 }
1020
1021 return true
1022}
1023
1024type serverKeyExchangeMsg struct {
1025 raw []byte
1026 key []byte
1027}
1028
Adam Langley95c29f32014-06-20 12:00:00 -07001029func (m *serverKeyExchangeMsg) marshal() []byte {
1030 if m.raw != nil {
1031 return m.raw
1032 }
1033 length := len(m.key)
1034 x := make([]byte, length+4)
1035 x[0] = typeServerKeyExchange
1036 x[1] = uint8(length >> 16)
1037 x[2] = uint8(length >> 8)
1038 x[3] = uint8(length)
1039 copy(x[4:], m.key)
1040
1041 m.raw = x
1042 return x
1043}
1044
1045func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1046 m.raw = data
1047 if len(data) < 4 {
1048 return false
1049 }
1050 m.key = data[4:]
1051 return true
1052}
1053
1054type certificateStatusMsg struct {
1055 raw []byte
1056 statusType uint8
1057 response []byte
1058}
1059
Adam Langley95c29f32014-06-20 12:00:00 -07001060func (m *certificateStatusMsg) marshal() []byte {
1061 if m.raw != nil {
1062 return m.raw
1063 }
1064
1065 var x []byte
1066 if m.statusType == statusTypeOCSP {
1067 x = make([]byte, 4+4+len(m.response))
1068 x[0] = typeCertificateStatus
1069 l := len(m.response) + 4
1070 x[1] = byte(l >> 16)
1071 x[2] = byte(l >> 8)
1072 x[3] = byte(l)
1073 x[4] = statusTypeOCSP
1074
1075 l -= 4
1076 x[5] = byte(l >> 16)
1077 x[6] = byte(l >> 8)
1078 x[7] = byte(l)
1079 copy(x[8:], m.response)
1080 } else {
1081 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1082 }
1083
1084 m.raw = x
1085 return x
1086}
1087
1088func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1089 m.raw = data
1090 if len(data) < 5 {
1091 return false
1092 }
1093 m.statusType = data[4]
1094
1095 m.response = nil
1096 if m.statusType == statusTypeOCSP {
1097 if len(data) < 8 {
1098 return false
1099 }
1100 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1101 if uint32(len(data)) != 4+4+respLen {
1102 return false
1103 }
1104 m.response = data[8:]
1105 }
1106 return true
1107}
1108
1109type serverHelloDoneMsg struct{}
1110
Adam Langley95c29f32014-06-20 12:00:00 -07001111func (m *serverHelloDoneMsg) marshal() []byte {
1112 x := make([]byte, 4)
1113 x[0] = typeServerHelloDone
1114 return x
1115}
1116
1117func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1118 return len(data) == 4
1119}
1120
1121type clientKeyExchangeMsg struct {
1122 raw []byte
1123 ciphertext []byte
1124}
1125
Adam Langley95c29f32014-06-20 12:00:00 -07001126func (m *clientKeyExchangeMsg) marshal() []byte {
1127 if m.raw != nil {
1128 return m.raw
1129 }
1130 length := len(m.ciphertext)
1131 x := make([]byte, length+4)
1132 x[0] = typeClientKeyExchange
1133 x[1] = uint8(length >> 16)
1134 x[2] = uint8(length >> 8)
1135 x[3] = uint8(length)
1136 copy(x[4:], m.ciphertext)
1137
1138 m.raw = x
1139 return x
1140}
1141
1142func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1143 m.raw = data
1144 if len(data) < 4 {
1145 return false
1146 }
1147 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1148 if l != len(data)-4 {
1149 return false
1150 }
1151 m.ciphertext = data[4:]
1152 return true
1153}
1154
1155type finishedMsg struct {
1156 raw []byte
1157 verifyData []byte
1158}
1159
Adam Langley95c29f32014-06-20 12:00:00 -07001160func (m *finishedMsg) marshal() (x []byte) {
1161 if m.raw != nil {
1162 return m.raw
1163 }
1164
1165 x = make([]byte, 4+len(m.verifyData))
1166 x[0] = typeFinished
1167 x[3] = byte(len(m.verifyData))
1168 copy(x[4:], m.verifyData)
1169 m.raw = x
1170 return
1171}
1172
1173func (m *finishedMsg) unmarshal(data []byte) bool {
1174 m.raw = data
1175 if len(data) < 4 {
1176 return false
1177 }
1178 m.verifyData = data[4:]
1179 return true
1180}
1181
1182type nextProtoMsg struct {
1183 raw []byte
1184 proto string
1185}
1186
Adam Langley95c29f32014-06-20 12:00:00 -07001187func (m *nextProtoMsg) marshal() []byte {
1188 if m.raw != nil {
1189 return m.raw
1190 }
1191 l := len(m.proto)
1192 if l > 255 {
1193 l = 255
1194 }
1195
1196 padding := 32 - (l+2)%32
1197 length := l + padding + 2
1198 x := make([]byte, length+4)
1199 x[0] = typeNextProtocol
1200 x[1] = uint8(length >> 16)
1201 x[2] = uint8(length >> 8)
1202 x[3] = uint8(length)
1203
1204 y := x[4:]
1205 y[0] = byte(l)
1206 copy(y[1:], []byte(m.proto[0:l]))
1207 y = y[1+l:]
1208 y[0] = byte(padding)
1209
1210 m.raw = x
1211
1212 return x
1213}
1214
1215func (m *nextProtoMsg) unmarshal(data []byte) bool {
1216 m.raw = data
1217
1218 if len(data) < 5 {
1219 return false
1220 }
1221 data = data[4:]
1222 protoLen := int(data[0])
1223 data = data[1:]
1224 if len(data) < protoLen {
1225 return false
1226 }
1227 m.proto = string(data[0:protoLen])
1228 data = data[protoLen:]
1229
1230 if len(data) < 1 {
1231 return false
1232 }
1233 paddingLen := int(data[0])
1234 data = data[1:]
1235 if len(data) != paddingLen {
1236 return false
1237 }
1238
1239 return true
1240}
1241
1242type certificateRequestMsg struct {
1243 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001244 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001245 // of signature and hash functions. This change was introduced with TLS
1246 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001247 hasSignatureAlgorithm bool
Adam Langley95c29f32014-06-20 12:00:00 -07001248
1249 certificateTypes []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001250 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001251 certificateAuthorities [][]byte
1252}
1253
Nick Harper7e0442a2016-07-01 17:40:09 -04001254func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001255 if m.raw != nil {
1256 return m.raw
1257 }
1258
1259 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001260 builder := newByteBuilder()
1261 builder.addU8(typeCertificateRequest)
1262 body := builder.addU24LengthPrefixed()
1263
1264 certificateTypes := body.addU8LengthPrefixed()
1265 certificateTypes.addBytes(m.certificateTypes)
Adam Langley95c29f32014-06-20 12:00:00 -07001266
Nick Harper60edffd2016-06-21 15:19:24 -07001267 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001268 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001269 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001270 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001271 }
1272 }
1273
Nick Harper7e0442a2016-07-01 17:40:09 -04001274 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001275 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001276 caEntry := certificateAuthorities.addU16LengthPrefixed()
1277 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001278 }
1279
Nick Harper7e0442a2016-07-01 17:40:09 -04001280 m.raw = builder.finish()
1281 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001282}
1283
1284func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1285 m.raw = data
1286
1287 if len(data) < 5 {
1288 return false
1289 }
1290
1291 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1292 if uint32(len(data))-4 != length {
1293 return false
1294 }
1295
1296 numCertTypes := int(data[4])
1297 data = data[5:]
1298 if numCertTypes == 0 || len(data) <= numCertTypes {
1299 return false
1300 }
1301
1302 m.certificateTypes = make([]byte, numCertTypes)
1303 if copy(m.certificateTypes, data) != numCertTypes {
1304 return false
1305 }
1306
1307 data = data[numCertTypes:]
1308
Nick Harper60edffd2016-06-21 15:19:24 -07001309 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001310 if len(data) < 2 {
1311 return false
1312 }
Nick Harper60edffd2016-06-21 15:19:24 -07001313 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001314 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001315 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001316 return false
1317 }
Nick Harper60edffd2016-06-21 15:19:24 -07001318 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001319 return false
1320 }
Nick Harper60edffd2016-06-21 15:19:24 -07001321 numSigAlgs := sigAlgsLen / 2
1322 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1323 for i := range m.signatureAlgorithms {
1324 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001325 data = data[2:]
1326 }
1327 }
1328
1329 if len(data) < 2 {
1330 return false
1331 }
1332 casLength := uint16(data[0])<<8 | uint16(data[1])
1333 data = data[2:]
1334 if len(data) < int(casLength) {
1335 return false
1336 }
1337 cas := make([]byte, casLength)
1338 copy(cas, data)
1339 data = data[casLength:]
1340
1341 m.certificateAuthorities = nil
1342 for len(cas) > 0 {
1343 if len(cas) < 2 {
1344 return false
1345 }
1346 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1347 cas = cas[2:]
1348
1349 if len(cas) < int(caLen) {
1350 return false
1351 }
1352
1353 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1354 cas = cas[caLen:]
1355 }
1356 if len(data) > 0 {
1357 return false
1358 }
1359
1360 return true
1361}
1362
1363type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07001364 raw []byte
1365 hasSignatureAlgorithm bool
1366 signatureAlgorithm signatureAlgorithm
1367 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001368}
1369
Adam Langley95c29f32014-06-20 12:00:00 -07001370func (m *certificateVerifyMsg) marshal() (x []byte) {
1371 if m.raw != nil {
1372 return m.raw
1373 }
1374
1375 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1376 siglength := len(m.signature)
1377 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07001378 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001379 length += 2
1380 }
1381 x = make([]byte, 4+length)
1382 x[0] = typeCertificateVerify
1383 x[1] = uint8(length >> 16)
1384 x[2] = uint8(length >> 8)
1385 x[3] = uint8(length)
1386 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001387 if m.hasSignatureAlgorithm {
1388 y[0] = byte(m.signatureAlgorithm >> 8)
1389 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07001390 y = y[2:]
1391 }
1392 y[0] = uint8(siglength >> 8)
1393 y[1] = uint8(siglength)
1394 copy(y[2:], m.signature)
1395
1396 m.raw = x
1397
1398 return
1399}
1400
1401func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1402 m.raw = data
1403
1404 if len(data) < 6 {
1405 return false
1406 }
1407
1408 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1409 if uint32(len(data))-4 != length {
1410 return false
1411 }
1412
1413 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001414 if m.hasSignatureAlgorithm {
1415 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001416 data = data[2:]
1417 }
1418
1419 if len(data) < 2 {
1420 return false
1421 }
1422 siglength := int(data[0])<<8 + int(data[1])
1423 data = data[2:]
1424 if len(data) != siglength {
1425 return false
1426 }
1427
1428 m.signature = data
1429
1430 return true
1431}
1432
1433type newSessionTicketMsg struct {
1434 raw []byte
1435 ticket []byte
1436}
1437
Adam Langley95c29f32014-06-20 12:00:00 -07001438func (m *newSessionTicketMsg) marshal() (x []byte) {
1439 if m.raw != nil {
1440 return m.raw
1441 }
1442
1443 // See http://tools.ietf.org/html/rfc5077#section-3.3
1444 ticketLen := len(m.ticket)
1445 length := 2 + 4 + ticketLen
1446 x = make([]byte, 4+length)
1447 x[0] = typeNewSessionTicket
1448 x[1] = uint8(length >> 16)
1449 x[2] = uint8(length >> 8)
1450 x[3] = uint8(length)
1451 x[8] = uint8(ticketLen >> 8)
1452 x[9] = uint8(ticketLen)
1453 copy(x[10:], m.ticket)
1454
1455 m.raw = x
1456
1457 return
1458}
1459
1460func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
1461 m.raw = data
1462
1463 if len(data) < 10 {
1464 return false
1465 }
1466
1467 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1468 if uint32(len(data))-4 != length {
1469 return false
1470 }
1471
1472 ticketLen := int(data[8])<<8 + int(data[9])
1473 if len(data)-10 != ticketLen {
1474 return false
1475 }
1476
1477 m.ticket = data[10:]
1478
1479 return true
1480}
1481
David Benjamind86c7672014-08-02 04:07:12 -04001482type v2ClientHelloMsg struct {
1483 raw []byte
1484 vers uint16
1485 cipherSuites []uint16
1486 sessionId []byte
1487 challenge []byte
1488}
1489
David Benjamind86c7672014-08-02 04:07:12 -04001490func (m *v2ClientHelloMsg) marshal() []byte {
1491 if m.raw != nil {
1492 return m.raw
1493 }
1494
1495 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
1496
1497 x := make([]byte, length)
1498 x[0] = 1
1499 x[1] = uint8(m.vers >> 8)
1500 x[2] = uint8(m.vers)
1501 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
1502 x[4] = uint8(len(m.cipherSuites) * 3)
1503 x[5] = uint8(len(m.sessionId) >> 8)
1504 x[6] = uint8(len(m.sessionId))
1505 x[7] = uint8(len(m.challenge) >> 8)
1506 x[8] = uint8(len(m.challenge))
1507 y := x[9:]
1508 for i, spec := range m.cipherSuites {
1509 y[i*3] = 0
1510 y[i*3+1] = uint8(spec >> 8)
1511 y[i*3+2] = uint8(spec)
1512 }
1513 y = y[len(m.cipherSuites)*3:]
1514 copy(y, m.sessionId)
1515 y = y[len(m.sessionId):]
1516 copy(y, m.challenge)
1517
1518 m.raw = x
1519
1520 return x
1521}
1522
David Benjamin83c0bc92014-08-04 01:23:53 -04001523type helloVerifyRequestMsg struct {
1524 raw []byte
1525 vers uint16
1526 cookie []byte
1527}
1528
David Benjamin83c0bc92014-08-04 01:23:53 -04001529func (m *helloVerifyRequestMsg) marshal() []byte {
1530 if m.raw != nil {
1531 return m.raw
1532 }
1533
1534 length := 2 + 1 + len(m.cookie)
1535
1536 x := make([]byte, 4+length)
1537 x[0] = typeHelloVerifyRequest
1538 x[1] = uint8(length >> 16)
1539 x[2] = uint8(length >> 8)
1540 x[3] = uint8(length)
1541 vers := versionToWire(m.vers, true)
1542 x[4] = uint8(vers >> 8)
1543 x[5] = uint8(vers)
1544 x[6] = uint8(len(m.cookie))
1545 copy(x[7:7+len(m.cookie)], m.cookie)
1546
1547 return x
1548}
1549
1550func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
1551 if len(data) < 4+2+1 {
1552 return false
1553 }
1554 m.raw = data
1555 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), true)
1556 cookieLen := int(data[6])
1557 if cookieLen > 32 || len(data) != 7+cookieLen {
1558 return false
1559 }
1560 m.cookie = data[7 : 7+cookieLen]
1561
1562 return true
1563}
1564
David Benjamin24599a82016-06-30 18:56:53 -04001565type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04001566 raw []byte
1567 channelID []byte
1568}
1569
David Benjamin24599a82016-06-30 18:56:53 -04001570func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04001571 if m.raw != nil {
1572 return m.raw
1573 }
1574
1575 length := 2 + 2 + len(m.channelID)
1576
1577 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04001578 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04001579 x[1] = uint8(length >> 16)
1580 x[2] = uint8(length >> 8)
1581 x[3] = uint8(length)
1582 x[4] = uint8(extensionChannelID >> 8)
1583 x[5] = uint8(extensionChannelID & 0xff)
1584 x[6] = uint8(len(m.channelID) >> 8)
1585 x[7] = uint8(len(m.channelID) & 0xff)
1586 copy(x[8:], m.channelID)
1587
1588 return x
1589}
1590
David Benjamin24599a82016-06-30 18:56:53 -04001591func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04001592 if len(data) != 4+2+2+128 {
1593 return false
1594 }
1595 m.raw = data
1596 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
1597 return false
1598 }
1599 if int(data[6])<<8|int(data[7]) != 128 {
1600 return false
1601 }
1602 m.channelID = data[4+2+2:]
1603
1604 return true
1605}
1606
Adam Langley2ae77d22014-10-28 17:29:33 -07001607type helloRequestMsg struct {
1608}
1609
1610func (*helloRequestMsg) marshal() []byte {
1611 return []byte{typeHelloRequest, 0, 0, 0}
1612}
1613
1614func (*helloRequestMsg) unmarshal(data []byte) bool {
1615 return len(data) == 4
1616}
1617
Adam Langley95c29f32014-06-20 12:00:00 -07001618func eqUint16s(x, y []uint16) bool {
1619 if len(x) != len(y) {
1620 return false
1621 }
1622 for i, v := range x {
1623 if y[i] != v {
1624 return false
1625 }
1626 }
1627 return true
1628}
1629
1630func eqCurveIDs(x, y []CurveID) bool {
1631 if len(x) != len(y) {
1632 return false
1633 }
1634 for i, v := range x {
1635 if y[i] != v {
1636 return false
1637 }
1638 }
1639 return true
1640}
1641
1642func eqStrings(x, y []string) bool {
1643 if len(x) != len(y) {
1644 return false
1645 }
1646 for i, v := range x {
1647 if y[i] != v {
1648 return false
1649 }
1650 }
1651 return true
1652}
1653
1654func eqByteSlices(x, y [][]byte) bool {
1655 if len(x) != len(y) {
1656 return false
1657 }
1658 for i, v := range x {
1659 if !bytes.Equal(v, y[i]) {
1660 return false
1661 }
1662 }
1663 return true
1664}
1665
Nick Harper60edffd2016-06-21 15:19:24 -07001666func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07001667 if len(x) != len(y) {
1668 return false
1669 }
1670 for i, v := range x {
1671 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07001672 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07001673 return false
1674 }
1675 }
1676 return true
1677}
Nick Harperf8b0e702016-06-30 19:59:01 -04001678
1679func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
1680 if len(x) != len(y) {
1681 return false
1682 }
1683 for i, v := range x {
1684 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
1685 return false
1686 }
1687 }
1688 return true
1689
1690}