// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package runner

import (
	"errors"
	"fmt"

	"golang.org/x/crypto/cryptobyte"
)

func readUint8LengthPrefixedBytes(s *cryptobyte.String, out *[]byte) bool {
	var child cryptobyte.String
	if !s.ReadUint8LengthPrefixed(&child) {
		return false
	}
	*out = child
	return true
}

func readUint16LengthPrefixedBytes(s *cryptobyte.String, out *[]byte) bool {
	var child cryptobyte.String
	if !s.ReadUint16LengthPrefixed(&child) {
		return false
	}
	*out = child
	return true
}

func readUint24LengthPrefixedBytes(s *cryptobyte.String, out *[]byte) bool {
	var child cryptobyte.String
	if !s.ReadUint24LengthPrefixed(&child) {
		return false
	}
	*out = child
	return true
}

func addUint8LengthPrefixedBytes(b *cryptobyte.Builder, v []byte) {
	b.AddUint8LengthPrefixed(func(child *cryptobyte.Builder) { child.AddBytes(v) })
}

func addUint16LengthPrefixedBytes(b *cryptobyte.Builder, v []byte) {
	b.AddUint16LengthPrefixed(func(child *cryptobyte.Builder) { child.AddBytes(v) })
}

func addUint24LengthPrefixedBytes(b *cryptobyte.Builder, v []byte) {
	b.AddUint24LengthPrefixed(func(child *cryptobyte.Builder) { child.AddBytes(v) })
}

type keyShareEntry struct {
	group       CurveID
	keyExchange []byte
}

type pskIdentity struct {
	ticket              []uint8
	obfuscatedTicketAge uint32
}

type HPKECipherSuite struct {
	KDF  uint16
	AEAD uint16
}

type ECHConfig struct {
	Raw          []byte
	ConfigID     uint8
	KEM          uint16
	PublicKey    []byte
	MaxNameLen   uint8
	PublicName   string
	CipherSuites []HPKECipherSuite
	// The following fields are only used by CreateECHConfig().
	UnsupportedExtension          bool
	UnsupportedMandatoryExtension bool
}

func CreateECHConfig(template *ECHConfig) *ECHConfig {
	bb := cryptobyte.NewBuilder(nil)
	// ECHConfig reuses the encrypted_client_hello extension codepoint as a
	// version identifier.
	bb.AddUint16(extensionEncryptedClientHello)
	bb.AddUint16LengthPrefixed(func(contents *cryptobyte.Builder) {
		contents.AddUint8(template.ConfigID)
		contents.AddUint16(template.KEM)
		addUint16LengthPrefixedBytes(contents, template.PublicKey)
		contents.AddUint16LengthPrefixed(func(cipherSuites *cryptobyte.Builder) {
			for _, suite := range template.CipherSuites {
				cipherSuites.AddUint16(suite.KDF)
				cipherSuites.AddUint16(suite.AEAD)
			}
		})
		contents.AddUint8(template.MaxNameLen)
		addUint8LengthPrefixedBytes(contents, []byte(template.PublicName))
		contents.AddUint16LengthPrefixed(func(extensions *cryptobyte.Builder) {
			// Mandatory extensions have the high bit set.
			if template.UnsupportedExtension {
				extensions.AddUint16(0x1111)
				addUint16LengthPrefixedBytes(extensions, []byte("test"))
			}
			if template.UnsupportedMandatoryExtension {
				extensions.AddUint16(0xaaaa)
				addUint16LengthPrefixedBytes(extensions, []byte("test"))
			}
		})
	})

	// This ought to be a call to a function like ParseECHConfig(bb.BytesOrPanic()),
	// but this constrains us to constructing ECHConfigs we are willing to
	// support. We need to test the client's behavior in response to unparsable
	// or unsupported ECHConfigs, so populate fields from the template directly.
	ret := *template
	ret.Raw = bb.BytesOrPanic()
	return &ret
}

func CreateECHConfigList(configs ...[]byte) []byte {
	bb := cryptobyte.NewBuilder(nil)
	bb.AddUint16LengthPrefixed(func(list *cryptobyte.Builder) {
		for _, config := range configs {
			list.AddBytes(config)
		}
	})
	return bb.BytesOrPanic()
}

type ServerECHConfig struct {
	ECHConfig *ECHConfig
	Key       []byte
}

const (
	echClientTypeOuter byte = 0
	echClientTypeInner byte = 1
)

type echClientOuter struct {
	kdfID    uint16
	aeadID   uint16
	configID uint8
	enc      []byte
	payload  []byte
}

type pakeShare struct {
	id  uint16
	msg []byte
}

type clientHelloMsg struct {
	raw                                      []byte
	isDTLS                                   bool
	isV2ClientHello                          bool
	vers                                     uint16
	random                                   []byte
	v2Challenge                              []byte
	sessionID                                []byte
	cookie                                   []byte
	cipherSuites                             []uint16
	compressionMethods                       []uint8
	nextProtoNeg                             bool
	serverName                               string
	echOuter                                 *echClientOuter
	echInner                                 bool
	invalidECHInner                          []byte
	ocspStapling                             bool
	supportedCurves                          []CurveID
	supportedPoints                          []uint8
	hasKeyShares                             bool
	keyShares                                []keyShareEntry
	keySharesRaw                             []byte
	trailingKeyShareData                     bool
	pskIdentities                            []pskIdentity
	pskKEModes                               []byte
	pskBinders                               [][]uint8
	hasEarlyData                             bool
	tls13Cookie                              []byte
	ticketSupported                          bool
	sessionTicket                            []uint8
	signatureAlgorithms                      []signatureAlgorithm
	signatureAlgorithmsCert                  []signatureAlgorithm
	supportedVersions                        []uint16
	secureRenegotiation                      []byte
	alpnProtocols                            []string
	quicTransportParams                      []byte
	quicTransportParamsLegacy                []byte
	duplicateExtension                       bool
	channelIDSupported                       bool
	extendedMasterSecret                     bool
	srtpProtectionProfiles                   []uint16
	srtpMasterKeyIdentifier                  string
	sctListSupported                         bool
	customExtension                          string
	hasGREASEExtension                       bool
	omitExtensions                           bool
	emptyExtensions                          bool
	pad                                      int
	compressedCertAlgs                       []uint16
	delegatedCredential                      []signatureAlgorithm
	alpsProtocols                            []string
	alpsProtocolsOld                         []string
	pakeClientID                             []byte
	pakeServerID                             []byte
	pakeShares                               []pakeShare
	outerExtensions                          []uint16
	reorderOuterExtensionsWithoutCompressing bool
	prefixExtensions                         []uint16
	// The following fields are only filled in by |unmarshal| and ignored when
	// marshaling a new ClientHello.
	echPayloadStart int
	echPayloadEnd   int
	rawExtensions   []byte
}

func (m *clientHelloMsg) marshalKeyShares(bb *cryptobyte.Builder) {
	bb.AddUint16LengthPrefixed(func(keyShares *cryptobyte.Builder) {
		for _, keyShare := range m.keyShares {
			keyShares.AddUint16(uint16(keyShare.group))
			addUint16LengthPrefixedBytes(keyShares, keyShare.keyExchange)
		}
		if m.trailingKeyShareData {
			keyShares.AddUint8(0)
		}
	})
}

type clientHelloType int

const (
	clientHelloNormal clientHelloType = iota
	clientHelloEncodedInner
)

func (m *clientHelloMsg) marshalBody(hello *cryptobyte.Builder, typ clientHelloType) {
	hello.AddUint16(m.vers)
	hello.AddBytes(m.random)
	hello.AddUint8LengthPrefixed(func(sessionID *cryptobyte.Builder) {
		if typ != clientHelloEncodedInner {
			sessionID.AddBytes(m.sessionID)
		}
	})
	if m.isDTLS {
		hello.AddUint8LengthPrefixed(func(cookie *cryptobyte.Builder) {
			cookie.AddBytes(m.cookie)
		})
	}
	hello.AddUint16LengthPrefixed(func(cipherSuites *cryptobyte.Builder) {
		for _, suite := range m.cipherSuites {
			cipherSuites.AddUint16(suite)
		}
	})
	hello.AddUint8LengthPrefixed(func(compressionMethods *cryptobyte.Builder) {
		compressionMethods.AddBytes(m.compressionMethods)
	})

	type extension struct {
		id   uint16
		body []byte
	}
	var extensions []extension

	if m.duplicateExtension {
		// Add a duplicate bogus extension at the beginning and end.
		extensions = append(extensions, extension{id: extensionDuplicate})
	}
	if m.nextProtoNeg {
		extensions = append(extensions, extension{id: extensionNextProtoNeg})
	}
	if len(m.serverName) > 0 {
		// RFC 3546, section 3.1
		//
		// struct {
		//     NameType name_type;
		//     select (name_type) {
		//         case host_name: HostName;
		//     } name;
		// } ServerName;
		//
		// enum {
		//     host_name(0), (255)
		// } NameType;
		//
		// opaque HostName<1..2^16-1>;
		//
		// struct {
		//     ServerName server_name_list<1..2^16-1>
		// } ServerNameList;

		serverNameList := cryptobyte.NewBuilder(nil)
		serverNameList.AddUint16LengthPrefixed(func(serverName *cryptobyte.Builder) {
			serverName.AddUint8(0) // NameType host_name(0)
			addUint16LengthPrefixedBytes(serverName, []byte(m.serverName))
		})

		extensions = append(extensions, extension{
			id:   extensionServerName,
			body: serverNameList.BytesOrPanic(),
		})
	}
	if m.echOuter != nil {
		body := cryptobyte.NewBuilder(nil)
		body.AddUint8(echClientTypeOuter)
		body.AddUint16(m.echOuter.kdfID)
		body.AddUint16(m.echOuter.aeadID)
		body.AddUint8(m.echOuter.configID)
		addUint16LengthPrefixedBytes(body, m.echOuter.enc)
		addUint16LengthPrefixedBytes(body, m.echOuter.payload)
		extensions = append(extensions, extension{
			id:   extensionEncryptedClientHello,
			body: body.BytesOrPanic(),
		})
	}
	if m.echInner {
		body := cryptobyte.NewBuilder(nil)
		body.AddUint8(echClientTypeInner)
		// If unset, invalidECHInner is empty, which is the correct serialization.
		body.AddBytes(m.invalidECHInner)
		extensions = append(extensions, extension{
			id:   extensionEncryptedClientHello,
			body: body.BytesOrPanic(),
		})
	}
	if m.ocspStapling {
		certificateStatusRequest := cryptobyte.NewBuilder(nil)
		// RFC 4366, section 3.6
		certificateStatusRequest.AddUint8(1) // OCSP type
		// Two zero valued uint16s for the two lengths.
		certificateStatusRequest.AddUint16(0) // ResponderID length
		certificateStatusRequest.AddUint16(0) // Extensions length
		extensions = append(extensions, extension{
			id:   extensionStatusRequest,
			body: certificateStatusRequest.BytesOrPanic(),
		})
	}
	if len(m.supportedCurves) > 0 {
		// http://tools.ietf.org/html/rfc4492#section-5.1.1
		supportedCurvesList := cryptobyte.NewBuilder(nil)
		supportedCurvesList.AddUint16LengthPrefixed(func(supportedCurves *cryptobyte.Builder) {
			for _, curve := range m.supportedCurves {
				supportedCurves.AddUint16(uint16(curve))
			}
		})
		extensions = append(extensions, extension{
			id:   extensionSupportedCurves,
			body: supportedCurvesList.BytesOrPanic(),
		})
	}
	if len(m.supportedPoints) > 0 {
		// http://tools.ietf.org/html/rfc4492#section-5.1.2
		supportedPointsList := cryptobyte.NewBuilder(nil)
		addUint8LengthPrefixedBytes(supportedPointsList, m.supportedPoints)
		extensions = append(extensions, extension{
			id:   extensionSupportedPoints,
			body: supportedPointsList.BytesOrPanic(),
		})
	}
	if m.hasKeyShares {
		keyShareList := cryptobyte.NewBuilder(nil)
		m.marshalKeyShares(keyShareList)
		extensions = append(extensions, extension{
			id:   extensionKeyShare,
			body: keyShareList.BytesOrPanic(),
		})
	}
	if len(m.pskKEModes) > 0 {
		pskModesExtension := cryptobyte.NewBuilder(nil)
		addUint8LengthPrefixedBytes(pskModesExtension, m.pskKEModes)
		extensions = append(extensions, extension{
			id:   extensionPSKKeyExchangeModes,
			body: pskModesExtension.BytesOrPanic(),
		})
	}
	if m.hasEarlyData {
		extensions = append(extensions, extension{id: extensionEarlyData})
	}
	if len(m.tls13Cookie) > 0 {
		body := cryptobyte.NewBuilder(nil)
		addUint16LengthPrefixedBytes(body, m.tls13Cookie)
		extensions = append(extensions, extension{
			id:   extensionCookie,
			body: body.BytesOrPanic(),
		})
	}
	if m.ticketSupported {
		// http://tools.ietf.org/html/rfc5077#section-3.2
		extensions = append(extensions, extension{
			id:   extensionSessionTicket,
			body: m.sessionTicket,
		})
	}
	if len(m.signatureAlgorithms) > 0 {
		// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
		signatureAlgorithmsExtension := cryptobyte.NewBuilder(nil)
		signatureAlgorithmsExtension.AddUint16LengthPrefixed(func(signatureAlgorithms *cryptobyte.Builder) {
			for _, sigAlg := range m.signatureAlgorithms {
				signatureAlgorithms.AddUint16(uint16(sigAlg))
			}
		})
		extensions = append(extensions, extension{
			id:   extensionSignatureAlgorithms,
			body: signatureAlgorithmsExtension.BytesOrPanic(),
		})
	}
	if len(m.signatureAlgorithmsCert) > 0 {
		signatureAlgorithmsCertExtension := cryptobyte.NewBuilder(nil)
		signatureAlgorithmsCertExtension.AddUint16LengthPrefixed(func(signatureAlgorithmsCert *cryptobyte.Builder) {
			for _, sigAlg := range m.signatureAlgorithmsCert {
				signatureAlgorithmsCert.AddUint16(uint16(sigAlg))
			}
		})
		extensions = append(extensions, extension{
			id:   extensionSignatureAlgorithmsCert,
			body: signatureAlgorithmsCertExtension.BytesOrPanic(),
		})
	}
	if len(m.supportedVersions) > 0 {
		supportedVersionsExtension := cryptobyte.NewBuilder(nil)
		supportedVersionsExtension.AddUint8LengthPrefixed(func(supportedVersions *cryptobyte.Builder) {
			for _, version := range m.supportedVersions {
				supportedVersions.AddUint16(uint16(version))
			}
		})
		extensions = append(extensions, extension{
			id:   extensionSupportedVersions,
			body: supportedVersionsExtension.BytesOrPanic(),
		})
	}
	if m.secureRenegotiation != nil {
		secureRenegoExt := cryptobyte.NewBuilder(nil)
		addUint8LengthPrefixedBytes(secureRenegoExt, m.secureRenegotiation)
		extensions = append(extensions, extension{
			id:   extensionRenegotiationInfo,
			body: secureRenegoExt.BytesOrPanic(),
		})
	}
	if len(m.alpnProtocols) > 0 {
		// https://tools.ietf.org/html/rfc7301#section-3.1
		alpnExtension := cryptobyte.NewBuilder(nil)
		alpnExtension.AddUint16LengthPrefixed(func(protocolNameList *cryptobyte.Builder) {
			for _, s := range m.alpnProtocols {
				addUint8LengthPrefixedBytes(protocolNameList, []byte(s))
			}
		})
		extensions = append(extensions, extension{
			id:   extensionALPN,
			body: alpnExtension.BytesOrPanic(),
		})
	}
	if len(m.quicTransportParams) > 0 {
		extensions = append(extensions, extension{
			id:   extensionQUICTransportParams,
			body: m.quicTransportParams,
		})
	}
	if len(m.quicTransportParamsLegacy) > 0 {
		extensions = append(extensions, extension{
			id:   extensionQUICTransportParamsLegacy,
			body: m.quicTransportParamsLegacy,
		})
	}
	if m.channelIDSupported {
		extensions = append(extensions, extension{id: extensionChannelID})
	}
	if m.duplicateExtension {
		// Add a duplicate bogus extension at the beginning and end.
		extensions = append(extensions, extension{id: extensionDuplicate})
	}
	if m.extendedMasterSecret {
		// https://tools.ietf.org/html/rfc7627
		extensions = append(extensions, extension{id: extensionExtendedMasterSecret})
	}
	if len(m.srtpProtectionProfiles) > 0 {
		// https://tools.ietf.org/html/rfc5764#section-4.1.1
		useSrtpExt := cryptobyte.NewBuilder(nil)

		useSrtpExt.AddUint16LengthPrefixed(func(srtpProtectionProfiles *cryptobyte.Builder) {
			for _, p := range m.srtpProtectionProfiles {
				srtpProtectionProfiles.AddUint16(p)
			}
		})
		addUint8LengthPrefixedBytes(useSrtpExt, []byte(m.srtpMasterKeyIdentifier))

		extensions = append(extensions, extension{
			id:   extensionUseSRTP,
			body: useSrtpExt.BytesOrPanic(),
		})
	}
	if m.sctListSupported {
		extensions = append(extensions, extension{id: extensionSignedCertificateTimestamp})
	}
	if len(m.customExtension) > 0 {
		extensions = append(extensions, extension{
			id:   extensionCustom,
			body: []byte(m.customExtension),
		})
	}
	if len(m.compressedCertAlgs) > 0 {
		body := cryptobyte.NewBuilder(nil)
		body.AddUint8LengthPrefixed(func(algIDs *cryptobyte.Builder) {
			for _, v := range m.compressedCertAlgs {
				algIDs.AddUint16(v)
			}
		})
		extensions = append(extensions, extension{
			id:   extensionCompressedCertAlgs,
			body: body.BytesOrPanic(),
		})
	}
	if len(m.delegatedCredential) > 0 {
		body := cryptobyte.NewBuilder(nil)
		body.AddUint16LengthPrefixed(func(signatureSchemeList *cryptobyte.Builder) {
			for _, sigAlg := range m.delegatedCredential {
				signatureSchemeList.AddUint16(uint16(sigAlg))
			}
		})
		extensions = append(extensions, extension{
			id:   extensionDelegatedCredential,
			body: body.BytesOrPanic(),
		})
	}
	if len(m.alpsProtocols) > 0 {
		body := cryptobyte.NewBuilder(nil)
		body.AddUint16LengthPrefixed(func(protocolNameList *cryptobyte.Builder) {
			for _, s := range m.alpsProtocols {
				addUint8LengthPrefixedBytes(protocolNameList, []byte(s))
			}
		})
		extensions = append(extensions, extension{
			id:   extensionApplicationSettings,
			body: body.BytesOrPanic(),
		})
	}
	if len(m.alpsProtocolsOld) > 0 {
		body := cryptobyte.NewBuilder(nil)
		body.AddUint16LengthPrefixed(func(protocolNameList *cryptobyte.Builder) {
			for _, s := range m.alpsProtocolsOld {
				addUint8LengthPrefixedBytes(protocolNameList, []byte(s))
			}
		})
		extensions = append(extensions, extension{
			id:   extensionApplicationSettingsOld,
			body: body.BytesOrPanic(),
		})
	}
	if len(m.pakeShares) > 0 {
		body := cryptobyte.NewBuilder(nil)
		addUint16LengthPrefixedBytes(body, m.pakeClientID)
		addUint16LengthPrefixedBytes(body, m.pakeServerID)
		body.AddUint16LengthPrefixed(func(shares *cryptobyte.Builder) {
			for _, share := range m.pakeShares {
				shares.AddUint16(share.id)
				addUint16LengthPrefixedBytes(shares, share.msg)
			}
		})
		extensions = append(extensions, extension{
			id:   extensionPAKE,
			body: body.BytesOrPanic(),
		})
	}
	// The PSK extension must be last. See https://tools.ietf.org/html/rfc8446#section-4.2.11
	if len(m.pskIdentities) > 0 {
		pskExtension := cryptobyte.NewBuilder(nil)
		pskExtension.AddUint16LengthPrefixed(func(pskIdentities *cryptobyte.Builder) {
			for _, psk := range m.pskIdentities {
				addUint16LengthPrefixedBytes(pskIdentities, psk.ticket)
				pskIdentities.AddUint32(psk.obfuscatedTicketAge)
			}
		})
		pskExtension.AddUint16LengthPrefixed(func(pskBinders *cryptobyte.Builder) {
			for _, binder := range m.pskBinders {
				addUint8LengthPrefixedBytes(pskBinders, binder)
			}
		})
		extensions = append(extensions, extension{
			id:   extensionPreSharedKey,
			body: pskExtension.BytesOrPanic(),
		})
	}

	if m.omitExtensions {
		return
	}
	hello.AddUint16LengthPrefixed(func(extensionsBB *cryptobyte.Builder) {
		if m.emptyExtensions {
			return
		}
		extMap := make(map[uint16][]byte)
		extsWritten := make(map[uint16]struct{})
		for _, ext := range extensions {
			extMap[ext.id] = ext.body
		}
		// Write each of the prefix extensions, if we have it.
		for _, extID := range m.prefixExtensions {
			if body, ok := extMap[extID]; ok {
				extensionsBB.AddUint16(extID)
				addUint16LengthPrefixedBytes(extensionsBB, body)
				extsWritten[extID] = struct{}{}
			}
		}
		// Write outer extensions, possibly in compressed form.
		if m.outerExtensions != nil {
			if typ == clientHelloEncodedInner && !m.reorderOuterExtensionsWithoutCompressing {
				extensionsBB.AddUint16(extensionECHOuterExtensions)
				extensionsBB.AddUint16LengthPrefixed(func(child *cryptobyte.Builder) {
					child.AddUint8LengthPrefixed(func(list *cryptobyte.Builder) {
						for _, extID := range m.outerExtensions {
							list.AddUint16(extID)
							extsWritten[extID] = struct{}{}
						}
					})
				})
			} else {
				for _, extID := range m.outerExtensions {
					// m.outerExtensions may intentionally contain duplicates to test the
					// server's reaction. If m.reorderOuterExtensionsWithoutCompressing
					// is set, we are targetting the second ClientHello and wish to send a
					// valid first ClientHello. In that case, deduplicate so the error
					// only appears later.
					if _, written := extsWritten[extID]; m.reorderOuterExtensionsWithoutCompressing && written {
						continue
					}
					if body, ok := extMap[extID]; ok {
						extensionsBB.AddUint16(extID)
						addUint16LengthPrefixedBytes(extensionsBB, body)
						extsWritten[extID] = struct{}{}
					}
				}
			}
		}

		// Write each of the remaining extensions in their original order.
		for _, ext := range extensions {
			if _, written := extsWritten[ext.id]; !written {
				extensionsBB.AddUint16(ext.id)
				addUint16LengthPrefixedBytes(extensionsBB, ext.body)
			}
		}

		if m.pad != 0 && len(hello.BytesOrPanic())%m.pad != 0 {
			extensionsBB.AddUint16(extensionPadding)
			extensionsBB.AddUint16LengthPrefixed(func(padding *cryptobyte.Builder) {
				// Note hello.len() has changed at this point from the length
				// prefix.
				if l := len(hello.BytesOrPanic()) % m.pad; l != 0 {
					padding.AddBytes(make([]byte, m.pad-l))
				}
			})
		}
	})
}

func (m *clientHelloMsg) marshalForEncodedInner() []byte {
	hello := cryptobyte.NewBuilder(nil)
	m.marshalBody(hello, clientHelloEncodedInner)
	return hello.BytesOrPanic()
}

func (m *clientHelloMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	if m.isV2ClientHello {
		v2Msg := cryptobyte.NewBuilder(nil)
		v2Msg.AddUint8(1)
		v2Msg.AddUint16(m.vers)
		v2Msg.AddUint16(uint16(len(m.cipherSuites) * 3))
		v2Msg.AddUint16(uint16(len(m.sessionID)))
		v2Msg.AddUint16(uint16(len(m.v2Challenge)))
		for _, spec := range m.cipherSuites {
			v2Msg.AddUint24(uint32(spec))
		}
		v2Msg.AddBytes(m.sessionID)
		v2Msg.AddBytes(m.v2Challenge)
		m.raw = v2Msg.BytesOrPanic()
		return m.raw
	}

	handshakeMsg := cryptobyte.NewBuilder(nil)
	handshakeMsg.AddUint8(typeClientHello)
	handshakeMsg.AddUint24LengthPrefixed(func(hello *cryptobyte.Builder) {
		m.marshalBody(hello, clientHelloNormal)
	})
	m.raw = handshakeMsg.BytesOrPanic()
	// Sanity-check padding.
	if m.pad != 0 && (len(m.raw)-4)%m.pad != 0 {
		panic(fmt.Sprintf("%d is not a multiple of %d", len(m.raw)-4, m.pad))
	}
	return m.raw
}

func parseSignatureAlgorithms(reader *cryptobyte.String, out *[]signatureAlgorithm, allowEmpty bool) bool {
	var sigAlgs cryptobyte.String
	if !reader.ReadUint16LengthPrefixed(&sigAlgs) {
		return false
	}
	if !allowEmpty && len(sigAlgs) == 0 {
		return false
	}
	*out = make([]signatureAlgorithm, 0, len(sigAlgs)/2)
	for len(sigAlgs) > 0 {
		var v uint16
		if !sigAlgs.ReadUint16(&v) {
			return false
		}
		if signatureAlgorithm(v) == signatureRSAPKCS1WithMD5AndSHA1 {
			// signatureRSAPKCS1WithMD5AndSHA1 is an internal value BoringSSL
			// uses to represent the TLS 1.0 MD5/SHA-1 concatenation. It should
			// never appear on the wire.
			return false
		}
		*out = append(*out, signatureAlgorithm(v))
	}
	return true
}

func checkDuplicateExtensions(extensions cryptobyte.String) bool {
	seen := make(map[uint16]struct{})
	for len(extensions) > 0 {
		var extension uint16
		var body cryptobyte.String
		if !extensions.ReadUint16(&extension) ||
			!extensions.ReadUint16LengthPrefixed(&body) {
			return false
		}
		if _, ok := seen[extension]; ok {
			return false
		}
		seen[extension] = struct{}{}
	}
	return true
}

func (m *clientHelloMsg) unmarshal(data []byte) bool {
	m.raw = data
	reader := cryptobyte.String(data[4:])
	if !reader.ReadUint16(&m.vers) ||
		!reader.ReadBytes(&m.random, 32) ||
		!readUint8LengthPrefixedBytes(&reader, &m.sessionID) ||
		len(m.sessionID) > 32 {
		return false
	}
	if m.isDTLS && !readUint8LengthPrefixedBytes(&reader, &m.cookie) {
		return false
	}
	var cipherSuites cryptobyte.String
	if !reader.ReadUint16LengthPrefixed(&cipherSuites) ||
		!readUint8LengthPrefixedBytes(&reader, &m.compressionMethods) {
		return false
	}

	m.cipherSuites = make([]uint16, 0, len(cipherSuites)/2)
	for len(cipherSuites) > 0 {
		var v uint16
		if !cipherSuites.ReadUint16(&v) {
			return false
		}
		m.cipherSuites = append(m.cipherSuites, v)
		if v == scsvRenegotiation {
			m.secureRenegotiation = []byte{}
		}
	}

	m.nextProtoNeg = false
	m.serverName = ""
	m.ocspStapling = false
	m.keyShares = nil
	m.pskIdentities = nil
	m.hasEarlyData = false
	m.ticketSupported = false
	m.sessionTicket = nil
	m.signatureAlgorithms = nil
	m.signatureAlgorithmsCert = nil
	m.supportedVersions = nil
	m.alpnProtocols = nil
	m.extendedMasterSecret = false
	m.customExtension = ""
	m.delegatedCredential = nil
	m.alpsProtocols = nil
	m.alpsProtocolsOld = nil
	m.pakeClientID = nil
	m.pakeServerID = nil
	m.pakeShares = nil

	if len(reader) == 0 {
		// ClientHello is optionally followed by extension data
		return true
	}

	var extensions cryptobyte.String
	if !reader.ReadUint16LengthPrefixed(&extensions) || len(reader) != 0 || !checkDuplicateExtensions(extensions) {
		return false
	}
	m.rawExtensions = extensions
	for len(extensions) > 0 {
		var extension uint16
		var body cryptobyte.String
		if !extensions.ReadUint16(&extension) ||
			!extensions.ReadUint16LengthPrefixed(&body) {
			return false
		}
		switch extension {
		case extensionServerName:
			var names cryptobyte.String
			if !body.ReadUint16LengthPrefixed(&names) || len(body) != 0 {
				return false
			}
			for len(names) > 0 {
				var nameType byte
				var name []byte
				if !names.ReadUint8(&nameType) ||
					!readUint16LengthPrefixedBytes(&names, &name) {
					return false
				}
				if nameType == 0 {
					m.serverName = string(name)
				}
			}
		case extensionEncryptedClientHello:
			var typ byte
			if !body.ReadUint8(&typ) {
				return false
			}
			switch typ {
			case echClientTypeOuter:
				var echOuter echClientOuter
				if !body.ReadUint16(&echOuter.kdfID) ||
					!body.ReadUint16(&echOuter.aeadID) ||
					!body.ReadUint8(&echOuter.configID) ||
					!readUint16LengthPrefixedBytes(&body, &echOuter.enc) ||
					!readUint16LengthPrefixedBytes(&body, &echOuter.payload) ||
					len(echOuter.payload) == 0 ||
					len(body) > 0 {
					return false
				}
				m.echOuter = &echOuter
				m.echPayloadEnd = len(data) - len(extensions)
				m.echPayloadStart = m.echPayloadEnd - len(echOuter.payload)
			case echClientTypeInner:
				if len(body) > 0 {
					return false
				}
				m.echInner = true
			default:
				return false
			}
		case extensionNextProtoNeg:
			if len(body) != 0 {
				return false
			}
			m.nextProtoNeg = true
		case extensionStatusRequest:
			// This parse is stricter than a production implementation would
			// use. The status_request extension has many layers of interior
			// extensibility, but we expect our client to only send empty
			// requests of type OCSP.
			var statusType uint8
			var responderIDList, innerExtensions cryptobyte.String
			if !body.ReadUint8(&statusType) ||
				statusType != statusTypeOCSP ||
				!body.ReadUint16LengthPrefixed(&responderIDList) ||
				!body.ReadUint16LengthPrefixed(&innerExtensions) ||
				len(responderIDList) != 0 ||
				len(innerExtensions) != 0 ||
				len(body) != 0 {
				return false
			}
			m.ocspStapling = true
		case extensionSupportedCurves:
			// http://tools.ietf.org/html/rfc4492#section-5.5.1
			var curves cryptobyte.String
			if !body.ReadUint16LengthPrefixed(&curves) || len(body) != 0 {
				return false
			}
			m.supportedCurves = make([]CurveID, 0, len(curves)/2)
			for len(curves) > 0 {
				var v uint16
				if !curves.ReadUint16(&v) {
					return false
				}
				m.supportedCurves = append(m.supportedCurves, CurveID(v))
			}
		case extensionSupportedPoints:
			// http://tools.ietf.org/html/rfc4492#section-5.1.2
			if !readUint8LengthPrefixedBytes(&body, &m.supportedPoints) || len(m.supportedPoints) == 0 || len(body) != 0 {
				return false
			}
		case extensionSessionTicket:
			// http://tools.ietf.org/html/rfc5077#section-3.2
			m.ticketSupported = true
			m.sessionTicket = []byte(body)
		case extensionKeyShare:
			// https://tools.ietf.org/html/rfc8446#section-4.2.8
			m.hasKeyShares = true
			m.keySharesRaw = body
			var keyShares cryptobyte.String
			if !body.ReadUint16LengthPrefixed(&keyShares) || len(body) != 0 {
				return false
			}
			for len(keyShares) > 0 {
				var entry keyShareEntry
				var group uint16
				if !keyShares.ReadUint16(&group) ||
					!readUint16LengthPrefixedBytes(&keyShares, &entry.keyExchange) {
					return false
				}
				entry.group = CurveID(group)
				m.keyShares = append(m.keyShares, entry)
			}
		case extensionPreSharedKey:
			// https://tools.ietf.org/html/rfc8446#section-4.2.11
			var psks, binders cryptobyte.String
			if !body.ReadUint16LengthPrefixed(&psks) ||
				!body.ReadUint16LengthPrefixed(&binders) ||
				len(body) != 0 {
				return false
			}
			for len(psks) > 0 {
				var psk pskIdentity
				if !readUint16LengthPrefixedBytes(&psks, &psk.ticket) ||
					!psks.ReadUint32(&psk.obfuscatedTicketAge) {
					return false
				}
				m.pskIdentities = append(m.pskIdentities, psk)
			}
			for len(binders) > 0 {
				var binder []byte
				if !readUint8LengthPrefixedBytes(&binders, &binder) {
					return false
				}
				m.pskBinders = append(m.pskBinders, binder)
			}

			// There must be the same number of identities as binders.
			if len(m.pskIdentities) != len(m.pskBinders) {
				return false
			}
		case extensionPSKKeyExchangeModes:
			// https://tools.ietf.org/html/rfc8446#section-4.2.9
			if !readUint8LengthPrefixedBytes(&body, &m.pskKEModes) || len(body) != 0 {
				return false
			}
		case extensionEarlyData:
			// https://tools.ietf.org/html/rfc8446#section-4.2.10
			if len(body) != 0 {
				return false
			}
			m.hasEarlyData = true
		case extensionCookie:
			if !readUint16LengthPrefixedBytes(&body, &m.tls13Cookie) || len(body) != 0 {
				return false
			}
		case extensionSignatureAlgorithms:
			// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
			if !parseSignatureAlgorithms(&body, &m.signatureAlgorithms, false) || len(body) != 0 {
				return false
			}
		case extensionSignatureAlgorithmsCert:
			if !parseSignatureAlgorithms(&body, &m.signatureAlgorithmsCert, false) || len(body) != 0 {
				return false
			}
		case extensionSupportedVersions:
			var versions cryptobyte.String
			if !body.ReadUint8LengthPrefixed(&versions) || len(body) != 0 {
				return false
			}
			m.supportedVersions = make([]uint16, 0, len(versions)/2)
			for len(versions) > 0 {
				var v uint16
				if !versions.ReadUint16(&v) {
					return false
				}
				m.supportedVersions = append(m.supportedVersions, v)
			}
		case extensionRenegotiationInfo:
			if !readUint8LengthPrefixedBytes(&body, &m.secureRenegotiation) || len(body) != 0 {
				return false
			}
		case extensionALPN:
			var protocols cryptobyte.String
			if !body.ReadUint16LengthPrefixed(&protocols) || len(body) != 0 {
				return false
			}
			for len(protocols) > 0 {
				var protocol []byte
				if !readUint8LengthPrefixedBytes(&protocols, &protocol) || len(protocol) == 0 {
					return false
				}
				m.alpnProtocols = append(m.alpnProtocols, string(protocol))
			}
		case extensionQUICTransportParams:
			m.quicTransportParams = body
		case extensionQUICTransportParamsLegacy:
			m.quicTransportParamsLegacy = body
		case extensionChannelID:
			if len(body) != 0 {
				return false
			}
			m.channelIDSupported = true
		case extensionExtendedMasterSecret:
			if len(body) != 0 {
				return false
			}
			m.extendedMasterSecret = true
		case extensionUseSRTP:
			var profiles cryptobyte.String
			var mki []byte
			if !body.ReadUint16LengthPrefixed(&profiles) ||
				!readUint8LengthPrefixedBytes(&body, &mki) ||
				len(body) != 0 {
				return false
			}
			m.srtpProtectionProfiles = make([]uint16, 0, len(profiles)/2)
			for len(profiles) > 0 {
				var v uint16
				if !profiles.ReadUint16(&v) {
					return false
				}
				m.srtpProtectionProfiles = append(m.srtpProtectionProfiles, v)
			}
			m.srtpMasterKeyIdentifier = string(mki)
		case extensionSignedCertificateTimestamp:
			if len(body) != 0 {
				return false
			}
			m.sctListSupported = true
		case extensionCustom:
			m.customExtension = string(body)
		case extensionCompressedCertAlgs:
			var algIDs cryptobyte.String
			if !body.ReadUint8LengthPrefixed(&algIDs) {
				return false
			}

			seen := make(map[uint16]struct{})
			for len(algIDs) > 0 {
				var algID uint16
				if !algIDs.ReadUint16(&algID) {
					return false
				}
				if _, ok := seen[algID]; ok {
					return false
				}
				seen[algID] = struct{}{}
				m.compressedCertAlgs = append(m.compressedCertAlgs, algID)
			}
		case extensionPadding:
			// Padding bytes must be all zero.
			for _, b := range body {
				if b != 0 {
					return false
				}
			}
		case extensionDelegatedCredential:
			if !parseSignatureAlgorithms(&body, &m.delegatedCredential, false) || len(body) != 0 {
				return false
			}
		case extensionApplicationSettings:
			var protocols cryptobyte.String
			if !body.ReadUint16LengthPrefixed(&protocols) || len(body) != 0 {
				return false
			}
			for len(protocols) > 0 {
				var protocol []byte
				if !readUint8LengthPrefixedBytes(&protocols, &protocol) || len(protocol) == 0 {
					return false
				}
				m.alpsProtocols = append(m.alpsProtocols, string(protocol))
			}
		case extensionApplicationSettingsOld:
			var protocols cryptobyte.String
			if !body.ReadUint16LengthPrefixed(&protocols) || len(body) != 0 {
				return false
			}
			for len(protocols) > 0 {
				var protocol []byte
				if !readUint8LengthPrefixedBytes(&protocols, &protocol) || len(protocol) == 0 {
					return false
				}
				m.alpsProtocolsOld = append(m.alpsProtocolsOld, string(protocol))
			}
		case extensionPAKE:
			var clientId, serverId, shares cryptobyte.String
			if !body.ReadUint16LengthPrefixed(&clientId) ||
				!body.ReadUint16LengthPrefixed(&serverId) ||
				!body.ReadUint16LengthPrefixed(&shares) ||
				len(body) != 0 {
				return false
			}
			for len(shares) > 0 {
				var id uint16
				var msg cryptobyte.String
				if !shares.ReadUint16(&id) ||
					!shares.ReadUint16LengthPrefixed(&msg) {
					return false
				}
				m.pakeClientID = []byte(clientId)
				m.pakeServerID = []byte(serverId)
				m.pakeShares = append(m.pakeShares, pakeShare{id: id, msg: msg})
			}
		}

		if isGREASEValue(extension) {
			m.hasGREASEExtension = true
		}
	}

	return true
}

func decodeClientHelloInner(config *Config, encoded []byte, helloOuter *clientHelloMsg) (*clientHelloMsg, error) {
	reader := cryptobyte.String(encoded)
	var versAndRandom, sessionID, cookie, cipherSuites, compressionMethods []byte
	var extensions cryptobyte.String
	if !reader.ReadBytes(&versAndRandom, 2+32) ||
		!readUint8LengthPrefixedBytes(&reader, &sessionID) ||
		len(sessionID) != 0 { // Copied from |helloOuter|
		return nil, errors.New("tls: error parsing EncodedClientHelloInner")
	}
	if helloOuter.isDTLS {
		if !readUint8LengthPrefixedBytes(&reader, &cookie) || len(cookie) != 0 {
			return nil, errors.New("tls: error parsing EncodedClientHelloInner")
		}
	}
	if !readUint16LengthPrefixedBytes(&reader, &cipherSuites) ||
		!readUint8LengthPrefixedBytes(&reader, &compressionMethods) ||
		!reader.ReadUint16LengthPrefixed(&extensions) {
		return nil, errors.New("tls: error parsing EncodedClientHelloInner")
	}

	// The remainder of the structure is padding.
	for _, padding := range reader {
		if padding != 0 {
			return nil, errors.New("tls: non-zero padding in EncodedClientHelloInner")
		}
	}

	copied := make(map[uint16]struct{})
	builder := cryptobyte.NewBuilder(nil)
	builder.AddUint8(typeClientHello)
	builder.AddUint24LengthPrefixed(func(body *cryptobyte.Builder) {
		body.AddBytes(versAndRandom)
		addUint8LengthPrefixedBytes(body, helloOuter.sessionID)
		if helloOuter.isDTLS {
			addUint8LengthPrefixedBytes(body, cookie)
		}
		addUint16LengthPrefixedBytes(body, cipherSuites)
		addUint8LengthPrefixedBytes(body, compressionMethods)
		body.AddUint16LengthPrefixed(func(newExtensions *cryptobyte.Builder) {
			var seenOuterExtensions bool
			outerExtensions := cryptobyte.String(helloOuter.rawExtensions)
			for len(extensions) > 0 {
				var extType uint16
				var extBody cryptobyte.String
				if !extensions.ReadUint16(&extType) ||
					!extensions.ReadUint16LengthPrefixed(&extBody) {
					newExtensions.SetError(errors.New("tls: error parsing EncodedClientHelloInner"))
					return
				}
				if extType != extensionECHOuterExtensions {
					newExtensions.AddUint16(extType)
					addUint16LengthPrefixedBytes(newExtensions, extBody)
					continue
				}
				if seenOuterExtensions {
					newExtensions.SetError(errors.New("tls: duplicate ech_outer_extensions extension"))
					return
				}
				seenOuterExtensions = true
				var extList cryptobyte.String
				if !extBody.ReadUint8LengthPrefixed(&extList) || len(extList) == 0 || len(extBody) != 0 {
					newExtensions.SetError(errors.New("tls: error parsing ech_outer_extensions"))
					return
				}
				for len(extList) != 0 {
					var newExtType uint16
					if !extList.ReadUint16(&newExtType) {
						newExtensions.SetError(errors.New("tls: error parsing ech_outer_extensions"))
						return
					}
					if newExtType == extensionEncryptedClientHello {
						newExtensions.SetError(errors.New("tls: error parsing ech_outer_extensions"))
						return
					}
					for {
						if len(outerExtensions) == 0 {
							newExtensions.SetError(fmt.Errorf("tls: extension %d not found in ClientHelloOuter", newExtType))
							return
						}
						var foundExt uint16
						var newExtBody []byte
						if !outerExtensions.ReadUint16(&foundExt) ||
							!readUint16LengthPrefixedBytes(&outerExtensions, &newExtBody) {
							newExtensions.SetError(errors.New("tls: error parsing ClientHelloOuter"))
							return
						}
						if foundExt == newExtType {
							newExtensions.AddUint16(newExtType)
							addUint16LengthPrefixedBytes(newExtensions, newExtBody)
							copied[newExtType] = struct{}{}
							break
						}
					}
				}
			}
		})
	})

	bytes, err := builder.Bytes()
	if err != nil {
		return nil, err
	}

	for _, expected := range config.Bugs.ExpectECHOuterExtensions {
		if _, ok := copied[expected]; !ok {
			return nil, fmt.Errorf("tls: extension %d not found in ech_outer_extensions", expected)
		}
	}
	for _, expected := range config.Bugs.ExpectECHUncompressedExtensions {
		if _, ok := copied[expected]; ok {
			return nil, fmt.Errorf("tls: extension %d unexpectedly found in ech_outer_extensions", expected)
		}
	}

	ret := &clientHelloMsg{isDTLS: helloOuter.isDTLS}
	if !ret.unmarshal(bytes) {
		return nil, errors.New("tls: error parsing reconstructed ClientHello")
	}

	return ret, nil
}

type serverHelloMsg struct {
	raw                   []byte
	isDTLS                bool
	vers                  uint16
	versOverride          uint16
	supportedVersOverride uint16
	omitSupportedVers     bool
	random                []byte
	sessionID             []byte
	cipherSuite           uint16
	hasKeyShare           bool
	keyShare              keyShareEntry
	hasPSKIdentity        bool
	pskIdentity           uint16
	compressionMethod     uint8
	customExtension       string
	unencryptedALPN       string
	omitExtensions        bool
	emptyExtensions       bool
	extensions            serverExtensions
	pakeID                uint16
	pakeMessage           []byte
}

func (m *serverHelloMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	handshakeMsg := cryptobyte.NewBuilder(nil)
	handshakeMsg.AddUint8(typeServerHello)
	handshakeMsg.AddUint24LengthPrefixed(func(hello *cryptobyte.Builder) {
		// m.vers is used both to determine the format of the rest of the
		// ServerHello and to override the value, so include a second version
		// field.
		vers, ok := wireToVersion(m.vers, m.isDTLS)
		if !ok {
			panic("unknown version")
		}
		if m.versOverride != 0 {
			hello.AddUint16(m.versOverride)
		} else if vers >= VersionTLS13 {
			legacyVersion := uint16(VersionTLS12)
			if m.isDTLS {
				legacyVersion = VersionDTLS12
			}
			hello.AddUint16(legacyVersion)
		} else {
			hello.AddUint16(m.vers)
		}

		hello.AddBytes(m.random)
		addUint8LengthPrefixedBytes(hello, m.sessionID)
		hello.AddUint16(m.cipherSuite)
		hello.AddUint8(m.compressionMethod)

		hello.AddUint16LengthPrefixed(func(extensions *cryptobyte.Builder) {
			if vers >= VersionTLS13 {
				if m.hasKeyShare {
					extensions.AddUint16(extensionKeyShare)
					extensions.AddUint16LengthPrefixed(func(keyShare *cryptobyte.Builder) {
						keyShare.AddUint16(uint16(m.keyShare.group))
						addUint16LengthPrefixedBytes(keyShare, m.keyShare.keyExchange)
					})
				}
				if m.hasPSKIdentity {
					extensions.AddUint16(extensionPreSharedKey)
					extensions.AddUint16(2) // Length
					extensions.AddUint16(m.pskIdentity)
				}
				if !m.omitSupportedVers {
					extensions.AddUint16(extensionSupportedVersions)
					extensions.AddUint16(2) // Length
					if m.supportedVersOverride != 0 {
						extensions.AddUint16(m.supportedVersOverride)
					} else {
						extensions.AddUint16(m.vers)
					}
				}
				if len(m.pakeMessage) != 0 {
					extensions.AddUint16(extensionPAKE)
					extensions.AddUint16LengthPrefixed(func(share *cryptobyte.Builder) {
						share.AddUint16(m.pakeID)
						addUint16LengthPrefixedBytes(share, m.pakeMessage)
					})
				}
				if len(m.customExtension) > 0 {
					extensions.AddUint16(extensionCustom)
					addUint16LengthPrefixedBytes(extensions, []byte(m.customExtension))
				}
				if len(m.unencryptedALPN) > 0 {
					extensions.AddUint16(extensionALPN)
					extensions.AddUint16LengthPrefixed(func(extension *cryptobyte.Builder) {
						extension.AddUint16LengthPrefixed(func(protocolNameList *cryptobyte.Builder) {
							addUint8LengthPrefixedBytes(protocolNameList, []byte(m.unencryptedALPN))
						})
					})
				}
			} else {
				m.extensions.marshal(extensions)
			}
			if m.omitExtensions || m.emptyExtensions {
				// Silently erasing server extensions will break the handshake. Instead,
				// assert that tests which use this field also disable all features which
				// would write an extension. Note the length includes the length prefix.
				if b := extensions.BytesOrPanic(); len(b) != 2 {
					panic(fmt.Sprintf("ServerHello unexpectedly contained extensions: %x, %+v", b, m))
				}
			}
		})
		// Remove the length prefix.
		if m.omitExtensions {
			hello.Unwrite(2)
		}
	})

	m.raw = handshakeMsg.BytesOrPanic()
	return m.raw
}

func (m *serverHelloMsg) unmarshal(data []byte) bool {
	m.raw = data
	reader := cryptobyte.String(data[4:])
	if !reader.ReadUint16(&m.vers) ||
		!reader.ReadBytes(&m.random, 32) {
		return false
	}
	vers, ok := wireToVersion(m.vers, m.isDTLS)
	if !ok {
		return false
	}
	if !readUint8LengthPrefixedBytes(&reader, &m.sessionID) ||
		!reader.ReadUint16(&m.cipherSuite) ||
		!reader.ReadUint8(&m.compressionMethod) {
		return false
	}

	if len(reader) == 0 && m.vers < VersionTLS13 {
		// Extension data is optional before TLS 1.3.
		m.extensions = serverExtensions{}
		m.omitExtensions = true
		return true
	}

	var extensions cryptobyte.String
	if !reader.ReadUint16LengthPrefixed(&extensions) || len(reader) != 0 || !checkDuplicateExtensions(extensions) {
		return false
	}

	// Parse out the version from supported_versions if available.
	if vers == VersionTLS12 {
		extensionsCopy := extensions
		for len(extensionsCopy) > 0 {
			var extension uint16
			var body cryptobyte.String
			if !extensionsCopy.ReadUint16(&extension) ||
				!extensionsCopy.ReadUint16LengthPrefixed(&body) {
				return false
			}
			if extension == extensionSupportedVersions {
				if !body.ReadUint16(&m.vers) || len(body) != 0 {
					return false
				}
				vers, ok = wireToVersion(m.vers, m.isDTLS)
				if !ok {
					return false
				}
			}
		}
	}

	if vers >= VersionTLS13 {
		for len(extensions) > 0 {
			var extension uint16
			var body cryptobyte.String
			if !extensions.ReadUint16(&extension) ||
				!extensions.ReadUint16LengthPrefixed(&body) {
				return false
			}
			switch extension {
			case extensionKeyShare:
				m.hasKeyShare = true
				var group uint16
				if !body.ReadUint16(&group) ||
					!readUint16LengthPrefixedBytes(&body, &m.keyShare.keyExchange) ||
					len(body) != 0 {
					return false
				}
				m.keyShare.group = CurveID(group)
			case extensionPreSharedKey:
				if !body.ReadUint16(&m.pskIdentity) || len(body) != 0 {
					return false
				}
				m.hasPSKIdentity = true
			case extensionSupportedVersions:
				// Parsed above.
			case extensionPAKE:
				if !body.ReadUint16(&m.pakeID) || !readUint16LengthPrefixedBytes(&body, &m.pakeMessage) {
					return false
				}
			default:
				// Only allow the 3 extensions that are sent in
				// the clear in TLS 1.3.
				return false
			}
		}
	} else if !m.extensions.unmarshal(extensions, vers) {
		return false
	}

	return true
}

type encryptedExtensionsMsg struct {
	raw        []byte
	extensions serverExtensions
	empty      bool
}

func (m *encryptedExtensionsMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	encryptedExtensionsMsg := cryptobyte.NewBuilder(nil)
	encryptedExtensionsMsg.AddUint8(typeEncryptedExtensions)
	encryptedExtensionsMsg.AddUint24LengthPrefixed(func(encryptedExtensions *cryptobyte.Builder) {
		if !m.empty {
			encryptedExtensions.AddUint16LengthPrefixed(func(extensions *cryptobyte.Builder) {
				m.extensions.marshal(extensions)
			})
		}
	})

	m.raw = encryptedExtensionsMsg.BytesOrPanic()
	return m.raw
}

func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
	m.raw = data
	reader := cryptobyte.String(data[4:])
	var extensions cryptobyte.String
	if !reader.ReadUint16LengthPrefixed(&extensions) || len(reader) != 0 {
		return false
	}
	return m.extensions.unmarshal(extensions, VersionTLS13)
}

type serverExtensions struct {
	nextProtoNeg              bool
	nextProtos                []string
	ocspStapling              bool
	ticketSupported           bool
	secureRenegotiation       []byte
	alpnProtocol              string
	alpnProtocolEmpty         bool
	duplicateExtension        bool
	channelIDRequested        bool
	extendedMasterSecret      bool
	srtpProtectionProfile     uint16
	srtpMasterKeyIdentifier   string
	sctList                   []byte
	customExtension           string
	npnAfterAlpn              bool
	hasKeyShare               bool
	hasEarlyData              bool
	keyShare                  keyShareEntry
	supportedVersion          uint16
	supportedPoints           []uint8
	supportedCurves           []CurveID
	quicTransportParams       []byte
	quicTransportParamsLegacy []byte
	serverNameAck             bool
	applicationSettings       []byte
	hasApplicationSettings    bool
	applicationSettingsOld    []byte
	hasApplicationSettingsOld bool
	echRetryConfigs           []byte
}

func (m *serverExtensions) marshal(extensions *cryptobyte.Builder) {
	if m.duplicateExtension {
		// Add a duplicate bogus extension at the beginning and end.
		extensions.AddUint16(extensionDuplicate)
		extensions.AddUint16(0) // length = 0 for empty extension
	}
	if m.nextProtoNeg && !m.npnAfterAlpn {
		extensions.AddUint16(extensionNextProtoNeg)
		extensions.AddUint16LengthPrefixed(func(extension *cryptobyte.Builder) {
			for _, v := range m.nextProtos {
				addUint8LengthPrefixedBytes(extension, []byte(v))
			}
		})
	}
	if m.ocspStapling {
		extensions.AddUint16(extensionStatusRequest)
		extensions.AddUint16(0)
	}
	if m.ticketSupported {
		extensions.AddUint16(extensionSessionTicket)
		extensions.AddUint16(0)
	}
	if m.secureRenegotiation != nil {
		extensions.AddUint16(extensionRenegotiationInfo)
		extensions.AddUint16LengthPrefixed(func(extension *cryptobyte.Builder) {
			addUint8LengthPrefixedBytes(extension, m.secureRenegotiation)
		})
	}
	if len(m.alpnProtocol) > 0 || m.alpnProtocolEmpty {
		extensions.AddUint16(extensionALPN)
		extensions.AddUint16LengthPrefixed(func(extension *cryptobyte.Builder) {
			extension.AddUint16LengthPrefixed(func(protocolNameList *cryptobyte.Builder) {
				addUint8LengthPrefixedBytes(protocolNameList, []byte(m.alpnProtocol))
			})
		})
	}
	if m.channelIDRequested {
		extensions.AddUint16(extensionChannelID)
		extensions.AddUint16(0)
	}
	if m.duplicateExtension {
		// Add a duplicate bogus extension at the beginning and end.
		extensions.AddUint16(extensionDuplicate)
		extensions.AddUint16(0)
	}
	if m.extendedMasterSecret {
		extensions.AddUint16(extensionExtendedMasterSecret)
		extensions.AddUint16(0)
	}
	if m.srtpProtectionProfile != 0 {
		extensions.AddUint16(extensionUseSRTP)
		extensions.AddUint16LengthPrefixed(func(extension *cryptobyte.Builder) {
			extension.AddUint16LengthPrefixed(func(srtpProtectionProfiles *cryptobyte.Builder) {
				srtpProtectionProfiles.AddUint16(m.srtpProtectionProfile)
			})
			addUint8LengthPrefixedBytes(extension, []byte(m.srtpMasterKeyIdentifier))
		})
	}
	if m.sctList != nil {
		extensions.AddUint16(extensionSignedCertificateTimestamp)
		addUint16LengthPrefixedBytes(extensions, m.sctList)
	}
	if l := len(m.customExtension); l > 0 {
		extensions.AddUint16(extensionCustom)
		addUint16LengthPrefixedBytes(extensions, []byte(m.customExtension))
	}
	if m.nextProtoNeg && m.npnAfterAlpn {
		extensions.AddUint16(extensionNextProtoNeg)
		extensions.AddUint16LengthPrefixed(func(extension *cryptobyte.Builder) {
			for _, v := range m.nextProtos {
				addUint8LengthPrefixedBytes(extension, []byte(v))
			}
		})
	}
	if m.hasKeyShare {
		extensions.AddUint16(extensionKeyShare)
		extensions.AddUint16LengthPrefixed(func(keyShare *cryptobyte.Builder) {
			keyShare.AddUint16(uint16(m.keyShare.group))
			addUint16LengthPrefixedBytes(keyShare, m.keyShare.keyExchange)
		})
	}
	if m.supportedVersion != 0 {
		extensions.AddUint16(extensionSupportedVersions)
		extensions.AddUint16(2) // Length
		extensions.AddUint16(m.supportedVersion)
	}
	if len(m.supportedPoints) > 0 {
		// http://tools.ietf.org/html/rfc4492#section-5.1.2
		extensions.AddUint16(extensionSupportedPoints)
		extensions.AddUint16LengthPrefixed(func(supportedPointsList *cryptobyte.Builder) {
			addUint8LengthPrefixedBytes(supportedPointsList, m.supportedPoints)
		})
	}
	if len(m.supportedCurves) > 0 {
		// https://tools.ietf.org/html/rfc8446#section-4.2.7
		extensions.AddUint16(extensionSupportedCurves)
		extensions.AddUint16LengthPrefixed(func(supportedCurvesList *cryptobyte.Builder) {
			supportedCurvesList.AddUint16LengthPrefixed(func(supportedCurves *cryptobyte.Builder) {
				for _, curve := range m.supportedCurves {
					supportedCurves.AddUint16(uint16(curve))
				}
			})
		})
	}
	if len(m.quicTransportParams) > 0 {
		extensions.AddUint16(extensionQUICTransportParams)
		addUint16LengthPrefixedBytes(extensions, m.quicTransportParams)
	}
	if len(m.quicTransportParamsLegacy) > 0 {
		extensions.AddUint16(extensionQUICTransportParamsLegacy)
		addUint16LengthPrefixedBytes(extensions, m.quicTransportParamsLegacy)
	}
	if m.hasEarlyData {
		extensions.AddUint16(extensionEarlyData)
		extensions.AddBytes([]byte{0, 0})
	}
	if m.serverNameAck {
		extensions.AddUint16(extensionServerName)
		extensions.AddUint16(0) // zero length
	}
	if m.hasApplicationSettings {
		extensions.AddUint16(extensionApplicationSettings)
		addUint16LengthPrefixedBytes(extensions, m.applicationSettings)
	}
	if m.hasApplicationSettingsOld {
		extensions.AddUint16(extensionApplicationSettingsOld)
		addUint16LengthPrefixedBytes(extensions, m.applicationSettingsOld)
	}
	if len(m.echRetryConfigs) > 0 {
		extensions.AddUint16(extensionEncryptedClientHello)
		addUint16LengthPrefixedBytes(extensions, m.echRetryConfigs)
	}
}

func (m *serverExtensions) unmarshal(data cryptobyte.String, version uint16) bool {
	// Reset all fields.
	*m = serverExtensions{}

	if !checkDuplicateExtensions(data) {
		return false
	}

	for len(data) > 0 {
		var extension uint16
		var body cryptobyte.String
		if !data.ReadUint16(&extension) ||
			!data.ReadUint16LengthPrefixed(&body) {
			return false
		}
		switch extension {
		case extensionNextProtoNeg:
			m.nextProtoNeg = true
			for len(body) > 0 {
				var protocol []byte
				if !readUint8LengthPrefixedBytes(&body, &protocol) {
					return false
				}
				m.nextProtos = append(m.nextProtos, string(protocol))
			}
		case extensionStatusRequest:
			if len(body) != 0 {
				return false
			}
			m.ocspStapling = true
		case extensionSessionTicket:
			if len(body) != 0 {
				return false
			}
			m.ticketSupported = true
		case extensionRenegotiationInfo:
			if !readUint8LengthPrefixedBytes(&body, &m.secureRenegotiation) || len(body) != 0 {
				return false
			}
		case extensionALPN:
			var pakes, protocol cryptobyte.String
			if !body.ReadUint16LengthPrefixed(&pakes) ||
				len(body) != 0 ||
				!pakes.ReadUint8LengthPrefixed(&protocol) ||
				len(pakes) != 0 {
				return false
			}
			m.alpnProtocol = string(protocol)
			m.alpnProtocolEmpty = len(protocol) == 0
		case extensionChannelID:
			if len(body) != 0 {
				return false
			}
			m.channelIDRequested = true
		case extensionExtendedMasterSecret:
			if len(body) != 0 {
				return false
			}
			m.extendedMasterSecret = true
		case extensionUseSRTP:
			var profiles, mki cryptobyte.String
			if !body.ReadUint16LengthPrefixed(&profiles) ||
				!profiles.ReadUint16(&m.srtpProtectionProfile) ||
				len(profiles) != 0 ||
				!body.ReadUint8LengthPrefixed(&mki) ||
				len(body) != 0 {
				return false
			}
			m.srtpMasterKeyIdentifier = string(mki)
		case extensionSignedCertificateTimestamp:
			m.sctList = []byte(body)
		case extensionCustom:
			m.customExtension = string(body)
		case extensionServerName:
			if len(body) != 0 {
				return false
			}
			m.serverNameAck = true
		case extensionSupportedPoints:
			// supported_points is illegal in TLS 1.3.
			if version >= VersionTLS13 {
				return false
			}
			// http://tools.ietf.org/html/rfc4492#section-5.5.2
			if !readUint8LengthPrefixedBytes(&body, &m.supportedPoints) || len(body) != 0 {
				return false
			}
		case extensionSupportedCurves:
			// The server can only send supported_curves in TLS 1.3.
			if version < VersionTLS13 {
				return false
			}
		case extensionQUICTransportParams:
			m.quicTransportParams = body
		case extensionQUICTransportParamsLegacy:
			m.quicTransportParamsLegacy = body
		case extensionEarlyData:
			if version < VersionTLS13 || len(body) != 0 {
				return false
			}
			m.hasEarlyData = true
		case extensionApplicationSettings:
			m.hasApplicationSettings = true
			m.applicationSettings = body
		case extensionApplicationSettingsOld:
			m.hasApplicationSettingsOld = true
			m.applicationSettingsOld = body
		case extensionEncryptedClientHello:
			if version < VersionTLS13 {
				return false
			}
			m.echRetryConfigs = body

			// Validate the ECHConfig with a top-level parse.
			var echConfigs cryptobyte.String
			if !body.ReadUint16LengthPrefixed(&echConfigs) {
				return false
			}
			for len(echConfigs) > 0 {
				var version uint16
				var contents cryptobyte.String
				if !echConfigs.ReadUint16(&version) ||
					!echConfigs.ReadUint16LengthPrefixed(&contents) {
					return false
				}
			}
			if len(body) > 0 {
				return false
			}
		default:
			// Unknown extensions are illegal from the server.
			return false
		}
	}

	return true
}

type clientEncryptedExtensionsMsg struct {
	raw                       []byte
	applicationSettings       []byte
	hasApplicationSettings    bool
	applicationSettingsOld    []byte
	hasApplicationSettingsOld bool
	customExtension           []byte
}

func (m *clientEncryptedExtensionsMsg) marshal() (x []byte) {
	if m.raw != nil {
		return m.raw
	}

	builder := cryptobyte.NewBuilder(nil)
	builder.AddUint8(typeEncryptedExtensions)
	builder.AddUint24LengthPrefixed(func(body *cryptobyte.Builder) {
		body.AddUint16LengthPrefixed(func(extensions *cryptobyte.Builder) {
			if m.hasApplicationSettings {
				extensions.AddUint16(extensionApplicationSettings)
				addUint16LengthPrefixedBytes(extensions, m.applicationSettings)
			}
			if m.hasApplicationSettingsOld {
				extensions.AddUint16(extensionApplicationSettingsOld)
				addUint16LengthPrefixedBytes(extensions, m.applicationSettingsOld)
			}
			if len(m.customExtension) > 0 {
				extensions.AddUint16(extensionCustom)
				addUint16LengthPrefixedBytes(extensions, m.customExtension)
			}
		})
	})

	m.raw = builder.BytesOrPanic()
	return m.raw
}

func (m *clientEncryptedExtensionsMsg) unmarshal(data []byte) bool {
	m.raw = data
	reader := cryptobyte.String(data[4:])

	var extensions cryptobyte.String
	if !reader.ReadUint16LengthPrefixed(&extensions) ||
		len(reader) != 0 {
		return false
	}

	if !checkDuplicateExtensions(extensions) {
		return false
	}

	for len(extensions) > 0 {
		var extension uint16
		var body cryptobyte.String
		if !extensions.ReadUint16(&extension) ||
			!extensions.ReadUint16LengthPrefixed(&body) {
			return false
		}
		switch extension {
		case extensionApplicationSettings:
			m.hasApplicationSettings = true
			m.applicationSettings = body
		case extensionApplicationSettingsOld:
			m.hasApplicationSettingsOld = true
			m.applicationSettingsOld = body
		default:
			// Unknown extensions are illegal in EncryptedExtensions.
			return false
		}
	}
	return true
}

type helloRetryRequestMsg struct {
	isDTLS                bool
	raw                   []byte
	vers                  uint16
	sessionID             []byte
	cipherSuite           uint16
	compressionMethod     uint8
	hasSelectedGroup      bool
	selectedGroup         CurveID
	cookie                []byte
	customExtension       string
	echConfirmation       []byte
	echConfirmationOffset int
	duplicateExtensions   bool
	pakeID                uint16
	pakeMessage           []byte
}

func (m *helloRetryRequestMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	retryRequestMsg := cryptobyte.NewBuilder(nil)
	retryRequestMsg.AddUint8(typeServerHello)
	retryRequestMsg.AddUint24LengthPrefixed(func(retryRequest *cryptobyte.Builder) {
		legacyVersion := uint16(VersionTLS12)
		if m.isDTLS {
			legacyVersion = VersionDTLS12
		}
		retryRequest.AddUint16(legacyVersion)
		retryRequest.AddBytes(tls13HelloRetryRequest)
		addUint8LengthPrefixedBytes(retryRequest, m.sessionID)
		retryRequest.AddUint16(m.cipherSuite)
		retryRequest.AddUint8(m.compressionMethod)

		retryRequest.AddUint16LengthPrefixed(func(extensions *cryptobyte.Builder) {
			count := 1
			if m.duplicateExtensions {
				count = 2
			}

			for i := 0; i < count; i++ {
				extensions.AddUint16(extensionSupportedVersions)
				extensions.AddUint16(2) // Length
				extensions.AddUint16(m.vers)
				if m.hasSelectedGroup {
					extensions.AddUint16(extensionKeyShare)
					extensions.AddUint16(2) // length
					extensions.AddUint16(uint16(m.selectedGroup))
				}
				if len(m.pakeMessage) != 0 {
					extensions.AddUint16(extensionPAKE)
					extensions.AddUint16LengthPrefixed(func(share *cryptobyte.Builder) {
						share.AddUint16(m.pakeID)
						addUint16LengthPrefixedBytes(share, m.pakeMessage)
					})
				}
				// m.cookie may be a non-nil empty slice for empty cookie tests.
				if m.cookie != nil {
					extensions.AddUint16(extensionCookie)
					extensions.AddUint16LengthPrefixed(func(body *cryptobyte.Builder) {
						addUint16LengthPrefixedBytes(body, m.cookie)
					})
				}
				if len(m.customExtension) > 0 {
					extensions.AddUint16(extensionCustom)
					addUint16LengthPrefixedBytes(extensions, []byte(m.customExtension))
				}
				if len(m.echConfirmation) > 0 {
					extensions.AddUint16(extensionEncryptedClientHello)
					addUint16LengthPrefixedBytes(extensions, m.echConfirmation)
				}
			}
		})
	})

	m.raw = retryRequestMsg.BytesOrPanic()
	return m.raw
}

func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
	expectedLegacyVers := uint16(VersionTLS12)
	if m.isDTLS {
		expectedLegacyVers = VersionDTLS12
	}

	m.raw = data
	reader := cryptobyte.String(data[4:])
	var legacyVers uint16
	var random []byte
	var compressionMethod byte
	var extensions cryptobyte.String
	if !reader.ReadUint16(&legacyVers) ||
		legacyVers != expectedLegacyVers ||
		!reader.ReadBytes(&random, 32) ||
		!readUint8LengthPrefixedBytes(&reader, &m.sessionID) ||
		!reader.ReadUint16(&m.cipherSuite) ||
		!reader.ReadUint8(&compressionMethod) ||
		compressionMethod != 0 ||
		!reader.ReadUint16LengthPrefixed(&extensions) ||
		len(reader) != 0 {
		return false
	}
	for len(extensions) > 0 {
		var extension uint16
		var body cryptobyte.String
		if !extensions.ReadUint16(&extension) ||
			!extensions.ReadUint16LengthPrefixed(&body) {
			return false
		}
		switch extension {
		case extensionSupportedVersions:
			if !body.ReadUint16(&m.vers) ||
				len(body) != 0 {
				return false
			}
		case extensionKeyShare:
			var v uint16
			if !body.ReadUint16(&v) || len(body) != 0 {
				return false
			}
			m.hasSelectedGroup = true
			m.selectedGroup = CurveID(v)
		case extensionCookie:
			if !readUint16LengthPrefixedBytes(&body, &m.cookie) ||
				len(m.cookie) == 0 ||
				len(body) != 0 {
				return false
			}
		case extensionEncryptedClientHello:
			if len(body) != echAcceptConfirmationLength {
				return false
			}
			m.echConfirmation = body
			m.echConfirmationOffset = len(m.raw) - len(extensions) - len(body)
		default:
			// Unknown extensions are illegal from the server.
			return false
		}
	}
	return true
}

type certificateEntry struct {
	data                []byte
	ocspResponse        []byte
	sctList             []byte
	duplicateExtensions bool
	extraExtension      []byte
	delegatedCredential *delegatedCredential
}

type delegatedCredential struct {
	// https://www.rfc-editor.org/rfc/rfc9345.html#section-4
	raw              []byte
	signedBytes      []byte
	lifetimeSecs     uint32
	dcCertVerifyAlgo signatureAlgorithm
	pkixPublicKey    []byte
	algorithm        signatureAlgorithm
	signature        []byte
}

type certificateMsg struct {
	raw               []byte
	hasRequestContext bool
	requestContext    []byte
	certificates      []certificateEntry
}

func (m *certificateMsg) marshal() (x []byte) {
	if m.raw != nil {
		return m.raw
	}

	certMsg := cryptobyte.NewBuilder(nil)
	certMsg.AddUint8(typeCertificate)
	certMsg.AddUint24LengthPrefixed(func(certificate *cryptobyte.Builder) {
		if m.hasRequestContext {
			addUint8LengthPrefixedBytes(certificate, m.requestContext)
		}
		certificate.AddUint24LengthPrefixed(func(certificateList *cryptobyte.Builder) {
			for _, cert := range m.certificates {
				addUint24LengthPrefixedBytes(certificateList, cert.data)
				if m.hasRequestContext {
					certificateList.AddUint16LengthPrefixed(func(extensions *cryptobyte.Builder) {
						count := 1
						if cert.duplicateExtensions {
							count = 2
						}

						for i := 0; i < count; i++ {
							if cert.ocspResponse != nil {
								extensions.AddUint16(extensionStatusRequest)
								extensions.AddUint16LengthPrefixed(func(body *cryptobyte.Builder) {
									body.AddUint8(statusTypeOCSP)
									addUint24LengthPrefixedBytes(body, cert.ocspResponse)
								})
							}

							if cert.sctList != nil {
								extensions.AddUint16(extensionSignedCertificateTimestamp)
								addUint16LengthPrefixedBytes(extensions, cert.sctList)
							}
						}
						if cert.extraExtension != nil {
							extensions.AddBytes(cert.extraExtension)
						}
					})
				}
			}
		})
	})

	m.raw = certMsg.BytesOrPanic()
	return m.raw
}

func (m *certificateMsg) unmarshal(data []byte) bool {
	m.raw = data
	reader := cryptobyte.String(data[4:])

	if m.hasRequestContext && !readUint8LengthPrefixedBytes(&reader, &m.requestContext) {
		return false
	}

	var certs cryptobyte.String
	if !reader.ReadUint24LengthPrefixed(&certs) || len(reader) != 0 {
		return false
	}
	m.certificates = nil
	for len(certs) > 0 {
		var cert certificateEntry
		if !readUint24LengthPrefixedBytes(&certs, &cert.data) {
			return false
		}
		if m.hasRequestContext {
			var extensions cryptobyte.String
			if !certs.ReadUint16LengthPrefixed(&extensions) || !checkDuplicateExtensions(extensions) {
				return false
			}
			for len(extensions) > 0 {
				var extension uint16
				var body cryptobyte.String
				if !extensions.ReadUint16(&extension) ||
					!extensions.ReadUint16LengthPrefixed(&body) {
					return false
				}
				switch extension {
				case extensionStatusRequest:
					var statusType byte
					if !body.ReadUint8(&statusType) ||
						statusType != statusTypeOCSP ||
						!readUint24LengthPrefixedBytes(&body, &cert.ocspResponse) ||
						len(body) != 0 {
						return false
					}
				case extensionSignedCertificateTimestamp:
					cert.sctList = []byte(body)
				case extensionDelegatedCredential:
					// https://www.rfc-editor.org/rfc/rfc9345.html#section-4
					if cert.delegatedCredential != nil {
						return false
					}

					dc := new(delegatedCredential)
					origBody := body
					var dcCertVerifyAlgo, algorithm uint16

					if !body.ReadUint32(&dc.lifetimeSecs) ||
						!body.ReadUint16(&dcCertVerifyAlgo) ||
						!readUint24LengthPrefixedBytes(&body, &dc.pkixPublicKey) ||
						!body.ReadUint16(&algorithm) ||
						!readUint16LengthPrefixedBytes(&body, &dc.signature) ||
						len(body) != 0 {
						return false
					}

					dc.dcCertVerifyAlgo = signatureAlgorithm(dcCertVerifyAlgo)
					dc.algorithm = signatureAlgorithm(algorithm)
					dc.raw = origBody
					dc.signedBytes = []byte(origBody)[:4+2+3+len(dc.pkixPublicKey)]
					cert.delegatedCredential = dc
				default:
					return false
				}
			}
		}
		m.certificates = append(m.certificates, cert)
	}

	return true
}

type compressedCertificateMsg struct {
	raw                []byte
	algID              uint16
	uncompressedLength uint32
	compressed         []byte
}

func (m *compressedCertificateMsg) marshal() (x []byte) {
	if m.raw != nil {
		return m.raw
	}

	certMsg := cryptobyte.NewBuilder(nil)
	certMsg.AddUint8(typeCompressedCertificate)
	certMsg.AddUint24LengthPrefixed(func(certificate *cryptobyte.Builder) {
		certificate.AddUint16(m.algID)
		certificate.AddUint24(m.uncompressedLength)
		addUint24LengthPrefixedBytes(certificate, m.compressed)
	})

	m.raw = certMsg.BytesOrPanic()
	return m.raw
}

func (m *compressedCertificateMsg) unmarshal(data []byte) bool {
	m.raw = data
	reader := cryptobyte.String(data[4:])

	if !reader.ReadUint16(&m.algID) ||
		!reader.ReadUint24(&m.uncompressedLength) ||
		!readUint24LengthPrefixedBytes(&reader, &m.compressed) ||
		len(reader) != 0 {
		return false
	}

	if m.uncompressedLength >= 1<<17 {
		return false
	}

	return true
}

type serverKeyExchangeMsg struct {
	raw []byte
	key []byte
}

func (m *serverKeyExchangeMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}
	msg := cryptobyte.NewBuilder(nil)
	msg.AddUint8(typeServerKeyExchange)
	addUint24LengthPrefixedBytes(msg, m.key)
	m.raw = msg.BytesOrPanic()
	return m.raw
}

func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
	m.raw = data
	if len(data) < 4 {
		return false
	}
	m.key = data[4:]
	return true
}

type certificateStatusMsg struct {
	raw        []byte
	statusType uint8
	response   []byte
}

func (m *certificateStatusMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	var x []byte
	if m.statusType == statusTypeOCSP {
		msg := cryptobyte.NewBuilder(nil)
		msg.AddUint8(typeCertificateStatus)
		msg.AddUint24LengthPrefixed(func(body *cryptobyte.Builder) {
			body.AddUint8(statusTypeOCSP)
			addUint24LengthPrefixedBytes(body, m.response)
		})
		x = msg.BytesOrPanic()
	} else {
		x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
	}

	m.raw = x
	return x
}

func (m *certificateStatusMsg) unmarshal(data []byte) bool {
	m.raw = data
	reader := cryptobyte.String(data[4:])
	if !reader.ReadUint8(&m.statusType) ||
		m.statusType != statusTypeOCSP ||
		!readUint24LengthPrefixedBytes(&reader, &m.response) ||
		len(reader) != 0 {
		return false
	}
	return true
}

type serverHelloDoneMsg struct{}

func (m *serverHelloDoneMsg) marshal() []byte {
	x := make([]byte, 4)
	x[0] = typeServerHelloDone
	return x
}

func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
	return len(data) == 4
}

type clientKeyExchangeMsg struct {
	raw        []byte
	ciphertext []byte
}

func (m *clientKeyExchangeMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}
	msg := cryptobyte.NewBuilder(nil)
	msg.AddUint8(typeClientKeyExchange)
	addUint24LengthPrefixedBytes(msg, m.ciphertext)
	m.raw = msg.BytesOrPanic()
	return m.raw
}

func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
	m.raw = data
	if len(data) < 4 {
		return false
	}
	l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
	if l != len(data)-4 {
		return false
	}
	m.ciphertext = data[4:]
	return true
}

type finishedMsg struct {
	raw        []byte
	verifyData []byte
}

func (m *finishedMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	msg := cryptobyte.NewBuilder(nil)
	msg.AddUint8(typeFinished)
	addUint24LengthPrefixedBytes(msg, m.verifyData)
	m.raw = msg.BytesOrPanic()
	return m.raw
}

func (m *finishedMsg) unmarshal(data []byte) bool {
	m.raw = data
	if len(data) < 4 {
		return false
	}
	m.verifyData = data[4:]
	return true
}

type nextProtoMsg struct {
	raw   []byte
	proto string
}

func (m *nextProtoMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	padding := 32 - (len(m.proto)+2)%32

	msg := cryptobyte.NewBuilder(nil)
	msg.AddUint8(typeNextProtocol)
	msg.AddUint24LengthPrefixed(func(body *cryptobyte.Builder) {
		addUint8LengthPrefixedBytes(body, []byte(m.proto))
		addUint8LengthPrefixedBytes(body, make([]byte, padding))
	})
	m.raw = msg.BytesOrPanic()
	return m.raw
}

func (m *nextProtoMsg) unmarshal(data []byte) bool {
	m.raw = data
	reader := cryptobyte.String(data[4:])
	var proto, padding []byte
	if !readUint8LengthPrefixedBytes(&reader, &proto) ||
		!readUint8LengthPrefixedBytes(&reader, &padding) ||
		len(reader) != 0 {
		return false
	}
	m.proto = string(proto)

	// Padding is not meant to be checked normally, but as this is a testing
	// implementation, we check the padding is as expected.
	if len(padding) != 32-(len(m.proto)+2)%32 {
		return false
	}
	for _, v := range padding {
		if v != 0 {
			return false
		}
	}

	return true
}

type certificateRequestMsg struct {
	raw  []byte
	vers uint16
	// hasSignatureAlgorithm indicates whether this message includes a list
	// of signature and hash functions. This change was introduced with TLS
	// 1.2.
	hasSignatureAlgorithm bool
	// hasRequestContext indicates whether this message includes a context
	// field instead of certificateTypes. This change was introduced with
	// TLS 1.3.
	hasRequestContext bool

	certificateTypes        []byte
	requestContext          []byte
	signatureAlgorithms     []signatureAlgorithm
	signatureAlgorithmsCert []signatureAlgorithm
	certificateAuthorities  [][]byte
	hasCAExtension          bool
	customExtension         uint16
}

func (m *certificateRequestMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	// See http://tools.ietf.org/html/rfc4346#section-7.4.4
	builder := cryptobyte.NewBuilder(nil)
	builder.AddUint8(typeCertificateRequest)
	builder.AddUint24LengthPrefixed(func(body *cryptobyte.Builder) {
		if m.hasRequestContext {
			addUint8LengthPrefixedBytes(body, m.requestContext)
			body.AddUint16LengthPrefixed(func(extensions *cryptobyte.Builder) {
				if m.hasSignatureAlgorithm {
					extensions.AddUint16(extensionSignatureAlgorithms)
					extensions.AddUint16LengthPrefixed(func(extension *cryptobyte.Builder) {
						extension.AddUint16LengthPrefixed(func(signatureAlgorithms *cryptobyte.Builder) {
							for _, sigAlg := range m.signatureAlgorithms {
								signatureAlgorithms.AddUint16(uint16(sigAlg))
							}
						})
					})
				}
				if len(m.signatureAlgorithmsCert) > 0 {
					extensions.AddUint16(extensionSignatureAlgorithmsCert)
					extensions.AddUint16LengthPrefixed(func(extension *cryptobyte.Builder) {
						extension.AddUint16LengthPrefixed(func(signatureAlgorithmsCert *cryptobyte.Builder) {
							for _, sigAlg := range m.signatureAlgorithmsCert {
								signatureAlgorithmsCert.AddUint16(uint16(sigAlg))
							}
						})
					})
				}
				if len(m.certificateAuthorities) > 0 {
					extensions.AddUint16(extensionCertificateAuthorities)
					extensions.AddUint16LengthPrefixed(func(extension *cryptobyte.Builder) {
						extension.AddUint16LengthPrefixed(func(certificateAuthorities *cryptobyte.Builder) {
							for _, ca := range m.certificateAuthorities {
								addUint16LengthPrefixedBytes(certificateAuthorities, ca)
							}
						})
					})
				}

				if m.customExtension > 0 {
					extensions.AddUint16(m.customExtension)
					extensions.AddUint16(0) // Empty extension
				}
			})
		} else {
			addUint8LengthPrefixedBytes(body, m.certificateTypes)

			if m.hasSignatureAlgorithm {
				body.AddUint16LengthPrefixed(func(signatureAlgorithms *cryptobyte.Builder) {
					for _, sigAlg := range m.signatureAlgorithms {
						signatureAlgorithms.AddUint16(uint16(sigAlg))
					}
				})
			}

			body.AddUint16LengthPrefixed(func(certificateAuthorities *cryptobyte.Builder) {
				for _, ca := range m.certificateAuthorities {
					addUint16LengthPrefixedBytes(certificateAuthorities, ca)
				}
			})
		}
	})

	m.raw = builder.BytesOrPanic()
	return m.raw
}

func parseCAs(reader *cryptobyte.String, out *[][]byte) bool {
	var cas cryptobyte.String
	if !reader.ReadUint16LengthPrefixed(&cas) {
		return false
	}
	for len(cas) > 0 {
		var ca []byte
		if !readUint16LengthPrefixedBytes(&cas, &ca) {
			return false
		}
		*out = append(*out, ca)
	}
	return true
}

func (m *certificateRequestMsg) unmarshal(data []byte) bool {
	m.raw = data
	reader := cryptobyte.String(data[4:])

	if m.hasRequestContext {
		var extensions cryptobyte.String
		if !readUint8LengthPrefixedBytes(&reader, &m.requestContext) ||
			!reader.ReadUint16LengthPrefixed(&extensions) ||
			len(reader) != 0 ||
			!checkDuplicateExtensions(extensions) {
			return false
		}
		for len(extensions) > 0 {
			var extension uint16
			var body cryptobyte.String
			if !extensions.ReadUint16(&extension) ||
				!extensions.ReadUint16LengthPrefixed(&body) {
				return false
			}
			switch extension {
			case extensionSignatureAlgorithms:
				if !parseSignatureAlgorithms(&body, &m.signatureAlgorithms, false) || len(body) != 0 {
					return false
				}
			case extensionSignatureAlgorithmsCert:
				if !parseSignatureAlgorithms(&body, &m.signatureAlgorithmsCert, false) || len(body) != 0 {
					return false
				}
			case extensionCertificateAuthorities:
				if !parseCAs(&body, &m.certificateAuthorities) || len(body) != 0 {
					return false
				}
				m.hasCAExtension = true
			}
		}
	} else {
		if !readUint8LengthPrefixedBytes(&reader, &m.certificateTypes) {
			return false
		}
		// In TLS 1.2, the supported_signature_algorithms field in
		// CertificateRequest may be empty.
		if m.hasSignatureAlgorithm && !parseSignatureAlgorithms(&reader, &m.signatureAlgorithms, true) {
			return false
		}
		if !parseCAs(&reader, &m.certificateAuthorities) ||
			len(reader) != 0 {
			return false
		}
	}

	return true
}

type certificateVerifyMsg struct {
	raw                   []byte
	hasSignatureAlgorithm bool
	signatureAlgorithm    signatureAlgorithm
	signature             []byte
}

func (m *certificateVerifyMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	// See http://tools.ietf.org/html/rfc4346#section-7.4.8
	msg := cryptobyte.NewBuilder(nil)
	msg.AddUint8(typeCertificateVerify)
	msg.AddUint24LengthPrefixed(func(body *cryptobyte.Builder) {
		if m.hasSignatureAlgorithm {
			body.AddUint16(uint16(m.signatureAlgorithm))
		}
		addUint16LengthPrefixedBytes(body, m.signature)
	})

	m.raw = msg.BytesOrPanic()
	return m.raw
}

func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
	m.raw = data
	reader := cryptobyte.String(data[4:])
	if m.hasSignatureAlgorithm {
		var v uint16
		if !reader.ReadUint16(&v) {
			return false
		}
		m.signatureAlgorithm = signatureAlgorithm(v)
	}
	if !readUint16LengthPrefixedBytes(&reader, &m.signature) ||
		!reader.Empty() {
		return false
	}
	return true
}

type newSessionTicketMsg struct {
	raw                         []byte
	vers                        uint16
	isDTLS                      bool
	ticketLifetime              uint32
	ticketAgeAdd                uint32
	ticketNonce                 []byte
	ticket                      []byte
	maxEarlyDataSize            uint32
	customExtension             string
	duplicateEarlyDataExtension bool
	hasGREASEExtension          bool
}

func (m *newSessionTicketMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	version, ok := wireToVersion(m.vers, m.isDTLS)
	if !ok {
		panic("unknown version")
	}

	// See http://tools.ietf.org/html/rfc5077#section-3.3
	ticketMsg := cryptobyte.NewBuilder(nil)
	ticketMsg.AddUint8(typeNewSessionTicket)
	ticketMsg.AddUint24LengthPrefixed(func(body *cryptobyte.Builder) {
		body.AddUint32(m.ticketLifetime)
		if version >= VersionTLS13 {
			body.AddUint32(m.ticketAgeAdd)
			addUint8LengthPrefixedBytes(body, m.ticketNonce)
		}

		addUint16LengthPrefixedBytes(body, m.ticket)

		if version >= VersionTLS13 {
			body.AddUint16LengthPrefixed(func(extensions *cryptobyte.Builder) {
				if m.maxEarlyDataSize > 0 {
					extensions.AddUint16(extensionEarlyData)
					extensions.AddUint16LengthPrefixed(func(child *cryptobyte.Builder) {
						child.AddUint32(m.maxEarlyDataSize)
					})
					if m.duplicateEarlyDataExtension {
						extensions.AddUint16(extensionEarlyData)
						extensions.AddUint16LengthPrefixed(func(child *cryptobyte.Builder) {
							child.AddUint32(m.maxEarlyDataSize)
						})
					}
				}
				if len(m.customExtension) > 0 {
					extensions.AddUint16(extensionCustom)
					addUint16LengthPrefixedBytes(extensions, []byte(m.customExtension))
				}
			})
		}
	})

	m.raw = ticketMsg.BytesOrPanic()
	return m.raw
}

func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
	m.raw = data

	version, ok := wireToVersion(m.vers, m.isDTLS)
	if !ok {
		panic("unknown version")
	}

	reader := cryptobyte.String(data[4:])
	if !reader.ReadUint32(&m.ticketLifetime) {
		return false
	}

	if version >= VersionTLS13 {
		if !reader.ReadUint32(&m.ticketAgeAdd) ||
			!readUint8LengthPrefixedBytes(&reader, &m.ticketNonce) {
			return false
		}
	}

	if !readUint16LengthPrefixedBytes(&reader, &m.ticket) ||
		(version >= VersionTLS13 && len(m.ticket) == 0) {
		return false
	}

	if version >= VersionTLS13 {
		var extensions cryptobyte.String
		if !reader.ReadUint16LengthPrefixed(&extensions) || !reader.Empty() {
			return false
		}

		for !extensions.Empty() {
			var extension uint16
			var body cryptobyte.String
			if !extensions.ReadUint16(&extension) ||
				!extensions.ReadUint16LengthPrefixed(&body) {
				return false
			}

			switch extension {
			case extensionEarlyData:
				if !body.ReadUint32(&m.maxEarlyDataSize) || !body.Empty() {
					return false
				}
			default:
				if isGREASEValue(extension) {
					m.hasGREASEExtension = true
				}
			}
		}
	}

	return reader.Empty()
}

type helloVerifyRequestMsg struct {
	raw    []byte
	vers   uint16
	cookie []byte
}

func (m *helloVerifyRequestMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	length := 2 + 1 + len(m.cookie)

	x := make([]byte, 4+length)
	x[0] = typeHelloVerifyRequest
	x[1] = uint8(length >> 16)
	x[2] = uint8(length >> 8)
	x[3] = uint8(length)
	vers := m.vers
	x[4] = uint8(vers >> 8)
	x[5] = uint8(vers)
	x[6] = uint8(len(m.cookie))
	copy(x[7:7+len(m.cookie)], m.cookie)

	return x
}

func (m *helloVerifyRequestMsg) unmarshal(data []byte) bool {
	if len(data) < 4+2+1 {
		return false
	}
	m.raw = data
	m.vers = uint16(data[4])<<8 | uint16(data[5])
	cookieLen := int(data[6])
	if cookieLen > 32 || len(data) != 7+cookieLen {
		return false
	}
	m.cookie = data[7 : 7+cookieLen]

	return true
}

type channelIDMsg struct {
	raw       []byte
	channelID []byte
}

func (m *channelIDMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	length := 2 + 2 + len(m.channelID)

	x := make([]byte, 4+length)
	x[0] = typeChannelID
	x[1] = uint8(length >> 16)
	x[2] = uint8(length >> 8)
	x[3] = uint8(length)
	x[4] = uint8(extensionChannelID >> 8)
	x[5] = uint8(extensionChannelID & 0xff)
	x[6] = uint8(len(m.channelID) >> 8)
	x[7] = uint8(len(m.channelID) & 0xff)
	copy(x[8:], m.channelID)

	return x
}

func (m *channelIDMsg) unmarshal(data []byte) bool {
	if len(data) != 4+2+2+128 {
		return false
	}
	m.raw = data
	if (uint16(data[4])<<8)|uint16(data[5]) != extensionChannelID {
		return false
	}
	if int(data[6])<<8|int(data[7]) != 128 {
		return false
	}
	m.channelID = data[4+2+2:]

	return true
}

type helloRequestMsg struct{}

func (*helloRequestMsg) marshal() []byte {
	return []byte{typeHelloRequest, 0, 0, 0}
}

func (*helloRequestMsg) unmarshal(data []byte) bool {
	return len(data) == 4
}

type keyUpdateMsg struct {
	raw              []byte
	keyUpdateRequest byte
}

func (m *keyUpdateMsg) marshal() []byte {
	if m.raw != nil {
		return m.raw
	}

	return []byte{typeKeyUpdate, 0, 0, 1, m.keyUpdateRequest}
}

func (m *keyUpdateMsg) unmarshal(data []byte) bool {
	m.raw = data

	if len(data) != 5 {
		return false
	}

	length := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
	if len(data)-4 != length {
		return false
	}

	m.keyUpdateRequest = data[4]
	return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
}

type endOfEarlyDataMsg struct {
	nonEmpty bool
}

func (m *endOfEarlyDataMsg) marshal() []byte {
	if m.nonEmpty {
		return []byte{typeEndOfEarlyData, 0, 0, 1, 42}
	}
	return []byte{typeEndOfEarlyData, 0, 0, 0}
}

func (*endOfEarlyDataMsg) unmarshal(data []byte) bool {
	return len(data) == 4
}
