blob: ac52eed476f36684692fb470c8c27abeb9af51ce [file] [log] [blame]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001// 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
Kenny Roote99801b2015-11-06 15:31:15 -08005package runner
Adam Langleyd9e397b2015-01-22 14:27:53 -08006
David Benjaminc895d6b2016-08-11 13:26:41 -04007import (
8 "bytes"
9 "encoding/binary"
Robert Sloana12bf462017-07-17 07:08:26 -070010 "fmt"
David Benjaminc895d6b2016-08-11 13:26:41 -040011)
12
13func writeLen(buf []byte, v, size int) {
14 for i := 0; i < size; i++ {
15 buf[size-i-1] = byte(v)
16 v >>= 8
17 }
18 if v != 0 {
19 panic("length is too long")
20 }
21}
22
23type byteBuilder struct {
24 buf *[]byte
25 start int
26 prefixLen int
27 child *byteBuilder
28}
29
30func newByteBuilder() *byteBuilder {
31 buf := make([]byte, 0, 32)
32 return &byteBuilder{buf: &buf}
33}
34
35func (bb *byteBuilder) len() int {
36 return len(*bb.buf) - bb.start - bb.prefixLen
37}
38
Robert Sloana12bf462017-07-17 07:08:26 -070039func (bb *byteBuilder) data() []byte {
40 bb.flush()
41 return (*bb.buf)[bb.start+bb.prefixLen:]
42}
43
David Benjaminc895d6b2016-08-11 13:26:41 -040044func (bb *byteBuilder) flush() {
45 if bb.child == nil {
46 return
47 }
48 bb.child.flush()
49 writeLen((*bb.buf)[bb.child.start:], bb.child.len(), bb.child.prefixLen)
50 bb.child = nil
51 return
52}
53
54func (bb *byteBuilder) finish() []byte {
55 bb.flush()
56 return *bb.buf
57}
58
59func (bb *byteBuilder) addU8(u uint8) {
60 bb.flush()
61 *bb.buf = append(*bb.buf, u)
62}
63
64func (bb *byteBuilder) addU16(u uint16) {
65 bb.flush()
66 *bb.buf = append(*bb.buf, byte(u>>8), byte(u))
67}
68
69func (bb *byteBuilder) addU24(u int) {
70 bb.flush()
71 *bb.buf = append(*bb.buf, byte(u>>16), byte(u>>8), byte(u))
72}
73
74func (bb *byteBuilder) addU32(u uint32) {
75 bb.flush()
76 *bb.buf = append(*bb.buf, byte(u>>24), byte(u>>16), byte(u>>8), byte(u))
77}
78
79func (bb *byteBuilder) addU64(u uint64) {
80 bb.flush()
81 var b [8]byte
82 binary.BigEndian.PutUint64(b[:], u)
83 *bb.buf = append(*bb.buf, b[:]...)
84}
85
86func (bb *byteBuilder) addU8LengthPrefixed() *byteBuilder {
87 return bb.createChild(1)
88}
89
90func (bb *byteBuilder) addU16LengthPrefixed() *byteBuilder {
91 return bb.createChild(2)
92}
93
94func (bb *byteBuilder) addU24LengthPrefixed() *byteBuilder {
95 return bb.createChild(3)
96}
97
98func (bb *byteBuilder) addU32LengthPrefixed() *byteBuilder {
99 return bb.createChild(4)
100}
101
102func (bb *byteBuilder) addBytes(b []byte) {
103 bb.flush()
104 *bb.buf = append(*bb.buf, b...)
105}
106
107func (bb *byteBuilder) createChild(lengthPrefixSize int) *byteBuilder {
108 bb.flush()
109 bb.child = &byteBuilder{
110 buf: bb.buf,
111 start: len(*bb.buf),
112 prefixLen: lengthPrefixSize,
113 }
114 for i := 0; i < lengthPrefixSize; i++ {
115 *bb.buf = append(*bb.buf, 0)
116 }
117 return bb.child
118}
119
120func (bb *byteBuilder) discardChild() {
Robert Sloana12bf462017-07-17 07:08:26 -0700121 if bb.child == nil {
David Benjaminc895d6b2016-08-11 13:26:41 -0400122 return
123 }
Robert Sloana12bf462017-07-17 07:08:26 -0700124 *bb.buf = (*bb.buf)[:bb.child.start]
David Benjaminc895d6b2016-08-11 13:26:41 -0400125 bb.child = nil
David Benjaminc895d6b2016-08-11 13:26:41 -0400126}
127
Robert Sloana815d5a2017-12-04 11:49:16 -0800128type byteReader []byte
129
130func (br *byteReader) readInternal(out *byteReader, n int) bool {
131 if len(*br) < n {
132 return false
133 }
134 *out = (*br)[:n]
135 *br = (*br)[n:]
136 return true
137}
138
139func (br *byteReader) readBytes(out *[]byte, n int) bool {
140 var child byteReader
141 if !br.readInternal(&child, n) {
142 return false
143 }
144 *out = []byte(child)
145 return true
146}
147
148func (br *byteReader) readUint(out *uint64, n int) bool {
149 var b []byte
150 if !br.readBytes(&b, n) {
151 return false
152 }
153 *out = 0
154 for _, v := range b {
155 *out <<= 8
156 *out |= uint64(v)
157 }
158 return true
159}
160
161func (br *byteReader) readU8(out *uint8) bool {
162 var b []byte
163 if !br.readBytes(&b, 1) {
164 return false
165 }
166 *out = b[0]
167 return true
168}
169
170func (br *byteReader) readU16(out *uint16) bool {
171 var v uint64
172 if !br.readUint(&v, 2) {
173 return false
174 }
175 *out = uint16(v)
176 return true
177}
178
179func (br *byteReader) readU24(out *uint32) bool {
180 var v uint64
181 if !br.readUint(&v, 3) {
182 return false
183 }
184 *out = uint32(v)
185 return true
186}
187
188func (br *byteReader) readU32(out *uint32) bool {
189 var v uint64
190 if !br.readUint(&v, 4) {
191 return false
192 }
193 *out = uint32(v)
194 return true
195}
196
197func (br *byteReader) readU64(out *uint64) bool {
198 return br.readUint(out, 8)
199}
200
201func (br *byteReader) readLengthPrefixed(out *byteReader, n int) bool {
202 var length uint64
203 return br.readUint(&length, n) &&
204 uint64(len(*br)) >= length &&
205 br.readInternal(out, int(length))
206}
207
208func (br *byteReader) readLengthPrefixedBytes(out *[]byte, n int) bool {
209 var length uint64
210 return br.readUint(&length, n) &&
211 uint64(len(*br)) >= length &&
212 br.readBytes(out, int(length))
213}
214
215func (br *byteReader) readU8LengthPrefixed(out *byteReader) bool {
216 return br.readLengthPrefixed(out, 1)
217}
218func (br *byteReader) readU8LengthPrefixedBytes(out *[]byte) bool {
219 return br.readLengthPrefixedBytes(out, 1)
220}
221
222func (br *byteReader) readU16LengthPrefixed(out *byteReader) bool {
223 return br.readLengthPrefixed(out, 2)
224}
225func (br *byteReader) readU16LengthPrefixedBytes(out *[]byte) bool {
226 return br.readLengthPrefixedBytes(out, 2)
227}
228
229func (br *byteReader) readU24LengthPrefixed(out *byteReader) bool {
230 return br.readLengthPrefixed(out, 3)
231}
232func (br *byteReader) readU24LengthPrefixedBytes(out *[]byte) bool {
233 return br.readLengthPrefixedBytes(out, 3)
234}
235
236func (br *byteReader) readU32LengthPrefixed(out *byteReader) bool {
237 return br.readLengthPrefixed(out, 4)
238}
239func (br *byteReader) readU32LengthPrefixedBytes(out *[]byte) bool {
240 return br.readLengthPrefixedBytes(out, 4)
241}
242
David Benjaminc895d6b2016-08-11 13:26:41 -0400243type keyShareEntry struct {
244 group CurveID
245 keyExchange []byte
246}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800247
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400248type pskIdentity struct {
Steven Valdez909b19f2016-11-21 15:35:44 -0500249 ticket []uint8
250 obfuscatedTicketAge uint32
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400251}
252
Adam Langleyd9e397b2015-01-22 14:27:53 -0800253type clientHelloMsg struct {
David Benjamin95add822016-10-19 01:09:12 -0400254 raw []byte
255 isDTLS bool
256 vers uint16
257 random []byte
258 sessionId []byte
Adam Langleyd9e397b2015-01-22 14:27:53 -0800259 cookie []byte
260 cipherSuites []uint16
261 compressionMethods []uint8
262 nextProtoNeg bool
263 serverName string
264 ocspStapling bool
265 supportedCurves []CurveID
266 supportedPoints []uint8
David Benjaminc895d6b2016-08-11 13:26:41 -0400267 hasKeyShares bool
268 keyShares []keyShareEntry
Robert Sloanc9abfe42018-11-26 12:19:07 -0800269 keySharesRaw []byte
David Benjamin7c0d06c2016-08-11 13:26:41 -0400270 trailingKeyShareData bool
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400271 pskIdentities []pskIdentity
Steven Valdez909b19f2016-11-21 15:35:44 -0500272 pskKEModes []byte
273 pskBinders [][]uint8
David Benjaminc895d6b2016-08-11 13:26:41 -0400274 hasEarlyData bool
David Benjamin95add822016-10-19 01:09:12 -0400275 tls13Cookie []byte
Adam Langleyd9e397b2015-01-22 14:27:53 -0800276 ticketSupported bool
277 sessionTicket []uint8
David Benjaminc895d6b2016-08-11 13:26:41 -0400278 signatureAlgorithms []signatureAlgorithm
Robert Sloan5cbb5c82018-04-24 11:35:46 -0700279 signatureAlgorithmsCert []signatureAlgorithm
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400280 supportedVersions []uint16
Adam Langleyd9e397b2015-01-22 14:27:53 -0800281 secureRenegotiation []byte
282 alpnProtocols []string
Robert Sloan8542c082018-02-05 09:07:34 -0800283 quicTransportParams []byte
Adam Langleyd9e397b2015-01-22 14:27:53 -0800284 duplicateExtension bool
285 channelIDSupported bool
Robert Sloan978112c2018-01-22 12:53:01 -0800286 tokenBindingParams []byte
287 tokenBindingVersion uint16
Steven Valdez909b19f2016-11-21 15:35:44 -0500288 npnAfterAlpn bool
Adam Langleyd9e397b2015-01-22 14:27:53 -0800289 extendedMasterSecret bool
290 srtpProtectionProfiles []uint16
291 srtpMasterKeyIdentifier string
292 sctListSupported bool
Kenny Rootb8494592015-09-25 02:29:14 +0000293 customExtension string
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400294 hasGREASEExtension bool
Steven Valdez909b19f2016-11-21 15:35:44 -0500295 pskBinderFirst bool
Robert Sloana12bf462017-07-17 07:08:26 -0700296 omitExtensions bool
297 emptyExtensions bool
Robert Sloand1d118f2017-09-11 09:00:48 -0700298 pad int
Adam Vartanianbfcf3a72018-08-10 14:55:24 +0100299 compressedCertAlgs []uint16
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800300 delegatedCredentials bool
Pete Bentley0c61efe2019-08-13 09:32:23 +0100301 pqExperimentSignal bool
Adam Langleyd9e397b2015-01-22 14:27:53 -0800302}
303
304func (m *clientHelloMsg) equal(i interface{}) bool {
305 m1, ok := i.(*clientHelloMsg)
306 if !ok {
307 return false
308 }
309
310 return bytes.Equal(m.raw, m1.raw) &&
311 m.isDTLS == m1.isDTLS &&
312 m.vers == m1.vers &&
313 bytes.Equal(m.random, m1.random) &&
314 bytes.Equal(m.sessionId, m1.sessionId) &&
315 bytes.Equal(m.cookie, m1.cookie) &&
316 eqUint16s(m.cipherSuites, m1.cipherSuites) &&
317 bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
318 m.nextProtoNeg == m1.nextProtoNeg &&
319 m.serverName == m1.serverName &&
320 m.ocspStapling == m1.ocspStapling &&
321 eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
322 bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
David Benjaminc895d6b2016-08-11 13:26:41 -0400323 m.hasKeyShares == m1.hasKeyShares &&
324 eqKeyShareEntryLists(m.keyShares, m1.keyShares) &&
David Benjamin7c0d06c2016-08-11 13:26:41 -0400325 m.trailingKeyShareData == m1.trailingKeyShareData &&
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400326 eqPSKIdentityLists(m.pskIdentities, m1.pskIdentities) &&
Steven Valdez909b19f2016-11-21 15:35:44 -0500327 bytes.Equal(m.pskKEModes, m1.pskKEModes) &&
328 eqByteSlices(m.pskBinders, m1.pskBinders) &&
David Benjaminc895d6b2016-08-11 13:26:41 -0400329 m.hasEarlyData == m1.hasEarlyData &&
David Benjamin95add822016-10-19 01:09:12 -0400330 bytes.Equal(m.tls13Cookie, m1.tls13Cookie) &&
Adam Langleyd9e397b2015-01-22 14:27:53 -0800331 m.ticketSupported == m1.ticketSupported &&
332 bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
David Benjaminc895d6b2016-08-11 13:26:41 -0400333 eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
Robert Sloan5cbb5c82018-04-24 11:35:46 -0700334 eqSignatureAlgorithms(m.signatureAlgorithmsCert, m1.signatureAlgorithmsCert) &&
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400335 eqUint16s(m.supportedVersions, m1.supportedVersions) &&
Adam Langleyd9e397b2015-01-22 14:27:53 -0800336 bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
337 (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
338 eqStrings(m.alpnProtocols, m1.alpnProtocols) &&
Robert Sloan8542c082018-02-05 09:07:34 -0800339 bytes.Equal(m.quicTransportParams, m1.quicTransportParams) &&
Adam Langleyd9e397b2015-01-22 14:27:53 -0800340 m.duplicateExtension == m1.duplicateExtension &&
341 m.channelIDSupported == m1.channelIDSupported &&
Robert Sloan978112c2018-01-22 12:53:01 -0800342 bytes.Equal(m.tokenBindingParams, m1.tokenBindingParams) &&
343 m.tokenBindingVersion == m1.tokenBindingVersion &&
Steven Valdez909b19f2016-11-21 15:35:44 -0500344 m.npnAfterAlpn == m1.npnAfterAlpn &&
Adam Langleyd9e397b2015-01-22 14:27:53 -0800345 m.extendedMasterSecret == m1.extendedMasterSecret &&
346 eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
347 m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
Kenny Rootb8494592015-09-25 02:29:14 +0000348 m.sctListSupported == m1.sctListSupported &&
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400349 m.customExtension == m1.customExtension &&
Steven Valdez909b19f2016-11-21 15:35:44 -0500350 m.hasGREASEExtension == m1.hasGREASEExtension &&
Robert Sloana12bf462017-07-17 07:08:26 -0700351 m.pskBinderFirst == m1.pskBinderFirst &&
352 m.omitExtensions == m1.omitExtensions &&
Robert Sloand1d118f2017-09-11 09:00:48 -0700353 m.emptyExtensions == m1.emptyExtensions &&
Robert Sloan0db7f542018-01-16 15:48:33 -0800354 m.pad == m1.pad &&
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800355 eqUint16s(m.compressedCertAlgs, m1.compressedCertAlgs) &&
Pete Bentley0c61efe2019-08-13 09:32:23 +0100356 m.delegatedCredentials == m1.delegatedCredentials &&
357 m.pqExperimentSignal == m1.pqExperimentSignal
Adam Langleyd9e397b2015-01-22 14:27:53 -0800358}
359
Robert Sloanc9abfe42018-11-26 12:19:07 -0800360func (m *clientHelloMsg) marshalKeyShares(bb *byteBuilder) {
361 keyShares := bb.addU16LengthPrefixed()
362 for _, keyShare := range m.keyShares {
363 keyShares.addU16(uint16(keyShare.group))
364 keyExchange := keyShares.addU16LengthPrefixed()
365 keyExchange.addBytes(keyShare.keyExchange)
366 }
367 if m.trailingKeyShareData {
368 keyShares.addU8(0)
369 }
370}
371
Adam Langleyd9e397b2015-01-22 14:27:53 -0800372func (m *clientHelloMsg) marshal() []byte {
373 if m.raw != nil {
374 return m.raw
375 }
376
David Benjaminc895d6b2016-08-11 13:26:41 -0400377 handshakeMsg := newByteBuilder()
378 handshakeMsg.addU8(typeClientHello)
379 hello := handshakeMsg.addU24LengthPrefixed()
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400380 hello.addU16(m.vers)
David Benjaminc895d6b2016-08-11 13:26:41 -0400381 hello.addBytes(m.random)
382 sessionId := hello.addU8LengthPrefixed()
383 sessionId.addBytes(m.sessionId)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800384 if m.isDTLS {
David Benjaminc895d6b2016-08-11 13:26:41 -0400385 cookie := hello.addU8LengthPrefixed()
386 cookie.addBytes(m.cookie)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800387 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400388 cipherSuites := hello.addU16LengthPrefixed()
389 for _, suite := range m.cipherSuites {
390 cipherSuites.addU16(suite)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800391 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400392 compressionMethods := hello.addU8LengthPrefixed()
393 compressionMethods.addBytes(m.compressionMethods)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800394
David Benjaminc895d6b2016-08-11 13:26:41 -0400395 extensions := hello.addU16LengthPrefixed()
Steven Valdez909b19f2016-11-21 15:35:44 -0500396 if len(m.pskIdentities) > 0 && m.pskBinderFirst {
397 extensions.addU16(extensionPreSharedKey)
398 pskExtension := extensions.addU16LengthPrefixed()
399
400 pskIdentities := pskExtension.addU16LengthPrefixed()
401 for _, psk := range m.pskIdentities {
402 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
403 pskIdentities.addU32(psk.obfuscatedTicketAge)
404 }
405 pskBinders := pskExtension.addU16LengthPrefixed()
406 for _, binder := range m.pskBinders {
407 pskBinders.addU8LengthPrefixed().addBytes(binder)
408 }
409 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800410 if m.duplicateExtension {
411 // Add a duplicate bogus extension at the beginning and end.
David Benjaminc895d6b2016-08-11 13:26:41 -0400412 extensions.addU16(0xffff)
413 extensions.addU16(0) // 0-length for empty extension
Adam Langleyd9e397b2015-01-22 14:27:53 -0800414 }
Steven Valdez909b19f2016-11-21 15:35:44 -0500415 if m.nextProtoNeg && !m.npnAfterAlpn {
David Benjaminc895d6b2016-08-11 13:26:41 -0400416 extensions.addU16(extensionNextProtoNeg)
417 extensions.addU16(0) // The length is always 0
Adam Langleyd9e397b2015-01-22 14:27:53 -0800418 }
419 if len(m.serverName) > 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400420 extensions.addU16(extensionServerName)
421 serverNameList := extensions.addU16LengthPrefixed()
Adam Langleyd9e397b2015-01-22 14:27:53 -0800422
423 // RFC 3546, section 3.1
424 //
425 // struct {
426 // NameType name_type;
427 // select (name_type) {
428 // case host_name: HostName;
429 // } name;
430 // } ServerName;
431 //
432 // enum {
433 // host_name(0), (255)
434 // } NameType;
435 //
436 // opaque HostName<1..2^16-1>;
437 //
438 // struct {
439 // ServerName server_name_list<1..2^16-1>
440 // } ServerNameList;
441
David Benjaminc895d6b2016-08-11 13:26:41 -0400442 serverName := serverNameList.addU16LengthPrefixed()
443 serverName.addU8(0) // NameType host_name(0)
444 hostName := serverName.addU16LengthPrefixed()
445 hostName.addBytes([]byte(m.serverName))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800446 }
447 if m.ocspStapling {
David Benjaminc895d6b2016-08-11 13:26:41 -0400448 extensions.addU16(extensionStatusRequest)
449 certificateStatusRequest := extensions.addU16LengthPrefixed()
450
Adam Langleyd9e397b2015-01-22 14:27:53 -0800451 // RFC 4366, section 3.6
David Benjaminc895d6b2016-08-11 13:26:41 -0400452 certificateStatusRequest.addU8(1) // OCSP type
Adam Langleyd9e397b2015-01-22 14:27:53 -0800453 // Two zero valued uint16s for the two lengths.
David Benjaminc895d6b2016-08-11 13:26:41 -0400454 certificateStatusRequest.addU16(0) // ResponderID length
455 certificateStatusRequest.addU16(0) // Extensions length
Adam Langleyd9e397b2015-01-22 14:27:53 -0800456 }
Robert Sloan4562e9d2017-10-02 10:26:51 -0700457 if len(m.supportedCurves) > 0 {
458 // http://tools.ietf.org/html/rfc4492#section-5.1.1
459 extensions.addU16(extensionSupportedCurves)
460 supportedCurvesList := extensions.addU16LengthPrefixed()
461 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
462 for _, curve := range m.supportedCurves {
463 supportedCurves.addU16(uint16(curve))
464 }
465 }
466 if len(m.supportedPoints) > 0 {
467 // http://tools.ietf.org/html/rfc4492#section-5.1.2
468 extensions.addU16(extensionSupportedPoints)
469 supportedPointsList := extensions.addU16LengthPrefixed()
470 supportedPoints := supportedPointsList.addU8LengthPrefixed()
471 supportedPoints.addBytes(m.supportedPoints)
472 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400473 if m.hasKeyShares {
Robert Sloan8542c082018-02-05 09:07:34 -0800474 extensions.addU16(extensionKeyShare)
David Benjaminc895d6b2016-08-11 13:26:41 -0400475 keyShareList := extensions.addU16LengthPrefixed()
Robert Sloanc9abfe42018-11-26 12:19:07 -0800476 m.marshalKeyShares(keyShareList)
David Benjaminc895d6b2016-08-11 13:26:41 -0400477 }
Steven Valdez909b19f2016-11-21 15:35:44 -0500478 if len(m.pskKEModes) > 0 {
479 extensions.addU16(extensionPSKKeyExchangeModes)
480 pskModesExtension := extensions.addU16LengthPrefixed()
481 pskModesExtension.addU8LengthPrefixed().addBytes(m.pskKEModes)
David Benjaminc895d6b2016-08-11 13:26:41 -0400482 }
483 if m.hasEarlyData {
484 extensions.addU16(extensionEarlyData)
Steven Valdez909b19f2016-11-21 15:35:44 -0500485 extensions.addU16(0) // The length is zero.
David Benjaminc895d6b2016-08-11 13:26:41 -0400486 }
David Benjamin95add822016-10-19 01:09:12 -0400487 if len(m.tls13Cookie) > 0 {
488 extensions.addU16(extensionCookie)
489 body := extensions.addU16LengthPrefixed()
490 body.addU16LengthPrefixed().addBytes(m.tls13Cookie)
491 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800492 if m.ticketSupported {
493 // http://tools.ietf.org/html/rfc5077#section-3.2
David Benjaminc895d6b2016-08-11 13:26:41 -0400494 extensions.addU16(extensionSessionTicket)
495 sessionTicketExtension := extensions.addU16LengthPrefixed()
496 sessionTicketExtension.addBytes(m.sessionTicket)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800497 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400498 if len(m.signatureAlgorithms) > 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800499 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
David Benjaminc895d6b2016-08-11 13:26:41 -0400500 extensions.addU16(extensionSignatureAlgorithms)
501 signatureAlgorithmsExtension := extensions.addU16LengthPrefixed()
502 signatureAlgorithms := signatureAlgorithmsExtension.addU16LengthPrefixed()
503 for _, sigAlg := range m.signatureAlgorithms {
504 signatureAlgorithms.addU16(uint16(sigAlg))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800505 }
506 }
Robert Sloan5cbb5c82018-04-24 11:35:46 -0700507 if len(m.signatureAlgorithmsCert) > 0 {
508 extensions.addU16(extensionSignatureAlgorithmsCert)
509 signatureAlgorithmsCertExtension := extensions.addU16LengthPrefixed()
510 signatureAlgorithmsCert := signatureAlgorithmsCertExtension.addU16LengthPrefixed()
511 for _, sigAlg := range m.signatureAlgorithmsCert {
512 signatureAlgorithmsCert.addU16(uint16(sigAlg))
513 }
514 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400515 if len(m.supportedVersions) > 0 {
516 extensions.addU16(extensionSupportedVersions)
517 supportedVersionsExtension := extensions.addU16LengthPrefixed()
518 supportedVersions := supportedVersionsExtension.addU8LengthPrefixed()
519 for _, version := range m.supportedVersions {
520 supportedVersions.addU16(uint16(version))
521 }
522 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800523 if m.secureRenegotiation != nil {
David Benjaminc895d6b2016-08-11 13:26:41 -0400524 extensions.addU16(extensionRenegotiationInfo)
525 secureRenegoExt := extensions.addU16LengthPrefixed()
526 secureRenego := secureRenegoExt.addU8LengthPrefixed()
527 secureRenego.addBytes(m.secureRenegotiation)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800528 }
529 if len(m.alpnProtocols) > 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400530 // https://tools.ietf.org/html/rfc7301#section-3.1
531 extensions.addU16(extensionALPN)
532 alpnExtension := extensions.addU16LengthPrefixed()
Adam Langleyd9e397b2015-01-22 14:27:53 -0800533
David Benjaminc895d6b2016-08-11 13:26:41 -0400534 protocolNameList := alpnExtension.addU16LengthPrefixed()
Adam Langleyd9e397b2015-01-22 14:27:53 -0800535 for _, s := range m.alpnProtocols {
David Benjaminc895d6b2016-08-11 13:26:41 -0400536 protocolName := protocolNameList.addU8LengthPrefixed()
537 protocolName.addBytes([]byte(s))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800538 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800539 }
Robert Sloan8542c082018-02-05 09:07:34 -0800540 if len(m.quicTransportParams) > 0 {
541 extensions.addU16(extensionQUICTransportParams)
542 params := extensions.addU16LengthPrefixed()
543 params.addBytes(m.quicTransportParams)
544 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800545 if m.channelIDSupported {
David Benjaminc895d6b2016-08-11 13:26:41 -0400546 extensions.addU16(extensionChannelID)
547 extensions.addU16(0) // Length is always 0
Adam Langleyd9e397b2015-01-22 14:27:53 -0800548 }
Robert Sloan978112c2018-01-22 12:53:01 -0800549 if m.tokenBindingParams != nil {
550 extensions.addU16(extensionTokenBinding)
551 tokbindExtension := extensions.addU16LengthPrefixed()
552 tokbindExtension.addU16(m.tokenBindingVersion)
553 tokbindParams := tokbindExtension.addU8LengthPrefixed()
554 tokbindParams.addBytes(m.tokenBindingParams)
555 }
Steven Valdez909b19f2016-11-21 15:35:44 -0500556 if m.nextProtoNeg && m.npnAfterAlpn {
David Benjaminc895d6b2016-08-11 13:26:41 -0400557 extensions.addU16(extensionNextProtoNeg)
558 extensions.addU16(0) // Length is always 0
Adam Langleyd9e397b2015-01-22 14:27:53 -0800559 }
560 if m.duplicateExtension {
561 // Add a duplicate bogus extension at the beginning and end.
David Benjaminc895d6b2016-08-11 13:26:41 -0400562 extensions.addU16(0xffff)
563 extensions.addU16(0)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800564 }
565 if m.extendedMasterSecret {
David Benjamin4969cc92016-04-22 15:02:23 -0400566 // https://tools.ietf.org/html/rfc7627
David Benjaminc895d6b2016-08-11 13:26:41 -0400567 extensions.addU16(extensionExtendedMasterSecret)
568 extensions.addU16(0) // Length is always 0
Adam Langleyd9e397b2015-01-22 14:27:53 -0800569 }
570 if len(m.srtpProtectionProfiles) > 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400571 // https://tools.ietf.org/html/rfc5764#section-4.1.1
572 extensions.addU16(extensionUseSRTP)
573 useSrtpExt := extensions.addU16LengthPrefixed()
Adam Langleyd9e397b2015-01-22 14:27:53 -0800574
David Benjaminc895d6b2016-08-11 13:26:41 -0400575 srtpProtectionProfiles := useSrtpExt.addU16LengthPrefixed()
Adam Langleyd9e397b2015-01-22 14:27:53 -0800576 for _, p := range m.srtpProtectionProfiles {
Robert Sloana815d5a2017-12-04 11:49:16 -0800577 srtpProtectionProfiles.addU16(p)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800578 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400579 srtpMki := useSrtpExt.addU8LengthPrefixed()
580 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800581 }
582 if m.sctListSupported {
David Benjaminc895d6b2016-08-11 13:26:41 -0400583 extensions.addU16(extensionSignedCertificateTimestamp)
584 extensions.addU16(0) // Length is always 0
Adam Langleyd9e397b2015-01-22 14:27:53 -0800585 }
Kenny Rootb8494592015-09-25 02:29:14 +0000586 if l := len(m.customExtension); l > 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400587 extensions.addU16(extensionCustom)
588 customExt := extensions.addU16LengthPrefixed()
589 customExt.addBytes([]byte(m.customExtension))
590 }
Adam Vartanianbfcf3a72018-08-10 14:55:24 +0100591 if len(m.compressedCertAlgs) > 0 {
592 extensions.addU16(extensionCompressedCertAlgs)
593 body := extensions.addU16LengthPrefixed()
594 algIDs := body.addU8LengthPrefixed()
595 for _, v := range m.compressedCertAlgs {
596 algIDs.addU16(v)
597 }
598 }
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800599 if m.delegatedCredentials {
600 extensions.addU16(extensionDelegatedCredentials)
601 extensions.addU16(0) // Length is always 0
602 }
Pete Bentley0c61efe2019-08-13 09:32:23 +0100603 if m.pqExperimentSignal {
604 extensions.addU16(extensionPQExperimentSignal)
605 extensions.addU16(0) // Length is always 0
606 }
607
Robert Sloand9e572d2018-08-27 12:27:00 -0700608 // The PSK extension must be last. See https://tools.ietf.org/html/rfc8446#section-4.2.11
Steven Valdez909b19f2016-11-21 15:35:44 -0500609 if len(m.pskIdentities) > 0 && !m.pskBinderFirst {
610 extensions.addU16(extensionPreSharedKey)
611 pskExtension := extensions.addU16LengthPrefixed()
612
613 pskIdentities := pskExtension.addU16LengthPrefixed()
614 for _, psk := range m.pskIdentities {
615 pskIdentities.addU16LengthPrefixed().addBytes(psk.ticket)
616 pskIdentities.addU32(psk.obfuscatedTicketAge)
617 }
618 pskBinders := pskExtension.addU16LengthPrefixed()
619 for _, binder := range m.pskBinders {
620 pskBinders.addU8LengthPrefixed().addBytes(binder)
621 }
622 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800623
Robert Sloand1d118f2017-09-11 09:00:48 -0700624 if m.pad != 0 && hello.len()%m.pad != 0 {
625 extensions.addU16(extensionPadding)
626 padding := extensions.addU16LengthPrefixed()
627 // Note hello.len() has changed at this point from the length
628 // prefix.
629 if l := hello.len() % m.pad; l != 0 {
630 padding.addBytes(make([]byte, m.pad-l))
631 }
632 }
633
Robert Sloana12bf462017-07-17 07:08:26 -0700634 if m.omitExtensions || m.emptyExtensions {
635 // Silently erase any extensions which were sent.
David Benjaminc895d6b2016-08-11 13:26:41 -0400636 hello.discardChild()
Robert Sloana12bf462017-07-17 07:08:26 -0700637 if m.emptyExtensions {
638 hello.addU16(0)
639 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400640 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800641
David Benjaminc895d6b2016-08-11 13:26:41 -0400642 m.raw = handshakeMsg.finish()
Robert Sloand1d118f2017-09-11 09:00:48 -0700643 // Sanity-check padding.
644 if m.pad != 0 && (len(m.raw)-4)%m.pad != 0 {
645 panic(fmt.Sprintf("%d is not a multiple of %d", len(m.raw)-4, m.pad))
646 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400647 return m.raw
Adam Langleyd9e397b2015-01-22 14:27:53 -0800648}
649
Robert Sloan5cbb5c82018-04-24 11:35:46 -0700650func parseSignatureAlgorithms(reader *byteReader, out *[]signatureAlgorithm, allowEmpty bool) bool {
Robert Sloana815d5a2017-12-04 11:49:16 -0800651 var sigAlgs byteReader
652 if !reader.readU16LengthPrefixed(&sigAlgs) {
653 return false
654 }
Robert Sloan5cbb5c82018-04-24 11:35:46 -0700655 if !allowEmpty && len(sigAlgs) == 0 {
656 return false
657 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800658 *out = make([]signatureAlgorithm, 0, len(sigAlgs)/2)
659 for len(sigAlgs) > 0 {
660 var v uint16
661 if !sigAlgs.readU16(&v) {
662 return false
663 }
664 *out = append(*out, signatureAlgorithm(v))
665 }
666 return true
667}
668
Robert Sloan11c28bd2018-12-17 12:09:20 -0800669func checkDuplicateExtensions(extensions byteReader) bool {
670 seen := make(map[uint16]struct{})
671 for len(extensions) > 0 {
672 var extension uint16
673 var body byteReader
674 if !extensions.readU16(&extension) ||
675 !extensions.readU16LengthPrefixed(&body) {
676 return false
677 }
678 if _, ok := seen[extension]; ok {
679 return false
680 }
681 seen[extension] = struct{}{}
682 }
683 return true
684}
685
Adam Langleyd9e397b2015-01-22 14:27:53 -0800686func (m *clientHelloMsg) unmarshal(data []byte) bool {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800687 m.raw = data
Robert Sloana815d5a2017-12-04 11:49:16 -0800688 reader := byteReader(data[4:])
689 if !reader.readU16(&m.vers) ||
690 !reader.readBytes(&m.random, 32) ||
691 !reader.readU8LengthPrefixedBytes(&m.sessionId) ||
692 len(m.sessionId) > 32 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800693 return false
694 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800695 if m.isDTLS {
Robert Sloana815d5a2017-12-04 11:49:16 -0800696 if !reader.readU8LengthPrefixedBytes(&m.cookie) ||
697 len(m.cookie) > 32 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800698 return false
699 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800700 }
701 var cipherSuites byteReader
702 if !reader.readU16LengthPrefixed(&cipherSuites) ||
703 !reader.readU8LengthPrefixedBytes(&m.compressionMethods) {
704 return false
705 }
706
707 m.cipherSuites = make([]uint16, 0, len(cipherSuites)/2)
708 for len(cipherSuites) > 0 {
709 var v uint16
710 if !cipherSuites.readU16(&v) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800711 return false
712 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800713 m.cipherSuites = append(m.cipherSuites, v)
714 if v == scsvRenegotiation {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800715 m.secureRenegotiation = []byte{}
716 }
717 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800718
719 m.nextProtoNeg = false
720 m.serverName = ""
721 m.ocspStapling = false
David Benjaminc895d6b2016-08-11 13:26:41 -0400722 m.keyShares = nil
723 m.pskIdentities = nil
724 m.hasEarlyData = false
Adam Langleyd9e397b2015-01-22 14:27:53 -0800725 m.ticketSupported = false
726 m.sessionTicket = nil
David Benjaminc895d6b2016-08-11 13:26:41 -0400727 m.signatureAlgorithms = nil
Robert Sloan5cbb5c82018-04-24 11:35:46 -0700728 m.signatureAlgorithmsCert = nil
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400729 m.supportedVersions = nil
Adam Langleyd9e397b2015-01-22 14:27:53 -0800730 m.alpnProtocols = nil
731 m.extendedMasterSecret = false
Kenny Rootb8494592015-09-25 02:29:14 +0000732 m.customExtension = ""
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800733 m.delegatedCredentials = false
Pete Bentley0c61efe2019-08-13 09:32:23 +0100734 m.pqExperimentSignal = false
Adam Langleyd9e397b2015-01-22 14:27:53 -0800735
Robert Sloana815d5a2017-12-04 11:49:16 -0800736 if len(reader) == 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800737 // ClientHello is optionally followed by extension data
738 return true
739 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800740
741 var extensions byteReader
Robert Sloan11c28bd2018-12-17 12:09:20 -0800742 if !reader.readU16LengthPrefixed(&extensions) || len(reader) != 0 || !checkDuplicateExtensions(extensions) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800743 return false
744 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800745 for len(extensions) > 0 {
746 var extension uint16
747 var body byteReader
748 if !extensions.readU16(&extension) ||
749 !extensions.readU16LengthPrefixed(&body) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800750 return false
751 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800752 switch extension {
753 case extensionServerName:
Robert Sloana815d5a2017-12-04 11:49:16 -0800754 var names byteReader
755 if !body.readU16LengthPrefixed(&names) || len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800756 return false
757 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800758 for len(names) > 0 {
759 var nameType byte
760 var name []byte
761 if !names.readU8(&nameType) ||
762 !names.readU16LengthPrefixedBytes(&name) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800763 return false
764 }
765 if nameType == 0 {
Robert Sloana815d5a2017-12-04 11:49:16 -0800766 m.serverName = string(name)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800767 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800768 }
769 case extensionNextProtoNeg:
Robert Sloana815d5a2017-12-04 11:49:16 -0800770 if len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800771 return false
772 }
773 m.nextProtoNeg = true
774 case extensionStatusRequest:
Robert Sloana815d5a2017-12-04 11:49:16 -0800775 m.ocspStapling = len(body) > 0 && body[0] == statusTypeOCSP
Adam Langleyd9e397b2015-01-22 14:27:53 -0800776 case extensionSupportedCurves:
777 // http://tools.ietf.org/html/rfc4492#section-5.5.1
Robert Sloana815d5a2017-12-04 11:49:16 -0800778 var curves byteReader
779 if !body.readU16LengthPrefixed(&curves) || len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800780 return false
781 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800782 m.supportedCurves = make([]CurveID, 0, len(curves)/2)
783 for len(curves) > 0 {
784 var v uint16
785 if !curves.readU16(&v) {
786 return false
787 }
788 m.supportedCurves = append(m.supportedCurves, CurveID(v))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800789 }
790 case extensionSupportedPoints:
791 // http://tools.ietf.org/html/rfc4492#section-5.5.2
Robert Sloana815d5a2017-12-04 11:49:16 -0800792 if !body.readU8LengthPrefixedBytes(&m.supportedPoints) || len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800793 return false
794 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800795 case extensionSessionTicket:
796 // http://tools.ietf.org/html/rfc5077#section-3.2
797 m.ticketSupported = true
Robert Sloana815d5a2017-12-04 11:49:16 -0800798 m.sessionTicket = []byte(body)
Robert Sloan8542c082018-02-05 09:07:34 -0800799 case extensionKeyShare:
Robert Sloand9e572d2018-08-27 12:27:00 -0700800 // https://tools.ietf.org/html/rfc8446#section-4.2.8
Robert Sloanc9abfe42018-11-26 12:19:07 -0800801 m.hasKeyShares = true
802 m.keySharesRaw = body
Robert Sloana815d5a2017-12-04 11:49:16 -0800803 var keyShares byteReader
804 if !body.readU16LengthPrefixed(&keyShares) || len(body) != 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400805 return false
806 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800807 for len(keyShares) > 0 {
808 var entry keyShareEntry
809 var group uint16
810 if !keyShares.readU16(&group) ||
811 !keyShares.readU16LengthPrefixedBytes(&entry.keyExchange) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400812 return false
813 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800814 entry.group = CurveID(group)
David Benjaminc895d6b2016-08-11 13:26:41 -0400815 m.keyShares = append(m.keyShares, entry)
816 }
817 case extensionPreSharedKey:
Robert Sloand9e572d2018-08-27 12:27:00 -0700818 // https://tools.ietf.org/html/rfc8446#section-4.2.11
Robert Sloana815d5a2017-12-04 11:49:16 -0800819 var psks, binders byteReader
820 if !body.readU16LengthPrefixed(&psks) ||
821 !body.readU16LengthPrefixed(&binders) ||
822 len(body) != 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400823 return false
824 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800825 for len(psks) > 0 {
826 var psk pskIdentity
827 if !psks.readU16LengthPrefixedBytes(&psk.ticket) ||
828 !psks.readU32(&psk.obfuscatedTicketAge) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400829 return false
830 }
David Benjaminc895d6b2016-08-11 13:26:41 -0400831 m.pskIdentities = append(m.pskIdentities, psk)
David Benjaminc895d6b2016-08-11 13:26:41 -0400832 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800833 for len(binders) > 0 {
834 var binder []byte
835 if !binders.readU8LengthPrefixedBytes(&binder) {
Steven Valdez909b19f2016-11-21 15:35:44 -0500836 return false
837 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800838 m.pskBinders = append(m.pskBinders, binder)
Steven Valdez909b19f2016-11-21 15:35:44 -0500839 }
840
841 // There must be the same number of identities as binders.
842 if len(m.pskIdentities) != len(m.pskBinders) {
843 return false
844 }
845 case extensionPSKKeyExchangeModes:
Robert Sloand9e572d2018-08-27 12:27:00 -0700846 // https://tools.ietf.org/html/rfc8446#section-4.2.9
Robert Sloana815d5a2017-12-04 11:49:16 -0800847 if !body.readU8LengthPrefixedBytes(&m.pskKEModes) || len(body) != 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400848 return false
849 }
Steven Valdez909b19f2016-11-21 15:35:44 -0500850 case extensionEarlyData:
Robert Sloand9e572d2018-08-27 12:27:00 -0700851 // https://tools.ietf.org/html/rfc8446#section-4.2.10
Robert Sloana815d5a2017-12-04 11:49:16 -0800852 if len(body) != 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -0400853 return false
854 }
855 m.hasEarlyData = true
David Benjamin95add822016-10-19 01:09:12 -0400856 case extensionCookie:
Robert Sloana815d5a2017-12-04 11:49:16 -0800857 if !body.readU16LengthPrefixedBytes(&m.tls13Cookie) || len(body) != 0 {
David Benjamin95add822016-10-19 01:09:12 -0400858 return false
859 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800860 case extensionSignatureAlgorithms:
861 // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
Robert Sloan5cbb5c82018-04-24 11:35:46 -0700862 if !parseSignatureAlgorithms(&body, &m.signatureAlgorithms, false) || len(body) != 0 {
863 return false
864 }
865 case extensionSignatureAlgorithmsCert:
866 if !parseSignatureAlgorithms(&body, &m.signatureAlgorithmsCert, false) || len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800867 return false
868 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400869 case extensionSupportedVersions:
Robert Sloana815d5a2017-12-04 11:49:16 -0800870 var versions byteReader
871 if !body.readU8LengthPrefixed(&versions) || len(body) != 0 {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400872 return false
873 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800874 m.supportedVersions = make([]uint16, 0, len(versions)/2)
875 for len(versions) > 0 {
876 var v uint16
877 if !versions.readU16(&v) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800878 return false
879 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800880 m.supportedVersions = append(m.supportedVersions, v)
881 }
882 case extensionRenegotiationInfo:
883 if !body.readU8LengthPrefixedBytes(&m.secureRenegotiation) || len(body) != 0 {
884 return false
885 }
886 case extensionALPN:
887 var protocols byteReader
888 if !body.readU16LengthPrefixed(&protocols) || len(body) != 0 {
889 return false
890 }
891 for len(protocols) > 0 {
892 var protocol []byte
893 if !protocols.readU8LengthPrefixedBytes(&protocol) {
894 return false
895 }
896 m.alpnProtocols = append(m.alpnProtocols, string(protocol))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800897 }
Robert Sloan8542c082018-02-05 09:07:34 -0800898 case extensionQUICTransportParams:
899 m.quicTransportParams = body
Adam Langleyd9e397b2015-01-22 14:27:53 -0800900 case extensionChannelID:
Robert Sloana815d5a2017-12-04 11:49:16 -0800901 if len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800902 return false
903 }
904 m.channelIDSupported = true
Robert Sloan978112c2018-01-22 12:53:01 -0800905 case extensionTokenBinding:
906 if !body.readU16(&m.tokenBindingVersion) ||
907 !body.readU8LengthPrefixedBytes(&m.tokenBindingParams) ||
908 len(body) != 0 {
909 return false
910 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800911 case extensionExtendedMasterSecret:
Robert Sloana815d5a2017-12-04 11:49:16 -0800912 if len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800913 return false
914 }
915 m.extendedMasterSecret = true
916 case extensionUseSRTP:
Robert Sloana815d5a2017-12-04 11:49:16 -0800917 var profiles byteReader
918 var mki []byte
919 if !body.readU16LengthPrefixed(&profiles) ||
920 !body.readU8LengthPrefixedBytes(&mki) ||
921 len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800922 return false
923 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800924 m.srtpProtectionProfiles = make([]uint16, 0, len(profiles)/2)
925 for len(profiles) > 0 {
926 var v uint16
927 if !profiles.readU16(&v) {
928 return false
929 }
930 m.srtpProtectionProfiles = append(m.srtpProtectionProfiles, v)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800931 }
Robert Sloana815d5a2017-12-04 11:49:16 -0800932 m.srtpMasterKeyIdentifier = string(mki)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800933 case extensionSignedCertificateTimestamp:
Robert Sloana815d5a2017-12-04 11:49:16 -0800934 if len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800935 return false
936 }
937 m.sctListSupported = true
Kenny Rootb8494592015-09-25 02:29:14 +0000938 case extensionCustom:
Robert Sloana815d5a2017-12-04 11:49:16 -0800939 m.customExtension = string(body)
Adam Vartanianbfcf3a72018-08-10 14:55:24 +0100940 case extensionCompressedCertAlgs:
941 var algIDs byteReader
942 if !body.readU8LengthPrefixed(&algIDs) {
943 return false
944 }
945
946 seen := make(map[uint16]struct{})
947 for len(algIDs) > 0 {
948 var algID uint16
949 if !algIDs.readU16(&algID) {
950 return false
951 }
952 if _, ok := seen[algID]; ok {
953 return false
954 }
955 seen[algID] = struct{}{}
956 m.compressedCertAlgs = append(m.compressedCertAlgs, algID)
957 }
Robert Sloan11c28bd2018-12-17 12:09:20 -0800958 case extensionPadding:
959 // Padding bytes must be all zero.
960 for _, b := range body {
961 if b != 0 {
962 return false
963 }
964 }
Robert Sloan4c22c5f2019-03-01 15:53:37 -0800965 case extensionDelegatedCredentials:
966 if len(body) != 0 {
967 return false
968 }
969 m.delegatedCredentials = true
Pete Bentley0c61efe2019-08-13 09:32:23 +0100970 case extensionPQExperimentSignal:
971 if len(body) != 0 {
972 return false
973 }
974 m.pqExperimentSignal = true
Adam Langleyd9e397b2015-01-22 14:27:53 -0800975 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400976
977 if isGREASEValue(extension) {
978 m.hasGREASEExtension = true
979 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800980 }
981
982 return true
983}
984
985type serverHelloMsg struct {
Robert Sloana12bf462017-07-17 07:08:26 -0700986 raw []byte
987 isDTLS bool
988 vers uint16
989 versOverride uint16
990 supportedVersOverride uint16
Adam Vartanianbfcf3a72018-08-10 14:55:24 +0100991 omitSupportedVers bool
Robert Sloana12bf462017-07-17 07:08:26 -0700992 random []byte
993 sessionId []byte
994 cipherSuite uint16
995 hasKeyShare bool
996 keyShare keyShareEntry
997 hasPSKIdentity bool
998 pskIdentity uint16
999 compressionMethod uint8
1000 customExtension string
1001 unencryptedALPN string
1002 omitExtensions bool
1003 emptyExtensions bool
1004 extensions serverExtensions
David Benjaminc895d6b2016-08-11 13:26:41 -04001005}
1006
1007func (m *serverHelloMsg) marshal() []byte {
1008 if m.raw != nil {
1009 return m.raw
1010 }
1011
1012 handshakeMsg := newByteBuilder()
1013 handshakeMsg.addU8(typeServerHello)
1014 hello := handshakeMsg.addU24LengthPrefixed()
Steven Valdezbb1ceac2016-10-07 10:34:51 -04001015
1016 // m.vers is used both to determine the format of the rest of the
1017 // ServerHello and to override the value, so include a second version
1018 // field.
1019 vers, ok := wireToVersion(m.vers, m.isDTLS)
1020 if !ok {
1021 panic("unknown version")
1022 }
1023 if m.versOverride != 0 {
1024 hello.addU16(m.versOverride)
Robert Sloan0da43952018-01-03 15:13:14 -08001025 } else if vers >= VersionTLS13 {
Robert Sloana12bf462017-07-17 07:08:26 -07001026 hello.addU16(VersionTLS12)
Steven Valdezbb1ceac2016-10-07 10:34:51 -04001027 } else {
1028 hello.addU16(m.vers)
1029 }
1030
David Benjaminc895d6b2016-08-11 13:26:41 -04001031 hello.addBytes(m.random)
Robert Sloan0da43952018-01-03 15:13:14 -08001032 sessionId := hello.addU8LengthPrefixed()
1033 sessionId.addBytes(m.sessionId)
David Benjaminc895d6b2016-08-11 13:26:41 -04001034 hello.addU16(m.cipherSuite)
Robert Sloan0da43952018-01-03 15:13:14 -08001035 hello.addU8(m.compressionMethod)
David Benjaminc895d6b2016-08-11 13:26:41 -04001036
1037 extensions := hello.addU16LengthPrefixed()
1038
Steven Valdezbb1ceac2016-10-07 10:34:51 -04001039 if vers >= VersionTLS13 {
David Benjaminc895d6b2016-08-11 13:26:41 -04001040 if m.hasKeyShare {
Robert Sloan8542c082018-02-05 09:07:34 -08001041 extensions.addU16(extensionKeyShare)
David Benjaminc895d6b2016-08-11 13:26:41 -04001042 keyShare := extensions.addU16LengthPrefixed()
1043 keyShare.addU16(uint16(m.keyShare.group))
1044 keyExchange := keyShare.addU16LengthPrefixed()
1045 keyExchange.addBytes(m.keyShare.keyExchange)
1046 }
1047 if m.hasPSKIdentity {
1048 extensions.addU16(extensionPreSharedKey)
1049 extensions.addU16(2) // Length
1050 extensions.addU16(m.pskIdentity)
1051 }
Adam Vartanianbfcf3a72018-08-10 14:55:24 +01001052 if !m.omitSupportedVers {
1053 extensions.addU16(extensionSupportedVersions)
1054 extensions.addU16(2) // Length
1055 if m.supportedVersOverride != 0 {
1056 extensions.addU16(m.supportedVersOverride)
1057 } else {
1058 extensions.addU16(m.vers)
1059 }
Robert Sloana12bf462017-07-17 07:08:26 -07001060 }
David Benjamin95add822016-10-19 01:09:12 -04001061 if len(m.customExtension) > 0 {
1062 extensions.addU16(extensionCustom)
1063 customExt := extensions.addU16LengthPrefixed()
1064 customExt.addBytes([]byte(m.customExtension))
1065 }
1066 if len(m.unencryptedALPN) > 0 {
1067 extensions.addU16(extensionALPN)
1068 extension := extensions.addU16LengthPrefixed()
1069
1070 protocolNameList := extension.addU16LengthPrefixed()
1071 protocolName := protocolNameList.addU8LengthPrefixed()
1072 protocolName.addBytes([]byte(m.unencryptedALPN))
1073 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001074 } else {
Steven Valdez909b19f2016-11-21 15:35:44 -05001075 m.extensions.marshal(extensions)
Robert Sloana12bf462017-07-17 07:08:26 -07001076 if m.omitExtensions || m.emptyExtensions {
1077 // Silently erasing server extensions will break the handshake. Instead,
1078 // assert that tests which use this field also disable all features which
1079 // would write an extension.
1080 if extensions.len() != 0 {
1081 panic(fmt.Sprintf("ServerHello unexpectedly contained extensions: %x, %+v", extensions.data(), m))
1082 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001083 hello.discardChild()
Robert Sloana12bf462017-07-17 07:08:26 -07001084 if m.emptyExtensions {
1085 hello.addU16(0)
1086 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001087 }
1088 }
1089
1090 m.raw = handshakeMsg.finish()
1091 return m.raw
1092}
1093
1094func (m *serverHelloMsg) unmarshal(data []byte) bool {
Robert Sloana815d5a2017-12-04 11:49:16 -08001095 m.raw = data
1096 reader := byteReader(data[4:])
1097 if !reader.readU16(&m.vers) ||
1098 !reader.readBytes(&m.random, 32) {
David Benjaminc895d6b2016-08-11 13:26:41 -04001099 return false
1100 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -04001101 vers, ok := wireToVersion(m.vers, m.isDTLS)
1102 if !ok {
1103 return false
1104 }
Robert Sloan0da43952018-01-03 15:13:14 -08001105 if !reader.readU8LengthPrefixedBytes(&m.sessionId) ||
1106 !reader.readU16(&m.cipherSuite) ||
1107 !reader.readU8(&m.compressionMethod) {
David Benjaminc895d6b2016-08-11 13:26:41 -04001108 return false
1109 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001110
Robert Sloana815d5a2017-12-04 11:49:16 -08001111 if len(reader) == 0 && m.vers < VersionTLS13 {
David Benjaminc895d6b2016-08-11 13:26:41 -04001112 // Extension data is optional before TLS 1.3.
1113 m.extensions = serverExtensions{}
Robert Sloana27a6a42017-09-05 08:39:28 -07001114 m.omitExtensions = true
David Benjaminc895d6b2016-08-11 13:26:41 -04001115 return true
1116 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001117
Robert Sloana815d5a2017-12-04 11:49:16 -08001118 var extensions byteReader
Robert Sloan11c28bd2018-12-17 12:09:20 -08001119 if !reader.readU16LengthPrefixed(&extensions) || len(reader) != 0 || !checkDuplicateExtensions(extensions) {
David Benjaminc895d6b2016-08-11 13:26:41 -04001120 return false
1121 }
1122
Robert Sloana12bf462017-07-17 07:08:26 -07001123 // Parse out the version from supported_versions if available.
1124 if m.vers == VersionTLS12 {
Robert Sloana815d5a2017-12-04 11:49:16 -08001125 extensionsCopy := extensions
1126 for len(extensionsCopy) > 0 {
1127 var extension uint16
1128 var body byteReader
1129 if !extensionsCopy.readU16(&extension) ||
1130 !extensionsCopy.readU16LengthPrefixed(&body) {
Robert Sloana12bf462017-07-17 07:08:26 -07001131 return false
1132 }
Robert Sloana12bf462017-07-17 07:08:26 -07001133 if extension == extensionSupportedVersions {
Robert Sloana815d5a2017-12-04 11:49:16 -08001134 if !body.readU16(&m.vers) || len(body) != 0 {
Robert Sloana12bf462017-07-17 07:08:26 -07001135 return false
1136 }
Robert Sloana12bf462017-07-17 07:08:26 -07001137 vers, ok = wireToVersion(m.vers, m.isDTLS)
1138 if !ok {
1139 return false
1140 }
1141 }
1142 }
1143 }
1144
Steven Valdezbb1ceac2016-10-07 10:34:51 -04001145 if vers >= VersionTLS13 {
Robert Sloana815d5a2017-12-04 11:49:16 -08001146 for len(extensions) > 0 {
1147 var extension uint16
1148 var body byteReader
1149 if !extensions.readU16(&extension) ||
1150 !extensions.readU16LengthPrefixed(&body) {
David Benjaminc895d6b2016-08-11 13:26:41 -04001151 return false
1152 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001153 switch extension {
1154 case extensionKeyShare:
1155 m.hasKeyShare = true
Robert Sloana815d5a2017-12-04 11:49:16 -08001156 var group uint16
1157 if !body.readU16(&group) ||
1158 !body.readU16LengthPrefixedBytes(&m.keyShare.keyExchange) ||
1159 len(body) != 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -04001160 return false
1161 }
Robert Sloana815d5a2017-12-04 11:49:16 -08001162 m.keyShare.group = CurveID(group)
David Benjaminc895d6b2016-08-11 13:26:41 -04001163 case extensionPreSharedKey:
Robert Sloana815d5a2017-12-04 11:49:16 -08001164 if !body.readU16(&m.pskIdentity) || len(body) != 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -04001165 return false
1166 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001167 m.hasPSKIdentity = true
Robert Sloana12bf462017-07-17 07:08:26 -07001168 case extensionSupportedVersions:
Robert Sloan0da43952018-01-03 15:13:14 -08001169 // Parsed above.
David Benjaminc895d6b2016-08-11 13:26:41 -04001170 default:
1171 // Only allow the 3 extensions that are sent in
1172 // the clear in TLS 1.3.
1173 return false
1174 }
1175 }
Robert Sloana815d5a2017-12-04 11:49:16 -08001176 } else if !m.extensions.unmarshal(extensions, vers) {
David Benjaminc895d6b2016-08-11 13:26:41 -04001177 return false
1178 }
1179
1180 return true
1181}
1182
1183type encryptedExtensionsMsg struct {
1184 raw []byte
1185 extensions serverExtensions
1186 empty bool
1187}
1188
1189func (m *encryptedExtensionsMsg) marshal() []byte {
1190 if m.raw != nil {
1191 return m.raw
1192 }
1193
1194 encryptedExtensionsMsg := newByteBuilder()
1195 encryptedExtensionsMsg.addU8(typeEncryptedExtensions)
1196 encryptedExtensions := encryptedExtensionsMsg.addU24LengthPrefixed()
1197 if !m.empty {
1198 extensions := encryptedExtensions.addU16LengthPrefixed()
Steven Valdez909b19f2016-11-21 15:35:44 -05001199 m.extensions.marshal(extensions)
David Benjaminc895d6b2016-08-11 13:26:41 -04001200 }
1201
1202 m.raw = encryptedExtensionsMsg.finish()
1203 return m.raw
1204}
1205
1206func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
1207 m.raw = data
Robert Sloana815d5a2017-12-04 11:49:16 -08001208 reader := byteReader(data[4:])
1209 var extensions byteReader
1210 if !reader.readU16LengthPrefixed(&extensions) || len(reader) != 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -04001211 return false
1212 }
Robert Sloana815d5a2017-12-04 11:49:16 -08001213 return m.extensions.unmarshal(extensions, VersionTLS13)
David Benjaminc895d6b2016-08-11 13:26:41 -04001214}
1215
1216type serverExtensions struct {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001217 nextProtoNeg bool
1218 nextProtos []string
1219 ocspStapling bool
1220 ticketSupported bool
1221 secureRenegotiation []byte
1222 alpnProtocol string
Kenny Rootb8494592015-09-25 02:29:14 +00001223 alpnProtocolEmpty bool
Adam Langleyd9e397b2015-01-22 14:27:53 -08001224 duplicateExtension bool
1225 channelIDRequested bool
Robert Sloan978112c2018-01-22 12:53:01 -08001226 tokenBindingParams []byte
1227 tokenBindingVersion uint16
Adam Langleyd9e397b2015-01-22 14:27:53 -08001228 extendedMasterSecret bool
1229 srtpProtectionProfile uint16
1230 srtpMasterKeyIdentifier string
1231 sctList []byte
Kenny Rootb8494592015-09-25 02:29:14 +00001232 customExtension string
Steven Valdez909b19f2016-11-21 15:35:44 -05001233 npnAfterAlpn bool
David Benjaminc895d6b2016-08-11 13:26:41 -04001234 hasKeyShare bool
Robert Sloan47f43ed2017-02-06 14:55:15 -08001235 hasEarlyData bool
David Benjaminc895d6b2016-08-11 13:26:41 -04001236 keyShare keyShareEntry
Robert Sloana12bf462017-07-17 07:08:26 -07001237 supportedVersion uint16
Robert Sloan69939df2017-01-09 10:53:07 -08001238 supportedPoints []uint8
Robert Sloanae1abf92017-10-05 12:50:08 -07001239 supportedCurves []CurveID
Robert Sloan8542c082018-02-05 09:07:34 -08001240 quicTransportParams []byte
Robert Sloan5d625782017-02-13 09:55:39 -08001241 serverNameAck bool
Pete Bentley0c61efe2019-08-13 09:32:23 +01001242 pqExperimentSignal bool
Adam Langleyd9e397b2015-01-22 14:27:53 -08001243}
1244
Steven Valdez909b19f2016-11-21 15:35:44 -05001245func (m *serverExtensions) marshal(extensions *byteBuilder) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001246 if m.duplicateExtension {
1247 // Add a duplicate bogus extension at the beginning and end.
David Benjaminc895d6b2016-08-11 13:26:41 -04001248 extensions.addU16(0xffff)
1249 extensions.addU16(0) // length = 0 for empty extension
Adam Langleyd9e397b2015-01-22 14:27:53 -08001250 }
Steven Valdez909b19f2016-11-21 15:35:44 -05001251 if m.nextProtoNeg && !m.npnAfterAlpn {
David Benjaminc895d6b2016-08-11 13:26:41 -04001252 extensions.addU16(extensionNextProtoNeg)
1253 extension := extensions.addU16LengthPrefixed()
Adam Langleyd9e397b2015-01-22 14:27:53 -08001254
1255 for _, v := range m.nextProtos {
David Benjaminc895d6b2016-08-11 13:26:41 -04001256 if len(v) > 255 {
1257 v = v[:255]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001258 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001259 npn := extension.addU8LengthPrefixed()
1260 npn.addBytes([]byte(v))
Adam Langleyd9e397b2015-01-22 14:27:53 -08001261 }
1262 }
Steven Valdez909b19f2016-11-21 15:35:44 -05001263 if m.ocspStapling {
1264 extensions.addU16(extensionStatusRequest)
1265 extensions.addU16(0)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001266 }
1267 if m.ticketSupported {
David Benjaminc895d6b2016-08-11 13:26:41 -04001268 extensions.addU16(extensionSessionTicket)
1269 extensions.addU16(0)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001270 }
1271 if m.secureRenegotiation != nil {
David Benjaminc895d6b2016-08-11 13:26:41 -04001272 extensions.addU16(extensionRenegotiationInfo)
1273 extension := extensions.addU16LengthPrefixed()
1274 secureRenego := extension.addU8LengthPrefixed()
1275 secureRenego.addBytes(m.secureRenegotiation)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001276 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001277 if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
1278 extensions.addU16(extensionALPN)
1279 extension := extensions.addU16LengthPrefixed()
1280
1281 protocolNameList := extension.addU16LengthPrefixed()
1282 protocolName := protocolNameList.addU8LengthPrefixed()
1283 protocolName.addBytes([]byte(m.alpnProtocol))
Adam Langleyd9e397b2015-01-22 14:27:53 -08001284 }
1285 if m.channelIDRequested {
David Benjaminc895d6b2016-08-11 13:26:41 -04001286 extensions.addU16(extensionChannelID)
1287 extensions.addU16(0)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001288 }
Robert Sloan978112c2018-01-22 12:53:01 -08001289 if m.tokenBindingParams != nil {
1290 extensions.addU16(extensionTokenBinding)
1291 tokbindExtension := extensions.addU16LengthPrefixed()
1292 tokbindExtension.addU16(m.tokenBindingVersion)
1293 tokbindParams := tokbindExtension.addU8LengthPrefixed()
1294 tokbindParams.addBytes(m.tokenBindingParams)
1295 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001296 if m.duplicateExtension {
1297 // Add a duplicate bogus extension at the beginning and end.
David Benjaminc895d6b2016-08-11 13:26:41 -04001298 extensions.addU16(0xffff)
1299 extensions.addU16(0)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001300 }
1301 if m.extendedMasterSecret {
David Benjaminc895d6b2016-08-11 13:26:41 -04001302 extensions.addU16(extensionExtendedMasterSecret)
1303 extensions.addU16(0)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001304 }
1305 if m.srtpProtectionProfile != 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -04001306 extensions.addU16(extensionUseSRTP)
1307 extension := extensions.addU16LengthPrefixed()
1308
1309 srtpProtectionProfiles := extension.addU16LengthPrefixed()
Robert Sloana815d5a2017-12-04 11:49:16 -08001310 srtpProtectionProfiles.addU16(m.srtpProtectionProfile)
David Benjaminc895d6b2016-08-11 13:26:41 -04001311 srtpMki := extension.addU8LengthPrefixed()
1312 srtpMki.addBytes([]byte(m.srtpMasterKeyIdentifier))
Adam Langleyd9e397b2015-01-22 14:27:53 -08001313 }
1314 if m.sctList != nil {
David Benjaminc895d6b2016-08-11 13:26:41 -04001315 extensions.addU16(extensionSignedCertificateTimestamp)
1316 extension := extensions.addU16LengthPrefixed()
1317 extension.addBytes(m.sctList)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001318 }
Kenny Rootb8494592015-09-25 02:29:14 +00001319 if l := len(m.customExtension); l > 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -04001320 extensions.addU16(extensionCustom)
1321 customExt := extensions.addU16LengthPrefixed()
1322 customExt.addBytes([]byte(m.customExtension))
Kenny Rootb8494592015-09-25 02:29:14 +00001323 }
Steven Valdez909b19f2016-11-21 15:35:44 -05001324 if m.nextProtoNeg && m.npnAfterAlpn {
David Benjaminc895d6b2016-08-11 13:26:41 -04001325 extensions.addU16(extensionNextProtoNeg)
1326 extension := extensions.addU16LengthPrefixed()
Kenny Rootb8494592015-09-25 02:29:14 +00001327
1328 for _, v := range m.nextProtos {
David Benjaminc895d6b2016-08-11 13:26:41 -04001329 if len(v) > 255 {
1330 v = v[0:255]
Kenny Rootb8494592015-09-25 02:29:14 +00001331 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001332 npn := extension.addU8LengthPrefixed()
1333 npn.addBytes([]byte(v))
Kenny Rootb8494592015-09-25 02:29:14 +00001334 }
1335 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001336 if m.hasKeyShare {
Robert Sloan8542c082018-02-05 09:07:34 -08001337 extensions.addU16(extensionKeyShare)
David Benjaminc895d6b2016-08-11 13:26:41 -04001338 keyShare := extensions.addU16LengthPrefixed()
1339 keyShare.addU16(uint16(m.keyShare.group))
1340 keyExchange := keyShare.addU16LengthPrefixed()
1341 keyExchange.addBytes(m.keyShare.keyExchange)
1342 }
Robert Sloana12bf462017-07-17 07:08:26 -07001343 if m.supportedVersion != 0 {
1344 extensions.addU16(extensionSupportedVersions)
1345 extensions.addU16(2) // Length
1346 extensions.addU16(m.supportedVersion)
1347 }
Robert Sloan69939df2017-01-09 10:53:07 -08001348 if len(m.supportedPoints) > 0 {
1349 // http://tools.ietf.org/html/rfc4492#section-5.1.2
1350 extensions.addU16(extensionSupportedPoints)
1351 supportedPointsList := extensions.addU16LengthPrefixed()
1352 supportedPoints := supportedPointsList.addU8LengthPrefixed()
1353 supportedPoints.addBytes(m.supportedPoints)
1354 }
Robert Sloanae1abf92017-10-05 12:50:08 -07001355 if len(m.supportedCurves) > 0 {
Robert Sloand9e572d2018-08-27 12:27:00 -07001356 // https://tools.ietf.org/html/rfc8446#section-4.2.7
Robert Sloanae1abf92017-10-05 12:50:08 -07001357 extensions.addU16(extensionSupportedCurves)
1358 supportedCurvesList := extensions.addU16LengthPrefixed()
1359 supportedCurves := supportedCurvesList.addU16LengthPrefixed()
1360 for _, curve := range m.supportedCurves {
1361 supportedCurves.addU16(uint16(curve))
1362 }
1363 }
Robert Sloan8542c082018-02-05 09:07:34 -08001364 if len(m.quicTransportParams) > 0 {
1365 extensions.addU16(extensionQUICTransportParams)
1366 params := extensions.addU16LengthPrefixed()
1367 params.addBytes(m.quicTransportParams)
1368 }
Robert Sloan47f43ed2017-02-06 14:55:15 -08001369 if m.hasEarlyData {
1370 extensions.addU16(extensionEarlyData)
1371 extensions.addBytes([]byte{0, 0})
1372 }
Robert Sloan5d625782017-02-13 09:55:39 -08001373 if m.serverNameAck {
1374 extensions.addU16(extensionServerName)
1375 extensions.addU16(0) // zero length
1376 }
Pete Bentley0c61efe2019-08-13 09:32:23 +01001377 if m.pqExperimentSignal {
1378 extensions.addU16(extensionPQExperimentSignal)
1379 extensions.addU16(0) // zero length
1380 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001381}
1382
Robert Sloana815d5a2017-12-04 11:49:16 -08001383func (m *serverExtensions) unmarshal(data byteReader, version uint16) bool {
David Benjaminc895d6b2016-08-11 13:26:41 -04001384 // Reset all fields.
1385 *m = serverExtensions{}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001386
Robert Sloan11c28bd2018-12-17 12:09:20 -08001387 if !checkDuplicateExtensions(data) {
1388 return false
1389 }
1390
Robert Sloana815d5a2017-12-04 11:49:16 -08001391 for len(data) > 0 {
1392 var extension uint16
1393 var body byteReader
1394 if !data.readU16(&extension) ||
1395 !data.readU16LengthPrefixed(&body) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001396 return false
1397 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001398 switch extension {
1399 case extensionNextProtoNeg:
1400 m.nextProtoNeg = true
Robert Sloana815d5a2017-12-04 11:49:16 -08001401 for len(body) > 0 {
1402 var protocol []byte
1403 if !body.readU8LengthPrefixedBytes(&protocol) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001404 return false
1405 }
Robert Sloana815d5a2017-12-04 11:49:16 -08001406 m.nextProtos = append(m.nextProtos, string(protocol))
Adam Langleyd9e397b2015-01-22 14:27:53 -08001407 }
1408 case extensionStatusRequest:
Robert Sloana815d5a2017-12-04 11:49:16 -08001409 if len(body) != 0 {
Steven Valdez909b19f2016-11-21 15:35:44 -05001410 return false
Adam Langleyd9e397b2015-01-22 14:27:53 -08001411 }
Steven Valdez909b19f2016-11-21 15:35:44 -05001412 m.ocspStapling = true
Adam Langleyd9e397b2015-01-22 14:27:53 -08001413 case extensionSessionTicket:
Robert Sloana815d5a2017-12-04 11:49:16 -08001414 if len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001415 return false
1416 }
1417 m.ticketSupported = true
1418 case extensionRenegotiationInfo:
Robert Sloana815d5a2017-12-04 11:49:16 -08001419 if !body.readU8LengthPrefixedBytes(&m.secureRenegotiation) || len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001420 return false
1421 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001422 case extensionALPN:
Robert Sloana815d5a2017-12-04 11:49:16 -08001423 var protocols, protocol byteReader
1424 if !body.readU16LengthPrefixed(&protocols) ||
1425 len(body) != 0 ||
1426 !protocols.readU8LengthPrefixed(&protocol) ||
1427 len(protocols) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001428 return false
1429 }
Robert Sloana815d5a2017-12-04 11:49:16 -08001430 m.alpnProtocol = string(protocol)
1431 m.alpnProtocolEmpty = len(protocol) == 0
Adam Langleyd9e397b2015-01-22 14:27:53 -08001432 case extensionChannelID:
Robert Sloana815d5a2017-12-04 11:49:16 -08001433 if len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001434 return false
1435 }
1436 m.channelIDRequested = true
Robert Sloan978112c2018-01-22 12:53:01 -08001437 case extensionTokenBinding:
1438 if !body.readU16(&m.tokenBindingVersion) ||
1439 !body.readU8LengthPrefixedBytes(&m.tokenBindingParams) ||
1440 len(m.tokenBindingParams) != 1 ||
1441 len(body) != 0 {
1442 return false
1443 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001444 case extensionExtendedMasterSecret:
Robert Sloana815d5a2017-12-04 11:49:16 -08001445 if len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001446 return false
1447 }
1448 m.extendedMasterSecret = true
1449 case extensionUseSRTP:
Robert Sloana815d5a2017-12-04 11:49:16 -08001450 var profiles, mki byteReader
1451 if !body.readU16LengthPrefixed(&profiles) ||
1452 !profiles.readU16(&m.srtpProtectionProfile) ||
1453 len(profiles) != 0 ||
1454 !body.readU8LengthPrefixed(&mki) ||
1455 len(body) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001456 return false
1457 }
Robert Sloana815d5a2017-12-04 11:49:16 -08001458 m.srtpMasterKeyIdentifier = string(mki)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001459 case extensionSignedCertificateTimestamp:
Robert Sloana815d5a2017-12-04 11:49:16 -08001460 m.sctList = []byte(body)
Kenny Rootb8494592015-09-25 02:29:14 +00001461 case extensionCustom:
Robert Sloana815d5a2017-12-04 11:49:16 -08001462 m.customExtension = string(body)
David Benjaminc895d6b2016-08-11 13:26:41 -04001463 case extensionServerName:
Robert Sloana815d5a2017-12-04 11:49:16 -08001464 if len(body) != 0 {
David Benjaminc895d6b2016-08-11 13:26:41 -04001465 return false
1466 }
Robert Sloan5d625782017-02-13 09:55:39 -08001467 m.serverNameAck = true
David Benjaminc895d6b2016-08-11 13:26:41 -04001468 case extensionSupportedPoints:
1469 // supported_points is illegal in TLS 1.3.
1470 if version >= VersionTLS13 {
1471 return false
1472 }
Robert Sloan69939df2017-01-09 10:53:07 -08001473 // http://tools.ietf.org/html/rfc4492#section-5.5.2
Robert Sloana815d5a2017-12-04 11:49:16 -08001474 if !body.readU8LengthPrefixedBytes(&m.supportedPoints) || len(body) != 0 {
Robert Sloan69939df2017-01-09 10:53:07 -08001475 return false
1476 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001477 case extensionSupportedCurves:
1478 // The server can only send supported_curves in TLS 1.3.
1479 if version < VersionTLS13 {
1480 return false
1481 }
Robert Sloan8542c082018-02-05 09:07:34 -08001482 case extensionQUICTransportParams:
1483 m.quicTransportParams = body
Robert Sloan47f43ed2017-02-06 14:55:15 -08001484 case extensionEarlyData:
Robert Sloana815d5a2017-12-04 11:49:16 -08001485 if version < VersionTLS13 || len(body) != 0 {
Robert Sloan47f43ed2017-02-06 14:55:15 -08001486 return false
1487 }
1488 m.hasEarlyData = true
Pete Bentley0c61efe2019-08-13 09:32:23 +01001489 case extensionPQExperimentSignal:
1490 if len(body) != 0 {
1491 return false
1492 }
1493 m.pqExperimentSignal = true
David Benjaminc895d6b2016-08-11 13:26:41 -04001494 default:
1495 // Unknown extensions are illegal from the server.
1496 return false
Adam Langleyd9e397b2015-01-22 14:27:53 -08001497 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001498 }
1499
1500 return true
1501}
1502
David Benjaminc895d6b2016-08-11 13:26:41 -04001503type helloRetryRequestMsg struct {
David Benjamin95add822016-10-19 01:09:12 -04001504 raw []byte
1505 vers uint16
Robert Sloand5c22152017-11-13 09:22:12 -08001506 isServerHello bool
1507 sessionId []byte
Robert Sloanb1b54b82017-11-06 13:50:02 -08001508 cipherSuite uint16
Robert Sloana815d5a2017-12-04 11:49:16 -08001509 compressionMethod uint8
David Benjamin95add822016-10-19 01:09:12 -04001510 hasSelectedGroup bool
1511 selectedGroup CurveID
1512 cookie []byte
1513 customExtension string
1514 duplicateExtensions bool
David Benjaminc895d6b2016-08-11 13:26:41 -04001515}
1516
1517func (m *helloRetryRequestMsg) marshal() []byte {
1518 if m.raw != nil {
1519 return m.raw
1520 }
1521
1522 retryRequestMsg := newByteBuilder()
Robert Sloan8542c082018-02-05 09:07:34 -08001523 retryRequestMsg.addU8(typeServerHello)
David Benjaminc895d6b2016-08-11 13:26:41 -04001524 retryRequest := retryRequestMsg.addU24LengthPrefixed()
Robert Sloan8542c082018-02-05 09:07:34 -08001525 retryRequest.addU16(VersionTLS12)
1526 retryRequest.addBytes(tls13HelloRetryRequest)
1527 sessionId := retryRequest.addU8LengthPrefixed()
1528 sessionId.addBytes(m.sessionId)
1529 retryRequest.addU16(m.cipherSuite)
1530 retryRequest.addU8(m.compressionMethod)
Robert Sloand5c22152017-11-13 09:22:12 -08001531
David Benjamin95add822016-10-19 01:09:12 -04001532 extensions := retryRequest.addU16LengthPrefixed()
1533
1534 count := 1
1535 if m.duplicateExtensions {
1536 count = 2
1537 }
1538
1539 for i := 0; i < count; i++ {
Robert Sloan8542c082018-02-05 09:07:34 -08001540 extensions.addU16(extensionSupportedVersions)
1541 extensions.addU16(2) // Length
1542 extensions.addU16(m.vers)
David Benjamin95add822016-10-19 01:09:12 -04001543 if m.hasSelectedGroup {
Robert Sloan8542c082018-02-05 09:07:34 -08001544 extensions.addU16(extensionKeyShare)
David Benjamin95add822016-10-19 01:09:12 -04001545 extensions.addU16(2) // length
1546 extensions.addU16(uint16(m.selectedGroup))
1547 }
Robert Sloan99319a12017-11-27 10:32:46 -08001548 // m.cookie may be a non-nil empty slice for empty cookie tests.
1549 if m.cookie != nil {
David Benjamin95add822016-10-19 01:09:12 -04001550 extensions.addU16(extensionCookie)
1551 body := extensions.addU16LengthPrefixed()
1552 body.addU16LengthPrefixed().addBytes(m.cookie)
1553 }
1554 if len(m.customExtension) > 0 {
1555 extensions.addU16(extensionCustom)
1556 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
1557 }
1558 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001559
1560 m.raw = retryRequestMsg.finish()
1561 return m.raw
1562}
1563
1564func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
1565 m.raw = data
Robert Sloana815d5a2017-12-04 11:49:16 -08001566 reader := byteReader(data[4:])
1567 if !reader.readU16(&m.vers) {
David Benjaminc895d6b2016-08-11 13:26:41 -04001568 return false
1569 }
Robert Sloand5c22152017-11-13 09:22:12 -08001570 if m.isServerHello {
Robert Sloana815d5a2017-12-04 11:49:16 -08001571 var random []byte
1572 var compressionMethod byte
1573 if !reader.readBytes(&random, 32) ||
1574 !reader.readU8LengthPrefixedBytes(&m.sessionId) ||
1575 !reader.readU16(&m.cipherSuite) ||
1576 !reader.readU8(&compressionMethod) ||
1577 compressionMethod != 0 {
Robert Sloand5c22152017-11-13 09:22:12 -08001578 return false
1579 }
Robert Sloan8542c082018-02-05 09:07:34 -08001580 } else if !reader.readU16(&m.cipherSuite) {
David Benjaminc895d6b2016-08-11 13:26:41 -04001581 return false
1582 }
Robert Sloana815d5a2017-12-04 11:49:16 -08001583 var extensions byteReader
1584 if !reader.readU16LengthPrefixed(&extensions) || len(reader) != 0 {
1585 return false
1586 }
Robert Sloan0db7f542018-01-16 15:48:33 -08001587 extensionsCopy := extensions
1588 for len(extensionsCopy) > 0 {
Robert Sloana815d5a2017-12-04 11:49:16 -08001589 var extension uint16
1590 var body byteReader
Robert Sloan0db7f542018-01-16 15:48:33 -08001591 if !extensionsCopy.readU16(&extension) ||
1592 !extensionsCopy.readU16LengthPrefixed(&body) {
David Benjamin95add822016-10-19 01:09:12 -04001593 return false
1594 }
David Benjamin95add822016-10-19 01:09:12 -04001595 switch extension {
Robert Sloand5c22152017-11-13 09:22:12 -08001596 case extensionSupportedVersions:
Robert Sloana815d5a2017-12-04 11:49:16 -08001597 if !m.isServerHello ||
1598 !body.readU16(&m.vers) ||
1599 len(body) != 0 {
Robert Sloand5c22152017-11-13 09:22:12 -08001600 return false
1601 }
Robert Sloan0db7f542018-01-16 15:48:33 -08001602 default:
1603 }
1604 }
Robert Sloan0db7f542018-01-16 15:48:33 -08001605 for len(extensions) > 0 {
1606 var extension uint16
1607 var body byteReader
1608 if !extensions.readU16(&extension) ||
1609 !extensions.readU16LengthPrefixed(&body) {
1610 return false
1611 }
1612 switch extension {
1613 case extensionSupportedVersions:
1614 // Parsed above.
David Benjamin95add822016-10-19 01:09:12 -04001615 case extensionKeyShare:
Robert Sloana815d5a2017-12-04 11:49:16 -08001616 var v uint16
1617 if !body.readU16(&v) || len(body) != 0 {
David Benjamin95add822016-10-19 01:09:12 -04001618 return false
1619 }
1620 m.hasSelectedGroup = true
Robert Sloana815d5a2017-12-04 11:49:16 -08001621 m.selectedGroup = CurveID(v)
David Benjamin95add822016-10-19 01:09:12 -04001622 case extensionCookie:
Robert Sloana815d5a2017-12-04 11:49:16 -08001623 if !body.readU16LengthPrefixedBytes(&m.cookie) || len(body) != 0 {
David Benjamin95add822016-10-19 01:09:12 -04001624 return false
1625 }
David Benjamin95add822016-10-19 01:09:12 -04001626 default:
1627 // Unknown extensions are illegal from the server.
1628 return false
1629 }
David Benjamin95add822016-10-19 01:09:12 -04001630 }
David Benjaminc895d6b2016-08-11 13:26:41 -04001631 return true
1632}
1633
Steven Valdez909b19f2016-11-21 15:35:44 -05001634type certificateEntry struct {
1635 data []byte
1636 ocspResponse []byte
1637 sctList []byte
1638 duplicateExtensions bool
1639 extraExtension []byte
Robert Sloan4c22c5f2019-03-01 15:53:37 -08001640 delegatedCredential *delegatedCredential
1641}
1642
1643type delegatedCredential struct {
1644 // https://tools.ietf.org/html/draft-ietf-tls-subcerts-03#section-3
1645 signedBytes []byte
1646 lifetimeSecs uint32
1647 expectedCertVerifyAlgo signatureAlgorithm
1648 pkixPublicKey []byte
1649 algorithm signatureAlgorithm
1650 signature []byte
Steven Valdez909b19f2016-11-21 15:35:44 -05001651}
1652
Adam Langleyd9e397b2015-01-22 14:27:53 -08001653type certificateMsg struct {
David Benjaminc895d6b2016-08-11 13:26:41 -04001654 raw []byte
1655 hasRequestContext bool
1656 requestContext []byte
Steven Valdez909b19f2016-11-21 15:35:44 -05001657 certificates []certificateEntry
Adam Langleyd9e397b2015-01-22 14:27:53 -08001658}
1659
Adam Langleyd9e397b2015-01-22 14:27:53 -08001660func (m *certificateMsg) marshal() (x []byte) {
1661 if m.raw != nil {
1662 return m.raw
1663 }
1664
David Benjaminc895d6b2016-08-11 13:26:41 -04001665 certMsg := newByteBuilder()
1666 certMsg.addU8(typeCertificate)
1667 certificate := certMsg.addU24LengthPrefixed()
1668 if m.hasRequestContext {
1669 context := certificate.addU8LengthPrefixed()
1670 context.addBytes(m.requestContext)
1671 }
1672 certificateList := certificate.addU24LengthPrefixed()
1673 for _, cert := range m.certificates {
1674 certEntry := certificateList.addU24LengthPrefixed()
Steven Valdez909b19f2016-11-21 15:35:44 -05001675 certEntry.addBytes(cert.data)
1676 if m.hasRequestContext {
1677 extensions := certificateList.addU16LengthPrefixed()
1678 count := 1
1679 if cert.duplicateExtensions {
1680 count = 2
1681 }
1682
1683 for i := 0; i < count; i++ {
1684 if cert.ocspResponse != nil {
1685 extensions.addU16(extensionStatusRequest)
1686 body := extensions.addU16LengthPrefixed()
1687 body.addU8(statusTypeOCSP)
1688 response := body.addU24LengthPrefixed()
1689 response.addBytes(cert.ocspResponse)
1690 }
1691
1692 if cert.sctList != nil {
1693 extensions.addU16(extensionSignedCertificateTimestamp)
1694 extension := extensions.addU16LengthPrefixed()
1695 extension.addBytes(cert.sctList)
1696 }
1697 }
1698 if cert.extraExtension != nil {
1699 extensions.addBytes(cert.extraExtension)
1700 }
1701 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001702 }
1703
David Benjaminc895d6b2016-08-11 13:26:41 -04001704 m.raw = certMsg.finish()
1705 return m.raw
Adam Langleyd9e397b2015-01-22 14:27:53 -08001706}
1707
1708func (m *certificateMsg) unmarshal(data []byte) bool {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001709 m.raw = data
Robert Sloana815d5a2017-12-04 11:49:16 -08001710 reader := byteReader(data[4:])
David Benjaminc895d6b2016-08-11 13:26:41 -04001711
Robert Sloana815d5a2017-12-04 11:49:16 -08001712 if m.hasRequestContext && !reader.readU8LengthPrefixedBytes(&m.requestContext) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001713 return false
1714 }
1715
Robert Sloana815d5a2017-12-04 11:49:16 -08001716 var certs byteReader
1717 if !reader.readU24LengthPrefixed(&certs) || len(reader) != 0 {
1718 return false
1719 }
Steven Valdez909b19f2016-11-21 15:35:44 -05001720 m.certificates = nil
Robert Sloana815d5a2017-12-04 11:49:16 -08001721 for len(certs) > 0 {
1722 var cert certificateEntry
1723 if !certs.readU24LengthPrefixedBytes(&cert.data) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001724 return false
1725 }
Steven Valdez909b19f2016-11-21 15:35:44 -05001726 if m.hasRequestContext {
Robert Sloana815d5a2017-12-04 11:49:16 -08001727 var extensions byteReader
Robert Sloan11c28bd2018-12-17 12:09:20 -08001728 if !certs.readU16LengthPrefixed(&extensions) || !checkDuplicateExtensions(extensions) {
Steven Valdez909b19f2016-11-21 15:35:44 -05001729 return false
1730 }
Robert Sloana815d5a2017-12-04 11:49:16 -08001731 for len(extensions) > 0 {
1732 var extension uint16
1733 var body byteReader
1734 if !extensions.readU16(&extension) ||
1735 !extensions.readU16LengthPrefixed(&body) {
Steven Valdez909b19f2016-11-21 15:35:44 -05001736 return false
1737 }
Steven Valdez909b19f2016-11-21 15:35:44 -05001738 switch extension {
1739 case extensionStatusRequest:
Robert Sloana815d5a2017-12-04 11:49:16 -08001740 var statusType byte
1741 if !body.readU8(&statusType) ||
1742 statusType != statusTypeOCSP ||
1743 !body.readU24LengthPrefixedBytes(&cert.ocspResponse) ||
1744 len(body) != 0 {
Steven Valdez909b19f2016-11-21 15:35:44 -05001745 return false
1746 }
Steven Valdez909b19f2016-11-21 15:35:44 -05001747 case extensionSignedCertificateTimestamp:
Robert Sloana815d5a2017-12-04 11:49:16 -08001748 cert.sctList = []byte(body)
Robert Sloan4c22c5f2019-03-01 15:53:37 -08001749 case extensionDelegatedCredentials:
1750 // https://tools.ietf.org/html/draft-ietf-tls-subcerts-03#section-3
1751 if cert.delegatedCredential != nil {
1752 return false
1753 }
1754
1755 dc := new(delegatedCredential)
1756 origBody := body
1757 var expectedCertVerifyAlgo, algorithm uint16
1758
1759 if !body.readU32(&dc.lifetimeSecs) ||
1760 !body.readU16(&expectedCertVerifyAlgo) ||
1761 !body.readU24LengthPrefixedBytes(&dc.pkixPublicKey) ||
1762 !body.readU16(&algorithm) ||
1763 !body.readU16LengthPrefixedBytes(&dc.signature) ||
1764 len(body) != 0 {
1765 return false
1766 }
1767
1768 dc.expectedCertVerifyAlgo = signatureAlgorithm(expectedCertVerifyAlgo)
1769 dc.algorithm = signatureAlgorithm(algorithm)
1770 dc.signedBytes = []byte(origBody)[:4+2+3+len(dc.pkixPublicKey)]
1771 cert.delegatedCredential = dc
Steven Valdez909b19f2016-11-21 15:35:44 -05001772 default:
1773 return false
1774 }
1775 }
1776 }
1777 m.certificates = append(m.certificates, cert)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001778 }
1779
1780 return true
1781}
1782
Adam Vartanianbfcf3a72018-08-10 14:55:24 +01001783type compressedCertificateMsg struct {
1784 raw []byte
1785 algID uint16
1786 uncompressedLength uint32
1787 compressed []byte
1788}
1789
1790func (m *compressedCertificateMsg) marshal() (x []byte) {
1791 if m.raw != nil {
1792 return m.raw
1793 }
1794
1795 certMsg := newByteBuilder()
1796 certMsg.addU8(typeCompressedCertificate)
1797 certificate := certMsg.addU24LengthPrefixed()
1798 certificate.addU16(m.algID)
1799 certificate.addU24(int(m.uncompressedLength))
1800 compressed := certificate.addU24LengthPrefixed()
1801 compressed.addBytes(m.compressed)
1802
1803 m.raw = certMsg.finish()
1804 return m.raw
1805}
1806
1807func (m *compressedCertificateMsg) unmarshal(data []byte) bool {
1808 m.raw = data
1809 reader := byteReader(data[4:])
1810
1811 if !reader.readU16(&m.algID) ||
1812 !reader.readU24(&m.uncompressedLength) ||
1813 !reader.readU24LengthPrefixedBytes(&m.compressed) ||
1814 len(reader) != 0 {
1815 return false
1816 }
1817
1818 if m.uncompressedLength >= 1<<17 {
1819 return false
1820 }
1821
1822 return true
1823}
1824
Adam Langleyd9e397b2015-01-22 14:27:53 -08001825type serverKeyExchangeMsg struct {
1826 raw []byte
1827 key []byte
1828}
1829
Adam Langleyd9e397b2015-01-22 14:27:53 -08001830func (m *serverKeyExchangeMsg) marshal() []byte {
1831 if m.raw != nil {
1832 return m.raw
1833 }
Robert Sloana815d5a2017-12-04 11:49:16 -08001834 msg := newByteBuilder()
1835 msg.addU8(typeServerKeyExchange)
1836 msg.addU24LengthPrefixed().addBytes(m.key)
1837 m.raw = msg.finish()
1838 return m.raw
Adam Langleyd9e397b2015-01-22 14:27:53 -08001839}
1840
1841func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
1842 m.raw = data
1843 if len(data) < 4 {
1844 return false
1845 }
1846 m.key = data[4:]
1847 return true
1848}
1849
1850type certificateStatusMsg struct {
1851 raw []byte
1852 statusType uint8
1853 response []byte
1854}
1855
Adam Langleyd9e397b2015-01-22 14:27:53 -08001856func (m *certificateStatusMsg) marshal() []byte {
1857 if m.raw != nil {
1858 return m.raw
1859 }
1860
1861 var x []byte
1862 if m.statusType == statusTypeOCSP {
Robert Sloana815d5a2017-12-04 11:49:16 -08001863 msg := newByteBuilder()
1864 msg.addU8(typeCertificateStatus)
1865 body := msg.addU24LengthPrefixed()
1866 body.addU8(statusTypeOCSP)
1867 body.addU24LengthPrefixed().addBytes(m.response)
1868 x = msg.finish()
Adam Langleyd9e397b2015-01-22 14:27:53 -08001869 } else {
1870 x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
1871 }
1872
1873 m.raw = x
1874 return x
1875}
1876
1877func (m *certificateStatusMsg) unmarshal(data []byte) bool {
1878 m.raw = data
Robert Sloana815d5a2017-12-04 11:49:16 -08001879 reader := byteReader(data[4:])
1880 if !reader.readU8(&m.statusType) ||
1881 m.statusType != statusTypeOCSP ||
1882 !reader.readU24LengthPrefixedBytes(&m.response) ||
1883 len(reader) != 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001884 return false
1885 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001886 return true
1887}
1888
1889type serverHelloDoneMsg struct{}
1890
Adam Langleyd9e397b2015-01-22 14:27:53 -08001891func (m *serverHelloDoneMsg) marshal() []byte {
1892 x := make([]byte, 4)
1893 x[0] = typeServerHelloDone
1894 return x
1895}
1896
1897func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
1898 return len(data) == 4
1899}
1900
1901type clientKeyExchangeMsg struct {
1902 raw []byte
1903 ciphertext []byte
1904}
1905
Adam Langleyd9e397b2015-01-22 14:27:53 -08001906func (m *clientKeyExchangeMsg) marshal() []byte {
1907 if m.raw != nil {
1908 return m.raw
1909 }
Robert Sloana815d5a2017-12-04 11:49:16 -08001910 msg := newByteBuilder()
1911 msg.addU8(typeClientKeyExchange)
1912 msg.addU24LengthPrefixed().addBytes(m.ciphertext)
1913 m.raw = msg.finish()
1914 return m.raw
Adam Langleyd9e397b2015-01-22 14:27:53 -08001915}
1916
1917func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
1918 m.raw = data
1919 if len(data) < 4 {
1920 return false
1921 }
1922 l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
1923 if l != len(data)-4 {
1924 return false
1925 }
1926 m.ciphertext = data[4:]
1927 return true
1928}
1929
1930type finishedMsg struct {
1931 raw []byte
1932 verifyData []byte
1933}
1934
Robert Sloana815d5a2017-12-04 11:49:16 -08001935func (m *finishedMsg) marshal() []byte {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001936 if m.raw != nil {
1937 return m.raw
1938 }
1939
Robert Sloana815d5a2017-12-04 11:49:16 -08001940 msg := newByteBuilder()
1941 msg.addU8(typeFinished)
1942 msg.addU24LengthPrefixed().addBytes(m.verifyData)
1943 m.raw = msg.finish()
1944 return m.raw
Adam Langleyd9e397b2015-01-22 14:27:53 -08001945}
1946
1947func (m *finishedMsg) unmarshal(data []byte) bool {
1948 m.raw = data
1949 if len(data) < 4 {
1950 return false
1951 }
1952 m.verifyData = data[4:]
1953 return true
1954}
1955
1956type nextProtoMsg struct {
1957 raw []byte
1958 proto string
1959}
1960
Adam Langleyd9e397b2015-01-22 14:27:53 -08001961func (m *nextProtoMsg) marshal() []byte {
1962 if m.raw != nil {
1963 return m.raw
1964 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001965
Robert Sloana815d5a2017-12-04 11:49:16 -08001966 padding := 32 - (len(m.proto)+2)%32
Adam Langleyd9e397b2015-01-22 14:27:53 -08001967
Robert Sloana815d5a2017-12-04 11:49:16 -08001968 msg := newByteBuilder()
1969 msg.addU8(typeNextProtocol)
1970 body := msg.addU24LengthPrefixed()
1971 body.addU8LengthPrefixed().addBytes([]byte(m.proto))
1972 body.addU8LengthPrefixed().addBytes(make([]byte, padding))
1973 m.raw = msg.finish()
1974 return m.raw
Adam Langleyd9e397b2015-01-22 14:27:53 -08001975}
1976
1977func (m *nextProtoMsg) unmarshal(data []byte) bool {
1978 m.raw = data
Robert Sloana815d5a2017-12-04 11:49:16 -08001979 reader := byteReader(data[4:])
1980 var proto, padding []byte
1981 if !reader.readU8LengthPrefixedBytes(&proto) ||
1982 !reader.readU8LengthPrefixedBytes(&padding) ||
1983 len(reader) != 0 {
1984 return false
1985 }
1986 m.proto = string(proto)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001987
Robert Sloana815d5a2017-12-04 11:49:16 -08001988 // Padding is not meant to be checked normally, but as this is a testing
1989 // implementation, we check the padding is as expected.
1990 if len(padding) != 32-(len(m.proto)+2)%32 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001991 return false
1992 }
Robert Sloana815d5a2017-12-04 11:49:16 -08001993 for _, v := range padding {
1994 if v != 0 {
1995 return false
1996 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001997 }
1998
1999 return true
2000}
2001
2002type certificateRequestMsg struct {
Robert Sloanb1b54b82017-11-06 13:50:02 -08002003 raw []byte
2004 vers uint16
David Benjaminc895d6b2016-08-11 13:26:41 -04002005 // hasSignatureAlgorithm indicates whether this message includes a list
Adam Langleyd9e397b2015-01-22 14:27:53 -08002006 // of signature and hash functions. This change was introduced with TLS
2007 // 1.2.
David Benjaminc895d6b2016-08-11 13:26:41 -04002008 hasSignatureAlgorithm bool
2009 // hasRequestContext indicates whether this message includes a context
2010 // field instead of certificateTypes. This change was introduced with
2011 // TLS 1.3.
2012 hasRequestContext bool
Adam Langleyd9e397b2015-01-22 14:27:53 -08002013
Robert Sloan5cbb5c82018-04-24 11:35:46 -07002014 certificateTypes []byte
2015 requestContext []byte
2016 signatureAlgorithms []signatureAlgorithm
2017 signatureAlgorithmsCert []signatureAlgorithm
2018 certificateAuthorities [][]byte
2019 hasCAExtension bool
2020 customExtension uint16
Adam Langleyd9e397b2015-01-22 14:27:53 -08002021}
2022
David Benjaminc895d6b2016-08-11 13:26:41 -04002023func (m *certificateRequestMsg) marshal() []byte {
Adam Langleyd9e397b2015-01-22 14:27:53 -08002024 if m.raw != nil {
2025 return m.raw
2026 }
2027
2028 // See http://tools.ietf.org/html/rfc4346#section-7.4.4
David Benjaminc895d6b2016-08-11 13:26:41 -04002029 builder := newByteBuilder()
2030 builder.addU8(typeCertificateRequest)
2031 body := builder.addU24LengthPrefixed()
Adam Langleyd9e397b2015-01-22 14:27:53 -08002032
David Benjaminc895d6b2016-08-11 13:26:41 -04002033 if m.hasRequestContext {
2034 requestContext := body.addU8LengthPrefixed()
2035 requestContext.addBytes(m.requestContext)
Robert Sloanb1b54b82017-11-06 13:50:02 -08002036 extensions := newByteBuilder()
Robert Sloan8542c082018-02-05 09:07:34 -08002037 extensions = body.addU16LengthPrefixed()
2038 if m.hasSignatureAlgorithm {
2039 extensions.addU16(extensionSignatureAlgorithms)
2040 signatureAlgorithms := extensions.addU16LengthPrefixed().addU16LengthPrefixed()
2041 for _, sigAlg := range m.signatureAlgorithms {
2042 signatureAlgorithms.addU16(uint16(sigAlg))
Robert Sloanb1b54b82017-11-06 13:50:02 -08002043 }
Robert Sloan8542c082018-02-05 09:07:34 -08002044 }
Robert Sloan5cbb5c82018-04-24 11:35:46 -07002045 if len(m.signatureAlgorithmsCert) > 0 {
2046 extensions.addU16(extensionSignatureAlgorithmsCert)
2047 signatureAlgorithmsCert := extensions.addU16LengthPrefixed().addU16LengthPrefixed()
2048 for _, sigAlg := range m.signatureAlgorithmsCert {
2049 signatureAlgorithmsCert.addU16(uint16(sigAlg))
2050 }
2051 }
Robert Sloan8542c082018-02-05 09:07:34 -08002052 if len(m.certificateAuthorities) > 0 {
2053 extensions.addU16(extensionCertificateAuthorities)
2054 certificateAuthorities := extensions.addU16LengthPrefixed().addU16LengthPrefixed()
Robert Sloanb1b54b82017-11-06 13:50:02 -08002055 for _, ca := range m.certificateAuthorities {
2056 caEntry := certificateAuthorities.addU16LengthPrefixed()
2057 caEntry.addBytes(ca)
2058 }
Robert Sloanb1b54b82017-11-06 13:50:02 -08002059 }
2060
2061 if m.customExtension > 0 {
2062 extensions.addU16(m.customExtension)
2063 extensions.addU16LengthPrefixed()
2064 }
David Benjaminc895d6b2016-08-11 13:26:41 -04002065 } else {
2066 certificateTypes := body.addU8LengthPrefixed()
2067 certificateTypes.addBytes(m.certificateTypes)
Adam Langleyd9e397b2015-01-22 14:27:53 -08002068
Robert Sloanb1b54b82017-11-06 13:50:02 -08002069 if m.hasSignatureAlgorithm {
2070 signatureAlgorithms := body.addU16LengthPrefixed()
2071 for _, sigAlg := range m.signatureAlgorithms {
2072 signatureAlgorithms.addU16(uint16(sigAlg))
2073 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08002074 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08002075
Robert Sloanb1b54b82017-11-06 13:50:02 -08002076 certificateAuthorities := body.addU16LengthPrefixed()
2077 for _, ca := range m.certificateAuthorities {
2078 caEntry := certificateAuthorities.addU16LengthPrefixed()
2079 caEntry.addBytes(ca)
2080 }
David Benjaminc895d6b2016-08-11 13:26:41 -04002081 }
2082
2083 m.raw = builder.finish()
2084 return m.raw
Adam Langleyd9e397b2015-01-22 14:27:53 -08002085}
2086
Robert Sloana815d5a2017-12-04 11:49:16 -08002087func parseCAs(reader *byteReader, out *[][]byte) bool {
2088 var cas byteReader
2089 if !reader.readU16LengthPrefixed(&cas) {
2090 return false
Robert Sloanb1b54b82017-11-06 13:50:02 -08002091 }
Robert Sloanb1b54b82017-11-06 13:50:02 -08002092 for len(cas) > 0 {
Robert Sloana815d5a2017-12-04 11:49:16 -08002093 var ca []byte
2094 if !cas.readU16LengthPrefixedBytes(&ca) {
2095 return false
Robert Sloanb1b54b82017-11-06 13:50:02 -08002096 }
Robert Sloana815d5a2017-12-04 11:49:16 -08002097 *out = append(*out, ca)
Robert Sloanb1b54b82017-11-06 13:50:02 -08002098 }
Robert Sloana815d5a2017-12-04 11:49:16 -08002099 return true
Robert Sloanb1b54b82017-11-06 13:50:02 -08002100}
2101
Adam Langleyd9e397b2015-01-22 14:27:53 -08002102func (m *certificateRequestMsg) unmarshal(data []byte) bool {
2103 m.raw = data
Robert Sloana815d5a2017-12-04 11:49:16 -08002104 reader := byteReader(data[4:])
Adam Langleyd9e397b2015-01-22 14:27:53 -08002105
Robert Sloan8542c082018-02-05 09:07:34 -08002106 if m.hasRequestContext {
Robert Sloana815d5a2017-12-04 11:49:16 -08002107 var extensions byteReader
2108 if !reader.readU8LengthPrefixedBytes(&m.requestContext) ||
2109 !reader.readU16LengthPrefixed(&extensions) ||
Robert Sloan11c28bd2018-12-17 12:09:20 -08002110 len(reader) != 0 ||
2111 !checkDuplicateExtensions(extensions) {
David Benjaminc895d6b2016-08-11 13:26:41 -04002112 return false
2113 }
Robert Sloana815d5a2017-12-04 11:49:16 -08002114 for len(extensions) > 0 {
2115 var extension uint16
2116 var body byteReader
2117 if !extensions.readU16(&extension) ||
2118 !extensions.readU16LengthPrefixed(&body) {
Robert Sloanb1b54b82017-11-06 13:50:02 -08002119 return false
2120 }
Robert Sloana815d5a2017-12-04 11:49:16 -08002121 switch extension {
2122 case extensionSignatureAlgorithms:
Robert Sloan5cbb5c82018-04-24 11:35:46 -07002123 if !parseSignatureAlgorithms(&body, &m.signatureAlgorithms, false) || len(body) != 0 {
2124 return false
2125 }
2126 case extensionSignatureAlgorithmsCert:
2127 if !parseSignatureAlgorithms(&body, &m.signatureAlgorithmsCert, false) || len(body) != 0 {
Robert Sloanb1b54b82017-11-06 13:50:02 -08002128 return false
2129 }
Robert Sloana815d5a2017-12-04 11:49:16 -08002130 case extensionCertificateAuthorities:
2131 if !parseCAs(&body, &m.certificateAuthorities) || len(body) != 0 {
Robert Sloanb1b54b82017-11-06 13:50:02 -08002132 return false
2133 }
Robert Sloana815d5a2017-12-04 11:49:16 -08002134 m.hasCAExtension = true
Robert Sloanb1b54b82017-11-06 13:50:02 -08002135 }
Robert Sloanb1b54b82017-11-06 13:50:02 -08002136 }
David Benjaminc895d6b2016-08-11 13:26:41 -04002137 } else {
Robert Sloana815d5a2017-12-04 11:49:16 -08002138 if !reader.readU8LengthPrefixedBytes(&m.certificateTypes) {
David Benjaminc895d6b2016-08-11 13:26:41 -04002139 return false
2140 }
Robert Sloan5cbb5c82018-04-24 11:35:46 -07002141 // In TLS 1.2, the supported_signature_algorithms field in
2142 // CertificateRequest may be empty.
2143 if m.hasSignatureAlgorithm && !parseSignatureAlgorithms(&reader, &m.signatureAlgorithms, true) {
David Benjaminc895d6b2016-08-11 13:26:41 -04002144 return false
2145 }
Robert Sloana815d5a2017-12-04 11:49:16 -08002146 if !parseCAs(&reader, &m.certificateAuthorities) ||
2147 len(reader) != 0 {
2148 return false
2149 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08002150 }
2151
2152 return true
2153}
2154
2155type certificateVerifyMsg struct {
David Benjaminc895d6b2016-08-11 13:26:41 -04002156 raw []byte
2157 hasSignatureAlgorithm bool
2158 signatureAlgorithm signatureAlgorithm
2159 signature []byte
Adam Langleyd9e397b2015-01-22 14:27:53 -08002160}
2161
Adam Langleyd9e397b2015-01-22 14:27:53 -08002162func (m *certificateVerifyMsg) marshal() (x []byte) {
2163 if m.raw != nil {
2164 return m.raw
2165 }
2166
2167 // See http://tools.ietf.org/html/rfc4346#section-7.4.8
2168 siglength := len(m.signature)
2169 length := 2 + siglength
David Benjaminc895d6b2016-08-11 13:26:41 -04002170 if m.hasSignatureAlgorithm {
Adam Langleyd9e397b2015-01-22 14:27:53 -08002171 length += 2
2172 }
2173 x = make([]byte, 4+length)
2174 x[0] = typeCertificateVerify
2175 x[1] = uint8(length >> 16)
2176 x[2] = uint8(length >> 8)
2177 x[3] = uint8(length)
2178 y := x[4:]
David Benjaminc895d6b2016-08-11 13:26:41 -04002179 if m.hasSignatureAlgorithm {
2180 y[0] = byte(m.signatureAlgorithm >> 8)
2181 y[1] = byte(m.signatureAlgorithm)
Adam Langleyd9e397b2015-01-22 14:27:53 -08002182 y = y[2:]
2183 }
2184 y[0] = uint8(siglength >> 8)
2185 y[1] = uint8(siglength)
2186 copy(y[2:], m.signature)
2187
2188 m.raw = x
2189
2190 return
2191}
2192
2193func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
2194 m.raw = data
2195
2196 if len(data) < 6 {
2197 return false
2198 }
2199
2200 length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2201 if uint32(len(data))-4 != length {
2202 return false
2203 }
2204
2205 data = data[4:]
David Benjaminc895d6b2016-08-11 13:26:41 -04002206 if m.hasSignatureAlgorithm {
2207 m.signatureAlgorithm = signatureAlgorithm(data[0])<<8 | signatureAlgorithm(data[1])
Adam Langleyd9e397b2015-01-22 14:27:53 -08002208 data = data[2:]
2209 }
2210
2211 if len(data) < 2 {
2212 return false
2213 }
2214 siglength := int(data[0])<<8 + int(data[1])
2215 data = data[2:]
2216 if len(data) != siglength {
2217 return false
2218 }
2219
2220 m.signature = data
2221
2222 return true
2223}
2224
2225type newSessionTicketMsg struct {
Robert Sloanb1b54b82017-11-06 13:50:02 -08002226 raw []byte
2227 vers uint16
2228 isDTLS bool
2229 ticketLifetime uint32
2230 ticketAgeAdd uint32
2231 ticketNonce []byte
2232 ticket []byte
2233 maxEarlyDataSize uint32
2234 customExtension string
2235 duplicateEarlyDataExtension bool
2236 hasGREASEExtension bool
Adam Langleyd9e397b2015-01-22 14:27:53 -08002237}
2238
David Benjaminc895d6b2016-08-11 13:26:41 -04002239func (m *newSessionTicketMsg) marshal() []byte {
Adam Langleyd9e397b2015-01-22 14:27:53 -08002240 if m.raw != nil {
2241 return m.raw
2242 }
2243
Robert Sloanb1b54b82017-11-06 13:50:02 -08002244 version, ok := wireToVersion(m.vers, m.isDTLS)
2245 if !ok {
2246 panic("unknown version")
2247 }
2248
Adam Langleyd9e397b2015-01-22 14:27:53 -08002249 // See http://tools.ietf.org/html/rfc5077#section-3.3
David Benjaminc895d6b2016-08-11 13:26:41 -04002250 ticketMsg := newByteBuilder()
2251 ticketMsg.addU8(typeNewSessionTicket)
2252 body := ticketMsg.addU24LengthPrefixed()
2253 body.addU32(m.ticketLifetime)
Robert Sloanb1b54b82017-11-06 13:50:02 -08002254 if version >= VersionTLS13 {
Steven Valdez909b19f2016-11-21 15:35:44 -05002255 body.addU32(m.ticketAgeAdd)
Robert Sloan8542c082018-02-05 09:07:34 -08002256 body.addU8LengthPrefixed().addBytes(m.ticketNonce)
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002257 }
2258
2259 ticket := body.addU16LengthPrefixed()
2260 ticket.addBytes(m.ticket)
2261
Robert Sloanb1b54b82017-11-06 13:50:02 -08002262 if version >= VersionTLS13 {
David Benjamin95add822016-10-19 01:09:12 -04002263 extensions := body.addU16LengthPrefixed()
Robert Sloan47f43ed2017-02-06 14:55:15 -08002264 if m.maxEarlyDataSize > 0 {
Robert Sloan8542c082018-02-05 09:07:34 -08002265 extensions.addU16(extensionEarlyData)
Robert Sloan47f43ed2017-02-06 14:55:15 -08002266 extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
Robert Sloanb1b54b82017-11-06 13:50:02 -08002267 if m.duplicateEarlyDataExtension {
Robert Sloan8542c082018-02-05 09:07:34 -08002268 extensions.addU16(extensionEarlyData)
Robert Sloan47f43ed2017-02-06 14:55:15 -08002269 extensions.addU16LengthPrefixed().addU32(m.maxEarlyDataSize)
Robert Sloan69939df2017-01-09 10:53:07 -08002270 }
2271 }
David Benjamin95add822016-10-19 01:09:12 -04002272 if len(m.customExtension) > 0 {
Robert Sloan69939df2017-01-09 10:53:07 -08002273 extensions.addU16(extensionCustom)
David Benjamin95add822016-10-19 01:09:12 -04002274 extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
2275 }
David Benjaminc895d6b2016-08-11 13:26:41 -04002276 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08002277
David Benjaminc895d6b2016-08-11 13:26:41 -04002278 m.raw = ticketMsg.finish()
2279 return m.raw
Adam Langleyd9e397b2015-01-22 14:27:53 -08002280}
2281
2282func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
2283 m.raw = data
2284
Robert Sloanb1b54b82017-11-06 13:50:02 -08002285 version, ok := wireToVersion(m.vers, m.isDTLS)
2286 if !ok {
2287 panic("unknown version")
2288 }
2289
David Benjaminc895d6b2016-08-11 13:26:41 -04002290 if len(data) < 8 {
2291 return false
2292 }
2293 m.ticketLifetime = uint32(data[4])<<24 | uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
2294 data = data[8:]
2295
Robert Sloanb1b54b82017-11-06 13:50:02 -08002296 if version >= VersionTLS13 {
Steven Valdez909b19f2016-11-21 15:35:44 -05002297 if len(data) < 4 {
David Benjaminc895d6b2016-08-11 13:26:41 -04002298 return false
2299 }
Steven Valdez909b19f2016-11-21 15:35:44 -05002300 m.ticketAgeAdd = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
2301 data = data[4:]
Robert Sloan8542c082018-02-05 09:07:34 -08002302 nonceLen := int(data[0])
2303 data = data[1:]
2304 if len(data) < nonceLen {
2305 return false
Robert Sloanb1b54b82017-11-06 13:50:02 -08002306 }
Robert Sloan8542c082018-02-05 09:07:34 -08002307 m.ticketNonce = data[:nonceLen]
2308 data = data[nonceLen:]
David Benjaminc895d6b2016-08-11 13:26:41 -04002309 }
2310
2311 if len(data) < 2 {
2312 return false
2313 }
2314 ticketLen := int(data[0])<<8 + int(data[1])
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002315 data = data[2:]
2316 if len(data) < ticketLen {
David Benjaminc895d6b2016-08-11 13:26:41 -04002317 return false
2318 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002319
Robert Sloanb1b54b82017-11-06 13:50:02 -08002320 if version >= VersionTLS13 && ticketLen == 0 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08002321 return false
2322 }
2323
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002324 m.ticket = data[:ticketLen]
2325 data = data[ticketLen:]
2326
Robert Sloanb1b54b82017-11-06 13:50:02 -08002327 if version >= VersionTLS13 {
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002328 if len(data) < 2 {
2329 return false
2330 }
Robert Sloan69939df2017-01-09 10:53:07 -08002331
2332 extensionsLength := int(data[0])<<8 | int(data[1])
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002333 data = data[2:]
Robert Sloan69939df2017-01-09 10:53:07 -08002334 if extensionsLength != len(data) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002335 return false
2336 }
David Benjamin95add822016-10-19 01:09:12 -04002337
Robert Sloan69939df2017-01-09 10:53:07 -08002338 for len(data) != 0 {
2339 if len(data) < 4 {
David Benjamin95add822016-10-19 01:09:12 -04002340 return false
2341 }
Robert Sloan69939df2017-01-09 10:53:07 -08002342 extension := uint16(data[0])<<8 | uint16(data[1])
2343 length := int(data[2])<<8 | int(data[3])
2344 data = data[4:]
2345 if len(data) < length {
David Benjamin95add822016-10-19 01:09:12 -04002346 return false
2347 }
David Benjamin95add822016-10-19 01:09:12 -04002348
Robert Sloan69939df2017-01-09 10:53:07 -08002349 switch extension {
Robert Sloan8542c082018-02-05 09:07:34 -08002350 case extensionEarlyData:
Robert Sloan69939df2017-01-09 10:53:07 -08002351 if length != 4 {
2352 return false
2353 }
Robert Sloan47f43ed2017-02-06 14:55:15 -08002354 m.maxEarlyDataSize = uint32(data[0])<<24 | uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
Robert Sloan69939df2017-01-09 10:53:07 -08002355 default:
2356 if isGREASEValue(extension) {
2357 m.hasGREASEExtension = true
2358 }
David Benjamin95add822016-10-19 01:09:12 -04002359 }
Robert Sloan69939df2017-01-09 10:53:07 -08002360
2361 data = data[length:]
David Benjamin95add822016-10-19 01:09:12 -04002362 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002363 }
2364
2365 if len(data) > 0 {
2366 return false
2367 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08002368
2369 return true
2370}
2371
2372type v2ClientHelloMsg struct {
2373 raw []byte
2374 vers uint16
2375 cipherSuites []uint16
2376 sessionId []byte
2377 challenge []byte
2378}
2379
Adam Langleyd9e397b2015-01-22 14:27:53 -08002380func (m *v2ClientHelloMsg) marshal() []byte {
2381 if m.raw != nil {
2382 return m.raw
2383 }
2384
2385 length := 1 + 2 + 2 + 2 + 2 + len(m.cipherSuites)*3 + len(m.sessionId) + len(m.challenge)
2386
2387 x := make([]byte, length)
2388 x[0] = 1
2389 x[1] = uint8(m.vers >> 8)
2390 x[2] = uint8(m.vers)
2391 x[3] = uint8((len(m.cipherSuites) * 3) >> 8)
2392 x[4] = uint8(len(m.cipherSuites) * 3)
2393 x[5] = uint8(len(m.sessionId) >> 8)
2394 x[6] = uint8(len(m.sessionId))
2395 x[7] = uint8(len(m.challenge) >> 8)
2396 x[8] = uint8(len(m.challenge))
2397 y := x[9:]
2398 for i, spec := range m.cipherSuites {
2399 y[i*3] = 0
2400 y[i*3+1] = uint8(spec >> 8)
2401 y[i*3+2] = uint8(spec)
2402 }
2403 y = y[len(m.cipherSuites)*3:]
2404 copy(y, m.sessionId)
2405 y = y[len(m.sessionId):]
2406 copy(y, m.challenge)
2407
2408 m.raw = x
2409
2410 return x
2411}
2412
2413type helloVerifyRequestMsg struct {
2414 raw []byte
2415 vers uint16
2416 cookie []byte
2417}
2418
Adam Langleyd9e397b2015-01-22 14:27:53 -08002419func (m *helloVerifyRequestMsg) marshal() []byte {
2420 if m.raw != nil {
2421 return m.raw
2422 }
2423
2424 length := 2 + 1 + len(m.cookie)
2425
2426 x := make([]byte, 4+length)
2427 x[0] = typeHelloVerifyRequest
2428 x[1] = uint8(length >> 16)
2429 x[2] = uint8(length >> 8)
2430 x[3] = uint8(length)
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002431 vers := m.vers
Adam Langleyd9e397b2015-01-22 14:27:53 -08002432 x[4] = uint8(vers >> 8)
2433 x[5] = uint8(vers)
2434 x[6] = uint8(len(m.cookie))
2435 copy(x[7:7+len(m.cookie)], m.cookie)
2436
2437 return x
2438}
2439
2440func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
2441 if len(data) < 4+2+1 {
2442 return false
2443 }
2444 m.raw = data
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002445 m.vers = uint16(data[4])<<8 | uint16(data[5])
Adam Langleyd9e397b2015-01-22 14:27:53 -08002446 cookieLen := int(data[6])
2447 if cookieLen > 32 || len(data) != 7+cookieLen {
2448 return false
2449 }
2450 m.cookie = data[7 : 7+cookieLen]
2451
2452 return true
2453}
2454
David Benjaminc895d6b2016-08-11 13:26:41 -04002455type channelIDMsg struct {
Adam Langleyd9e397b2015-01-22 14:27:53 -08002456 raw []byte
2457 channelID []byte
2458}
2459
David Benjaminc895d6b2016-08-11 13:26:41 -04002460func (m *channelIDMsg) marshal() []byte {
Adam Langleyd9e397b2015-01-22 14:27:53 -08002461 if m.raw != nil {
2462 return m.raw
2463 }
2464
2465 length := 2 + 2 + len(m.channelID)
2466
2467 x := make([]byte, 4+length)
David Benjaminc895d6b2016-08-11 13:26:41 -04002468 x[0] = typeChannelID
Adam Langleyd9e397b2015-01-22 14:27:53 -08002469 x[1] = uint8(length >> 16)
2470 x[2] = uint8(length >> 8)
2471 x[3] = uint8(length)
2472 x[4] = uint8(extensionChannelID >> 8)
2473 x[5] = uint8(extensionChannelID & 0xff)
2474 x[6] = uint8(len(m.channelID) >> 8)
2475 x[7] = uint8(len(m.channelID) & 0xff)
2476 copy(x[8:], m.channelID)
2477
2478 return x
2479}
2480
David Benjaminc895d6b2016-08-11 13:26:41 -04002481func (m *channelIDMsg) unmarshal(data []byte) bool {
Adam Langleyd9e397b2015-01-22 14:27:53 -08002482 if len(data) != 4+2+2+128 {
2483 return false
2484 }
2485 m.raw = data
2486 if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
2487 return false
2488 }
2489 if int(data[6])<<8|int(data[7]) != 128 {
2490 return false
2491 }
2492 m.channelID = data[4+2+2:]
2493
2494 return true
2495}
2496
2497type helloRequestMsg struct {
2498}
2499
2500func (*helloRequestMsg) marshal() []byte {
2501 return []byte{typeHelloRequest, 0, 0, 0}
2502}
2503
2504func (*helloRequestMsg) unmarshal(data []byte) bool {
2505 return len(data) == 4
2506}
2507
David Benjaminc895d6b2016-08-11 13:26:41 -04002508type keyUpdateMsg struct {
David Benjamin95add822016-10-19 01:09:12 -04002509 raw []byte
2510 keyUpdateRequest byte
David Benjaminc895d6b2016-08-11 13:26:41 -04002511}
2512
David Benjamin95add822016-10-19 01:09:12 -04002513func (m *keyUpdateMsg) marshal() []byte {
2514 if m.raw != nil {
2515 return m.raw
2516 }
2517
2518 return []byte{typeKeyUpdate, 0, 0, 1, m.keyUpdateRequest}
David Benjaminc895d6b2016-08-11 13:26:41 -04002519}
2520
David Benjamin95add822016-10-19 01:09:12 -04002521func (m *keyUpdateMsg) unmarshal(data []byte) bool {
2522 m.raw = data
2523
2524 if len(data) != 5 {
2525 return false
2526 }
2527
2528 length := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
2529 if len(data)-4 != length {
2530 return false
2531 }
2532
2533 m.keyUpdateRequest = data[4]
2534 return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
David Benjaminc895d6b2016-08-11 13:26:41 -04002535}
2536
Robert Sloanb1b54b82017-11-06 13:50:02 -08002537type endOfEarlyDataMsg struct {
2538 nonEmpty bool
2539}
2540
2541func (m *endOfEarlyDataMsg) marshal() []byte {
2542 if m.nonEmpty {
2543 return []byte{typeEndOfEarlyData, 0, 0, 1, 42}
2544 }
2545 return []byte{typeEndOfEarlyData, 0, 0, 0}
2546}
2547
2548func (*endOfEarlyDataMsg) unmarshal(data []byte) bool {
2549 return len(data) == 4
2550}
2551
Robert Sloan69939df2017-01-09 10:53:07 -08002552// ssl3NoCertificateMsg is a dummy message to handle SSL 3.0 using a warning
2553// alert in the handshake.
2554type ssl3NoCertificateMsg struct{}
2555
Adam Langleyd9e397b2015-01-22 14:27:53 -08002556func eqUint16s(x, y []uint16) bool {
2557 if len(x) != len(y) {
2558 return false
2559 }
2560 for i, v := range x {
2561 if y[i] != v {
2562 return false
2563 }
2564 }
2565 return true
2566}
2567
2568func eqCurveIDs(x, y []CurveID) bool {
2569 if len(x) != len(y) {
2570 return false
2571 }
2572 for i, v := range x {
2573 if y[i] != v {
2574 return false
2575 }
2576 }
2577 return true
2578}
2579
2580func eqStrings(x, y []string) bool {
2581 if len(x) != len(y) {
2582 return false
2583 }
2584 for i, v := range x {
2585 if y[i] != v {
2586 return false
2587 }
2588 }
2589 return true
2590}
2591
2592func eqByteSlices(x, y [][]byte) bool {
2593 if len(x) != len(y) {
2594 return false
2595 }
2596 for i, v := range x {
2597 if !bytes.Equal(v, y[i]) {
2598 return false
2599 }
2600 }
2601 return true
2602}
2603
David Benjaminc895d6b2016-08-11 13:26:41 -04002604func eqSignatureAlgorithms(x, y []signatureAlgorithm) bool {
Adam Langleyd9e397b2015-01-22 14:27:53 -08002605 if len(x) != len(y) {
2606 return false
2607 }
2608 for i, v := range x {
2609 v2 := y[i]
David Benjaminc895d6b2016-08-11 13:26:41 -04002610 if v != v2 {
Adam Langleyd9e397b2015-01-22 14:27:53 -08002611 return false
2612 }
2613 }
2614 return true
2615}
David Benjaminc895d6b2016-08-11 13:26:41 -04002616
2617func eqKeyShareEntryLists(x, y []keyShareEntry) bool {
2618 if len(x) != len(y) {
2619 return false
2620 }
2621 for i, v := range x {
2622 if y[i].group != v.group || !bytes.Equal(y[i].keyExchange, v.keyExchange) {
2623 return false
2624 }
2625 }
2626 return true
2627
2628}
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002629
2630func eqPSKIdentityLists(x, y []pskIdentity) bool {
2631 if len(x) != len(y) {
2632 return false
2633 }
2634 for i, v := range x {
Steven Valdez909b19f2016-11-21 15:35:44 -05002635 if !bytes.Equal(y[i].ticket, v.ticket) || y[i].obfuscatedTicketAge != v.obfuscatedTicketAge {
Steven Valdezbb1ceac2016-10-07 10:34:51 -04002636 return false
2637 }
2638 }
2639 return true
2640
2641}