blob: 6d0f9205fa9e741836c4a75d52802c22855e7ab7 [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 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400114 raw []byte
115 isDTLS bool
116 vers uint16
117 random []byte
118 sessionId []byte
119 // TODO(davidben): Add support for TLS 1.3 cookies which are larger and
120 // use an extension.
David Benjaminca6c8262014-11-15 19:06:08 -0500121 cookie []byte
122 cipherSuites []uint16
123 compressionMethods []uint8
124 nextProtoNeg bool
125 serverName string
126 ocspStapling bool
127 supportedCurves []CurveID
128 supportedPoints []uint8
Nick Harperf8b0e702016-06-30 19:59:01 -0400129 keyShares []keyShareEntry
130 pskIdentities [][]uint8
131 hasEarlyData bool
132 earlyDataContext []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500133 ticketSupported bool
134 sessionTicket []uint8
Nick Harper60edffd2016-06-21 15:19:24 -0700135 signatureAlgorithms []signatureAlgorithm
David Benjaminca6c8262014-11-15 19:06:08 -0500136 secureRenegotiation []byte
137 alpnProtocols []string
138 duplicateExtension bool
139 channelIDSupported bool
140 npnLast bool
141 extendedMasterSecret bool
142 srtpProtectionProfiles []uint16
143 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -0500144 sctListSupported bool
Adam Langley09505632015-07-30 18:10:13 -0700145 customExtension string
Adam Langley95c29f32014-06-20 12:00:00 -0700146}
147
148func (m *clientHelloMsg) equal(i interface{}) bool {
149 m1, ok := i.(*clientHelloMsg)
150 if !ok {
151 return false
152 }
153
154 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400155 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700156 m.vers == m1.vers &&
157 bytes.Equal(m.random, m1.random) &&
158 bytes.Equal(m.sessionId, m1.sessionId) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400159 bytes.Equal(m.cookie, m1.cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700160 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
161 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
162 m.nextProtoNeg == m1.nextProtoNeg &&
163 m.serverName == m1.serverName &&
164 m.ocspStapling == m1.ocspStapling &&
165 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
166 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400167 eqKeyShareEntryLists(m.keyShares, m1.keyShares) &&
168 eqByteSlices(m.pskIdentities, m1.pskIdentities) &&
169 m.hasEarlyData == m1.hasEarlyData &&
170 bytes.Equal(m.earlyDataContext, m1.earlyDataContext) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700171 m.ticketSupported == m1.ticketSupported &&
172 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
Nick Harper60edffd2016-06-21 15:19:24 -0700173 eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700174 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
175 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400176 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -0400177 m.duplicateExtension == m1.duplicateExtension &&
David Benjaminfc7b0862014-09-06 13:21:53 -0400178 m.channelIDSupported == m1.channelIDSupported &&
Adam Langley75712922014-10-10 16:23:43 -0700179 m.npnLast == m1.npnLast &&
David Benjaminca6c8262014-11-15 19:06:08 -0500180 m.extendedMasterSecret == m1.extendedMasterSecret &&
181 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
David Benjamin61f95272014-11-25 01:55:35 -0500182 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
Adam Langley09505632015-07-30 18:10:13 -0700183 m.sctListSupported == m1.sctListSupported &&
184 m.customExtension == m1.customExtension
Adam Langley95c29f32014-06-20 12:00:00 -0700185}
186
187func (m *clientHelloMsg) marshal() []byte {
188 if m.raw != nil {
189 return m.raw
190 }
191
Nick Harper8dda5cc2016-06-30 18:51:11 -0400192 handshakeMsg := newByteBuilder()
193 handshakeMsg.addU8(typeClientHello)
194 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin83c0bc92014-08-04 01:23:53 -0400195 vers := versionToWire(m.vers, m.isDTLS)
Nick Harper8dda5cc2016-06-30 18:51:11 -0400196 hello.addU16(vers)
197 hello.addBytes(m.random)
198 sessionId := hello.addU8LengthPrefixed()
199 sessionId.addBytes(m.sessionId)
David Benjamin83c0bc92014-08-04 01:23:53 -0400200 if m.isDTLS {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400201 cookie := hello.addU8LengthPrefixed()
202 cookie.addBytes(m.cookie)
David Benjamin83c0bc92014-08-04 01:23:53 -0400203 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400204 cipherSuites := hello.addU16LengthPrefixed()
205 for _, suite := range m.cipherSuites {
206 cipherSuites.addU16(suite)
Adam Langley95c29f32014-06-20 12:00:00 -0700207 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400208 compressionMethods := hello.addU8LengthPrefixed()
209 compressionMethods.addBytes(m.compressionMethods)
Adam Langley95c29f32014-06-20 12:00:00 -0700210
Nick Harper8dda5cc2016-06-30 18:51:11 -0400211 extensions := hello.addU16LengthPrefixed()
David Benjamin35a7a442014-07-05 00:23:20 -0400212 if m.duplicateExtension {
213 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400214 extensions.addU16(0xffff)
215 extensions.addU16(0) // 0-length for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400216 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400217 if m.nextProtoNeg && !m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400218 extensions.addU16(extensionNextProtoNeg)
219 extensions.addU16(0) // The length is always 0
Adam Langley95c29f32014-06-20 12:00:00 -0700220 }
221 if len(m.serverName) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400222 extensions.addU16(extensionServerName)
223 serverNameList := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700224
225 // RFC 3546, section 3.1
226 //
227 // struct {
228 // NameType name_type;
229 // select (name_type) {
230 // case host_name: HostName;
231 // } name;
232 // } ServerName;
233 //
234 // enum {
235 // host_name(0), (255)
236 // } NameType;
237 //
238 // opaque HostName<1..2^16-1>;
239 //
240 // struct {
241 // ServerName server_name_list<1..2^16-1>
242 // } ServerNameList;
243
Nick Harper8dda5cc2016-06-30 18:51:11 -0400244 serverName := serverNameList.addU16LengthPrefixed()
245 serverName.addU8(0) // NameType host_name(0)
246 hostName := serverName.addU16LengthPrefixed()
247 hostName.addBytes([]byte(m.serverName))
Adam Langley95c29f32014-06-20 12:00:00 -0700248 }
249 if m.ocspStapling {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400250 extensions.addU16(extensionStatusRequest)
251 certificateStatusRequest := extensions.addU16LengthPrefixed()
252
Adam Langley95c29f32014-06-20 12:00:00 -0700253 // RFC 4366, section 3.6
Nick Harper8dda5cc2016-06-30 18:51:11 -0400254 certificateStatusRequest.addU8(1) // OCSP type
Adam Langley95c29f32014-06-20 12:00:00 -0700255 // Two zero valued uint16s for the two lengths.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400256 certificateStatusRequest.addU16(0) // ResponderID length
257 certificateStatusRequest.addU16(0) // Extensions length
Adam Langley95c29f32014-06-20 12:00:00 -0700258 }
259 if len(m.supportedCurves) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400260 // http://tools.ietf.org/html/rfc4492#section-5.1.1
261 extensions.addU16(extensionSupportedCurves)
262 supportedCurvesList := extensions.addU16LengthPrefixed()
263 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700264 for _, curve := range m.supportedCurves {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400265 supportedCurves.addU16(uint16(curve))
Adam Langley95c29f32014-06-20 12:00:00 -0700266 }
267 }
268 if len(m.supportedPoints) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400269 // http://tools.ietf.org/html/rfc4492#section-5.1.2
270 extensions.addU16(extensionSupportedPoints)
271 supportedPointsList := extensions.addU16LengthPrefixed()
272 supportedPoints := supportedPointsList.addU8LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700273 for _, pointFormat := range m.supportedPoints {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400274 supportedPoints.addU8(pointFormat)
Adam Langley95c29f32014-06-20 12:00:00 -0700275 }
276 }
Nick Harperf8b0e702016-06-30 19:59:01 -0400277 if len(m.keyShares) > 0 {
278 extensions.addU16(extensionKeyShare)
279 keyShareList := extensions.addU16LengthPrefixed()
280
281 keyShares := keyShareList.addU16LengthPrefixed()
282 for _, keyShare := range m.keyShares {
283 keyShares.addU16(uint16(keyShare.group))
284 keyExchange := keyShares.addU16LengthPrefixed()
285 keyExchange.addBytes(keyShare.keyExchange)
286 }
287 }
288 if len(m.pskIdentities) > 0 {
289 extensions.addU16(extensionPreSharedKey)
290 pskExtension := extensions.addU16LengthPrefixed()
291
292 pskIdentities := pskExtension.addU16LengthPrefixed()
293 for _, psk := range m.pskIdentities {
294 pskIdentity := pskIdentities.addU16LengthPrefixed()
295 pskIdentity.addBytes(psk)
296 }
297 }
298 if m.hasEarlyData {
299 extensions.addU16(extensionEarlyData)
300 earlyDataIndication := extensions.addU16LengthPrefixed()
301
302 context := earlyDataIndication.addU8LengthPrefixed()
303 context.addBytes(m.earlyDataContext)
304 }
Adam Langley95c29f32014-06-20 12:00:00 -0700305 if m.ticketSupported {
306 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400307 extensions.addU16(extensionSessionTicket)
308 sessionTicketExtension := extensions.addU16LengthPrefixed()
309 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700310 }
Nick Harper60edffd2016-06-21 15:19:24 -0700311 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700312 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400313 extensions.addU16(extensionSignatureAlgorithms)
314 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
315 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700316 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400317 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700318 }
319 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700320 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400321 extensions.addU16(extensionRenegotiationInfo)
322 secureRenegoExt := extensions.addU16LengthPrefixed()
323 secureRenego := secureRenegoExt.addU8LengthPrefixed()
324 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700325 }
David Benjaminfa055a22014-09-15 16:51:51 -0400326 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400327 // https://tools.ietf.org/html/rfc7301#section-3.1
328 extensions.addU16(extensionALPN)
329 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400330
Nick Harper8dda5cc2016-06-30 18:51:11 -0400331 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400332 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400333 protocolName := protocolNameList.addU8LengthPrefixed()
334 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400335 }
David Benjaminfa055a22014-09-15 16:51:51 -0400336 }
David Benjamind30a9902014-08-24 01:44:23 -0400337 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400338 extensions.addU16(extensionChannelID)
339 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400340 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400341 if m.nextProtoNeg && m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400342 extensions.addU16(extensionNextProtoNeg)
343 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400344 }
David Benjamin35a7a442014-07-05 00:23:20 -0400345 if m.duplicateExtension {
346 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400347 extensions.addU16(0xffff)
348 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400349 }
Adam Langley75712922014-10-10 16:23:43 -0700350 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500351 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400352 extensions.addU16(extensionExtendedMasterSecret)
353 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700354 }
David Benjaminca6c8262014-11-15 19:06:08 -0500355 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400356 // https://tools.ietf.org/html/rfc5764#section-4.1.1
357 extensions.addU16(extensionUseSRTP)
358 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500359
Nick Harper8dda5cc2016-06-30 18:51:11 -0400360 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500361 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400362 // An SRTPProtectionProfile is defined as uint8[2],
363 // not uint16. For some reason, we're storing it
364 // as a uint16.
365 srtpProtectionProfiles.addU8(byte(p >> 8))
366 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500367 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400368 srtpMki := useSrtpExt.addU8LengthPrefixed()
369 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500370 }
David Benjamin61f95272014-11-25 01:55:35 -0500371 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400372 extensions.addU16(extensionSignedCertificateTimestamp)
373 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500374 }
Adam Langley09505632015-07-30 18:10:13 -0700375 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400376 extensions.addU16(extensionCustom)
377 customExt := extensions.addU16LengthPrefixed()
378 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700379 }
Adam Langley95c29f32014-06-20 12:00:00 -0700380
Nick Harper8dda5cc2016-06-30 18:51:11 -0400381 if extensions.len() == 0 {
382 hello.discardChild()
383 }
Adam Langley95c29f32014-06-20 12:00:00 -0700384
Nick Harper8dda5cc2016-06-30 18:51:11 -0400385 m.raw = handshakeMsg.finish()
386 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700387}
388
389func (m *clientHelloMsg) unmarshal(data []byte) bool {
390 if len(data) < 42 {
391 return false
392 }
393 m.raw = data
David Benjamin83c0bc92014-08-04 01:23:53 -0400394 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
Adam Langley95c29f32014-06-20 12:00:00 -0700395 m.random = data[6:38]
396 sessionIdLen := int(data[38])
397 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
398 return false
399 }
400 m.sessionId = data[39 : 39+sessionIdLen]
401 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400402 if m.isDTLS {
403 if len(data) < 1 {
404 return false
405 }
406 cookieLen := int(data[0])
407 if cookieLen > 32 || len(data) < 1+cookieLen {
408 return false
409 }
410 m.cookie = data[1 : 1+cookieLen]
411 data = data[1+cookieLen:]
412 }
Adam Langley95c29f32014-06-20 12:00:00 -0700413 if len(data) < 2 {
414 return false
415 }
416 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
417 // they are uint16s, the number must be even.
418 cipherSuiteLen := int(data[0])<<8 | int(data[1])
419 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
420 return false
421 }
422 numCipherSuites := cipherSuiteLen / 2
423 m.cipherSuites = make([]uint16, numCipherSuites)
424 for i := 0; i < numCipherSuites; i++ {
425 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
426 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700427 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700428 }
429 }
430 data = data[2+cipherSuiteLen:]
431 if len(data) < 1 {
432 return false
433 }
434 compressionMethodsLen := int(data[0])
435 if len(data) < 1+compressionMethodsLen {
436 return false
437 }
438 m.compressionMethods = data[1 : 1+compressionMethodsLen]
439
440 data = data[1+compressionMethodsLen:]
441
442 m.nextProtoNeg = false
443 m.serverName = ""
444 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400445 m.keyShares = nil
446 m.pskIdentities = nil
447 m.hasEarlyData = false
448 m.earlyDataContext = nil
Adam Langley95c29f32014-06-20 12:00:00 -0700449 m.ticketSupported = false
450 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700451 m.signatureAlgorithms = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400452 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700453 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700454 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700455
456 if len(data) == 0 {
457 // ClientHello is optionally followed by extension data
458 return true
459 }
460 if len(data) < 2 {
461 return false
462 }
463
464 extensionsLength := int(data[0])<<8 | int(data[1])
465 data = data[2:]
466 if extensionsLength != len(data) {
467 return false
468 }
469
470 for len(data) != 0 {
471 if len(data) < 4 {
472 return false
473 }
474 extension := uint16(data[0])<<8 | uint16(data[1])
475 length := int(data[2])<<8 | int(data[3])
476 data = data[4:]
477 if len(data) < length {
478 return false
479 }
480
481 switch extension {
482 case extensionServerName:
483 if length < 2 {
484 return false
485 }
486 numNames := int(data[0])<<8 | int(data[1])
487 d := data[2:]
488 for i := 0; i < numNames; i++ {
489 if len(d) < 3 {
490 return false
491 }
492 nameType := d[0]
493 nameLen := int(d[1])<<8 | int(d[2])
494 d = d[3:]
495 if len(d) < nameLen {
496 return false
497 }
498 if nameType == 0 {
499 m.serverName = string(d[0:nameLen])
500 break
501 }
502 d = d[nameLen:]
503 }
504 case extensionNextProtoNeg:
505 if length > 0 {
506 return false
507 }
508 m.nextProtoNeg = true
509 case extensionStatusRequest:
510 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
511 case extensionSupportedCurves:
512 // http://tools.ietf.org/html/rfc4492#section-5.5.1
513 if length < 2 {
514 return false
515 }
516 l := int(data[0])<<8 | int(data[1])
517 if l%2 == 1 || length != l+2 {
518 return false
519 }
520 numCurves := l / 2
521 m.supportedCurves = make([]CurveID, numCurves)
522 d := data[2:]
523 for i := 0; i < numCurves; i++ {
524 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
525 d = d[2:]
526 }
527 case extensionSupportedPoints:
528 // http://tools.ietf.org/html/rfc4492#section-5.5.2
529 if length < 1 {
530 return false
531 }
532 l := int(data[0])
533 if length != l+1 {
534 return false
535 }
536 m.supportedPoints = make([]uint8, l)
537 copy(m.supportedPoints, data[1:])
538 case extensionSessionTicket:
539 // http://tools.ietf.org/html/rfc5077#section-3.2
540 m.ticketSupported = true
541 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400542 case extensionKeyShare:
543 // draft-ietf-tls-tls13 section 6.3.2.3
544 if length < 2 {
545 return false
546 }
547 l := int(data[0])<<8 | int(data[1])
548 if l != length-2 {
549 return false
550 }
551 d := data[2:length]
552 for len(d) > 0 {
553 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
554 // key_exchange (2-byte length prefix with at least 1 byte of content).
555 if len(d) < 5 {
556 return false
557 }
558 entry := keyShareEntry{}
559 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
560 keyExchLen := int(d[2])<<8 | int(d[3])
561 d = d[4:]
562 if len(d) < keyExchLen {
563 return false
564 }
565 entry.keyExchange = d[:keyExchLen]
566 d = d[keyExchLen:]
567 m.keyShares = append(m.keyShares, entry)
568 }
569 case extensionPreSharedKey:
570 // draft-ietf-tls-tls13 section 6.3.2.4
571 if length < 2 {
572 return false
573 }
574 l := int(data[0])<<8 | int(data[1])
575 if l != length-2 {
576 return false
577 }
578 d := data[2:length]
579 for len(d) > 0 {
580 if len(d) < 2 {
581 return false
582 }
583 pskLen := int(d[0])<<8 | int(d[1])
584 d = d[2:]
585 if len(d) < pskLen {
586 return false
587 }
588 psk := d[:pskLen]
589 m.pskIdentities = append(m.pskIdentities, psk)
590 d = d[pskLen:]
591 }
592 case extensionEarlyData:
593 // draft-ietf-tls-tls13 section 6.3.2.5
594 if length < 1 {
595 return false
596 }
597 l := int(data[0])
598 if length != l+1 {
599 return false
600 }
601 m.hasEarlyData = true
602 m.earlyDataContext = data[1:length]
Adam Langley95c29f32014-06-20 12:00:00 -0700603 case extensionSignatureAlgorithms:
604 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
605 if length < 2 || length&1 != 0 {
606 return false
607 }
608 l := int(data[0])<<8 | int(data[1])
609 if l != length-2 {
610 return false
611 }
612 n := l / 2
613 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700614 m.signatureAlgorithms = make([]signatureAlgorithm, n)
615 for i := range m.signatureAlgorithms {
616 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700617 d = d[2:]
618 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700619 case extensionRenegotiationInfo:
620 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700621 return false
622 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700623 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400624 case extensionALPN:
625 if length < 2 {
626 return false
627 }
628 l := int(data[0])<<8 | int(data[1])
629 if l != length-2 {
630 return false
631 }
632 d := data[2:length]
633 for len(d) != 0 {
634 stringLen := int(d[0])
635 d = d[1:]
636 if stringLen == 0 || stringLen > len(d) {
637 return false
638 }
639 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
640 d = d[stringLen:]
641 }
David Benjamind30a9902014-08-24 01:44:23 -0400642 case extensionChannelID:
643 if length > 0 {
644 return false
645 }
646 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700647 case extensionExtendedMasterSecret:
648 if length != 0 {
649 return false
650 }
651 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500652 case extensionUseSRTP:
653 if length < 2 {
654 return false
655 }
656 l := int(data[0])<<8 | int(data[1])
657 if l > length-2 || l%2 != 0 {
658 return false
659 }
660 n := l / 2
661 m.srtpProtectionProfiles = make([]uint16, n)
662 d := data[2:length]
663 for i := 0; i < n; i++ {
664 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
665 d = d[2:]
666 }
667 if len(d) < 1 || int(d[0]) != len(d)-1 {
668 return false
669 }
670 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500671 case extensionSignedCertificateTimestamp:
672 if length != 0 {
673 return false
674 }
675 m.sctListSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700676 case extensionCustom:
677 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700678 }
679 data = data[length:]
680 }
681
682 return true
683}
684
685type serverHelloMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -0400686 raw []byte
687 isDTLS bool
688 vers uint16
689 random []byte
690 sessionId []byte
691 cipherSuite uint16
692 hasKeyShare bool
693 keyShare keyShareEntry
694 hasPSKIdentity bool
695 pskIdentity uint16
696 earlyDataIndication bool
697 compressionMethod uint8
698 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700699}
700
Adam Langley95c29f32014-06-20 12:00:00 -0700701func (m *serverHelloMsg) marshal() []byte {
702 if m.raw != nil {
703 return m.raw
704 }
705
Nick Harper5212ef82016-06-30 19:26:07 -0400706 handshakeMsg := newByteBuilder()
707 handshakeMsg.addU8(typeServerHello)
708 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin83c0bc92014-08-04 01:23:53 -0400709 vers := versionToWire(m.vers, m.isDTLS)
Nick Harper5212ef82016-06-30 19:26:07 -0400710 hello.addU16(vers)
711 hello.addBytes(m.random)
Nick Harperb41d2e42016-07-01 17:50:32 -0400712 if m.vers < VersionTLS13 || !enableTLS13Handshake {
713 sessionId := hello.addU8LengthPrefixed()
714 sessionId.addBytes(m.sessionId)
715 }
Nick Harper5212ef82016-06-30 19:26:07 -0400716 hello.addU16(m.cipherSuite)
Nick Harperb41d2e42016-07-01 17:50:32 -0400717 if m.vers < VersionTLS13 || !enableTLS13Handshake {
718 hello.addU8(m.compressionMethod)
719 }
Adam Langley95c29f32014-06-20 12:00:00 -0700720
Nick Harper5212ef82016-06-30 19:26:07 -0400721 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400722
Nick Harperb41d2e42016-07-01 17:50:32 -0400723 if m.vers >= VersionTLS13 && enableTLS13Handshake {
724 if m.hasKeyShare {
725 extensions.addU16(extensionKeyShare)
726 keyShare := extensions.addU16LengthPrefixed()
727 keyShare.addU16(uint16(m.keyShare.group))
728 keyExchange := keyShare.addU16LengthPrefixed()
729 keyExchange.addBytes(m.keyShare.keyExchange)
730 }
731 if m.hasPSKIdentity {
732 extensions.addU16(extensionPreSharedKey)
733 extensions.addU16(2) // Length
734 extensions.addU16(m.pskIdentity)
735 }
736 if m.earlyDataIndication {
737 extensions.addU16(extensionEarlyData)
738 extensions.addU16(0) // Length
739 }
740 } else {
David Benjamin44b33bc2016-07-01 22:40:23 -0400741 m.extensions.marshal(extensions, m.vers)
Nick Harperb41d2e42016-07-01 17:50:32 -0400742 if extensions.len() == 0 {
743 hello.discardChild()
744 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400745 }
746
747 m.raw = handshakeMsg.finish()
748 return m.raw
749}
750
751func (m *serverHelloMsg) unmarshal(data []byte) bool {
752 if len(data) < 42 {
753 return false
754 }
755 m.raw = data
756 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
757 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400758 data = data[38:]
759 if m.vers < VersionTLS13 || !enableTLS13Handshake {
760 sessionIdLen := int(data[0])
761 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
762 return false
763 }
764 m.sessionId = data[1 : 1+sessionIdLen]
765 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400766 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400767 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400768 return false
769 }
770 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400771 data = data[2:]
772 if m.vers < VersionTLS13 || !enableTLS13Handshake {
773 if len(data) < 1 {
774 return false
775 }
776 m.compressionMethod = data[0]
777 data = data[1:]
778 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400779
Nick Harperb41d2e42016-07-01 17:50:32 -0400780 if len(data) == 0 && (m.vers < VersionTLS13 || enableTLS13Handshake) {
781 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400782 m.extensions = serverExtensions{}
783 return true
784 }
785 if len(data) < 2 {
786 return false
787 }
788
789 extensionsLength := int(data[0])<<8 | int(data[1])
790 data = data[2:]
791 if len(data) != extensionsLength {
792 return false
793 }
794
Nick Harperb41d2e42016-07-01 17:50:32 -0400795 if m.vers >= VersionTLS13 && enableTLS13Handshake {
796 for len(data) != 0 {
797 if len(data) < 4 {
798 return false
799 }
800 extension := uint16(data[0])<<8 | uint16(data[1])
801 length := int(data[2])<<8 | int(data[3])
802 data = data[4:]
803
804 if len(data) < length {
805 return false
806 }
807 d := data[:length]
808 data = data[length:]
809
810 switch extension {
811 case extensionKeyShare:
812 m.hasKeyShare = true
813 if len(d) < 4 {
814 return false
815 }
816 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
817 keyExchLen := int(d[2])<<8 | int(d[3])
818 if keyExchLen != len(d)-4 {
819 return false
820 }
821 m.keyShare.keyExchange = make([]byte, keyExchLen)
822 copy(m.keyShare.keyExchange, d[4:])
823 case extensionPreSharedKey:
824 if len(d) != 2 {
825 return false
826 }
827 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
828 m.hasPSKIdentity = true
829 case extensionEarlyData:
830 if len(d) != 0 {
831 return false
832 }
833 m.earlyDataIndication = true
834 default:
835 // Only allow the 3 extensions that are sent in
836 // the clear in TLS 1.3.
837 return false
838 }
839 }
David Benjamin44b33bc2016-07-01 22:40:23 -0400840 } else if !m.extensions.unmarshal(data, m.vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -0400841 return false
842 }
843
844 return true
845}
846
Nick Harperb41d2e42016-07-01 17:50:32 -0400847type encryptedExtensionsMsg struct {
848 raw []byte
849 extensions serverExtensions
850}
851
852func (m *encryptedExtensionsMsg) marshal() []byte {
853 if m.raw != nil {
854 return m.raw
855 }
856
857 encryptedExtensionsMsg := newByteBuilder()
858 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
859 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
860 extensions := encryptedExtensions.addU16LengthPrefixed()
David Benjamin44b33bc2016-07-01 22:40:23 -0400861 m.extensions.marshal(extensions, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -0400862
863 m.raw = encryptedExtensionsMsg.finish()
864 return m.raw
865}
866
867func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -0400868 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -0400869 if len(data) < 6 {
870 return false
871 }
872 if data[0] != typeEncryptedExtensions {
873 return false
874 }
875 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
876 data = data[4:]
877 if len(data) != msgLen {
878 return false
879 }
880 extLen := int(data[0])<<8 | int(data[1])
881 data = data[2:]
882 if extLen != len(data) {
883 return false
884 }
David Benjamin44b33bc2016-07-01 22:40:23 -0400885 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -0400886}
887
Nick Harperb3d51be2016-07-01 11:43:18 -0400888type serverExtensions struct {
889 nextProtoNeg bool
890 nextProtos []string
891 ocspStapling bool
David Benjamin44b33bc2016-07-01 22:40:23 -0400892 ocspResponse []byte
Nick Harperb3d51be2016-07-01 11:43:18 -0400893 ticketSupported bool
894 secureRenegotiation []byte
895 alpnProtocol string
896 alpnProtocolEmpty bool
897 duplicateExtension bool
898 channelIDRequested bool
899 extendedMasterSecret bool
900 srtpProtectionProfile uint16
901 srtpMasterKeyIdentifier string
902 sctList []byte
903 customExtension string
904 npnLast bool
905}
906
David Benjamin44b33bc2016-07-01 22:40:23 -0400907func (m *serverExtensions) marshal(extensions *byteBuilder, version uint16) {
David Benjamin35a7a442014-07-05 00:23:20 -0400908 if m.duplicateExtension {
909 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -0400910 extensions.addU16(0xffff)
911 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400912 }
David Benjamin76c2efc2015-08-31 14:24:29 -0400913 if m.nextProtoNeg && !m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -0400914 extensions.addU16(extensionNextProtoNeg)
915 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700916
917 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -0400918 if len(v) > 255 {
919 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -0700920 }
Nick Harper5212ef82016-06-30 19:26:07 -0400921 npn := extension.addU8LengthPrefixed()
922 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -0700923 }
924 }
David Benjamin44b33bc2016-07-01 22:40:23 -0400925 if version >= VersionTLS13 && enableTLS13Handshake {
926 if m.ocspResponse != nil {
927 extensions.addU16(extensionStatusRequest)
928 body := extensions.addU16LengthPrefixed()
929 body.addU8(statusTypeOCSP)
930 response := body.addU24LengthPrefixed()
931 response.addBytes(m.ocspResponse)
932 }
933 } else {
934 if m.ocspStapling {
935 extensions.addU16(extensionStatusRequest)
936 extensions.addU16(0)
937 }
Adam Langley95c29f32014-06-20 12:00:00 -0700938 }
939 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -0400940 extensions.addU16(extensionSessionTicket)
941 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -0700942 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700943 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -0400944 extensions.addU16(extensionRenegotiationInfo)
945 extension := extensions.addU16LengthPrefixed()
946 secureRenego := extension.addU8LengthPrefixed()
947 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700948 }
Nick Harper5212ef82016-06-30 19:26:07 -0400949 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
950 extensions.addU16(extensionALPN)
951 extension := extensions.addU16LengthPrefixed()
952
953 protocolNameList := extension.addU16LengthPrefixed()
954 protocolName := protocolNameList.addU8LengthPrefixed()
955 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -0400956 }
David Benjamind30a9902014-08-24 01:44:23 -0400957 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -0400958 extensions.addU16(extensionChannelID)
959 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -0400960 }
David Benjamin35a7a442014-07-05 00:23:20 -0400961 if m.duplicateExtension {
962 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -0400963 extensions.addU16(0xffff)
964 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400965 }
Adam Langley75712922014-10-10 16:23:43 -0700966 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -0400967 extensions.addU16(extensionExtendedMasterSecret)
968 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -0700969 }
David Benjaminca6c8262014-11-15 19:06:08 -0500970 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -0400971 extensions.addU16(extensionUseSRTP)
972 extension := extensions.addU16LengthPrefixed()
973
974 srtpProtectionProfiles := extension.addU16LengthPrefixed()
975 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
976 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
977 srtpMki := extension.addU8LengthPrefixed()
978 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500979 }
David Benjamin61f95272014-11-25 01:55:35 -0500980 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -0400981 extensions.addU16(extensionSignedCertificateTimestamp)
982 extension := extensions.addU16LengthPrefixed()
983 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -0500984 }
Adam Langley09505632015-07-30 18:10:13 -0700985 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -0400986 extensions.addU16(extensionCustom)
987 customExt := extensions.addU16LengthPrefixed()
988 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700989 }
David Benjamin76c2efc2015-08-31 14:24:29 -0400990 if m.nextProtoNeg && m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -0400991 extensions.addU16(extensionNextProtoNeg)
992 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -0400993
994 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -0400995 if len(v) > 255 {
996 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -0400997 }
Nick Harper5212ef82016-06-30 19:26:07 -0400998 npn := extension.addU8LengthPrefixed()
999 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001000 }
1001 }
Adam Langley95c29f32014-06-20 12:00:00 -07001002}
1003
David Benjamin44b33bc2016-07-01 22:40:23 -04001004func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001005 // Reset all fields.
1006 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001007
1008 for len(data) != 0 {
1009 if len(data) < 4 {
1010 return false
1011 }
1012 extension := uint16(data[0])<<8 | uint16(data[1])
1013 length := int(data[2])<<8 | int(data[3])
1014 data = data[4:]
1015 if len(data) < length {
1016 return false
1017 }
1018
1019 switch extension {
1020 case extensionNextProtoNeg:
1021 m.nextProtoNeg = true
1022 d := data[:length]
1023 for len(d) > 0 {
1024 l := int(d[0])
1025 d = d[1:]
1026 if l == 0 || l > len(d) {
1027 return false
1028 }
1029 m.nextProtos = append(m.nextProtos, string(d[:l]))
1030 d = d[l:]
1031 }
1032 case extensionStatusRequest:
David Benjamin44b33bc2016-07-01 22:40:23 -04001033 if version >= VersionTLS13 && enableTLS13Handshake {
1034 if length < 4 {
1035 return false
1036 }
1037 d := data[:length]
1038 if d[0] != statusTypeOCSP {
1039 return false
1040 }
1041 respLen := int(d[1])<<16 | int(d[2])<<8 | int(d[3])
1042 if respLen+4 != len(d) || respLen == 0 {
1043 return false
1044 }
1045 m.ocspResponse = d[4:]
1046 } else {
1047 if length > 0 {
1048 return false
1049 }
1050 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001051 }
Adam Langley95c29f32014-06-20 12:00:00 -07001052 case extensionSessionTicket:
1053 if length > 0 {
1054 return false
1055 }
1056 m.ticketSupported = true
1057 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001058 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001059 return false
1060 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001061 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001062 case extensionALPN:
1063 d := data[:length]
1064 if len(d) < 3 {
1065 return false
1066 }
1067 l := int(d[0])<<8 | int(d[1])
1068 if l != len(d)-2 {
1069 return false
1070 }
1071 d = d[2:]
1072 l = int(d[0])
1073 if l != len(d)-1 {
1074 return false
1075 }
1076 d = d[1:]
1077 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001078 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001079 case extensionChannelID:
1080 if length > 0 {
1081 return false
1082 }
1083 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001084 case extensionExtendedMasterSecret:
1085 if length != 0 {
1086 return false
1087 }
1088 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001089 case extensionUseSRTP:
1090 if length < 2+2+1 {
1091 return false
1092 }
1093 if data[0] != 0 || data[1] != 2 {
1094 return false
1095 }
1096 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1097 d := data[4:length]
1098 l := int(d[0])
1099 if l != len(d)-1 {
1100 return false
1101 }
1102 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001103 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001104 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001105 case extensionCustom:
1106 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001107 case extensionServerName:
1108 if length != 0 {
1109 return false
1110 }
1111 // Ignore this extension from the server.
1112 case extensionSupportedPoints:
1113 // supported_points is illegal in TLS 1.3.
1114 if version >= VersionTLS13 && enableTLS13Handshake {
1115 return false
1116 }
1117 // Ignore this extension from the server.
David Benjamin4ee027f2016-07-17 12:34:41 +02001118 case extensionSupportedCurves:
1119 // The server can only send supported_curves in TLS 1.3.
1120 if version < VersionTLS13 || !enableTLS13Handshake {
1121 return false
1122 }
David Benjamin46f94bd2016-07-14 16:43:37 -04001123 default:
1124 // Unknown extensions are illegal from the server.
1125 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001126 }
1127 data = data[length:]
1128 }
1129
1130 return true
1131}
1132
1133type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001134 raw []byte
1135 hasRequestContext bool
1136 requestContext []byte
1137 certificates [][]byte
Adam Langley95c29f32014-06-20 12:00:00 -07001138}
1139
Adam Langley95c29f32014-06-20 12:00:00 -07001140func (m *certificateMsg) marshal() (x []byte) {
1141 if m.raw != nil {
1142 return m.raw
1143 }
1144
Nick Harper7e0442a2016-07-01 17:40:09 -04001145 certMsg := newByteBuilder()
1146 certMsg.addU8(typeCertificate)
1147 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001148 if m.hasRequestContext {
1149 context := certificate.addU8LengthPrefixed()
1150 context.addBytes(m.requestContext)
1151 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001152 certificateList := certificate.addU24LengthPrefixed()
1153 for _, cert := range m.certificates {
1154 certEntry := certificateList.addU24LengthPrefixed()
1155 certEntry.addBytes(cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001156 }
1157
Nick Harper7e0442a2016-07-01 17:40:09 -04001158 m.raw = certMsg.finish()
1159 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001160}
1161
1162func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001163 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001164 return false
1165 }
1166
1167 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001168 data = data[4:]
1169
1170 if m.hasRequestContext {
1171 if len(data) == 0 {
1172 return false
1173 }
1174 contextLen := int(data[0])
1175 if len(data) < 1+contextLen {
1176 return false
1177 }
1178 m.requestContext = make([]byte, contextLen)
1179 copy(m.requestContext, data[1:])
1180 data = data[1+contextLen:]
1181 }
1182
1183 if len(data) < 3 {
1184 return false
1185 }
1186 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1187 data = data[3:]
1188 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001189 return false
1190 }
1191
1192 numCerts := 0
Nick Harperb41d2e42016-07-01 17:50:32 -04001193 d := data
Adam Langley95c29f32014-06-20 12:00:00 -07001194 for certsLen > 0 {
1195 if len(d) < 4 {
1196 return false
1197 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001198 certLen := int(d[0])<<16 | int(d[1])<<8 | int(d[2])
1199 if len(d) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001200 return false
1201 }
1202 d = d[3+certLen:]
1203 certsLen -= 3 + certLen
1204 numCerts++
1205 }
1206
1207 m.certificates = make([][]byte, numCerts)
Nick Harperb41d2e42016-07-01 17:50:32 -04001208 d = data
Adam Langley95c29f32014-06-20 12:00:00 -07001209 for i := 0; i < numCerts; i++ {
1210 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
1211 m.certificates[i] = d[3 : 3+certLen]
1212 d = d[3+certLen:]
1213 }
1214
1215 return true
1216}
1217
1218type serverKeyExchangeMsg struct {
1219 raw []byte
1220 key []byte
1221}
1222
Adam Langley95c29f32014-06-20 12:00:00 -07001223func (m *serverKeyExchangeMsg) marshal() []byte {
1224 if m.raw != nil {
1225 return m.raw
1226 }
1227 length := len(m.key)
1228 x := make([]byte, length+4)
1229 x[0] = typeServerKeyExchange
1230 x[1] = uint8(length >> 16)
1231 x[2] = uint8(length >> 8)
1232 x[3] = uint8(length)
1233 copy(x[4:], m.key)
1234
1235 m.raw = x
1236 return x
1237}
1238
1239func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1240 m.raw = data
1241 if len(data) < 4 {
1242 return false
1243 }
1244 m.key = data[4:]
1245 return true
1246}
1247
1248type certificateStatusMsg struct {
1249 raw []byte
1250 statusType uint8
1251 response []byte
1252}
1253
Adam Langley95c29f32014-06-20 12:00:00 -07001254func (m *certificateStatusMsg) marshal() []byte {
1255 if m.raw != nil {
1256 return m.raw
1257 }
1258
1259 var x []byte
1260 if m.statusType == statusTypeOCSP {
1261 x = make([]byte, 4+4+len(m.response))
1262 x[0] = typeCertificateStatus
1263 l := len(m.response) + 4
1264 x[1] = byte(l >> 16)
1265 x[2] = byte(l >> 8)
1266 x[3] = byte(l)
1267 x[4] = statusTypeOCSP
1268
1269 l -= 4
1270 x[5] = byte(l >> 16)
1271 x[6] = byte(l >> 8)
1272 x[7] = byte(l)
1273 copy(x[8:], m.response)
1274 } else {
1275 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1276 }
1277
1278 m.raw = x
1279 return x
1280}
1281
1282func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1283 m.raw = data
1284 if len(data) < 5 {
1285 return false
1286 }
1287 m.statusType = data[4]
1288
1289 m.response = nil
1290 if m.statusType == statusTypeOCSP {
1291 if len(data) < 8 {
1292 return false
1293 }
1294 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1295 if uint32(len(data)) != 4+4+respLen {
1296 return false
1297 }
1298 m.response = data[8:]
1299 }
1300 return true
1301}
1302
1303type serverHelloDoneMsg struct{}
1304
Adam Langley95c29f32014-06-20 12:00:00 -07001305func (m *serverHelloDoneMsg) marshal() []byte {
1306 x := make([]byte, 4)
1307 x[0] = typeServerHelloDone
1308 return x
1309}
1310
1311func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1312 return len(data) == 4
1313}
1314
1315type clientKeyExchangeMsg struct {
1316 raw []byte
1317 ciphertext []byte
1318}
1319
Adam Langley95c29f32014-06-20 12:00:00 -07001320func (m *clientKeyExchangeMsg) marshal() []byte {
1321 if m.raw != nil {
1322 return m.raw
1323 }
1324 length := len(m.ciphertext)
1325 x := make([]byte, length+4)
1326 x[0] = typeClientKeyExchange
1327 x[1] = uint8(length >> 16)
1328 x[2] = uint8(length >> 8)
1329 x[3] = uint8(length)
1330 copy(x[4:], m.ciphertext)
1331
1332 m.raw = x
1333 return x
1334}
1335
1336func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1337 m.raw = data
1338 if len(data) < 4 {
1339 return false
1340 }
1341 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1342 if l != len(data)-4 {
1343 return false
1344 }
1345 m.ciphertext = data[4:]
1346 return true
1347}
1348
1349type finishedMsg struct {
1350 raw []byte
1351 verifyData []byte
1352}
1353
Adam Langley95c29f32014-06-20 12:00:00 -07001354func (m *finishedMsg) marshal() (x []byte) {
1355 if m.raw != nil {
1356 return m.raw
1357 }
1358
1359 x = make([]byte, 4+len(m.verifyData))
1360 x[0] = typeFinished
1361 x[3] = byte(len(m.verifyData))
1362 copy(x[4:], m.verifyData)
1363 m.raw = x
1364 return
1365}
1366
1367func (m *finishedMsg) unmarshal(data []byte) bool {
1368 m.raw = data
1369 if len(data) < 4 {
1370 return false
1371 }
1372 m.verifyData = data[4:]
1373 return true
1374}
1375
1376type nextProtoMsg struct {
1377 raw []byte
1378 proto string
1379}
1380
Adam Langley95c29f32014-06-20 12:00:00 -07001381func (m *nextProtoMsg) marshal() []byte {
1382 if m.raw != nil {
1383 return m.raw
1384 }
1385 l := len(m.proto)
1386 if l > 255 {
1387 l = 255
1388 }
1389
1390 padding := 32 - (l+2)%32
1391 length := l + padding + 2
1392 x := make([]byte, length+4)
1393 x[0] = typeNextProtocol
1394 x[1] = uint8(length >> 16)
1395 x[2] = uint8(length >> 8)
1396 x[3] = uint8(length)
1397
1398 y := x[4:]
1399 y[0] = byte(l)
1400 copy(y[1:], []byte(m.proto[0:l]))
1401 y = y[1+l:]
1402 y[0] = byte(padding)
1403
1404 m.raw = x
1405
1406 return x
1407}
1408
1409func (m *nextProtoMsg) unmarshal(data []byte) bool {
1410 m.raw = data
1411
1412 if len(data) < 5 {
1413 return false
1414 }
1415 data = data[4:]
1416 protoLen := int(data[0])
1417 data = data[1:]
1418 if len(data) < protoLen {
1419 return false
1420 }
1421 m.proto = string(data[0:protoLen])
1422 data = data[protoLen:]
1423
1424 if len(data) < 1 {
1425 return false
1426 }
1427 paddingLen := int(data[0])
1428 data = data[1:]
1429 if len(data) != paddingLen {
1430 return false
1431 }
1432
1433 return true
1434}
1435
1436type certificateRequestMsg struct {
1437 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001438 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001439 // of signature and hash functions. This change was introduced with TLS
1440 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001441 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001442 // hasRequestContext indicates whether this message includes a context
1443 // field instead of certificateTypes. This change was introduced with
1444 // TLS 1.3.
1445 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001446
1447 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001448 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001449 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001450 certificateAuthorities [][]byte
1451}
1452
Nick Harper7e0442a2016-07-01 17:40:09 -04001453func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001454 if m.raw != nil {
1455 return m.raw
1456 }
1457
1458 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001459 builder := newByteBuilder()
1460 builder.addU8(typeCertificateRequest)
1461 body := builder.addU24LengthPrefixed()
1462
Nick Harperb41d2e42016-07-01 17:50:32 -04001463 if m.hasRequestContext {
1464 requestContext := body.addU8LengthPrefixed()
1465 requestContext.addBytes(m.requestContext)
1466 } else {
1467 certificateTypes := body.addU8LengthPrefixed()
1468 certificateTypes.addBytes(m.certificateTypes)
1469 }
Adam Langley95c29f32014-06-20 12:00:00 -07001470
Nick Harper60edffd2016-06-21 15:19:24 -07001471 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001472 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001473 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001474 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001475 }
1476 }
1477
Nick Harper7e0442a2016-07-01 17:40:09 -04001478 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001479 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001480 caEntry := certificateAuthorities.addU16LengthPrefixed()
1481 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001482 }
1483
David Benjamin8d343b42016-07-09 14:26:01 -07001484 if m.hasRequestContext {
1485 // Emit no certificate extensions.
1486 body.addU16(0)
1487 }
1488
Nick Harper7e0442a2016-07-01 17:40:09 -04001489 m.raw = builder.finish()
1490 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001491}
1492
1493func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1494 m.raw = data
1495
1496 if len(data) < 5 {
1497 return false
1498 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001499 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001500
Nick Harperb41d2e42016-07-01 17:50:32 -04001501 if m.hasRequestContext {
1502 contextLen := int(data[0])
1503 if len(data) < 1+contextLen {
1504 return false
1505 }
1506 m.requestContext = make([]byte, contextLen)
1507 copy(m.requestContext, data[1:])
1508 data = data[1+contextLen:]
1509 } else {
1510 numCertTypes := int(data[0])
1511 if len(data) < 1+numCertTypes {
1512 return false
1513 }
1514 m.certificateTypes = make([]byte, numCertTypes)
1515 copy(m.certificateTypes, data[1:])
1516 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001517 }
1518
Nick Harper60edffd2016-06-21 15:19:24 -07001519 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001520 if len(data) < 2 {
1521 return false
1522 }
Nick Harper60edffd2016-06-21 15:19:24 -07001523 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001524 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001525 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001526 return false
1527 }
Nick Harper60edffd2016-06-21 15:19:24 -07001528 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001529 return false
1530 }
Nick Harper60edffd2016-06-21 15:19:24 -07001531 numSigAlgs := sigAlgsLen / 2
1532 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1533 for i := range m.signatureAlgorithms {
1534 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001535 data = data[2:]
1536 }
1537 }
1538
1539 if len(data) < 2 {
1540 return false
1541 }
1542 casLength := uint16(data[0])<<8 | uint16(data[1])
1543 data = data[2:]
1544 if len(data) < int(casLength) {
1545 return false
1546 }
1547 cas := make([]byte, casLength)
1548 copy(cas, data)
1549 data = data[casLength:]
1550
1551 m.certificateAuthorities = nil
1552 for len(cas) > 0 {
1553 if len(cas) < 2 {
1554 return false
1555 }
1556 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1557 cas = cas[2:]
1558
1559 if len(cas) < int(caLen) {
1560 return false
1561 }
1562
1563 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1564 cas = cas[caLen:]
1565 }
David Benjamin8d343b42016-07-09 14:26:01 -07001566
1567 if m.hasRequestContext {
1568 // Ignore certificate extensions.
1569 if len(data) < 2 {
1570 return false
1571 }
1572 extsLength := int(data[0])<<8 | int(data[1])
1573 if len(data) < 2+extsLength {
1574 return false
1575 }
1576 data = data[2+extsLength:]
1577 }
1578
Adam Langley95c29f32014-06-20 12:00:00 -07001579 if len(data) > 0 {
1580 return false
1581 }
1582
1583 return true
1584}
1585
1586type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07001587 raw []byte
1588 hasSignatureAlgorithm bool
1589 signatureAlgorithm signatureAlgorithm
1590 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001591}
1592
Adam Langley95c29f32014-06-20 12:00:00 -07001593func (m *certificateVerifyMsg) marshal() (x []byte) {
1594 if m.raw != nil {
1595 return m.raw
1596 }
1597
1598 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1599 siglength := len(m.signature)
1600 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07001601 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001602 length += 2
1603 }
1604 x = make([]byte, 4+length)
1605 x[0] = typeCertificateVerify
1606 x[1] = uint8(length >> 16)
1607 x[2] = uint8(length >> 8)
1608 x[3] = uint8(length)
1609 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001610 if m.hasSignatureAlgorithm {
1611 y[0] = byte(m.signatureAlgorithm >> 8)
1612 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07001613 y = y[2:]
1614 }
1615 y[0] = uint8(siglength >> 8)
1616 y[1] = uint8(siglength)
1617 copy(y[2:], m.signature)
1618
1619 m.raw = x
1620
1621 return
1622}
1623
1624func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1625 m.raw = data
1626
1627 if len(data) < 6 {
1628 return false
1629 }
1630
1631 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1632 if uint32(len(data))-4 != length {
1633 return false
1634 }
1635
1636 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001637 if m.hasSignatureAlgorithm {
1638 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001639 data = data[2:]
1640 }
1641
1642 if len(data) < 2 {
1643 return false
1644 }
1645 siglength := int(data[0])<<8 + int(data[1])
1646 data = data[2:]
1647 if len(data) != siglength {
1648 return false
1649 }
1650
1651 m.signature = data
1652
1653 return true
1654}
1655
1656type newSessionTicketMsg struct {
1657 raw []byte
1658 ticket []byte
1659}
1660
Adam Langley95c29f32014-06-20 12:00:00 -07001661func (m *newSessionTicketMsg) marshal() (x []byte) {
1662 if m.raw != nil {
1663 return m.raw
1664 }
1665
1666 // See http://tools.ietf.org/html/rfc5077#section-3.3
1667 ticketLen := len(m.ticket)
1668 length := 2 + 4 + ticketLen
1669 x = make([]byte, 4+length)
1670 x[0] = typeNewSessionTicket
1671 x[1] = uint8(length >> 16)
1672 x[2] = uint8(length >> 8)
1673 x[3] = uint8(length)
1674 x[8] = uint8(ticketLen >> 8)
1675 x[9] = uint8(ticketLen)
1676 copy(x[10:], m.ticket)
1677
1678 m.raw = x
1679
1680 return
1681}
1682
1683func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
1684 m.raw = data
1685
1686 if len(data) < 10 {
1687 return false
1688 }
1689
1690 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1691 if uint32(len(data))-4 != length {
1692 return false
1693 }
1694
1695 ticketLen := int(data[8])<<8 + int(data[9])
1696 if len(data)-10 != ticketLen {
1697 return false
1698 }
1699
1700 m.ticket = data[10:]
1701
1702 return true
1703}
1704
David Benjamind86c7672014-08-02 04:07:12 -04001705type v2ClientHelloMsg struct {
1706 raw []byte
1707 vers uint16
1708 cipherSuites []uint16
1709 sessionId []byte
1710 challenge []byte
1711}
1712
David Benjamind86c7672014-08-02 04:07:12 -04001713func (m *v2ClientHelloMsg) marshal() []byte {
1714 if m.raw != nil {
1715 return m.raw
1716 }
1717
1718 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
1719
1720 x := make([]byte, length)
1721 x[0] = 1
1722 x[1] = uint8(m.vers >> 8)
1723 x[2] = uint8(m.vers)
1724 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
1725 x[4] = uint8(len(m.cipherSuites) * 3)
1726 x[5] = uint8(len(m.sessionId) >> 8)
1727 x[6] = uint8(len(m.sessionId))
1728 x[7] = uint8(len(m.challenge) >> 8)
1729 x[8] = uint8(len(m.challenge))
1730 y := x[9:]
1731 for i, spec := range m.cipherSuites {
1732 y[i*3] = 0
1733 y[i*3+1] = uint8(spec >> 8)
1734 y[i*3+2] = uint8(spec)
1735 }
1736 y = y[len(m.cipherSuites)*3:]
1737 copy(y, m.sessionId)
1738 y = y[len(m.sessionId):]
1739 copy(y, m.challenge)
1740
1741 m.raw = x
1742
1743 return x
1744}
1745
David Benjamin83c0bc92014-08-04 01:23:53 -04001746type helloVerifyRequestMsg struct {
1747 raw []byte
1748 vers uint16
1749 cookie []byte
1750}
1751
David Benjamin83c0bc92014-08-04 01:23:53 -04001752func (m *helloVerifyRequestMsg) marshal() []byte {
1753 if m.raw != nil {
1754 return m.raw
1755 }
1756
1757 length := 2 + 1 + len(m.cookie)
1758
1759 x := make([]byte, 4+length)
1760 x[0] = typeHelloVerifyRequest
1761 x[1] = uint8(length >> 16)
1762 x[2] = uint8(length >> 8)
1763 x[3] = uint8(length)
1764 vers := versionToWire(m.vers, true)
1765 x[4] = uint8(vers >> 8)
1766 x[5] = uint8(vers)
1767 x[6] = uint8(len(m.cookie))
1768 copy(x[7:7+len(m.cookie)], m.cookie)
1769
1770 return x
1771}
1772
1773func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
1774 if len(data) < 4+2+1 {
1775 return false
1776 }
1777 m.raw = data
1778 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), true)
1779 cookieLen := int(data[6])
1780 if cookieLen > 32 || len(data) != 7+cookieLen {
1781 return false
1782 }
1783 m.cookie = data[7 : 7+cookieLen]
1784
1785 return true
1786}
1787
David Benjamin24599a82016-06-30 18:56:53 -04001788type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04001789 raw []byte
1790 channelID []byte
1791}
1792
David Benjamin24599a82016-06-30 18:56:53 -04001793func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04001794 if m.raw != nil {
1795 return m.raw
1796 }
1797
1798 length := 2 + 2 + len(m.channelID)
1799
1800 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04001801 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04001802 x[1] = uint8(length >> 16)
1803 x[2] = uint8(length >> 8)
1804 x[3] = uint8(length)
1805 x[4] = uint8(extensionChannelID >> 8)
1806 x[5] = uint8(extensionChannelID & 0xff)
1807 x[6] = uint8(len(m.channelID) >> 8)
1808 x[7] = uint8(len(m.channelID) & 0xff)
1809 copy(x[8:], m.channelID)
1810
1811 return x
1812}
1813
David Benjamin24599a82016-06-30 18:56:53 -04001814func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04001815 if len(data) != 4+2+2+128 {
1816 return false
1817 }
1818 m.raw = data
1819 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
1820 return false
1821 }
1822 if int(data[6])<<8|int(data[7]) != 128 {
1823 return false
1824 }
1825 m.channelID = data[4+2+2:]
1826
1827 return true
1828}
1829
Adam Langley2ae77d22014-10-28 17:29:33 -07001830type helloRequestMsg struct {
1831}
1832
1833func (*helloRequestMsg) marshal() []byte {
1834 return []byte{typeHelloRequest, 0, 0, 0}
1835}
1836
1837func (*helloRequestMsg) unmarshal(data []byte) bool {
1838 return len(data) == 4
1839}
1840
Adam Langley95c29f32014-06-20 12:00:00 -07001841func eqUint16s(x, y []uint16) bool {
1842 if len(x) != len(y) {
1843 return false
1844 }
1845 for i, v := range x {
1846 if y[i] != v {
1847 return false
1848 }
1849 }
1850 return true
1851}
1852
1853func eqCurveIDs(x, y []CurveID) bool {
1854 if len(x) != len(y) {
1855 return false
1856 }
1857 for i, v := range x {
1858 if y[i] != v {
1859 return false
1860 }
1861 }
1862 return true
1863}
1864
1865func eqStrings(x, y []string) bool {
1866 if len(x) != len(y) {
1867 return false
1868 }
1869 for i, v := range x {
1870 if y[i] != v {
1871 return false
1872 }
1873 }
1874 return true
1875}
1876
1877func eqByteSlices(x, y [][]byte) bool {
1878 if len(x) != len(y) {
1879 return false
1880 }
1881 for i, v := range x {
1882 if !bytes.Equal(v, y[i]) {
1883 return false
1884 }
1885 }
1886 return true
1887}
1888
Nick Harper60edffd2016-06-21 15:19:24 -07001889func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07001890 if len(x) != len(y) {
1891 return false
1892 }
1893 for i, v := range x {
1894 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07001895 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07001896 return false
1897 }
1898 }
1899 return true
1900}
Nick Harperf8b0e702016-06-30 19:59:01 -04001901
1902func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
1903 if len(x) != len(y) {
1904 return false
1905 }
1906 for i, v := range x {
1907 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
1908 return false
1909 }
1910 }
1911 return true
1912
1913}