blob: 8e73a3c6247eb385ccef67e3e28c245d41ba0b48 [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 Harperdcfbc672016-07-16 17:47:31 +0200129 hasKeyShares bool
Nick Harperf8b0e702016-06-30 19:59:01 -0400130 keyShares []keyShareEntry
131 pskIdentities [][]uint8
132 hasEarlyData bool
133 earlyDataContext []byte
David Benjaminca6c8262014-11-15 19:06:08 -0500134 ticketSupported bool
135 sessionTicket []uint8
Nick Harper60edffd2016-06-21 15:19:24 -0700136 signatureAlgorithms []signatureAlgorithm
David Benjaminca6c8262014-11-15 19:06:08 -0500137 secureRenegotiation []byte
138 alpnProtocols []string
139 duplicateExtension bool
140 channelIDSupported bool
141 npnLast bool
142 extendedMasterSecret bool
143 srtpProtectionProfiles []uint16
144 srtpMasterKeyIdentifier string
David Benjamin61f95272014-11-25 01:55:35 -0500145 sctListSupported bool
Adam Langley09505632015-07-30 18:10:13 -0700146 customExtension string
Adam Langley95c29f32014-06-20 12:00:00 -0700147}
148
149func (m *clientHelloMsg) equal(i interface{}) bool {
150 m1, ok := i.(*clientHelloMsg)
151 if !ok {
152 return false
153 }
154
155 return bytes.Equal(m.raw, m1.raw) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400156 m.isDTLS == m1.isDTLS &&
Adam Langley95c29f32014-06-20 12:00:00 -0700157 m.vers == m1.vers &&
158 bytes.Equal(m.random, m1.random) &&
159 bytes.Equal(m.sessionId, m1.sessionId) &&
David Benjamin83c0bc92014-08-04 01:23:53 -0400160 bytes.Equal(m.cookie, m1.cookie) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700161 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
162 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
163 m.nextProtoNeg == m1.nextProtoNeg &&
164 m.serverName == m1.serverName &&
165 m.ocspStapling == m1.ocspStapling &&
166 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
167 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
Nick Harperdcfbc672016-07-16 17:47:31 +0200168 m.hasKeyShares == m1.hasKeyShares &&
Nick Harperf8b0e702016-06-30 19:59:01 -0400169 eqKeyShareEntryLists(m.keyShares, m1.keyShares) &&
170 eqByteSlices(m.pskIdentities, m1.pskIdentities) &&
171 m.hasEarlyData == m1.hasEarlyData &&
172 bytes.Equal(m.earlyDataContext, m1.earlyDataContext) &&
Adam Langley95c29f32014-06-20 12:00:00 -0700173 m.ticketSupported == m1.ticketSupported &&
174 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
Nick Harper60edffd2016-06-21 15:19:24 -0700175 eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
Adam Langley2ae77d22014-10-28 17:29:33 -0700176 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
177 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
David Benjaminfa055a22014-09-15 16:51:51 -0400178 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
David Benjamind30a9902014-08-24 01:44:23 -0400179 m.duplicateExtension == m1.duplicateExtension &&
David Benjaminfc7b0862014-09-06 13:21:53 -0400180 m.channelIDSupported == m1.channelIDSupported &&
Adam Langley75712922014-10-10 16:23:43 -0700181 m.npnLast == m1.npnLast &&
David Benjaminca6c8262014-11-15 19:06:08 -0500182 m.extendedMasterSecret == m1.extendedMasterSecret &&
183 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
David Benjamin61f95272014-11-25 01:55:35 -0500184 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
Adam Langley09505632015-07-30 18:10:13 -0700185 m.sctListSupported == m1.sctListSupported &&
186 m.customExtension == m1.customExtension
Adam Langley95c29f32014-06-20 12:00:00 -0700187}
188
189func (m *clientHelloMsg) marshal() []byte {
190 if m.raw != nil {
191 return m.raw
192 }
193
Nick Harper8dda5cc2016-06-30 18:51:11 -0400194 handshakeMsg := newByteBuilder()
195 handshakeMsg.addU8(typeClientHello)
196 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin83c0bc92014-08-04 01:23:53 -0400197 vers := versionToWire(m.vers, m.isDTLS)
Nick Harper8dda5cc2016-06-30 18:51:11 -0400198 hello.addU16(vers)
199 hello.addBytes(m.random)
200 sessionId := hello.addU8LengthPrefixed()
201 sessionId.addBytes(m.sessionId)
David Benjamin83c0bc92014-08-04 01:23:53 -0400202 if m.isDTLS {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400203 cookie := hello.addU8LengthPrefixed()
204 cookie.addBytes(m.cookie)
David Benjamin83c0bc92014-08-04 01:23:53 -0400205 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400206 cipherSuites := hello.addU16LengthPrefixed()
207 for _, suite := range m.cipherSuites {
208 cipherSuites.addU16(suite)
Adam Langley95c29f32014-06-20 12:00:00 -0700209 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400210 compressionMethods := hello.addU8LengthPrefixed()
211 compressionMethods.addBytes(m.compressionMethods)
Adam Langley95c29f32014-06-20 12:00:00 -0700212
Nick Harper8dda5cc2016-06-30 18:51:11 -0400213 extensions := hello.addU16LengthPrefixed()
David Benjamin35a7a442014-07-05 00:23:20 -0400214 if m.duplicateExtension {
215 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400216 extensions.addU16(0xffff)
217 extensions.addU16(0) // 0-length for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400218 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400219 if m.nextProtoNeg && !m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400220 extensions.addU16(extensionNextProtoNeg)
221 extensions.addU16(0) // The length is always 0
Adam Langley95c29f32014-06-20 12:00:00 -0700222 }
223 if len(m.serverName) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400224 extensions.addU16(extensionServerName)
225 serverNameList := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700226
227 // RFC 3546, section 3.1
228 //
229 // struct {
230 // NameType name_type;
231 // select (name_type) {
232 // case host_name: HostName;
233 // } name;
234 // } ServerName;
235 //
236 // enum {
237 // host_name(0), (255)
238 // } NameType;
239 //
240 // opaque HostName<1..2^16-1>;
241 //
242 // struct {
243 // ServerName server_name_list<1..2^16-1>
244 // } ServerNameList;
245
Nick Harper8dda5cc2016-06-30 18:51:11 -0400246 serverName := serverNameList.addU16LengthPrefixed()
247 serverName.addU8(0) // NameType host_name(0)
248 hostName := serverName.addU16LengthPrefixed()
249 hostName.addBytes([]byte(m.serverName))
Adam Langley95c29f32014-06-20 12:00:00 -0700250 }
251 if m.ocspStapling {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400252 extensions.addU16(extensionStatusRequest)
253 certificateStatusRequest := extensions.addU16LengthPrefixed()
254
Adam Langley95c29f32014-06-20 12:00:00 -0700255 // RFC 4366, section 3.6
Nick Harper8dda5cc2016-06-30 18:51:11 -0400256 certificateStatusRequest.addU8(1) // OCSP type
Adam Langley95c29f32014-06-20 12:00:00 -0700257 // Two zero valued uint16s for the two lengths.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400258 certificateStatusRequest.addU16(0) // ResponderID length
259 certificateStatusRequest.addU16(0) // Extensions length
Adam Langley95c29f32014-06-20 12:00:00 -0700260 }
261 if len(m.supportedCurves) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400262 // http://tools.ietf.org/html/rfc4492#section-5.1.1
263 extensions.addU16(extensionSupportedCurves)
264 supportedCurvesList := extensions.addU16LengthPrefixed()
265 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700266 for _, curve := range m.supportedCurves {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400267 supportedCurves.addU16(uint16(curve))
Adam Langley95c29f32014-06-20 12:00:00 -0700268 }
269 }
270 if len(m.supportedPoints) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400271 // http://tools.ietf.org/html/rfc4492#section-5.1.2
272 extensions.addU16(extensionSupportedPoints)
273 supportedPointsList := extensions.addU16LengthPrefixed()
274 supportedPoints := supportedPointsList.addU8LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700275 for _, pointFormat := range m.supportedPoints {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400276 supportedPoints.addU8(pointFormat)
Adam Langley95c29f32014-06-20 12:00:00 -0700277 }
278 }
Nick Harperdcfbc672016-07-16 17:47:31 +0200279 if m.hasKeyShares {
Nick Harperf8b0e702016-06-30 19:59:01 -0400280 extensions.addU16(extensionKeyShare)
281 keyShareList := extensions.addU16LengthPrefixed()
282
283 keyShares := keyShareList.addU16LengthPrefixed()
284 for _, keyShare := range m.keyShares {
285 keyShares.addU16(uint16(keyShare.group))
286 keyExchange := keyShares.addU16LengthPrefixed()
287 keyExchange.addBytes(keyShare.keyExchange)
288 }
289 }
290 if len(m.pskIdentities) > 0 {
291 extensions.addU16(extensionPreSharedKey)
292 pskExtension := extensions.addU16LengthPrefixed()
293
294 pskIdentities := pskExtension.addU16LengthPrefixed()
295 for _, psk := range m.pskIdentities {
296 pskIdentity := pskIdentities.addU16LengthPrefixed()
297 pskIdentity.addBytes(psk)
298 }
299 }
300 if m.hasEarlyData {
301 extensions.addU16(extensionEarlyData)
302 earlyDataIndication := extensions.addU16LengthPrefixed()
303
304 context := earlyDataIndication.addU8LengthPrefixed()
305 context.addBytes(m.earlyDataContext)
306 }
Adam Langley95c29f32014-06-20 12:00:00 -0700307 if m.ticketSupported {
308 // http://tools.ietf.org/html/rfc5077#section-3.2
Nick Harper8dda5cc2016-06-30 18:51:11 -0400309 extensions.addU16(extensionSessionTicket)
310 sessionTicketExtension := extensions.addU16LengthPrefixed()
311 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langley95c29f32014-06-20 12:00:00 -0700312 }
Nick Harper60edffd2016-06-21 15:19:24 -0700313 if len(m.signatureAlgorithms) > 0 {
Adam Langley95c29f32014-06-20 12:00:00 -0700314 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Nick Harper8dda5cc2016-06-30 18:51:11 -0400315 extensions.addU16(extensionSignatureAlgorithms)
316 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
317 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -0700318 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400319 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -0700320 }
321 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700322 if m.secureRenegotiation != nil {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400323 extensions.addU16(extensionRenegotiationInfo)
324 secureRenegoExt := extensions.addU16LengthPrefixed()
325 secureRenego := secureRenegoExt.addU8LengthPrefixed()
326 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700327 }
David Benjaminfa055a22014-09-15 16:51:51 -0400328 if len(m.alpnProtocols) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400329 // https://tools.ietf.org/html/rfc7301#section-3.1
330 extensions.addU16(extensionALPN)
331 alpnExtension := extensions.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400332
Nick Harper8dda5cc2016-06-30 18:51:11 -0400333 protocolNameList := alpnExtension.addU16LengthPrefixed()
David Benjaminfa055a22014-09-15 16:51:51 -0400334 for _, s := range m.alpnProtocols {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400335 protocolName := protocolNameList.addU8LengthPrefixed()
336 protocolName.addBytes([]byte(s))
David Benjaminfa055a22014-09-15 16:51:51 -0400337 }
David Benjaminfa055a22014-09-15 16:51:51 -0400338 }
David Benjamind30a9902014-08-24 01:44:23 -0400339 if m.channelIDSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400340 extensions.addU16(extensionChannelID)
341 extensions.addU16(0) // Length is always 0
David Benjamind30a9902014-08-24 01:44:23 -0400342 }
David Benjaminfc7b0862014-09-06 13:21:53 -0400343 if m.nextProtoNeg && m.npnLast {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400344 extensions.addU16(extensionNextProtoNeg)
345 extensions.addU16(0) // Length is always 0
David Benjaminfc7b0862014-09-06 13:21:53 -0400346 }
David Benjamin35a7a442014-07-05 00:23:20 -0400347 if m.duplicateExtension {
348 // Add a duplicate bogus extension at the beginning and end.
Nick Harper8dda5cc2016-06-30 18:51:11 -0400349 extensions.addU16(0xffff)
350 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400351 }
Adam Langley75712922014-10-10 16:23:43 -0700352 if m.extendedMasterSecret {
David Benjamin43946d42016-02-01 08:42:19 -0500353 // https://tools.ietf.org/html/rfc7627
Nick Harper8dda5cc2016-06-30 18:51:11 -0400354 extensions.addU16(extensionExtendedMasterSecret)
355 extensions.addU16(0) // Length is always 0
Adam Langley75712922014-10-10 16:23:43 -0700356 }
David Benjaminca6c8262014-11-15 19:06:08 -0500357 if len(m.srtpProtectionProfiles) > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400358 // https://tools.ietf.org/html/rfc5764#section-4.1.1
359 extensions.addU16(extensionUseSRTP)
360 useSrtpExt := extensions.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500361
Nick Harper8dda5cc2016-06-30 18:51:11 -0400362 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
David Benjaminca6c8262014-11-15 19:06:08 -0500363 for _, p := range m.srtpProtectionProfiles {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400364 // An SRTPProtectionProfile is defined as uint8[2],
365 // not uint16. For some reason, we're storing it
366 // as a uint16.
367 srtpProtectionProfiles.addU8(byte(p >> 8))
368 srtpProtectionProfiles.addU8(byte(p))
David Benjaminca6c8262014-11-15 19:06:08 -0500369 }
Nick Harper8dda5cc2016-06-30 18:51:11 -0400370 srtpMki := useSrtpExt.addU8LengthPrefixed()
371 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500372 }
David Benjamin61f95272014-11-25 01:55:35 -0500373 if m.sctListSupported {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400374 extensions.addU16(extensionSignedCertificateTimestamp)
375 extensions.addU16(0) // Length is always 0
David Benjamin61f95272014-11-25 01:55:35 -0500376 }
Adam Langley09505632015-07-30 18:10:13 -0700377 if l := len(m.customExtension); l > 0 {
Nick Harper8dda5cc2016-06-30 18:51:11 -0400378 extensions.addU16(extensionCustom)
379 customExt := extensions.addU16LengthPrefixed()
380 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -0700381 }
Nick Harper4d90c102016-07-17 10:53:26 +0200382 if m.vers == VersionTLS13 {
383 extensions.addU16(extensionTLS13Draft)
384 extValue := extensions.addU16LengthPrefixed()
385 extValue.addU16(tls13DraftVersion)
386 }
Adam Langley95c29f32014-06-20 12:00:00 -0700387
Nick Harper8dda5cc2016-06-30 18:51:11 -0400388 if extensions.len() == 0 {
389 hello.discardChild()
390 }
Adam Langley95c29f32014-06-20 12:00:00 -0700391
Nick Harper8dda5cc2016-06-30 18:51:11 -0400392 m.raw = handshakeMsg.finish()
393 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -0700394}
395
396func (m *clientHelloMsg) unmarshal(data []byte) bool {
397 if len(data) < 42 {
398 return false
399 }
400 m.raw = data
David Benjamin83c0bc92014-08-04 01:23:53 -0400401 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
Adam Langley95c29f32014-06-20 12:00:00 -0700402 m.random = data[6:38]
403 sessionIdLen := int(data[38])
404 if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
405 return false
406 }
407 m.sessionId = data[39 : 39+sessionIdLen]
408 data = data[39+sessionIdLen:]
David Benjamin83c0bc92014-08-04 01:23:53 -0400409 if m.isDTLS {
410 if len(data) < 1 {
411 return false
412 }
413 cookieLen := int(data[0])
414 if cookieLen > 32 || len(data) < 1+cookieLen {
415 return false
416 }
417 m.cookie = data[1 : 1+cookieLen]
418 data = data[1+cookieLen:]
419 }
Adam Langley95c29f32014-06-20 12:00:00 -0700420 if len(data) < 2 {
421 return false
422 }
423 // cipherSuiteLen is the number of bytes of cipher suite numbers. Since
424 // they are uint16s, the number must be even.
425 cipherSuiteLen := int(data[0])<<8 | int(data[1])
426 if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
427 return false
428 }
429 numCipherSuites := cipherSuiteLen / 2
430 m.cipherSuites = make([]uint16, numCipherSuites)
431 for i := 0; i < numCipherSuites; i++ {
432 m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
433 if m.cipherSuites[i] == scsvRenegotiation {
Adam Langley2ae77d22014-10-28 17:29:33 -0700434 m.secureRenegotiation = []byte{}
Adam Langley95c29f32014-06-20 12:00:00 -0700435 }
436 }
437 data = data[2+cipherSuiteLen:]
438 if len(data) < 1 {
439 return false
440 }
441 compressionMethodsLen := int(data[0])
442 if len(data) < 1+compressionMethodsLen {
443 return false
444 }
445 m.compressionMethods = data[1 : 1+compressionMethodsLen]
446
447 data = data[1+compressionMethodsLen:]
448
449 m.nextProtoNeg = false
450 m.serverName = ""
451 m.ocspStapling = false
Nick Harperf8b0e702016-06-30 19:59:01 -0400452 m.keyShares = nil
453 m.pskIdentities = nil
454 m.hasEarlyData = false
455 m.earlyDataContext = nil
Adam Langley95c29f32014-06-20 12:00:00 -0700456 m.ticketSupported = false
457 m.sessionTicket = nil
Nick Harper60edffd2016-06-21 15:19:24 -0700458 m.signatureAlgorithms = nil
David Benjaminfa055a22014-09-15 16:51:51 -0400459 m.alpnProtocols = nil
Adam Langley75712922014-10-10 16:23:43 -0700460 m.extendedMasterSecret = false
Adam Langley09505632015-07-30 18:10:13 -0700461 m.customExtension = ""
Adam Langley95c29f32014-06-20 12:00:00 -0700462
463 if len(data) == 0 {
464 // ClientHello is optionally followed by extension data
465 return true
466 }
467 if len(data) < 2 {
468 return false
469 }
470
471 extensionsLength := int(data[0])<<8 | int(data[1])
472 data = data[2:]
473 if extensionsLength != len(data) {
474 return false
475 }
476
477 for len(data) != 0 {
478 if len(data) < 4 {
479 return false
480 }
481 extension := uint16(data[0])<<8 | uint16(data[1])
482 length := int(data[2])<<8 | int(data[3])
483 data = data[4:]
484 if len(data) < length {
485 return false
486 }
487
488 switch extension {
489 case extensionServerName:
490 if length < 2 {
491 return false
492 }
493 numNames := int(data[0])<<8 | int(data[1])
494 d := data[2:]
495 for i := 0; i < numNames; i++ {
496 if len(d) < 3 {
497 return false
498 }
499 nameType := d[0]
500 nameLen := int(d[1])<<8 | int(d[2])
501 d = d[3:]
502 if len(d) < nameLen {
503 return false
504 }
505 if nameType == 0 {
506 m.serverName = string(d[0:nameLen])
507 break
508 }
509 d = d[nameLen:]
510 }
511 case extensionNextProtoNeg:
512 if length > 0 {
513 return false
514 }
515 m.nextProtoNeg = true
516 case extensionStatusRequest:
517 m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
518 case extensionSupportedCurves:
519 // http://tools.ietf.org/html/rfc4492#section-5.5.1
520 if length < 2 {
521 return false
522 }
523 l := int(data[0])<<8 | int(data[1])
524 if l%2 == 1 || length != l+2 {
525 return false
526 }
527 numCurves := l / 2
528 m.supportedCurves = make([]CurveID, numCurves)
529 d := data[2:]
530 for i := 0; i < numCurves; i++ {
531 m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
532 d = d[2:]
533 }
534 case extensionSupportedPoints:
535 // http://tools.ietf.org/html/rfc4492#section-5.5.2
536 if length < 1 {
537 return false
538 }
539 l := int(data[0])
540 if length != l+1 {
541 return false
542 }
543 m.supportedPoints = make([]uint8, l)
544 copy(m.supportedPoints, data[1:])
545 case extensionSessionTicket:
546 // http://tools.ietf.org/html/rfc5077#section-3.2
547 m.ticketSupported = true
548 m.sessionTicket = data[:length]
Nick Harperf8b0e702016-06-30 19:59:01 -0400549 case extensionKeyShare:
550 // draft-ietf-tls-tls13 section 6.3.2.3
551 if length < 2 {
552 return false
553 }
554 l := int(data[0])<<8 | int(data[1])
555 if l != length-2 {
556 return false
557 }
558 d := data[2:length]
Nick Harperdcfbc672016-07-16 17:47:31 +0200559 m.hasKeyShares = true
Nick Harperf8b0e702016-06-30 19:59:01 -0400560 for len(d) > 0 {
561 // The next KeyShareEntry contains a NamedGroup (2 bytes) and a
562 // key_exchange (2-byte length prefix with at least 1 byte of content).
563 if len(d) < 5 {
564 return false
565 }
566 entry := keyShareEntry{}
567 entry.group = CurveID(d[0])<<8 | CurveID(d[1])
568 keyExchLen := int(d[2])<<8 | int(d[3])
569 d = d[4:]
570 if len(d) < keyExchLen {
571 return false
572 }
573 entry.keyExchange = d[:keyExchLen]
574 d = d[keyExchLen:]
575 m.keyShares = append(m.keyShares, entry)
576 }
577 case extensionPreSharedKey:
578 // draft-ietf-tls-tls13 section 6.3.2.4
579 if length < 2 {
580 return false
581 }
582 l := int(data[0])<<8 | int(data[1])
583 if l != length-2 {
584 return false
585 }
586 d := data[2:length]
587 for len(d) > 0 {
588 if len(d) < 2 {
589 return false
590 }
591 pskLen := int(d[0])<<8 | int(d[1])
592 d = d[2:]
593 if len(d) < pskLen {
594 return false
595 }
596 psk := d[:pskLen]
597 m.pskIdentities = append(m.pskIdentities, psk)
598 d = d[pskLen:]
599 }
600 case extensionEarlyData:
601 // draft-ietf-tls-tls13 section 6.3.2.5
602 if length < 1 {
603 return false
604 }
605 l := int(data[0])
606 if length != l+1 {
607 return false
608 }
609 m.hasEarlyData = true
610 m.earlyDataContext = data[1:length]
Adam Langley95c29f32014-06-20 12:00:00 -0700611 case extensionSignatureAlgorithms:
612 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
613 if length < 2 || length&1 != 0 {
614 return false
615 }
616 l := int(data[0])<<8 | int(data[1])
617 if l != length-2 {
618 return false
619 }
620 n := l / 2
621 d := data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -0700622 m.signatureAlgorithms = make([]signatureAlgorithm, n)
623 for i := range m.signatureAlgorithms {
624 m.signatureAlgorithms[i] = signatureAlgorithm(d[0])<<8 | signatureAlgorithm(d[1])
Adam Langley95c29f32014-06-20 12:00:00 -0700625 d = d[2:]
626 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700627 case extensionRenegotiationInfo:
628 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -0700629 return false
630 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700631 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -0400632 case extensionALPN:
633 if length < 2 {
634 return false
635 }
636 l := int(data[0])<<8 | int(data[1])
637 if l != length-2 {
638 return false
639 }
640 d := data[2:length]
641 for len(d) != 0 {
642 stringLen := int(d[0])
643 d = d[1:]
644 if stringLen == 0 || stringLen > len(d) {
645 return false
646 }
647 m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
648 d = d[stringLen:]
649 }
David Benjamind30a9902014-08-24 01:44:23 -0400650 case extensionChannelID:
651 if length > 0 {
652 return false
653 }
654 m.channelIDSupported = true
Adam Langley75712922014-10-10 16:23:43 -0700655 case extensionExtendedMasterSecret:
656 if length != 0 {
657 return false
658 }
659 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -0500660 case extensionUseSRTP:
661 if length < 2 {
662 return false
663 }
664 l := int(data[0])<<8 | int(data[1])
665 if l > length-2 || l%2 != 0 {
666 return false
667 }
668 n := l / 2
669 m.srtpProtectionProfiles = make([]uint16, n)
670 d := data[2:length]
671 for i := 0; i < n; i++ {
672 m.srtpProtectionProfiles[i] = uint16(d[0])<<8 | uint16(d[1])
673 d = d[2:]
674 }
675 if len(d) < 1 || int(d[0]) != len(d)-1 {
676 return false
677 }
678 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -0500679 case extensionSignedCertificateTimestamp:
680 if length != 0 {
681 return false
682 }
683 m.sctListSupported = true
Adam Langley09505632015-07-30 18:10:13 -0700684 case extensionCustom:
685 m.customExtension = string(data[:length])
Adam Langley95c29f32014-06-20 12:00:00 -0700686 }
687 data = data[length:]
688 }
689
690 return true
691}
692
693type serverHelloMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -0400694 raw []byte
695 isDTLS bool
696 vers uint16
697 random []byte
698 sessionId []byte
699 cipherSuite uint16
700 hasKeyShare bool
701 keyShare keyShareEntry
702 hasPSKIdentity bool
703 pskIdentity uint16
704 earlyDataIndication bool
705 compressionMethod uint8
706 extensions serverExtensions
Adam Langley95c29f32014-06-20 12:00:00 -0700707}
708
Adam Langley95c29f32014-06-20 12:00:00 -0700709func (m *serverHelloMsg) marshal() []byte {
710 if m.raw != nil {
711 return m.raw
712 }
713
Nick Harper5212ef82016-06-30 19:26:07 -0400714 handshakeMsg := newByteBuilder()
715 handshakeMsg.addU8(typeServerHello)
716 hello := handshakeMsg.addU24LengthPrefixed()
David Benjamin83c0bc92014-08-04 01:23:53 -0400717 vers := versionToWire(m.vers, m.isDTLS)
Nick Harper5212ef82016-06-30 19:26:07 -0400718 hello.addU16(vers)
719 hello.addBytes(m.random)
David Benjamin8d315d72016-07-18 01:03:18 +0200720 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400721 sessionId := hello.addU8LengthPrefixed()
722 sessionId.addBytes(m.sessionId)
723 }
Nick Harper5212ef82016-06-30 19:26:07 -0400724 hello.addU16(m.cipherSuite)
David Benjamin8d315d72016-07-18 01:03:18 +0200725 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400726 hello.addU8(m.compressionMethod)
727 }
Adam Langley95c29f32014-06-20 12:00:00 -0700728
Nick Harper5212ef82016-06-30 19:26:07 -0400729 extensions := hello.addU16LengthPrefixed()
Nick Harperb3d51be2016-07-01 11:43:18 -0400730
David Benjamin8d315d72016-07-18 01:03:18 +0200731 if m.vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400732 if m.hasKeyShare {
733 extensions.addU16(extensionKeyShare)
734 keyShare := extensions.addU16LengthPrefixed()
735 keyShare.addU16(uint16(m.keyShare.group))
736 keyExchange := keyShare.addU16LengthPrefixed()
737 keyExchange.addBytes(m.keyShare.keyExchange)
738 }
739 if m.hasPSKIdentity {
740 extensions.addU16(extensionPreSharedKey)
741 extensions.addU16(2) // Length
742 extensions.addU16(m.pskIdentity)
743 }
744 if m.earlyDataIndication {
745 extensions.addU16(extensionEarlyData)
746 extensions.addU16(0) // Length
747 }
748 } else {
David Benjamin44b33bc2016-07-01 22:40:23 -0400749 m.extensions.marshal(extensions, m.vers)
Nick Harperb41d2e42016-07-01 17:50:32 -0400750 if extensions.len() == 0 {
751 hello.discardChild()
752 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400753 }
754
755 m.raw = handshakeMsg.finish()
756 return m.raw
757}
758
759func (m *serverHelloMsg) unmarshal(data []byte) bool {
760 if len(data) < 42 {
761 return false
762 }
763 m.raw = data
764 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), m.isDTLS)
765 m.random = data[6:38]
Nick Harperb41d2e42016-07-01 17:50:32 -0400766 data = data[38:]
David Benjamin8d315d72016-07-18 01:03:18 +0200767 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400768 sessionIdLen := int(data[0])
769 if sessionIdLen > 32 || len(data) < 1+sessionIdLen {
770 return false
771 }
772 m.sessionId = data[1 : 1+sessionIdLen]
773 data = data[1+sessionIdLen:]
Nick Harperb3d51be2016-07-01 11:43:18 -0400774 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400775 if len(data) < 2 {
Nick Harperb3d51be2016-07-01 11:43:18 -0400776 return false
777 }
778 m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
Nick Harperb41d2e42016-07-01 17:50:32 -0400779 data = data[2:]
David Benjamin8d315d72016-07-18 01:03:18 +0200780 if m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400781 if len(data) < 1 {
782 return false
783 }
784 m.compressionMethod = data[0]
785 data = data[1:]
786 }
Nick Harperb3d51be2016-07-01 11:43:18 -0400787
David Benjamin8d315d72016-07-18 01:03:18 +0200788 if len(data) == 0 && m.vers < VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400789 // Extension data is optional before TLS 1.3.
Nick Harperb3d51be2016-07-01 11:43:18 -0400790 m.extensions = serverExtensions{}
791 return true
792 }
793 if len(data) < 2 {
794 return false
795 }
796
797 extensionsLength := int(data[0])<<8 | int(data[1])
798 data = data[2:]
799 if len(data) != extensionsLength {
800 return false
801 }
802
David Benjamin8d315d72016-07-18 01:03:18 +0200803 if m.vers >= VersionTLS13 {
Nick Harperb41d2e42016-07-01 17:50:32 -0400804 for len(data) != 0 {
805 if len(data) < 4 {
806 return false
807 }
808 extension := uint16(data[0])<<8 | uint16(data[1])
809 length := int(data[2])<<8 | int(data[3])
810 data = data[4:]
811
812 if len(data) < length {
813 return false
814 }
815 d := data[:length]
816 data = data[length:]
817
818 switch extension {
819 case extensionKeyShare:
820 m.hasKeyShare = true
821 if len(d) < 4 {
822 return false
823 }
824 m.keyShare.group = CurveID(uint16(d[0])<<8 | uint16(d[1]))
825 keyExchLen := int(d[2])<<8 | int(d[3])
826 if keyExchLen != len(d)-4 {
827 return false
828 }
829 m.keyShare.keyExchange = make([]byte, keyExchLen)
830 copy(m.keyShare.keyExchange, d[4:])
831 case extensionPreSharedKey:
832 if len(d) != 2 {
833 return false
834 }
835 m.pskIdentity = uint16(d[0])<<8 | uint16(d[1])
836 m.hasPSKIdentity = true
837 case extensionEarlyData:
838 if len(d) != 0 {
839 return false
840 }
841 m.earlyDataIndication = true
842 default:
843 // Only allow the 3 extensions that are sent in
844 // the clear in TLS 1.3.
845 return false
846 }
847 }
David Benjamin44b33bc2016-07-01 22:40:23 -0400848 } else if !m.extensions.unmarshal(data, m.vers) {
Nick Harperb3d51be2016-07-01 11:43:18 -0400849 return false
850 }
851
852 return true
853}
854
Nick Harperb41d2e42016-07-01 17:50:32 -0400855type encryptedExtensionsMsg struct {
856 raw []byte
857 extensions serverExtensions
Steven Valdez143e8b32016-07-11 13:19:03 -0400858 empty bool
Nick Harperb41d2e42016-07-01 17:50:32 -0400859}
860
861func (m *encryptedExtensionsMsg) marshal() []byte {
862 if m.raw != nil {
863 return m.raw
864 }
865
866 encryptedExtensionsMsg := newByteBuilder()
867 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
868 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
Steven Valdez143e8b32016-07-11 13:19:03 -0400869 if !m.empty {
870 extensions := encryptedExtensions.addU16LengthPrefixed()
871 m.extensions.marshal(extensions, VersionTLS13)
872 }
Nick Harperb41d2e42016-07-01 17:50:32 -0400873
874 m.raw = encryptedExtensionsMsg.finish()
875 return m.raw
876}
877
878func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
David Benjamin6f8f4de2016-07-13 16:42:36 -0400879 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -0400880 if len(data) < 6 {
881 return false
882 }
883 if data[0] != typeEncryptedExtensions {
884 return false
885 }
886 msgLen := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
887 data = data[4:]
888 if len(data) != msgLen {
889 return false
890 }
891 extLen := int(data[0])<<8 | int(data[1])
892 data = data[2:]
893 if extLen != len(data) {
894 return false
895 }
David Benjamin44b33bc2016-07-01 22:40:23 -0400896 return m.extensions.unmarshal(data, VersionTLS13)
Nick Harperb41d2e42016-07-01 17:50:32 -0400897}
898
Nick Harperb3d51be2016-07-01 11:43:18 -0400899type serverExtensions struct {
900 nextProtoNeg bool
901 nextProtos []string
902 ocspStapling bool
David Benjamin44b33bc2016-07-01 22:40:23 -0400903 ocspResponse []byte
Nick Harperb3d51be2016-07-01 11:43:18 -0400904 ticketSupported bool
905 secureRenegotiation []byte
906 alpnProtocol string
907 alpnProtocolEmpty bool
908 duplicateExtension bool
909 channelIDRequested bool
910 extendedMasterSecret bool
911 srtpProtectionProfile uint16
912 srtpMasterKeyIdentifier string
913 sctList []byte
914 customExtension string
915 npnLast bool
Steven Valdez143e8b32016-07-11 13:19:03 -0400916 hasKeyShare bool
917 keyShare keyShareEntry
Nick Harperb3d51be2016-07-01 11:43:18 -0400918}
919
David Benjamin44b33bc2016-07-01 22:40:23 -0400920func (m *serverExtensions) marshal(extensions *byteBuilder, version uint16) {
David Benjamin35a7a442014-07-05 00:23:20 -0400921 if m.duplicateExtension {
922 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -0400923 extensions.addU16(0xffff)
924 extensions.addU16(0) // length = 0 for empty extension
David Benjamin35a7a442014-07-05 00:23:20 -0400925 }
David Benjamin76c2efc2015-08-31 14:24:29 -0400926 if m.nextProtoNeg && !m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -0400927 extensions.addU16(extensionNextProtoNeg)
928 extension := extensions.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -0700929
930 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -0400931 if len(v) > 255 {
932 v = v[:255]
Adam Langley95c29f32014-06-20 12:00:00 -0700933 }
Nick Harper5212ef82016-06-30 19:26:07 -0400934 npn := extension.addU8LengthPrefixed()
935 npn.addBytes([]byte(v))
Adam Langley95c29f32014-06-20 12:00:00 -0700936 }
937 }
David Benjamin8d315d72016-07-18 01:03:18 +0200938 if version >= VersionTLS13 {
David Benjamin44b33bc2016-07-01 22:40:23 -0400939 if m.ocspResponse != nil {
940 extensions.addU16(extensionStatusRequest)
941 body := extensions.addU16LengthPrefixed()
942 body.addU8(statusTypeOCSP)
943 response := body.addU24LengthPrefixed()
944 response.addBytes(m.ocspResponse)
945 }
946 } else {
947 if m.ocspStapling {
948 extensions.addU16(extensionStatusRequest)
949 extensions.addU16(0)
950 }
Adam Langley95c29f32014-06-20 12:00:00 -0700951 }
952 if m.ticketSupported {
Nick Harper5212ef82016-06-30 19:26:07 -0400953 extensions.addU16(extensionSessionTicket)
954 extensions.addU16(0)
Adam Langley95c29f32014-06-20 12:00:00 -0700955 }
Adam Langley2ae77d22014-10-28 17:29:33 -0700956 if m.secureRenegotiation != nil {
Nick Harper5212ef82016-06-30 19:26:07 -0400957 extensions.addU16(extensionRenegotiationInfo)
958 extension := extensions.addU16LengthPrefixed()
959 secureRenego := extension.addU8LengthPrefixed()
960 secureRenego.addBytes(m.secureRenegotiation)
Adam Langley95c29f32014-06-20 12:00:00 -0700961 }
Nick Harper5212ef82016-06-30 19:26:07 -0400962 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
963 extensions.addU16(extensionALPN)
964 extension := extensions.addU16LengthPrefixed()
965
966 protocolNameList := extension.addU16LengthPrefixed()
967 protocolName := protocolNameList.addU8LengthPrefixed()
968 protocolName.addBytes([]byte(m.alpnProtocol))
David Benjaminfa055a22014-09-15 16:51:51 -0400969 }
David Benjamind30a9902014-08-24 01:44:23 -0400970 if m.channelIDRequested {
Nick Harper5212ef82016-06-30 19:26:07 -0400971 extensions.addU16(extensionChannelID)
972 extensions.addU16(0)
David Benjamind30a9902014-08-24 01:44:23 -0400973 }
David Benjamin35a7a442014-07-05 00:23:20 -0400974 if m.duplicateExtension {
975 // Add a duplicate bogus extension at the beginning and end.
Nick Harper5212ef82016-06-30 19:26:07 -0400976 extensions.addU16(0xffff)
977 extensions.addU16(0)
David Benjamin35a7a442014-07-05 00:23:20 -0400978 }
Adam Langley75712922014-10-10 16:23:43 -0700979 if m.extendedMasterSecret {
Nick Harper5212ef82016-06-30 19:26:07 -0400980 extensions.addU16(extensionExtendedMasterSecret)
981 extensions.addU16(0)
Adam Langley75712922014-10-10 16:23:43 -0700982 }
David Benjaminca6c8262014-11-15 19:06:08 -0500983 if m.srtpProtectionProfile != 0 {
Nick Harper5212ef82016-06-30 19:26:07 -0400984 extensions.addU16(extensionUseSRTP)
985 extension := extensions.addU16LengthPrefixed()
986
987 srtpProtectionProfiles := extension.addU16LengthPrefixed()
988 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile >> 8))
989 srtpProtectionProfiles.addU8(byte(m.srtpProtectionProfile))
990 srtpMki := extension.addU8LengthPrefixed()
991 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
David Benjaminca6c8262014-11-15 19:06:08 -0500992 }
David Benjamin61f95272014-11-25 01:55:35 -0500993 if m.sctList != nil {
Nick Harper5212ef82016-06-30 19:26:07 -0400994 extensions.addU16(extensionSignedCertificateTimestamp)
995 extension := extensions.addU16LengthPrefixed()
996 extension.addBytes(m.sctList)
David Benjamin61f95272014-11-25 01:55:35 -0500997 }
Adam Langley09505632015-07-30 18:10:13 -0700998 if l := len(m.customExtension); l > 0 {
Nick Harper5212ef82016-06-30 19:26:07 -0400999 extensions.addU16(extensionCustom)
1000 customExt := extensions.addU16LengthPrefixed()
1001 customExt.addBytes([]byte(m.customExtension))
Adam Langley09505632015-07-30 18:10:13 -07001002 }
David Benjamin76c2efc2015-08-31 14:24:29 -04001003 if m.nextProtoNeg && m.npnLast {
Nick Harper5212ef82016-06-30 19:26:07 -04001004 extensions.addU16(extensionNextProtoNeg)
1005 extension := extensions.addU16LengthPrefixed()
David Benjamin76c2efc2015-08-31 14:24:29 -04001006
1007 for _, v := range m.nextProtos {
Nick Harper5212ef82016-06-30 19:26:07 -04001008 if len(v) > 255 {
1009 v = v[0:255]
David Benjamin76c2efc2015-08-31 14:24:29 -04001010 }
Nick Harper5212ef82016-06-30 19:26:07 -04001011 npn := extension.addU8LengthPrefixed()
1012 npn.addBytes([]byte(v))
David Benjamin76c2efc2015-08-31 14:24:29 -04001013 }
1014 }
Steven Valdez143e8b32016-07-11 13:19:03 -04001015 if m.hasKeyShare {
1016 extensions.addU16(extensionKeyShare)
1017 keyShare := extensions.addU16LengthPrefixed()
1018 keyShare.addU16(uint16(m.keyShare.group))
1019 keyExchange := keyShare.addU16LengthPrefixed()
1020 keyExchange.addBytes(m.keyShare.keyExchange)
1021 }
Adam Langley95c29f32014-06-20 12:00:00 -07001022}
1023
David Benjamin44b33bc2016-07-01 22:40:23 -04001024func (m *serverExtensions) unmarshal(data []byte, version uint16) bool {
Nick Harperb3d51be2016-07-01 11:43:18 -04001025 // Reset all fields.
1026 *m = serverExtensions{}
Adam Langley95c29f32014-06-20 12:00:00 -07001027
1028 for len(data) != 0 {
1029 if len(data) < 4 {
1030 return false
1031 }
1032 extension := uint16(data[0])<<8 | uint16(data[1])
1033 length := int(data[2])<<8 | int(data[3])
1034 data = data[4:]
1035 if len(data) < length {
1036 return false
1037 }
1038
1039 switch extension {
1040 case extensionNextProtoNeg:
1041 m.nextProtoNeg = true
1042 d := data[:length]
1043 for len(d) > 0 {
1044 l := int(d[0])
1045 d = d[1:]
1046 if l == 0 || l > len(d) {
1047 return false
1048 }
1049 m.nextProtos = append(m.nextProtos, string(d[:l]))
1050 d = d[l:]
1051 }
1052 case extensionStatusRequest:
David Benjamin8d315d72016-07-18 01:03:18 +02001053 if version >= VersionTLS13 {
David Benjamin44b33bc2016-07-01 22:40:23 -04001054 if length < 4 {
1055 return false
1056 }
1057 d := data[:length]
1058 if d[0] != statusTypeOCSP {
1059 return false
1060 }
1061 respLen := int(d[1])<<16 | int(d[2])<<8 | int(d[3])
1062 if respLen+4 != len(d) || respLen == 0 {
1063 return false
1064 }
1065 m.ocspResponse = d[4:]
1066 } else {
1067 if length > 0 {
1068 return false
1069 }
1070 m.ocspStapling = true
Adam Langley95c29f32014-06-20 12:00:00 -07001071 }
Adam Langley95c29f32014-06-20 12:00:00 -07001072 case extensionSessionTicket:
1073 if length > 0 {
1074 return false
1075 }
1076 m.ticketSupported = true
1077 case extensionRenegotiationInfo:
Adam Langley2ae77d22014-10-28 17:29:33 -07001078 if length < 1 || length != int(data[0])+1 {
Adam Langley95c29f32014-06-20 12:00:00 -07001079 return false
1080 }
Adam Langley2ae77d22014-10-28 17:29:33 -07001081 m.secureRenegotiation = data[1:length]
David Benjaminfa055a22014-09-15 16:51:51 -04001082 case extensionALPN:
1083 d := data[:length]
1084 if len(d) < 3 {
1085 return false
1086 }
1087 l := int(d[0])<<8 | int(d[1])
1088 if l != len(d)-2 {
1089 return false
1090 }
1091 d = d[2:]
1092 l = int(d[0])
1093 if l != len(d)-1 {
1094 return false
1095 }
1096 d = d[1:]
1097 m.alpnProtocol = string(d)
Adam Langleyefb0e162015-07-09 11:35:04 -07001098 m.alpnProtocolEmpty = len(d) == 0
David Benjamind30a9902014-08-24 01:44:23 -04001099 case extensionChannelID:
1100 if length > 0 {
1101 return false
1102 }
1103 m.channelIDRequested = true
Adam Langley75712922014-10-10 16:23:43 -07001104 case extensionExtendedMasterSecret:
1105 if length != 0 {
1106 return false
1107 }
1108 m.extendedMasterSecret = true
David Benjaminca6c8262014-11-15 19:06:08 -05001109 case extensionUseSRTP:
1110 if length < 2+2+1 {
1111 return false
1112 }
1113 if data[0] != 0 || data[1] != 2 {
1114 return false
1115 }
1116 m.srtpProtectionProfile = uint16(data[2])<<8 | uint16(data[3])
1117 d := data[4:length]
1118 l := int(d[0])
1119 if l != len(d)-1 {
1120 return false
1121 }
1122 m.srtpMasterKeyIdentifier = string(d[1:])
David Benjamin61f95272014-11-25 01:55:35 -05001123 case extensionSignedCertificateTimestamp:
Paul Lietar4fac72e2015-09-09 13:44:55 +01001124 m.sctList = data[:length]
Adam Langley09505632015-07-30 18:10:13 -07001125 case extensionCustom:
1126 m.customExtension = string(data[:length])
David Benjamin46f94bd2016-07-14 16:43:37 -04001127 case extensionServerName:
1128 if length != 0 {
1129 return false
1130 }
1131 // Ignore this extension from the server.
1132 case extensionSupportedPoints:
1133 // supported_points is illegal in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001134 if version >= VersionTLS13 {
David Benjamin46f94bd2016-07-14 16:43:37 -04001135 return false
1136 }
1137 // Ignore this extension from the server.
David Benjamin4ee027f2016-07-17 12:34:41 +02001138 case extensionSupportedCurves:
1139 // The server can only send supported_curves in TLS 1.3.
David Benjamin8d315d72016-07-18 01:03:18 +02001140 if version < VersionTLS13 {
David Benjamin4ee027f2016-07-17 12:34:41 +02001141 return false
1142 }
David Benjamin46f94bd2016-07-14 16:43:37 -04001143 default:
1144 // Unknown extensions are illegal from the server.
1145 return false
Adam Langley95c29f32014-06-20 12:00:00 -07001146 }
1147 data = data[length:]
1148 }
1149
1150 return true
1151}
1152
Nick Harperdcfbc672016-07-16 17:47:31 +02001153type helloRetryRequestMsg struct {
1154 raw []byte
1155 vers uint16
1156 cipherSuite uint16
1157 selectedGroup CurveID
1158}
1159
1160func (m *helloRetryRequestMsg) marshal() []byte {
1161 if m.raw != nil {
1162 return m.raw
1163 }
1164
1165 retryRequestMsg := newByteBuilder()
1166 retryRequestMsg.addU8(typeHelloRetryRequest)
1167 retryRequest := retryRequestMsg.addU24LengthPrefixed()
1168 retryRequest.addU16(m.vers)
1169 retryRequest.addU16(m.cipherSuite)
1170 retryRequest.addU16(uint16(m.selectedGroup))
1171 // Extensions field. We have none to send.
1172 retryRequest.addU16(0)
1173
1174 m.raw = retryRequestMsg.finish()
1175 return m.raw
1176}
1177
1178func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1179 m.raw = data
1180 if len(data) < 12 {
1181 return false
1182 }
1183 m.vers = uint16(data[4])<<8 | uint16(data[5])
1184 m.cipherSuite = uint16(data[6])<<8 | uint16(data[7])
1185 m.selectedGroup = CurveID(data[8])<<8 | CurveID(data[9])
1186 extLen := int(data[10])<<8 | int(data[11])
1187 data = data[12:]
1188 if len(data) != extLen {
1189 return false
1190 }
1191 return true
1192}
1193
Adam Langley95c29f32014-06-20 12:00:00 -07001194type certificateMsg struct {
Nick Harperb41d2e42016-07-01 17:50:32 -04001195 raw []byte
1196 hasRequestContext bool
1197 requestContext []byte
1198 certificates [][]byte
Adam Langley95c29f32014-06-20 12:00:00 -07001199}
1200
Adam Langley95c29f32014-06-20 12:00:00 -07001201func (m *certificateMsg) marshal() (x []byte) {
1202 if m.raw != nil {
1203 return m.raw
1204 }
1205
Nick Harper7e0442a2016-07-01 17:40:09 -04001206 certMsg := newByteBuilder()
1207 certMsg.addU8(typeCertificate)
1208 certificate := certMsg.addU24LengthPrefixed()
Nick Harperb41d2e42016-07-01 17:50:32 -04001209 if m.hasRequestContext {
1210 context := certificate.addU8LengthPrefixed()
1211 context.addBytes(m.requestContext)
1212 }
Nick Harper7e0442a2016-07-01 17:40:09 -04001213 certificateList := certificate.addU24LengthPrefixed()
1214 for _, cert := range m.certificates {
1215 certEntry := certificateList.addU24LengthPrefixed()
1216 certEntry.addBytes(cert)
Adam Langley95c29f32014-06-20 12:00:00 -07001217 }
1218
Nick Harper7e0442a2016-07-01 17:40:09 -04001219 m.raw = certMsg.finish()
1220 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001221}
1222
1223func (m *certificateMsg) unmarshal(data []byte) bool {
Nick Harperb41d2e42016-07-01 17:50:32 -04001224 if len(data) < 4 {
Adam Langley95c29f32014-06-20 12:00:00 -07001225 return false
1226 }
1227
1228 m.raw = data
Nick Harperb41d2e42016-07-01 17:50:32 -04001229 data = data[4:]
1230
1231 if m.hasRequestContext {
1232 if len(data) == 0 {
1233 return false
1234 }
1235 contextLen := int(data[0])
1236 if len(data) < 1+contextLen {
1237 return false
1238 }
1239 m.requestContext = make([]byte, contextLen)
1240 copy(m.requestContext, data[1:])
1241 data = data[1+contextLen:]
1242 }
1243
1244 if len(data) < 3 {
1245 return false
1246 }
1247 certsLen := int(data[0])<<16 | int(data[1])<<8 | int(data[2])
1248 data = data[3:]
1249 if len(data) != certsLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001250 return false
1251 }
1252
1253 numCerts := 0
Nick Harperb41d2e42016-07-01 17:50:32 -04001254 d := data
Adam Langley95c29f32014-06-20 12:00:00 -07001255 for certsLen > 0 {
1256 if len(d) < 4 {
1257 return false
1258 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001259 certLen := int(d[0])<<16 | int(d[1])<<8 | int(d[2])
1260 if len(d) < 3+certLen {
Adam Langley95c29f32014-06-20 12:00:00 -07001261 return false
1262 }
1263 d = d[3+certLen:]
1264 certsLen -= 3 + certLen
1265 numCerts++
1266 }
1267
1268 m.certificates = make([][]byte, numCerts)
Nick Harperb41d2e42016-07-01 17:50:32 -04001269 d = data
Adam Langley95c29f32014-06-20 12:00:00 -07001270 for i := 0; i < numCerts; i++ {
1271 certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
1272 m.certificates[i] = d[3 : 3+certLen]
1273 d = d[3+certLen:]
1274 }
1275
1276 return true
1277}
1278
1279type serverKeyExchangeMsg struct {
1280 raw []byte
1281 key []byte
1282}
1283
Adam Langley95c29f32014-06-20 12:00:00 -07001284func (m *serverKeyExchangeMsg) marshal() []byte {
1285 if m.raw != nil {
1286 return m.raw
1287 }
1288 length := len(m.key)
1289 x := make([]byte, length+4)
1290 x[0] = typeServerKeyExchange
1291 x[1] = uint8(length >> 16)
1292 x[2] = uint8(length >> 8)
1293 x[3] = uint8(length)
1294 copy(x[4:], m.key)
1295
1296 m.raw = x
1297 return x
1298}
1299
1300func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1301 m.raw = data
1302 if len(data) < 4 {
1303 return false
1304 }
1305 m.key = data[4:]
1306 return true
1307}
1308
1309type certificateStatusMsg struct {
1310 raw []byte
1311 statusType uint8
1312 response []byte
1313}
1314
Adam Langley95c29f32014-06-20 12:00:00 -07001315func (m *certificateStatusMsg) marshal() []byte {
1316 if m.raw != nil {
1317 return m.raw
1318 }
1319
1320 var x []byte
1321 if m.statusType == statusTypeOCSP {
1322 x = make([]byte, 4+4+len(m.response))
1323 x[0] = typeCertificateStatus
1324 l := len(m.response) + 4
1325 x[1] = byte(l >> 16)
1326 x[2] = byte(l >> 8)
1327 x[3] = byte(l)
1328 x[4] = statusTypeOCSP
1329
1330 l -= 4
1331 x[5] = byte(l >> 16)
1332 x[6] = byte(l >> 8)
1333 x[7] = byte(l)
1334 copy(x[8:], m.response)
1335 } else {
1336 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1337 }
1338
1339 m.raw = x
1340 return x
1341}
1342
1343func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1344 m.raw = data
1345 if len(data) < 5 {
1346 return false
1347 }
1348 m.statusType = data[4]
1349
1350 m.response = nil
1351 if m.statusType == statusTypeOCSP {
1352 if len(data) < 8 {
1353 return false
1354 }
1355 respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1356 if uint32(len(data)) != 4+4+respLen {
1357 return false
1358 }
1359 m.response = data[8:]
1360 }
1361 return true
1362}
1363
1364type serverHelloDoneMsg struct{}
1365
Adam Langley95c29f32014-06-20 12:00:00 -07001366func (m *serverHelloDoneMsg) marshal() []byte {
1367 x := make([]byte, 4)
1368 x[0] = typeServerHelloDone
1369 return x
1370}
1371
1372func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1373 return len(data) == 4
1374}
1375
1376type clientKeyExchangeMsg struct {
1377 raw []byte
1378 ciphertext []byte
1379}
1380
Adam Langley95c29f32014-06-20 12:00:00 -07001381func (m *clientKeyExchangeMsg) marshal() []byte {
1382 if m.raw != nil {
1383 return m.raw
1384 }
1385 length := len(m.ciphertext)
1386 x := make([]byte, length+4)
1387 x[0] = typeClientKeyExchange
1388 x[1] = uint8(length >> 16)
1389 x[2] = uint8(length >> 8)
1390 x[3] = uint8(length)
1391 copy(x[4:], m.ciphertext)
1392
1393 m.raw = x
1394 return x
1395}
1396
1397func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1398 m.raw = data
1399 if len(data) < 4 {
1400 return false
1401 }
1402 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1403 if l != len(data)-4 {
1404 return false
1405 }
1406 m.ciphertext = data[4:]
1407 return true
1408}
1409
1410type finishedMsg struct {
1411 raw []byte
1412 verifyData []byte
1413}
1414
Adam Langley95c29f32014-06-20 12:00:00 -07001415func (m *finishedMsg) marshal() (x []byte) {
1416 if m.raw != nil {
1417 return m.raw
1418 }
1419
1420 x = make([]byte, 4+len(m.verifyData))
1421 x[0] = typeFinished
1422 x[3] = byte(len(m.verifyData))
1423 copy(x[4:], m.verifyData)
1424 m.raw = x
1425 return
1426}
1427
1428func (m *finishedMsg) unmarshal(data []byte) bool {
1429 m.raw = data
1430 if len(data) < 4 {
1431 return false
1432 }
1433 m.verifyData = data[4:]
1434 return true
1435}
1436
1437type nextProtoMsg struct {
1438 raw []byte
1439 proto string
1440}
1441
Adam Langley95c29f32014-06-20 12:00:00 -07001442func (m *nextProtoMsg) marshal() []byte {
1443 if m.raw != nil {
1444 return m.raw
1445 }
1446 l := len(m.proto)
1447 if l > 255 {
1448 l = 255
1449 }
1450
1451 padding := 32 - (l+2)%32
1452 length := l + padding + 2
1453 x := make([]byte, length+4)
1454 x[0] = typeNextProtocol
1455 x[1] = uint8(length >> 16)
1456 x[2] = uint8(length >> 8)
1457 x[3] = uint8(length)
1458
1459 y := x[4:]
1460 y[0] = byte(l)
1461 copy(y[1:], []byte(m.proto[0:l]))
1462 y = y[1+l:]
1463 y[0] = byte(padding)
1464
1465 m.raw = x
1466
1467 return x
1468}
1469
1470func (m *nextProtoMsg) unmarshal(data []byte) bool {
1471 m.raw = data
1472
1473 if len(data) < 5 {
1474 return false
1475 }
1476 data = data[4:]
1477 protoLen := int(data[0])
1478 data = data[1:]
1479 if len(data) < protoLen {
1480 return false
1481 }
1482 m.proto = string(data[0:protoLen])
1483 data = data[protoLen:]
1484
1485 if len(data) < 1 {
1486 return false
1487 }
1488 paddingLen := int(data[0])
1489 data = data[1:]
1490 if len(data) != paddingLen {
1491 return false
1492 }
1493
1494 return true
1495}
1496
1497type certificateRequestMsg struct {
1498 raw []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001499 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langley95c29f32014-06-20 12:00:00 -07001500 // of signature and hash functions. This change was introduced with TLS
1501 // 1.2.
Nick Harper60edffd2016-06-21 15:19:24 -07001502 hasSignatureAlgorithm bool
Nick Harperb41d2e42016-07-01 17:50:32 -04001503 // hasRequestContext indicates whether this message includes a context
1504 // field instead of certificateTypes. This change was introduced with
1505 // TLS 1.3.
1506 hasRequestContext bool
Adam Langley95c29f32014-06-20 12:00:00 -07001507
1508 certificateTypes []byte
Nick Harperb41d2e42016-07-01 17:50:32 -04001509 requestContext []byte
Nick Harper60edffd2016-06-21 15:19:24 -07001510 signatureAlgorithms []signatureAlgorithm
Adam Langley95c29f32014-06-20 12:00:00 -07001511 certificateAuthorities [][]byte
1512}
1513
Nick Harper7e0442a2016-07-01 17:40:09 -04001514func (m *certificateRequestMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001515 if m.raw != nil {
1516 return m.raw
1517 }
1518
1519 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
Nick Harper7e0442a2016-07-01 17:40:09 -04001520 builder := newByteBuilder()
1521 builder.addU8(typeCertificateRequest)
1522 body := builder.addU24LengthPrefixed()
1523
Nick Harperb41d2e42016-07-01 17:50:32 -04001524 if m.hasRequestContext {
1525 requestContext := body.addU8LengthPrefixed()
1526 requestContext.addBytes(m.requestContext)
1527 } else {
1528 certificateTypes := body.addU8LengthPrefixed()
1529 certificateTypes.addBytes(m.certificateTypes)
1530 }
Adam Langley95c29f32014-06-20 12:00:00 -07001531
Nick Harper60edffd2016-06-21 15:19:24 -07001532 if m.hasSignatureAlgorithm {
Nick Harper7e0442a2016-07-01 17:40:09 -04001533 signatureAlgorithms := body.addU16LengthPrefixed()
Nick Harper60edffd2016-06-21 15:19:24 -07001534 for _, sigAlg := range m.signatureAlgorithms {
Nick Harper7e0442a2016-07-01 17:40:09 -04001535 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langley95c29f32014-06-20 12:00:00 -07001536 }
1537 }
1538
Nick Harper7e0442a2016-07-01 17:40:09 -04001539 certificateAuthorities := body.addU16LengthPrefixed()
Adam Langley95c29f32014-06-20 12:00:00 -07001540 for _, ca := range m.certificateAuthorities {
Nick Harper7e0442a2016-07-01 17:40:09 -04001541 caEntry := certificateAuthorities.addU16LengthPrefixed()
1542 caEntry.addBytes(ca)
Adam Langley95c29f32014-06-20 12:00:00 -07001543 }
1544
David Benjamin8d343b42016-07-09 14:26:01 -07001545 if m.hasRequestContext {
1546 // Emit no certificate extensions.
1547 body.addU16(0)
1548 }
1549
Nick Harper7e0442a2016-07-01 17:40:09 -04001550 m.raw = builder.finish()
1551 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001552}
1553
1554func (m *certificateRequestMsg) unmarshal(data []byte) bool {
1555 m.raw = data
1556
1557 if len(data) < 5 {
1558 return false
1559 }
Nick Harperb41d2e42016-07-01 17:50:32 -04001560 data = data[4:]
Adam Langley95c29f32014-06-20 12:00:00 -07001561
Nick Harperb41d2e42016-07-01 17:50:32 -04001562 if m.hasRequestContext {
1563 contextLen := int(data[0])
1564 if len(data) < 1+contextLen {
1565 return false
1566 }
1567 m.requestContext = make([]byte, contextLen)
1568 copy(m.requestContext, data[1:])
1569 data = data[1+contextLen:]
1570 } else {
1571 numCertTypes := int(data[0])
1572 if len(data) < 1+numCertTypes {
1573 return false
1574 }
1575 m.certificateTypes = make([]byte, numCertTypes)
1576 copy(m.certificateTypes, data[1:])
1577 data = data[1+numCertTypes:]
Adam Langley95c29f32014-06-20 12:00:00 -07001578 }
1579
Nick Harper60edffd2016-06-21 15:19:24 -07001580 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001581 if len(data) < 2 {
1582 return false
1583 }
Nick Harper60edffd2016-06-21 15:19:24 -07001584 sigAlgsLen := uint16(data[0])<<8 | uint16(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001585 data = data[2:]
Nick Harper60edffd2016-06-21 15:19:24 -07001586 if sigAlgsLen&1 != 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001587 return false
1588 }
Nick Harper60edffd2016-06-21 15:19:24 -07001589 if len(data) < int(sigAlgsLen) {
Adam Langley95c29f32014-06-20 12:00:00 -07001590 return false
1591 }
Nick Harper60edffd2016-06-21 15:19:24 -07001592 numSigAlgs := sigAlgsLen / 2
1593 m.signatureAlgorithms = make([]signatureAlgorithm, numSigAlgs)
1594 for i := range m.signatureAlgorithms {
1595 m.signatureAlgorithms[i] = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001596 data = data[2:]
1597 }
1598 }
1599
1600 if len(data) < 2 {
1601 return false
1602 }
1603 casLength := uint16(data[0])<<8 | uint16(data[1])
1604 data = data[2:]
1605 if len(data) < int(casLength) {
1606 return false
1607 }
1608 cas := make([]byte, casLength)
1609 copy(cas, data)
1610 data = data[casLength:]
1611
1612 m.certificateAuthorities = nil
1613 for len(cas) > 0 {
1614 if len(cas) < 2 {
1615 return false
1616 }
1617 caLen := uint16(cas[0])<<8 | uint16(cas[1])
1618 cas = cas[2:]
1619
1620 if len(cas) < int(caLen) {
1621 return false
1622 }
1623
1624 m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
1625 cas = cas[caLen:]
1626 }
David Benjamin8d343b42016-07-09 14:26:01 -07001627
1628 if m.hasRequestContext {
1629 // Ignore certificate extensions.
1630 if len(data) < 2 {
1631 return false
1632 }
1633 extsLength := int(data[0])<<8 | int(data[1])
1634 if len(data) < 2+extsLength {
1635 return false
1636 }
1637 data = data[2+extsLength:]
1638 }
1639
Adam Langley95c29f32014-06-20 12:00:00 -07001640 if len(data) > 0 {
1641 return false
1642 }
1643
1644 return true
1645}
1646
1647type certificateVerifyMsg struct {
Nick Harper60edffd2016-06-21 15:19:24 -07001648 raw []byte
1649 hasSignatureAlgorithm bool
1650 signatureAlgorithm signatureAlgorithm
1651 signature []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001652}
1653
Adam Langley95c29f32014-06-20 12:00:00 -07001654func (m *certificateVerifyMsg) marshal() (x []byte) {
1655 if m.raw != nil {
1656 return m.raw
1657 }
1658
1659 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
1660 siglength := len(m.signature)
1661 length := 2 + siglength
Nick Harper60edffd2016-06-21 15:19:24 -07001662 if m.hasSignatureAlgorithm {
Adam Langley95c29f32014-06-20 12:00:00 -07001663 length += 2
1664 }
1665 x = make([]byte, 4+length)
1666 x[0] = typeCertificateVerify
1667 x[1] = uint8(length >> 16)
1668 x[2] = uint8(length >> 8)
1669 x[3] = uint8(length)
1670 y := x[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001671 if m.hasSignatureAlgorithm {
1672 y[0] = byte(m.signatureAlgorithm >> 8)
1673 y[1] = byte(m.signatureAlgorithm)
Adam Langley95c29f32014-06-20 12:00:00 -07001674 y = y[2:]
1675 }
1676 y[0] = uint8(siglength >> 8)
1677 y[1] = uint8(siglength)
1678 copy(y[2:], m.signature)
1679
1680 m.raw = x
1681
1682 return
1683}
1684
1685func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
1686 m.raw = data
1687
1688 if len(data) < 6 {
1689 return false
1690 }
1691
1692 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1693 if uint32(len(data))-4 != length {
1694 return false
1695 }
1696
1697 data = data[4:]
Nick Harper60edffd2016-06-21 15:19:24 -07001698 if m.hasSignatureAlgorithm {
1699 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langley95c29f32014-06-20 12:00:00 -07001700 data = data[2:]
1701 }
1702
1703 if len(data) < 2 {
1704 return false
1705 }
1706 siglength := int(data[0])<<8 + int(data[1])
1707 data = data[2:]
1708 if len(data) != siglength {
1709 return false
1710 }
1711
1712 m.signature = data
1713
1714 return true
1715}
1716
1717type newSessionTicketMsg struct {
David Benjamin58104882016-07-18 01:25:41 +02001718 raw []byte
1719 version uint16
1720 ticketLifetime uint32
1721 ticketFlags uint32
1722 ticketAgeAdd uint32
1723 ticket []byte
Adam Langley95c29f32014-06-20 12:00:00 -07001724}
1725
David Benjamin58104882016-07-18 01:25:41 +02001726func (m *newSessionTicketMsg) marshal() []byte {
Adam Langley95c29f32014-06-20 12:00:00 -07001727 if m.raw != nil {
1728 return m.raw
1729 }
1730
1731 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjamin58104882016-07-18 01:25:41 +02001732 ticketMsg := newByteBuilder()
1733 ticketMsg.addU8(typeNewSessionTicket)
1734 body := ticketMsg.addU24LengthPrefixed()
1735 body.addU32(m.ticketLifetime)
1736 if m.version >= VersionTLS13 {
1737 body.addU32(m.ticketFlags)
1738 body.addU32(m.ticketAgeAdd)
1739 // Send no extensions.
1740 //
1741 // TODO(davidben): Add an option to send a custom extension to
1742 // test we correctly ignore unknown ones.
1743 body.addU16(0)
1744 }
1745 ticket := body.addU16LengthPrefixed()
1746 ticket.addBytes(m.ticket)
Adam Langley95c29f32014-06-20 12:00:00 -07001747
David Benjamin58104882016-07-18 01:25:41 +02001748 m.raw = ticketMsg.finish()
1749 return m.raw
Adam Langley95c29f32014-06-20 12:00:00 -07001750}
1751
1752func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
1753 m.raw = data
1754
David Benjamin58104882016-07-18 01:25:41 +02001755 if len(data) < 8 {
1756 return false
1757 }
1758 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1759 data = data[8:]
1760
1761 if m.version >= VersionTLS13 {
1762 if len(data) < 10 {
1763 return false
1764 }
1765 m.ticketFlags = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
1766 m.ticketAgeAdd = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
1767 extsLength := int(data[8])<<8 + int(data[9])
1768 data = data[10:]
1769 if len(data) < extsLength {
1770 return false
1771 }
1772 data = data[extsLength:]
1773 }
1774
1775 if len(data) < 2 {
1776 return false
1777 }
1778 ticketLen := int(data[0])<<8 + int(data[1])
1779 if len(data)-2 != ticketLen {
1780 return false
1781 }
1782 if m.version >= VersionTLS13 && ticketLen == 0 {
Adam Langley95c29f32014-06-20 12:00:00 -07001783 return false
1784 }
1785
David Benjamin58104882016-07-18 01:25:41 +02001786 m.ticket = data[2:]
Adam Langley95c29f32014-06-20 12:00:00 -07001787
1788 return true
1789}
1790
David Benjamind86c7672014-08-02 04:07:12 -04001791type v2ClientHelloMsg struct {
1792 raw []byte
1793 vers uint16
1794 cipherSuites []uint16
1795 sessionId []byte
1796 challenge []byte
1797}
1798
David Benjamind86c7672014-08-02 04:07:12 -04001799func (m *v2ClientHelloMsg) marshal() []byte {
1800 if m.raw != nil {
1801 return m.raw
1802 }
1803
1804 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
1805
1806 x := make([]byte, length)
1807 x[0] = 1
1808 x[1] = uint8(m.vers >> 8)
1809 x[2] = uint8(m.vers)
1810 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
1811 x[4] = uint8(len(m.cipherSuites) * 3)
1812 x[5] = uint8(len(m.sessionId) >> 8)
1813 x[6] = uint8(len(m.sessionId))
1814 x[7] = uint8(len(m.challenge) >> 8)
1815 x[8] = uint8(len(m.challenge))
1816 y := x[9:]
1817 for i, spec := range m.cipherSuites {
1818 y[i*3] = 0
1819 y[i*3+1] = uint8(spec >> 8)
1820 y[i*3+2] = uint8(spec)
1821 }
1822 y = y[len(m.cipherSuites)*3:]
1823 copy(y, m.sessionId)
1824 y = y[len(m.sessionId):]
1825 copy(y, m.challenge)
1826
1827 m.raw = x
1828
1829 return x
1830}
1831
David Benjamin83c0bc92014-08-04 01:23:53 -04001832type helloVerifyRequestMsg struct {
1833 raw []byte
1834 vers uint16
1835 cookie []byte
1836}
1837
David Benjamin83c0bc92014-08-04 01:23:53 -04001838func (m *helloVerifyRequestMsg) marshal() []byte {
1839 if m.raw != nil {
1840 return m.raw
1841 }
1842
1843 length := 2 + 1 + len(m.cookie)
1844
1845 x := make([]byte, 4+length)
1846 x[0] = typeHelloVerifyRequest
1847 x[1] = uint8(length >> 16)
1848 x[2] = uint8(length >> 8)
1849 x[3] = uint8(length)
1850 vers := versionToWire(m.vers, true)
1851 x[4] = uint8(vers >> 8)
1852 x[5] = uint8(vers)
1853 x[6] = uint8(len(m.cookie))
1854 copy(x[7:7+len(m.cookie)], m.cookie)
1855
1856 return x
1857}
1858
1859func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
1860 if len(data) < 4+2+1 {
1861 return false
1862 }
1863 m.raw = data
1864 m.vers = wireToVersion(uint16(data[4])<<8|uint16(data[5]), true)
1865 cookieLen := int(data[6])
1866 if cookieLen > 32 || len(data) != 7+cookieLen {
1867 return false
1868 }
1869 m.cookie = data[7 : 7+cookieLen]
1870
1871 return true
1872}
1873
David Benjamin24599a82016-06-30 18:56:53 -04001874type channelIDMsg struct {
David Benjamind30a9902014-08-24 01:44:23 -04001875 raw []byte
1876 channelID []byte
1877}
1878
David Benjamin24599a82016-06-30 18:56:53 -04001879func (m *channelIDMsg) marshal() []byte {
David Benjamind30a9902014-08-24 01:44:23 -04001880 if m.raw != nil {
1881 return m.raw
1882 }
1883
1884 length := 2 + 2 + len(m.channelID)
1885
1886 x := make([]byte, 4+length)
David Benjamin24599a82016-06-30 18:56:53 -04001887 x[0] = typeChannelID
David Benjamind30a9902014-08-24 01:44:23 -04001888 x[1] = uint8(length >> 16)
1889 x[2] = uint8(length >> 8)
1890 x[3] = uint8(length)
1891 x[4] = uint8(extensionChannelID >> 8)
1892 x[5] = uint8(extensionChannelID & 0xff)
1893 x[6] = uint8(len(m.channelID) >> 8)
1894 x[7] = uint8(len(m.channelID) & 0xff)
1895 copy(x[8:], m.channelID)
1896
1897 return x
1898}
1899
David Benjamin24599a82016-06-30 18:56:53 -04001900func (m *channelIDMsg) unmarshal(data []byte) bool {
David Benjamind30a9902014-08-24 01:44:23 -04001901 if len(data) != 4+2+2+128 {
1902 return false
1903 }
1904 m.raw = data
1905 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
1906 return false
1907 }
1908 if int(data[6])<<8|int(data[7]) != 128 {
1909 return false
1910 }
1911 m.channelID = data[4+2+2:]
1912
1913 return true
1914}
1915
Adam Langley2ae77d22014-10-28 17:29:33 -07001916type helloRequestMsg struct {
1917}
1918
1919func (*helloRequestMsg) marshal() []byte {
1920 return []byte{typeHelloRequest, 0, 0, 0}
1921}
1922
1923func (*helloRequestMsg) unmarshal(data []byte) bool {
1924 return len(data) == 4
1925}
1926
David Benjamin21c00282016-07-18 21:56:23 +02001927type keyUpdateMsg struct {
1928}
1929
1930func (*keyUpdateMsg) marshal() []byte {
1931 return []byte{typeKeyUpdate, 0, 0, 0}
1932}
1933
1934func (*keyUpdateMsg) unmarshal(data []byte) bool {
1935 return len(data) == 4
1936}
1937
Adam Langley95c29f32014-06-20 12:00:00 -07001938func eqUint16s(x, y []uint16) bool {
1939 if len(x) != len(y) {
1940 return false
1941 }
1942 for i, v := range x {
1943 if y[i] != v {
1944 return false
1945 }
1946 }
1947 return true
1948}
1949
1950func eqCurveIDs(x, y []CurveID) bool {
1951 if len(x) != len(y) {
1952 return false
1953 }
1954 for i, v := range x {
1955 if y[i] != v {
1956 return false
1957 }
1958 }
1959 return true
1960}
1961
1962func eqStrings(x, y []string) bool {
1963 if len(x) != len(y) {
1964 return false
1965 }
1966 for i, v := range x {
1967 if y[i] != v {
1968 return false
1969 }
1970 }
1971 return true
1972}
1973
1974func eqByteSlices(x, y [][]byte) bool {
1975 if len(x) != len(y) {
1976 return false
1977 }
1978 for i, v := range x {
1979 if !bytes.Equal(v, y[i]) {
1980 return false
1981 }
1982 }
1983 return true
1984}
1985
Nick Harper60edffd2016-06-21 15:19:24 -07001986func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langley95c29f32014-06-20 12:00:00 -07001987 if len(x) != len(y) {
1988 return false
1989 }
1990 for i, v := range x {
1991 v2 := y[i]
Nick Harper60edffd2016-06-21 15:19:24 -07001992 if v != v2 {
Adam Langley95c29f32014-06-20 12:00:00 -07001993 return false
1994 }
1995 }
1996 return true
1997}
Nick Harperf8b0e702016-06-30 19:59:01 -04001998
1999func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2000 if len(x) != len(y) {
2001 return false
2002 }
2003 for i, v := range x {
2004 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2005 return false
2006 }
2007 }
2008 return true
2009
2010}