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 tls

import (
	
	

	
)
The marshalingFunction type is an adapter to allow the use of ordinary functions as cryptobyte.MarshalingValue.
addBytesWithLength appends a sequence of bytes to the cryptobyte.Builder. If the length of the sequence is not the value specified, it produces an error.
func ( *cryptobyte.Builder,  []byte,  int) {
	.AddValue(marshalingFunction(func( *cryptobyte.Builder) error {
		if len() !=  {
			return fmt.Errorf("invalid value length: expected %d, got %d", , len())
		}
		.AddBytes()
		return nil
	}))
}
addUint64 appends a big-endian, 64-bit value to the cryptobyte.Builder.
func ( *cryptobyte.Builder,  uint64) {
	.AddUint32(uint32( >> 32))
	.AddUint32(uint32())
}
readUint64 decodes a big-endian, 64-bit value into out and advances over it. It reports whether the read was successful.
func ( *cryptobyte.String,  *uint64) bool {
	var ,  uint32
	if !.ReadUint32(&) || !.ReadUint32(&) {
		return false
	}
	* = uint64()<<32 | uint64()
	return true
}
readUint8LengthPrefixed acts like s.ReadUint8LengthPrefixed, but targets a []byte instead of a cryptobyte.String.
readUint16LengthPrefixed acts like s.ReadUint16LengthPrefixed, but targets a []byte instead of a cryptobyte.String.
If extensions aren't present, omit them.
		var  bool
		 := *

		.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
RFC 6066, Section 3
RFC 4366, Section 3.6
				.AddUint16(extensionStatusRequest)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint8(1)  // status_type = ocsp
					.AddUint16(0) // empty responder_id_list
					.AddUint16(0) // empty request_extensions
				})
			}
RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
RFC 5246, Section 7.4.1.4.1
RFC 8446, Section 4.2.3
RFC 7301, Section 3.1
RFC 6962, Section 3.3.1
				.AddUint16(extensionSCT)
				.AddUint16(0) // empty extension_data
			}
RFC 8446, Section 4.2.1
RFC 8446, Section 4.2.8
RFC 8446, Section 4.2.10
				.AddUint16(extensionEarlyData)
				.AddUint16(0) // empty extension_data
			}
RFC 8446, Section 4.2.11
				.AddUint16(extensionPreSharedKey)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						for ,  := range .pskIdentities {
							.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
								.AddBytes(.label)
							})
							.AddUint32(.obfuscatedTicketAge)
						}
					})
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						for ,  := range .pskBinders {
							.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
								.AddBytes()
							})
						}
					})
				})
			}

			 = len(.BytesOrPanic()) > 2
		})

		if ! {
			* = 
		}
	})

	.raw = .BytesOrPanic()
	return .raw
}
marshalWithoutBinders returns the ClientHello through the PreSharedKeyExtension.identities field, according to RFC 8446, Section 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length.
func ( *clientHelloMsg) () []byte {
	 := 2 // uint16 length prefix
	for ,  := range .pskBinders {
		 += 1 // uint8 length prefix
		 += len()
	}

	 := .marshal()
	return [:len()-]
}
updateBinders updates the m.pskBinders field, if necessary updating the cached marshaled representation. The supplied binders must have the same length as the current m.pskBinders.
func ( *clientHelloMsg) ( [][]byte) {
	if len() != len(.pskBinders) {
		panic("tls: internal error: pskBinders length mismatch")
	}
	for  := range .pskBinders {
		if len([]) != len(.pskBinders[]) {
			panic("tls: internal error: pskBinders length mismatch")
		}
	}
	.pskBinders = 
	if .raw != nil {
TODO(filippo): replace with NewFixedBuilder once CL 148882 is imported.
		 := cryptobyte.NewBuilder(.raw[:])
		.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
			for ,  := range .pskBinders {
				.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
					.AddBytes()
				})
			}
		})
		if len(.BytesOrPanic()) != len(.raw) {
			panic("tls: internal error: failed to update binders")
		}
	}
}

func ( *clientHelloMsg) ( []byte) bool {
	* = clientHelloMsg{raw: }
	 := cryptobyte.String()

	if !.Skip(4) || // message type and uint24 length field
		!.ReadUint16(&.vers) || !.ReadBytes(&.random, 32) ||
		!readUint8LengthPrefixed(&, &.sessionId) {
		return false
	}

	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) {
		return false
	}
	.cipherSuites = []uint16{}
	.secureRenegotiationSupported = false
	for !.Empty() {
		var  uint16
		if !.ReadUint16(&) {
			return false
		}
		if  == scsvRenegotiation {
			.secureRenegotiationSupported = true
		}
		.cipherSuites = append(.cipherSuites, )
	}

	if !readUint8LengthPrefixed(&, &.compressionMethods) {
		return false
	}

ClientHello is optionally followed by extension data
		return true
	}

	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || !.Empty() {
		return false
	}

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

		switch  {
RFC 6066, Section 3
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  uint8
				var  cryptobyte.String
				if !.ReadUint8(&) ||
					!.ReadUint16LengthPrefixed(&) ||
					.Empty() {
					return false
				}
				if  != 0 {
					continue
				}
Multiple names of the same name_type are prohibited.
					return false
				}
An SNI value may not include a trailing dot.
				if strings.HasSuffix(.serverName, ".") {
					return false
				}
			}
RFC 4366, Section 3.6
			var  uint8
			var  cryptobyte.String
			if !.ReadUint8(&) ||
				!.ReadUint16LengthPrefixed(&) ||
				!.ReadUint16LengthPrefixed(&) {
				return false
			}
			.ocspStapling =  == statusTypeOCSP
RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  uint16
				if !.ReadUint16(&) {
					return false
				}
				.supportedCurves = append(.supportedCurves, CurveID())
			}
RFC 4492, Section 5.1.2
			if !readUint8LengthPrefixed(&, &.supportedPoints) ||
				len(.supportedPoints) == 0 {
				return false
			}
RFC 5077, Section 3.2
			.ticketSupported = true
			.ReadBytes(&.sessionTicket, len())
RFC 5246, Section 7.4.1.4.1
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  uint16
				if !.ReadUint16(&) {
					return false
				}
				.supportedSignatureAlgorithms = append(
					.supportedSignatureAlgorithms, SignatureScheme())
			}
RFC 8446, Section 4.2.3
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  uint16
				if !.ReadUint16(&) {
					return false
				}
				.supportedSignatureAlgorithmsCert = append(
					.supportedSignatureAlgorithmsCert, SignatureScheme())
			}
RFC 5746, Section 3.2
RFC 7301, Section 3.1
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  cryptobyte.String
				if !.ReadUint8LengthPrefixed(&) || .Empty() {
					return false
				}
				.alpnProtocols = append(.alpnProtocols, string())
			}
RFC 6962, Section 3.3.1
			.scts = true
RFC 8446, Section 4.2.1
			var  cryptobyte.String
			if !.ReadUint8LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  uint16
				if !.ReadUint16(&) {
					return false
				}
				.supportedVersions = append(.supportedVersions, )
			}
RFC 8446, Section 4.2.2
			if !readUint16LengthPrefixed(&, &.cookie) ||
				len(.cookie) == 0 {
				return false
			}
RFC 8446, Section 4.2.8
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) {
				return false
			}
			for !.Empty() {
				var  keyShare
				if !.ReadUint16((*uint16)(&.group)) ||
					!readUint16LengthPrefixed(&, &.data) ||
					len(.data) == 0 {
					return false
				}
				.keyShares = append(.keyShares, )
			}
RFC 8446, Section 4.2.10
RFC 8446, Section 4.2.9
			if !readUint8LengthPrefixed(&, &.pskModes) {
				return false
			}
RFC 8446, Section 4.2.11
			if !.Empty() {
				return false // pre_shared_key must be the last extension
			}
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  pskIdentity
				if !readUint16LengthPrefixed(&, &.label) ||
					!.ReadUint32(&.obfuscatedTicketAge) ||
					len(.label) == 0 {
					return false
				}
				.pskIdentities = append(.pskIdentities, )
			}
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  []byte
				if !readUint8LengthPrefixed(&, &) ||
					len() == 0 {
					return false
				}
				.pskBinders = append(.pskBinders, )
			}
If extensions aren't present, omit them.
		var  bool
		 := *

		.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
			if .ocspStapling {
				.AddUint16(extensionStatusRequest)
				.AddUint16(0) // empty extension_data
			}
			if .ticketSupported {
				.AddUint16(extensionSessionTicket)
				.AddUint16(0) // empty extension_data
			}
			if .secureRenegotiationSupported {
				.AddUint16(extensionRenegotiationInfo)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
						.AddBytes(.secureRenegotiation)
					})
				})
			}
			if len(.alpnProtocol) > 0 {
				.AddUint16(extensionALPN)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
							.AddBytes([]byte(.alpnProtocol))
						})
					})
				})
			}
			if len(.scts) > 0 {
				.AddUint16(extensionSCT)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						for ,  := range .scts {
							.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
								.AddBytes()
							})
						}
					})
				})
			}
			if .supportedVersion != 0 {
				.AddUint16(extensionSupportedVersions)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16(.supportedVersion)
				})
			}
			if .serverShare.group != 0 {
				.AddUint16(extensionKeyShare)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16(uint16(.serverShare.group))
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						.AddBytes(.serverShare.data)
					})
				})
			}
			if .selectedIdentityPresent {
				.AddUint16(extensionPreSharedKey)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16(.selectedIdentity)
				})
			}

			if len(.cookie) > 0 {
				.AddUint16(extensionCookie)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						.AddBytes(.cookie)
					})
				})
			}
			if .selectedGroup != 0 {
				.AddUint16(extensionKeyShare)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16(uint16(.selectedGroup))
				})
			}
			if len(.supportedPoints) > 0 {
				.AddUint16(extensionSupportedPoints)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
						.AddBytes(.supportedPoints)
					})
				})
			}

			 = len(.BytesOrPanic()) > 2
		})

		if ! {
			* = 
		}
	})

	.raw = .BytesOrPanic()
	return .raw
}

func ( *serverHelloMsg) ( []byte) bool {
	* = serverHelloMsg{raw: }
	 := cryptobyte.String()

	if !.Skip(4) || // message type and uint24 length field
		!.ReadUint16(&.vers) || !.ReadBytes(&.random, 32) ||
		!readUint8LengthPrefixed(&, &.sessionId) ||
		!.ReadUint16(&.cipherSuite) ||
		!.ReadUint8(&.compressionMethod) {
		return false
	}

ServerHello is optionally followed by extension data
		return true
	}

	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || !.Empty() {
		return false
	}

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

		switch  {
		case extensionStatusRequest:
			.ocspStapling = true
		case extensionSessionTicket:
			.ticketSupported = true
		case extensionRenegotiationInfo:
			if !readUint8LengthPrefixed(&, &.secureRenegotiation) {
				return false
			}
			.secureRenegotiationSupported = true
		case extensionALPN:
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			var  cryptobyte.String
			if !.ReadUint8LengthPrefixed(&) ||
				.Empty() || !.Empty() {
				return false
			}
			.alpnProtocol = string()
		case extensionSCT:
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  []byte
				if !readUint16LengthPrefixed(&, &) ||
					len() == 0 {
					return false
				}
				.scts = append(.scts, )
			}
		case extensionSupportedVersions:
			if !.ReadUint16(&.supportedVersion) {
				return false
			}
		case extensionCookie:
			if !readUint16LengthPrefixed(&, &.cookie) ||
				len(.cookie) == 0 {
				return false
			}
This extension has different formats in SH and HRR, accept either and let the handshake logic decide. See RFC 8446, Section 4.2.8.
			if len() == 2 {
				if !.ReadUint16((*uint16)(&.selectedGroup)) {
					return false
				}
			} else {
				if !.ReadUint16((*uint16)(&.serverShare.group)) ||
					!readUint16LengthPrefixed(&, &.serverShare.data) {
					return false
				}
			}
		case extensionPreSharedKey:
			.selectedIdentityPresent = true
			if !.ReadUint16(&.selectedIdentity) {
				return false
			}
RFC 4492, Section 5.1.2
			if !readUint8LengthPrefixed(&, &.supportedPoints) ||
				len(.supportedPoints) == 0 {
				return false
			}
Ignore unknown extensions.
			continue
		}

		if !.Empty() {
			return false
		}
	}

	return true
}

type encryptedExtensionsMsg struct {
	raw          []byte
	alpnProtocol string
}

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

	var  cryptobyte.Builder
	.AddUint8(typeEncryptedExtensions)
	.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
		.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
			if len(.alpnProtocol) > 0 {
				.AddUint16(extensionALPN)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
							.AddBytes([]byte(.alpnProtocol))
						})
					})
				})
			}
		})
	})

	.raw = .BytesOrPanic()
	return .raw
}

func ( *encryptedExtensionsMsg) ( []byte) bool {
	* = encryptedExtensionsMsg{raw: }
	 := cryptobyte.String()

	var  cryptobyte.String
	if !.Skip(4) || // message type and uint24 length field
		!.ReadUint16LengthPrefixed(&) || !.Empty() {
		return false
	}

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

		switch  {
		case extensionALPN:
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			var  cryptobyte.String
			if !.ReadUint8LengthPrefixed(&) ||
				.Empty() || !.Empty() {
				return false
			}
			.alpnProtocol = string()
Ignore unknown extensions.
			continue
		}

		if !.Empty() {
			return false
		}
	}

	return true
}

type endOfEarlyDataMsg struct{}

func ( *endOfEarlyDataMsg) () []byte {
	 := make([]byte, 4)
	[0] = typeEndOfEarlyData
	return 
}

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

type keyUpdateMsg struct {
	raw             []byte
	updateRequested bool
}

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

	var  cryptobyte.Builder
	.AddUint8(typeKeyUpdate)
	.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
		if .updateRequested {
			.AddUint8(1)
		} else {
			.AddUint8(0)
		}
	})

	.raw = .BytesOrPanic()
	return .raw
}

func ( *keyUpdateMsg) ( []byte) bool {
	.raw = 
	 := cryptobyte.String()

	var  uint8
	if !.Skip(4) || // message type and uint24 length field
		!.ReadUint8(&) || !.Empty() {
		return false
	}
	switch  {
	case 0:
		.updateRequested = false
	case 1:
		.updateRequested = true
	default:
		return false
	}
	return true
}

type newSessionTicketMsgTLS13 struct {
	raw          []byte
	lifetime     uint32
	ageAdd       uint32
	nonce        []byte
	label        []byte
	maxEarlyData uint32
}

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

	var  cryptobyte.Builder
	.AddUint8(typeNewSessionTicket)
	.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
		.AddUint32(.lifetime)
		.AddUint32(.ageAdd)
		.AddUint8LengthPrefixed(func( *cryptobyte.Builder) {
			.AddBytes(.nonce)
		})
		.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
			.AddBytes(.label)
		})

		.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
			if .maxEarlyData > 0 {
				.AddUint16(extensionEarlyData)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint32(.maxEarlyData)
				})
			}
		})
	})

	.raw = .BytesOrPanic()
	return .raw
}

func ( *newSessionTicketMsgTLS13) ( []byte) bool {
	* = newSessionTicketMsgTLS13{raw: }
	 := cryptobyte.String()

	var  cryptobyte.String
	if !.Skip(4) || // message type and uint24 length field
		!.ReadUint32(&.lifetime) ||
		!.ReadUint32(&.ageAdd) ||
		!readUint8LengthPrefixed(&, &.nonce) ||
		!readUint16LengthPrefixed(&, &.label) ||
		!.ReadUint16LengthPrefixed(&) ||
		!.Empty() {
		return false
	}

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

		switch  {
		case extensionEarlyData:
			if !.ReadUint32(&.maxEarlyData) {
				return false
			}
certificate_request_context (SHALL be zero length unless used for post-handshake authentication)
		.AddUint8(0)

		.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
			if .ocspStapling {
				.AddUint16(extensionStatusRequest)
				.AddUint16(0) // empty extension_data
			}
RFC 8446, Section 4.4.2.1 makes no mention of signed_certificate_timestamp in CertificateRequest, but "Extensions in the Certificate message from the client MUST correspond to extensions in the CertificateRequest message from the server." and it appears in the table in Section 4.2.
				.AddUint16(extensionSCT)
				.AddUint16(0) // empty extension_data
			}
			if len(.supportedSignatureAlgorithms) > 0 {
				.AddUint16(extensionSignatureAlgorithms)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						for ,  := range .supportedSignatureAlgorithms {
							.AddUint16(uint16())
						}
					})
				})
			}
			if len(.supportedSignatureAlgorithmsCert) > 0 {
				.AddUint16(extensionSignatureAlgorithmsCert)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						for ,  := range .supportedSignatureAlgorithmsCert {
							.AddUint16(uint16())
						}
					})
				})
			}
			if len(.certificateAuthorities) > 0 {
				.AddUint16(extensionCertificateAuthorities)
				.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						for ,  := range .certificateAuthorities {
							.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
								.AddBytes()
							})
						}
					})
				})
			}
		})
	})

	.raw = .BytesOrPanic()
	return .raw
}

func ( *certificateRequestMsgTLS13) ( []byte) bool {
	* = certificateRequestMsgTLS13{raw: }
	 := cryptobyte.String()

	var ,  cryptobyte.String
	if !.Skip(4) || // message type and uint24 length field
		!.ReadUint8LengthPrefixed(&) || !.Empty() ||
		!.ReadUint16LengthPrefixed(&) ||
		!.Empty() {
		return false
	}

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

		switch  {
		case extensionStatusRequest:
			.ocspStapling = true
		case extensionSCT:
			.scts = true
		case extensionSignatureAlgorithms:
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  uint16
				if !.ReadUint16(&) {
					return false
				}
				.supportedSignatureAlgorithms = append(
					.supportedSignatureAlgorithms, SignatureScheme())
			}
		case extensionSignatureAlgorithmsCert:
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  uint16
				if !.ReadUint16(&) {
					return false
				}
				.supportedSignatureAlgorithmsCert = append(
					.supportedSignatureAlgorithmsCert, SignatureScheme())
			}
		case extensionCertificateAuthorities:
			var  cryptobyte.String
			if !.ReadUint16LengthPrefixed(&) || .Empty() {
				return false
			}
			for !.Empty() {
				var  []byte
				if !readUint16LengthPrefixed(&, &) || len() == 0 {
					return false
				}
				.certificateAuthorities = append(.certificateAuthorities, )
			}
Ignore unknown extensions.
			continue
		}

		if !.Empty() {
			return false
		}
	}

	return true
}

type certificateMsg struct {
	raw          []byte
	certificates [][]byte
}

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

	var  int
	for ,  := range .certificates {
		 += len()
	}

	 := 3 + 3*len(.certificates) + 
	 = make([]byte, 4+)
	[0] = typeCertificate
	[1] = uint8( >> 16)
	[2] = uint8( >> 8)
	[3] = uint8()

	 :=  - 3
	[4] = uint8( >> 16)
	[5] = uint8( >> 8)
	[6] = uint8()

	 := [7:]
	for ,  := range .certificates {
		[0] = uint8(len() >> 16)
		[1] = uint8(len() >> 8)
		[2] = uint8(len())
		copy([3:], )
		 = [3+len():]
	}

	.raw = 
	return
}

func ( *certificateMsg) ( []byte) bool {
	if len() < 7 {
		return false
	}

	.raw = 
	 := uint32([4])<<16 | uint32([5])<<8 | uint32([6])
	if uint32(len()) != +7 {
		return false
	}

	 := 0
	 := [7:]
	for  > 0 {
		if len() < 4 {
			return false
		}
		 := uint32([0])<<16 | uint32([1])<<8 | uint32([2])
		if uint32(len()) < 3+ {
			return false
		}
		 = [3+:]
		 -= 3 + 
		++
	}

	.certificates = make([][]byte, )
	 = [7:]
	for  := 0;  < ; ++ {
		 := uint32([0])<<16 | uint32([1])<<8 | uint32([2])
		.certificates[] = [3 : 3+]
		 = [3+:]
	}

	return true
}

type certificateMsgTLS13 struct {
	raw          []byte
	certificate  Certificate
	ocspStapling bool
	scts         bool
}

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

	var  cryptobyte.Builder
	.AddUint8(typeCertificate)
	.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
		.AddUint8(0) // certificate_request_context

		 := .certificate
		if !.ocspStapling {
			.OCSPStaple = nil
		}
		if !.scts {
			.SignedCertificateTimestamps = nil
		}
		marshalCertificate(, )
	})

	.raw = .BytesOrPanic()
	return .raw
}

func ( *cryptobyte.Builder,  Certificate) {
	.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
		for ,  := range .Certificate {
			.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
				.AddBytes()
			})
			.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
This library only supports OCSP and SCT for leaf certificates.
					return
				}
				if .OCSPStaple != nil {
					.AddUint16(extensionStatusRequest)
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						.AddUint8(statusTypeOCSP)
						.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
							.AddBytes(.OCSPStaple)
						})
					})
				}
				if .SignedCertificateTimestamps != nil {
					.AddUint16(extensionSCT)
					.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
						.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
							for ,  := range .SignedCertificateTimestamps {
								.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
									.AddBytes()
								})
							}
						})
					})
				}
			})
		}
	})
}

func ( *certificateMsgTLS13) ( []byte) bool {
	* = certificateMsgTLS13{raw: }
	 := cryptobyte.String()

	var  cryptobyte.String
	if !.Skip(4) || // message type and uint24 length field
		!.ReadUint8LengthPrefixed(&) || !.Empty() ||
		!unmarshalCertificate(&, &.certificate) ||
		!.Empty() {
		return false
	}

	.scts = .certificate.SignedCertificateTimestamps != nil
	.ocspStapling = .certificate.OCSPStaple != nil

	return true
}

func ( *cryptobyte.String,  *Certificate) bool {
	var  cryptobyte.String
	if !.ReadUint24LengthPrefixed(&) {
		return false
	}
	for !.Empty() {
		var  []byte
		var  cryptobyte.String
		if !readUint24LengthPrefixed(&, &) ||
			!.ReadUint16LengthPrefixed(&) {
			return false
		}
		.Certificate = append(.Certificate, )
		for !.Empty() {
			var  uint16
			var  cryptobyte.String
			if !.ReadUint16(&) ||
				!.ReadUint16LengthPrefixed(&) {
				return false
			}
This library only supports OCSP and SCT for leaf certificates.
				continue
			}

			switch  {
			case extensionStatusRequest:
				var  uint8
				if !.ReadUint8(&) ||  != statusTypeOCSP ||
					!readUint24LengthPrefixed(&, &.OCSPStaple) ||
					len(.OCSPStaple) == 0 {
					return false
				}
			case extensionSCT:
				var  cryptobyte.String
				if !.ReadUint16LengthPrefixed(&) || .Empty() {
					return false
				}
				for !.Empty() {
					var  []byte
					if !readUint16LengthPrefixed(&, &) ||
						len() == 0 {
						return false
					}
					.SignedCertificateTimestamps = append(
						.SignedCertificateTimestamps, )
				}
Ignore unknown extensions.
				continue
			}

			if !.Empty() {
				return false
			}
		}
	}
	return true
}

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

func ( *serverKeyExchangeMsg) () []byte {
	if .raw != nil {
		return .raw
	}
	 := len(.key)
	 := make([]byte, +4)
	[0] = typeServerKeyExchange
	[1] = uint8( >> 16)
	[2] = uint8( >> 8)
	[3] = uint8()
	copy([4:], .key)

	.raw = 
	return 
}

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

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

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

	var  cryptobyte.Builder
	.AddUint8(typeCertificateStatus)
	.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
		.AddUint8(statusTypeOCSP)
		.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
			.AddBytes(.response)
		})
	})

	.raw = .BytesOrPanic()
	return .raw
}

func ( *certificateStatusMsg) ( []byte) bool {
	.raw = 
	 := cryptobyte.String()

	var  uint8
	if !.Skip(4) || // message type and uint24 length field
		!.ReadUint8(&) ||  != statusTypeOCSP ||
		!readUint24LengthPrefixed(&, &.response) ||
		len(.response) == 0 || !.Empty() {
		return false
	}
	return true
}

type serverHelloDoneMsg struct{}

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

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

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

func ( *clientKeyExchangeMsg) () []byte {
	if .raw != nil {
		return .raw
	}
	 := len(.ciphertext)
	 := make([]byte, +4)
	[0] = typeClientKeyExchange
	[1] = uint8( >> 16)
	[2] = uint8( >> 8)
	[3] = uint8()
	copy([4:], .ciphertext)

	.raw = 
	return 
}

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

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

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

	var  cryptobyte.Builder
	.AddUint8(typeFinished)
	.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
		.AddBytes(.verifyData)
	})

	.raw = .BytesOrPanic()
	return .raw
}

func ( *finishedMsg) ( []byte) bool {
	.raw = 
	 := cryptobyte.String()
	return .Skip(1) &&
		readUint24LengthPrefixed(&, &.verifyData) &&
		.Empty()
}

type certificateRequestMsg struct {
hasSignatureAlgorithm indicates whether this message includes a list of supported signature algorithms. This change was introduced with TLS 1.2.
See RFC 4346, Section 7.4.4.
	 := 1 + len(.certificateTypes) + 2
	 := 0
	for ,  := range .certificateAuthorities {
		 += 2 + len()
	}
	 += 

	if .hasSignatureAlgorithm {
		 += 2 + 2*len(.supportedSignatureAlgorithms)
	}

	 = make([]byte, 4+)
	[0] = typeCertificateRequest
	[1] = uint8( >> 16)
	[2] = uint8( >> 8)
	[3] = uint8()

	[4] = uint8(len(.certificateTypes))

	copy([5:], .certificateTypes)
	 := [5+len(.certificateTypes):]

	if .hasSignatureAlgorithm {
		 := len(.supportedSignatureAlgorithms) * 2
		[0] = uint8( >> 8)
		[1] = uint8()
		 = [2:]
		for ,  := range .supportedSignatureAlgorithms {
			[0] = uint8( >> 8)
			[1] = uint8()
			 = [2:]
		}
	}

	[0] = uint8( >> 8)
	[1] = uint8()
	 = [2:]
	for ,  := range .certificateAuthorities {
		[0] = uint8(len() >> 8)
		[1] = uint8(len())
		 = [2:]
		copy(, )
		 = [len():]
	}

	.raw = 
	return
}

func ( *certificateRequestMsg) ( []byte) bool {
	.raw = 

	if len() < 5 {
		return false
	}

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

	 := int([4])
	 = [5:]
	if  == 0 || len() <=  {
		return false
	}

	.certificateTypes = make([]byte, )
	if copy(.certificateTypes, ) !=  {
		return false
	}

	 = [:]

	if .hasSignatureAlgorithm {
		if len() < 2 {
			return false
		}
		 := uint16([0])<<8 | uint16([1])
		 = [2:]
		if &1 != 0 {
			return false
		}
		if len() < int() {
			return false
		}
		 :=  / 2
		.supportedSignatureAlgorithms = make([]SignatureScheme, )
		for  := range .supportedSignatureAlgorithms {
			.supportedSignatureAlgorithms[] = SignatureScheme([0])<<8 | SignatureScheme([1])
			 = [2:]
		}
	}

	if len() < 2 {
		return false
	}
	 := uint16([0])<<8 | uint16([1])
	 = [2:]
	if len() < int() {
		return false
	}
	 := make([]byte, )
	copy(, )
	 = [:]

	.certificateAuthorities = nil
	for len() > 0 {
		if len() < 2 {
			return false
		}
		 := uint16([0])<<8 | uint16([1])
		 = [2:]

		if len() < int() {
			return false
		}

		.certificateAuthorities = append(.certificateAuthorities, [:])
		 = [:]
	}

	return len() == 0
}

type certificateVerifyMsg struct {
	raw                   []byte
	hasSignatureAlgorithm bool // format change introduced in TLS 1.2
	signatureAlgorithm    SignatureScheme
	signature             []byte
}

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

	var  cryptobyte.Builder
	.AddUint8(typeCertificateVerify)
	.AddUint24LengthPrefixed(func( *cryptobyte.Builder) {
		if .hasSignatureAlgorithm {
			.AddUint16(uint16(.signatureAlgorithm))
		}
		.AddUint16LengthPrefixed(func( *cryptobyte.Builder) {
			.AddBytes(.signature)
		})
	})

	.raw = .BytesOrPanic()
	return .raw
}

func ( *certificateVerifyMsg) ( []byte) bool {
	.raw = 
	 := cryptobyte.String()

	if !.Skip(4) { // message type and uint24 length field
		return false
	}
	if .hasSignatureAlgorithm {
		if !.ReadUint16((*uint16)(&.signatureAlgorithm)) {
			return false
		}
	}
	return readUint16LengthPrefixed(&, &.signature) && .Empty()
}

type newSessionTicketMsg struct {
	raw    []byte
	ticket []byte
}

func ( *newSessionTicketMsg) () ( []byte) {
	if .raw != nil {
		return .raw
	}
See RFC 5077, Section 3.3.
	 := len(.ticket)
	 := 2 + 4 + 
	 = make([]byte, 4+)
	[0] = typeNewSessionTicket
	[1] = uint8( >> 16)
	[2] = uint8( >> 8)
	[3] = uint8()
	[8] = uint8( >> 8)
	[9] = uint8()
	copy([10:], .ticket)

	.raw = 

	return
}

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

	if len() < 10 {
		return false
	}

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

	 := int([8])<<8 + int([9])
	if len()-10 !=  {
		return false
	}

	.ticket = [10:]

	return true
}

type helloRequestMsg struct {
}

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

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