// Copyright 2017 Google Inc. 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 (
	
	
	
	
	

	
	
)

// ExtensionFromID returns a TLSExtension for the given extension ID.
func ( uint16) TLSExtension {
	// deep copy
	switch  {
	case extensionServerName:
		return &SNIExtension{}
	case extensionStatusRequest:
		return &StatusRequestExtension{}
	case extensionSupportedCurves:
		return &SupportedCurvesExtension{}
	case extensionSupportedPoints:
		return &SupportedPointsExtension{}
	case extensionSignatureAlgorithms:
		return &SignatureAlgorithmsExtension{}
	case extensionALPN:
		return &ALPNExtension{}
	case extensionStatusRequestV2:
		return &StatusRequestV2Extension{}
	case extensionSCT:
		return &SCTExtension{}
	case utlsExtensionPadding:
		return &UtlsPaddingExtension{}
	case extensionExtendedMasterSecret:
		return &ExtendedMasterSecretExtension{}
	case fakeExtensionTokenBinding:
		return &FakeTokenBindingExtension{}
	case utlsExtensionCompressCertificate:
		return &UtlsCompressCertExtension{}
	case fakeRecordSizeLimit:
		return &FakeRecordSizeLimitExtension{}
	case fakeExtensionDelegatedCredentials:
		return &FakeDelegatedCredentialsExtension{}
	case extensionSessionTicket:
		return &SessionTicketExtension{}
	case extensionPreSharedKey:
		return (PreSharedKeyExtension)(&FakePreSharedKeyExtension{}) // To use the result, caller needs further inspection to decide between Fake or Utls.
	// case extensionEarlyData:
	// 	return &EarlyDataExtension{}
	case extensionSupportedVersions:
		return &SupportedVersionsExtension{}
	// case extensionCookie:
	// 	return &CookieExtension{}
	case extensionPSKModes:
		return &PSKKeyExchangeModesExtension{}
	// case extensionCertificateAuthorities:
	// 	return &CertificateAuthoritiesExtension{}
	case extensionSignatureAlgorithmsCert:
		return &SignatureAlgorithmsCertExtension{}
	case extensionKeyShare:
		return &KeyShareExtension{}
	case extensionQUICTransportParameters:
		return &QUICTransportParametersExtension{}
	case extensionNextProtoNeg:
		return &NPNExtension{}
	case utlsExtensionApplicationSettings:
		return &ApplicationSettingsExtension{}
	case utlsExtensionApplicationSettingsNew:
		return &ApplicationSettingsExtensionNew{}
	case fakeOldExtensionChannelID:
		return &FakeChannelIDExtension{true}
	case fakeExtensionChannelID:
		return &FakeChannelIDExtension{}
	case utlsExtensionECH:
		return &GREASEEncryptedClientHelloExtension{}
	case extensionRenegotiationInfo:
		return &RenegotiationInfoExtension{}
	default:
		if isGREASEUint16() {
			return &UtlsGREASEExtension{}
		}
		return nil // not returning GenericExtension, it should be handled by caller
	}
}

type TLSExtension interface {
	writeToUConn(*UConn) error

	Len() int // includes header

	// Read reads up to len(p) bytes into p.
	// It returns the number of bytes read (0 <= n <= len(p)) and any error encountered.
	Read(p []byte) (n int, err error) // implements io.Reader
}

// TLSExtensionWriter is an interface allowing a TLS extension to be
// auto-constucted/recovered by reading in a byte stream.
type TLSExtensionWriter interface {
	TLSExtension

	// Write writes the extension data as a byte slice, up to len(b) bytes from b.
	// It returns the number of bytes written (0 <= n <= len(b)) and any error encountered.
	//
	// The implementation MUST NOT silently drop data if consumed less than len(b) bytes,
	// instead, it MUST return an error.
	Write(b []byte) (n int, err error)
}

type TLSExtensionJSON interface {
	TLSExtension

	// UnmarshalJSON unmarshals the JSON-encoded data into the extension.
	UnmarshalJSON([]byte) error
}

// SNIExtension implements server_name (0)
type SNIExtension struct {
	ServerName string // not an array because go crypto/tls doesn't support multiple SNIs
}

func ( *SNIExtension) () int {
	// Literal IP addresses, absolute FQDNs, and empty strings are not permitted as SNI values.
	// See RFC 6066, Section 3.
	 := hostnameInSNI(.ServerName)
	if len() == 0 {
		return 0
	}
	return 4 + 2 + 1 + 2 + len()
}

func ( *SNIExtension) ( []byte) (int, error) {
	// Literal IP addresses, absolute FQDNs, and empty strings are not permitted as SNI values.
	// See RFC 6066, Section 3.
	 := hostnameInSNI(.ServerName)
	if len() == 0 {
		return 0, io.EOF
	}
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// RFC 3546, section 3.1
	[0] = byte(extensionServerName >> 8)
	[1] = byte(extensionServerName)
	[2] = byte((len() + 5) >> 8)
	[3] = byte(len() + 5)
	[4] = byte((len() + 3) >> 8)
	[5] = byte(len() + 3)
	// b[6] Server Name Type: host_name (0)
	[7] = byte(len() >> 8)
	[8] = byte(len())
	copy([9:], []byte())
	return .Len(), io.EOF
}

func ( *SNIExtension) ( []byte) error {
	return nil // no-op
}

// Write is a no-op for StatusRequestExtension.
// SNI should not be fingerprinted and is user controlled.
func ( *SNIExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	// RFC 6066, Section 3
	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || .Empty() {
		return , errors.New("unable to read server name extension data")
	}
	var  string
	for !.Empty() {
		var  uint8
		var  cryptobyte.String
		if !.ReadUint8(&) ||
			!.ReadUint16LengthPrefixed(&) ||
			.Empty() {
			return , errors.New("unable to read server name extension data")
		}
		if  != 0 {
			continue
		}
		if len() != 0 {
			return , errors.New("multiple names of the same name_type in server name extension are prohibited")
		}
		 = string()
		if strings.HasSuffix(, ".") {
			return , errors.New("SNI value may not include a trailing dot")
		}
	}
	// clientHelloSpec.Extensions = append(clientHelloSpec.Extensions, &SNIExtension{}) // gaukas moved this line out from the loop.

	// don't copy SNI from ClientHello to ClientHelloSpec!
	return , nil
}

func ( *SNIExtension) ( *UConn) error {
	if .config.EncryptedClientHelloConfigList == nil { // with ech, e.ServerName is the outer public name and should not be copied
		.config.ServerName = .ServerName
	}
	 := hostnameInSNI(.ServerName)
	.HandshakeState.Hello.ServerName = 

	return nil
}

// StatusRequestExtension implements status_request (5)
type StatusRequestExtension struct {
}

func ( *StatusRequestExtension) () int {
	return 9
}

func ( *StatusRequestExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// RFC 4366, section 3.6
	[0] = byte(extensionStatusRequest >> 8)
	[1] = byte(extensionStatusRequest)
	[2] = 0
	[3] = 5
	[4] = 1 // OCSP type
	// Two zero valued uint16s for the two lengths.
	return .Len(), io.EOF
}

func ( *StatusRequestExtension) ( []byte) error {
	return nil // no-op
}

// Write is a no-op for StatusRequestExtension. No data for this extension.
func ( *StatusRequestExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	// RFC 4366, Section 3.6
	var  uint8
	var  cryptobyte.String
	if !.ReadUint8(&) ||
		!.ReadUint16LengthPrefixed(&) ||
		!.ReadUint16LengthPrefixed(&) {
		return , errors.New("unable to read status request extension data")
	}

	if  != statusTypeOCSP {
		return , errors.New("status request extension statusType is not statusTypeOCSP(1)")
	}

	return , nil
}

func ( *StatusRequestExtension) ( *UConn) error {
	.HandshakeState.Hello.OcspStapling = true
	return nil
}

// SupportedCurvesExtension implements supported_groups (renamed from "elliptic_curves") (10)
type SupportedCurvesExtension struct {
	Curves []CurveID
}

func ( *SupportedCurvesExtension) () int {
	return 6 + 2*len(.Curves)
}

func ( *SupportedCurvesExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// http://tools.ietf.org/html/rfc4492#section-5.5.1
	[0] = byte(extensionSupportedCurves >> 8)
	[1] = byte(extensionSupportedCurves)
	[2] = byte((2 + 2*len(.Curves)) >> 8)
	[3] = byte(2 + 2*len(.Curves))
	[4] = byte((2 * len(.Curves)) >> 8)
	[5] = byte(2 * len(.Curves))
	for ,  := range .Curves {
		[6+2*] = byte( >> 8)
		[7+2*] = byte()
	}
	return .Len(), io.EOF
}

func ( *SupportedCurvesExtension) ( []byte) error {
	var  struct {
		 []string `json:"named_group_list"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	for ,  := range . {
		if  == "GREASE" {
			.Curves = append(.Curves, GREASE_PLACEHOLDER)
			continue
		}

		if ,  := dicttls.DictSupportedGroupsNameIndexed[];  {
			.Curves = append(.Curves, CurveID())
		} else {
			return fmt.Errorf("unknown named group: %s", )
		}
	}
	return nil
}

func ( *SupportedCurvesExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	// RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || .Empty() {
		return 0, errors.New("unable to read supported curves extension data")
	}
	 := []CurveID{}
	for !.Empty() {
		var  uint16
		if !.ReadUint16(&) {
			return 0, errors.New("unable to read supported curves extension data")
		}
		 = append(, CurveID(unGREASEUint16()))
	}
	.Curves = 
	return , nil
}

func ( *SupportedCurvesExtension) ( *UConn) error {
	.config.CurvePreferences = .Curves
	.HandshakeState.Hello.SupportedCurves = .Curves
	return nil
}

// SupportedPointsExtension implements ec_point_formats (11)
type SupportedPointsExtension struct {
	SupportedPoints []uint8
}

func ( *SupportedPointsExtension) () int {
	return 5 + len(.SupportedPoints)
}

func ( *SupportedPointsExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// http://tools.ietf.org/html/rfc4492#section-5.5.2
	[0] = byte(extensionSupportedPoints >> 8)
	[1] = byte(extensionSupportedPoints)
	[2] = byte((1 + len(.SupportedPoints)) >> 8)
	[3] = byte(1 + len(.SupportedPoints))
	[4] = byte(len(.SupportedPoints))
	for ,  := range .SupportedPoints {
		[5+] = 
	}
	return .Len(), io.EOF
}

func ( *SupportedPointsExtension) ( []byte) error {
	var  struct {
		 []string `json:"ec_point_format_list"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	for ,  := range . {
		if ,  := dicttls.DictECPointFormatNameIndexed[];  {
			.SupportedPoints = append(.SupportedPoints, )
		} else {
			return fmt.Errorf("unknown point format: %s", )
		}
	}
	return nil
}

func ( *SupportedPointsExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	// RFC 4492, Section 5.1.2
	 := []uint8{}
	if !readUint8LengthPrefixed(&, &) ||
		len() == 0 {
		return 0, errors.New("unable to read supported points extension data")
	}
	.SupportedPoints = 
	return , nil
}

func ( *SupportedPointsExtension) ( *UConn) error {
	.HandshakeState.Hello.SupportedPoints = .SupportedPoints
	return nil
}

// SignatureAlgorithmsExtension implements signature_algorithms (13)
type SignatureAlgorithmsExtension struct {
	SupportedSignatureAlgorithms []SignatureScheme
}

func ( *SignatureAlgorithmsExtension) () int {
	return 6 + 2*len(.SupportedSignatureAlgorithms)
}

func ( *SignatureAlgorithmsExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
	[0] = byte(extensionSignatureAlgorithms >> 8)
	[1] = byte(extensionSignatureAlgorithms)
	[2] = byte((2 + 2*len(.SupportedSignatureAlgorithms)) >> 8)
	[3] = byte(2 + 2*len(.SupportedSignatureAlgorithms))
	[4] = byte((2 * len(.SupportedSignatureAlgorithms)) >> 8)
	[5] = byte(2 * len(.SupportedSignatureAlgorithms))
	for ,  := range .SupportedSignatureAlgorithms {
		[6+2*] = byte( >> 8)
		[7+2*] = byte()
	}
	return .Len(), io.EOF
}

func ( *SignatureAlgorithmsExtension) ( []byte) error {
	var  struct {
		 []string `json:"supported_signature_algorithms"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	for ,  := range . {
		if  == "GREASE" {
			.SupportedSignatureAlgorithms = append(.SupportedSignatureAlgorithms, GREASE_PLACEHOLDER)
			continue
		}

		if ,  := dicttls.DictSignatureSchemeNameIndexed[];  {
			.SupportedSignatureAlgorithms = append(.SupportedSignatureAlgorithms, SignatureScheme())
		} else {
			return fmt.Errorf("unknown signature scheme: %s", )
		}
	}
	return nil
}

func ( *SignatureAlgorithmsExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	// RFC 5246, Section 7.4.1.4.1
	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || .Empty() {
		return 0, errors.New("unable to read signature algorithms extension data")
	}
	 := []SignatureScheme{}
	for !.Empty() {
		var  uint16
		if !.ReadUint16(&) {
			return 0, errors.New("unable to read signature algorithms extension data")
		}
		 = append(
			, SignatureScheme())
	}
	.SupportedSignatureAlgorithms = 
	return , nil
}

func ( *SignatureAlgorithmsExtension) ( *UConn) error {
	.HandshakeState.Hello.SupportedSignatureAlgorithms = .SupportedSignatureAlgorithms
	return nil
}

// StatusRequestV2Extension implements status_request_v2 (17)
type StatusRequestV2Extension struct {
}

func ( *StatusRequestV2Extension) ( *UConn) error {
	.HandshakeState.Hello.OcspStapling = true
	return nil
}

func ( *StatusRequestV2Extension) () int {
	return 13
}

func ( *StatusRequestV2Extension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// RFC 4366, section 3.6
	[0] = byte(extensionStatusRequestV2 >> 8)
	[1] = byte(extensionStatusRequestV2)
	[2] = 0
	[3] = 9
	[4] = 0
	[5] = 7
	[6] = 2 // OCSP type
	[7] = 0
	[8] = 4
	// Two zero valued uint16s for the two lengths.
	return .Len(), io.EOF
}

// Write is a no-op for StatusRequestV2Extension. No data for this extension.
func ( *StatusRequestV2Extension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	// RFC 4366, Section 3.6
	var  uint8
	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || !.ReadUint8(&) {
		return , errors.New("unable to read status request v2 extension data")
	}

	if  != statusV2TypeOCSP {
		return , errors.New("status request v2 extension statusType is not statusV2TypeOCSP(2)")
	}

	return , nil
}

func ( *StatusRequestV2Extension) ( []byte) error {
	return nil // no-op
}

// SignatureAlgorithmsCertExtension implements signature_algorithms_cert (50)
type SignatureAlgorithmsCertExtension struct {
	SupportedSignatureAlgorithms []SignatureScheme
}

func ( *SignatureAlgorithmsCertExtension) () int {
	return 6 + 2*len(.SupportedSignatureAlgorithms)
}

func ( *SignatureAlgorithmsCertExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
	[0] = byte(extensionSignatureAlgorithmsCert >> 8)
	[1] = byte(extensionSignatureAlgorithmsCert)
	[2] = byte((2 + 2*len(.SupportedSignatureAlgorithms)) >> 8)
	[3] = byte(2 + 2*len(.SupportedSignatureAlgorithms))
	[4] = byte((2 * len(.SupportedSignatureAlgorithms)) >> 8)
	[5] = byte(2 * len(.SupportedSignatureAlgorithms))
	for ,  := range .SupportedSignatureAlgorithms {
		[6+2*] = byte( >> 8)
		[7+2*] = byte()
	}
	return .Len(), io.EOF
}

// Copied from SignatureAlgorithmsExtension.UnmarshalJSON
func ( *SignatureAlgorithmsCertExtension) ( []byte) error {
	var  struct {
		 []string `json:"supported_signature_algorithms"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	for ,  := range . {
		if  == "GREASE" {
			.SupportedSignatureAlgorithms = append(.SupportedSignatureAlgorithms, GREASE_PLACEHOLDER)
			continue
		}

		if ,  := dicttls.DictSignatureSchemeNameIndexed[];  {
			.SupportedSignatureAlgorithms = append(.SupportedSignatureAlgorithms, SignatureScheme())
		} else {
			return fmt.Errorf("unknown cert signature scheme: %s", )
		}
	}
	return nil
}

// Write implementation copied from SignatureAlgorithmsExtension.Write
//
// Warning: not tested.
func ( *SignatureAlgorithmsCertExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	// RFC 8446, Section 4.2.3
	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || .Empty() {
		return 0, errors.New("unable to read signature algorithms extension data")
	}
	 := []SignatureScheme{}
	for !.Empty() {
		var  uint16
		if !.ReadUint16(&) {
			return 0, errors.New("unable to read signature algorithms extension data")
		}
		 = append(
			, SignatureScheme())
	}
	.SupportedSignatureAlgorithms = 
	return , nil
}

func ( *SignatureAlgorithmsCertExtension) ( *UConn) error {
	.HandshakeState.Hello.SupportedSignatureAlgorithms = .SupportedSignatureAlgorithms
	return nil
}

// ALPNExtension implements application_layer_protocol_negotiation (16)
type ALPNExtension struct {
	AlpnProtocols []string
}

func ( *ALPNExtension) ( *UConn) error {
	.config.NextProtos = .AlpnProtocols
	.HandshakeState.Hello.AlpnProtocols = .AlpnProtocols
	return nil
}

func ( *ALPNExtension) () int {
	 := 2 + 2 + 2
	for ,  := range .AlpnProtocols {
		 += 1 + len()
	}
	return 
}

func ( *ALPNExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}

	[0] = byte(extensionALPN >> 8)
	[1] = byte(extensionALPN & 0xff)
	 := [2:]
	 = [6:]

	 := 0
	for ,  := range .AlpnProtocols {
		 := len()
		[0] = byte()
		copy([1:], )
		 = [1+:]
		 += 1 + 
	}

	[2] = byte( >> 8)
	[3] = byte()
	 += 2
	[0] = byte( >> 8)
	[1] = byte()

	return .Len(), io.EOF
}

func ( *ALPNExtension) ( []byte) error {
	var  struct {
		 []string `json:"protocol_name_list"`
	}

	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	.AlpnProtocols = .
	return nil
}

func ( *ALPNExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	// RFC 7301, Section 3.1
	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || .Empty() {
		return 0, errors.New("unable to read ALPN extension data")
	}
	 := []string{}
	for !.Empty() {
		var  cryptobyte.String
		if !.ReadUint8LengthPrefixed(&) || .Empty() {
			return 0, errors.New("unable to read ALPN extension data")
		}
		 = append(, string())

	}
	.AlpnProtocols = 
	return , nil
}

// applicationSettingsExtension represents the TLS ALPS extension.
// At the time of this writing, this extension is currently a draft:
// https://datatracker.ietf.org/doc/html/draft-vvv-tls-alps-01
type applicationSettingsExtension struct {
	codePoint uint16
}

func ( *applicationSettingsExtension) ( *UConn) error {
	return nil
}

func ( *applicationSettingsExtension) ( []string) int {
	 := 2 + 2 + 2 // Type + Length + ALPS Extension length
	for ,  := range  {
		 += 1 + len() // Supported ALPN Length + actual length of protocol
	}
	return 
}

func ( *applicationSettingsExtension) ( []byte,  []string) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}

	// Read Type.
	[0] = byte(.codePoint >> 8)   // hex: 44 dec: 68
	[1] = byte(.codePoint & 0xff) // hex: 69 dec: 105

	 := [2:] // get the remaining buffer without Type
	 = [6:]        // set the buffer to the buffer without Type, Length and ALPS Extension Length (so only the Supported ALPN list remains)

	 := 0
	for ,  := range  {
		 := len()            // Supported ALPN Length
		[0] = byte()         // Supported ALPN Length in bytes hex: 02 dec: 2
		copy([1:], )         // copy the Supported ALPN as bytes to the buffer
		 = [1+:]            // set the buffer to the buffer without the Supported ALPN Length and Supported ALPN (so we can continue to the next protocol in this loop)
		 += 1 +  // Supported ALPN Length (the field itself) + Supported ALPN Length (the value)
	}

	[2] = byte( >> 8) // ALPS Extension Length hex: 00 dec: 0
	[3] = byte()      // ALPS Extension Length hex: 03 dec: 3
	 += 2                    // plus ALPS Extension Length field length
	[0] = byte( >> 8) // Length hex:00 dec: 0
	[1] = byte()      // Length hex: 05 dec: 5

	return .Len(), io.EOF
}

// Write implementation copied from ALPNExtension.Write
func ( *applicationSettingsExtension) ( []byte) ([]string, int, error) {
	 := len()
	 := cryptobyte.String()
	// https://datatracker.ietf.org/doc/html/draft-vvv-tls-alps-01
	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || .Empty() {
		return nil, 0, errors.New("unable to read ALPN extension data")
	}
	 := []string{}
	for !.Empty() {
		var  cryptobyte.String
		if !.ReadUint8LengthPrefixed(&) || .Empty() {
			return nil, 0, errors.New("unable to read ALPN extension data")
		}
		 = append(, string())

	}
	return , , nil
}

// ApplicationSettingsExtension embeds applicationSettingsExtension to implement the TLS ALPS extension on codepoint 17513
type ApplicationSettingsExtension struct {
	applicationSettingsExtension
	SupportedProtocols []string
}

func ( *ApplicationSettingsExtension) () int {
	return .applicationSettingsExtension.Len(.SupportedProtocols)
}

func ( *ApplicationSettingsExtension) ( []byte) (int, error) {
	.applicationSettingsExtension.codePoint = utlsExtensionApplicationSettings
	return .applicationSettingsExtension.Read(, .SupportedProtocols)
}

func ( *ApplicationSettingsExtension) ( []byte) error {
	var  struct {
		 []string `json:"supported_protocols"`
	}

	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	.SupportedProtocols = .
	return nil
}

// Write implementation copied from ALPNExtension.Write
func ( *ApplicationSettingsExtension) ( []byte) (int, error) {
	var (
		 int
		     error
	)
	.SupportedProtocols, ,  = .applicationSettingsExtension.Write()
	return , 
}

// ApplicationSettingsExtensionNew embeds applicationSettingsExtension to implement the TLS ALPS extension on codepoint 17613
// More information can be found here: https://chromestatus.com/feature/5149147365900288
type ApplicationSettingsExtensionNew struct {
	applicationSettingsExtension
	SupportedProtocols []string
}

func ( *ApplicationSettingsExtensionNew) () int {
	return .applicationSettingsExtension.Len(.SupportedProtocols)
}

func ( *ApplicationSettingsExtensionNew) ( []byte) (int, error) {
	.applicationSettingsExtension.codePoint = utlsExtensionApplicationSettingsNew
	return .applicationSettingsExtension.Read(, .SupportedProtocols)
}

func ( *ApplicationSettingsExtensionNew) ( []byte) error {
	var  struct {
		 []string `json:"supported_protocols"`
	}

	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	.SupportedProtocols = .
	return nil
}

// Write implementation copied from ALPNExtension.Write
func ( *ApplicationSettingsExtensionNew) ( []byte) (int, error) {
	var (
		 int
		     error
	)
	.SupportedProtocols, ,  = .applicationSettingsExtension.Write()
	return , 
}

// SCTExtension implements signed_certificate_timestamp (18)
type SCTExtension struct {
}

func ( *SCTExtension) ( *UConn) error {
	.HandshakeState.Hello.Scts = true
	return nil
}

func ( *SCTExtension) () int {
	return 4
}

func ( *SCTExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// https://tools.ietf.org/html/rfc6962#section-3.3.1
	[0] = byte(extensionSCT >> 8)
	[1] = byte(extensionSCT)
	// zero uint16 for the zero-length extension_data
	return .Len(), io.EOF
}

func ( *SCTExtension) ( []byte) error {
	return nil // no-op
}

func ( *SCTExtension) ( []byte) (int, error) {
	return 0, nil
}

// GenericExtension allows to include in ClientHello arbitrary unsupported extensions.
// It is not defined in TLS RFCs nor by IANA.
// If a server echoes this extension back, the handshake will likely fail due to no further support.
type GenericExtension struct {
	Id   uint16
	Data []byte
}

func ( *GenericExtension) ( *UConn) error {
	return nil
}

func ( *GenericExtension) () int {
	return 4 + len(.Data)
}

func ( *GenericExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}

	[0] = byte(.Id >> 8)
	[1] = byte(.Id)
	[2] = byte(len(.Data) >> 8)
	[3] = byte(len(.Data))
	if len(.Data) > 0 {
		copy([4:], .Data)
	}
	return .Len(), io.EOF
}

func ( *GenericExtension) ( []byte) error {
	var  struct {
		 string `json:"name"`
		 []byte `json:"data"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	// lookup extension ID by name
	if ,  := dicttls.DictExtTypeNameIndexed[.];  {
		.Id = 
	} else {
		return fmt.Errorf("unknown extension name %s", .)
	}
	.Data = .
	return nil
}

// ExtendedMasterSecretExtension implements extended_master_secret (23)
//
// Was named as ExtendedMasterSecretExtension, renamed due to crypto/tls
// implemented this extension's support.
type ExtendedMasterSecretExtension struct {
}

// TODO: update when this extension is implemented in crypto/tls
// but we probably won't have to enable it in Config
func ( *ExtendedMasterSecretExtension) ( *UConn) error {
	.HandshakeState.Hello.Ems = true
	return nil
}

func ( *ExtendedMasterSecretExtension) () int {
	return 4
}

func ( *ExtendedMasterSecretExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// https://tools.ietf.org/html/rfc7627
	[0] = byte(extensionExtendedMasterSecret >> 8)
	[1] = byte(extensionExtendedMasterSecret)
	// The length is 0
	return .Len(), io.EOF
}

func ( *ExtendedMasterSecretExtension) ( []byte) error {
	return nil // no-op
}

func ( *ExtendedMasterSecretExtension) ( []byte) (int, error) {
	// https://tools.ietf.org/html/rfc7627
	return 0, nil
}

// GREASE stinks with dead parrots, have to be super careful, and, if possible, not include GREASE
// https://github.com/google/boringssl/blob/1c68fa2350936ca5897a66b430ebaf333a0e43f5/ssl/internal.h
const (
	ssl_grease_cipher = iota
	ssl_grease_group
	ssl_grease_extension1
	ssl_grease_extension2
	ssl_grease_version
	ssl_grease_ticket_extension
	ssl_grease_last_index = ssl_grease_ticket_extension
)

// it is responsibility of user not to generate multiple grease extensions with same value
type UtlsGREASEExtension struct {
	Value uint16
	Body  []byte // in Chrome first grease has empty body, second grease has a single zero byte
}

func ( *UtlsGREASEExtension) ( *UConn) error {
	return nil
}

// will panic if ssl_grease_last_index[index] is out of bounds.
func ( [ssl_grease_last_index]uint16,  int) uint16 {
	// GREASE value is back from deterministic to random.
	// https://github.com/google/boringssl/blob/a365138ac60f38b64bfc608b493e0f879845cb88/ssl/handshake_client.c#L530
	 := uint16([])
	/* This generates a random value of the form 0xωaωa, for all 0 ≤ ω < 16. */
	 = ( & 0xf0) | 0x0a
	 |=  << 8
	return 
}

func ( *UtlsGREASEExtension) () int {
	return 4 + len(.Body)
}

func ( *UtlsGREASEExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}

	[0] = byte(.Value >> 8)
	[1] = byte(.Value)
	[2] = byte(len(.Body) >> 8)
	[3] = byte(len(.Body))
	if len(.Body) > 0 {
		copy([4:], .Body)
	}
	return .Len(), io.EOF
}

func ( *UtlsGREASEExtension) ( []byte) (int, error) {
	.Value = GREASE_PLACEHOLDER
	.Body = make([]byte, len())
	 := copy(.Body, )
	return , nil
}

func ( *UtlsGREASEExtension) ( []byte) error {
	var  struct {
		       uint16 `json:"id"`
		     []byte `json:"data"`
		   bool   `json:"keep_id"`
		 bool   `json:"keep_data"`
	}

	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	if . == 0 {
		return nil
	}

	if isGREASEUint16(.) {
		if . {
			.Value = .
		}
		if . {
			.Body = .
		}
		return nil
	} else {
		return errors.New("GREASE extension id must be a GREASE value")
	}
}

// UtlsPaddingExtension implements padding (21)
type UtlsPaddingExtension struct {
	PaddingLen int
	WillPad    bool // set to false to disable extension

	// Functor for deciding on padding length based on unpadded ClientHello length.
	// If willPad is false, then this extension should not be included.
	GetPaddingLen func(clientHelloUnpaddedLen int) (paddingLen int, willPad bool)
}

func ( *UtlsPaddingExtension) ( *UConn) error {
	return nil
}

func ( *UtlsPaddingExtension) () int {
	if .WillPad {
		return 4 + .PaddingLen
	} else {
		return 0
	}
}

func ( *UtlsPaddingExtension) ( int) {
	if .GetPaddingLen != nil {
		.PaddingLen, .WillPad = .GetPaddingLen()
	}
}

func ( *UtlsPaddingExtension) ( []byte) (int, error) {
	if !.WillPad {
		return 0, io.EOF
	}
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// https://tools.ietf.org/html/rfc7627
	[0] = byte(utlsExtensionPadding >> 8)
	[1] = byte(utlsExtensionPadding)
	[2] = byte(.PaddingLen >> 8)
	[3] = byte(.PaddingLen)
	return .Len(), io.EOF
}

func ( *UtlsPaddingExtension) ( []byte) error {
	var  struct {
		 uint `json:"len"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	if . == 0 {
		.GetPaddingLen = BoringPaddingStyle
	} else {
		.PaddingLen = int(.)
		.WillPad = true
	}

	return nil
}

func ( *UtlsPaddingExtension) ( []byte) (int, error) {
	.GetPaddingLen = BoringPaddingStyle
	return 0, nil
}

// https://github.com/google/boringssl/blob/7d7554b6b3c79e707e25521e61e066ce2b996e4c/ssl/t1_lib.c#L2803
func ( int) (int, bool) {
	if  > 0xff &&  < 0x200 {
		 := 0x200 - 
		if  >= 4+1 {
			 -= 4
		} else {
			 = 1
		}
		return , true
	}
	return 0, false
}

// AlwaysPadToLen could be used for parsed ClientHello, since some fingerprints
// might not use BoringSSL padding style and we want to pad to a the same length.
func ( int) func(int) (int, bool) {
	return func( int) (int, bool) {
		if  <  {
			 :=  - 
			if  >= 4+1 {
				 -= 4
			} else {
				 = 1
			}
			return , true
		}
		return 0, false
	}
}

// UtlsCompressCertExtension implements compress_certificate (27) and is only implemented client-side
// for server certificates. Alternate certificate message formats
// (https://datatracker.ietf.org/doc/html/rfc7250) are not supported.
//
// See https://datatracker.ietf.org/doc/html/rfc8879#section-3
type UtlsCompressCertExtension struct {
	Algorithms []CertCompressionAlgo
}

func ( *UtlsCompressCertExtension) ( *UConn) error {
	.certCompressionAlgs = .Algorithms
	return nil
}

func ( *UtlsCompressCertExtension) () int {
	return 4 + 1 + (2 * len(.Algorithms))
}

func ( *UtlsCompressCertExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	[0] = byte(utlsExtensionCompressCertificate >> 8)
	[1] = byte(utlsExtensionCompressCertificate & 0xff)

	 := 2 * len(.Algorithms)
	if  > 255 {
		return 0, errors.New("too many certificate compression methods")
	}

	// Extension data length.
	[2] = byte(( + 1) >> 8)
	[3] = byte(( + 1) & 0xff)

	// Methods length.
	[4] = byte()

	 := 5
	for ,  := range .Algorithms {
		[] = byte( >> 8)
		[+1] = byte()
		 += 2
	}
	return .Len(), io.EOF
}

func ( *UtlsCompressCertExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	 := []CertCompressionAlgo{}
	 := new(cryptobyte.String)
	if !.ReadUint8LengthPrefixed() {
		return 0, errors.New("unable to read cert compression algorithms extension data")
	}
	for !.Empty() {
		var  uint16
		if !.ReadUint16(&) {
			return 0, errors.New("unable to read cert compression algorithms extension data")
		}
		 = append(, CertCompressionAlgo())
	}

	.Algorithms = 
	return , nil
}

func ( *UtlsCompressCertExtension) ( []byte) error {
	var  struct {
		 []string `json:"algorithms"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	for ,  := range . {
		if ,  := dicttls.DictCertificateCompressionAlgorithmNameIndexed[];  {
			.Algorithms = append(.Algorithms, CertCompressionAlgo())
		} else {
			return fmt.Errorf("unknown certificate compression algorithm %s", )
		}
	}
	return nil
}

// KeyShareExtension implements key_share (51) and is for TLS 1.3 only.
type KeyShareExtension struct {
	KeyShares []KeyShare
}

func ( *KeyShareExtension) () int {
	return 4 + 2 + .keySharesLen()
}

func ( *KeyShareExtension) () int {
	 := 0
	for ,  := range .KeyShares {
		 += 4 + len(.Data)
	}
	return 
}

func ( *KeyShareExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}

	[0] = byte(extensionKeyShare >> 8)
	[1] = byte(extensionKeyShare)
	 := .keySharesLen()
	[2] = byte(( + 2) >> 8)
	[3] = byte( + 2)
	[4] = byte(() >> 8)
	[5] = byte()

	 := 6
	for ,  := range .KeyShares {
		[] = byte(.Group >> 8)
		[+1] = byte(.Group)
		[+2] = byte(len(.Data) >> 8)
		[+3] = byte(len(.Data))
		copy([+4:], .Data)
		 += 4 + len(.Data)
	}

	return .Len(), io.EOF
}

func ( *KeyShareExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	// RFC 8446, Section 4.2.8
	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) {
		return 0, errors.New("unable to read key share extension data")
	}
	 := []KeyShare{}
	for !.Empty() {
		var  KeyShare
		var  uint16
		if !.ReadUint16(&) ||
			!readUint16LengthPrefixed(&, &.Data) ||
			len(.Data) == 0 {
			return 0, errors.New("unable to read key share extension data")
		}
		.Group = CurveID(unGREASEUint16())
		// if not GREASE, key share data will be discarded as it should
		// be generated per connection
		if .Group != GREASE_PLACEHOLDER {
			.Data = nil
		}
		 = append(, )
	}
	.KeyShares = 
	return , nil
}

func ( *KeyShareExtension) ( *UConn) error {
	.HandshakeState.Hello.KeyShares = .KeyShares
	return nil
}

func ( *KeyShareExtension) ( []byte) error {
	var  struct {
		 []struct {
			       string  `json:"group"`
			 []uint8 `json:"key_exchange"`
		} `json:"client_shares"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	for ,  := range . {
		if . == "GREASE" {
			.KeyShares = append(.KeyShares, KeyShare{
				Group: GREASE_PLACEHOLDER,
				Data:  .,
			})
			continue
		}

		if ,  := dicttls.DictSupportedGroupsNameIndexed[.];  {
			 := KeyShare{
				Group: CurveID(),
				Data:  .,
			}
			.KeyShares = append(.KeyShares, )
		} else {
			return fmt.Errorf("unknown group %s", .)
		}
	}
	return nil
}

// QUICTransportParametersExtension implements quic_transport_parameters (57).
//
// Currently, it works as a fake extension and does not support parsing, since
// the QUICConn provided by this package does not really understand these
// parameters.
type QUICTransportParametersExtension struct {
	TransportParameters TransportParameters

	marshalResult []byte // TransportParameters will be marshaled into this slice
}

func ( *QUICTransportParametersExtension) () int {
	if .marshalResult == nil {
		.marshalResult = .TransportParameters.Marshal()
	}
	return 4 + len(.marshalResult)
}

func ( *QUICTransportParametersExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}

	[0] = byte(extensionQUICTransportParameters >> 8)
	[1] = byte(extensionQUICTransportParameters)
	// e.Len() is called before so that e.marshalResult is set
	[2] = byte((len(.marshalResult)) >> 8)
	[3] = byte(len(.marshalResult))
	copy([4:], .marshalResult)

	return .Len(), io.EOF
}

func ( *QUICTransportParametersExtension) (*UConn) error {
	// no need to set *UConn.quic.transportParams, since it is unused
	return nil
}

// PSKKeyExchangeModesExtension implements psk_key_exchange_modes (45).
type PSKKeyExchangeModesExtension struct {
	Modes []uint8
}

func ( *PSKKeyExchangeModesExtension) () int {
	return 4 + 1 + len(.Modes)
}

func ( *PSKKeyExchangeModesExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}

	if len(.Modes) > 255 {
		return 0, errors.New("too many PSK Key Exchange modes")
	}

	[0] = byte(extensionPSKModes >> 8)
	[1] = byte(extensionPSKModes)

	 := len(.Modes)
	[2] = byte(( + 1) >> 8)
	[3] = byte( + 1)
	[4] = byte()

	if len(.Modes) > 0 {
		copy([5:], .Modes)
	}

	return .Len(), io.EOF
}

func ( *PSKKeyExchangeModesExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	// RFC 8446, Section 4.2.9
	// TODO: PSK Modes have their own form of GREASE-ing which is not currently implemented
	// the current functionality will NOT re-GREASE/re-randomize these values when using a fingerprinted spec
	// https://github.com/refraction-networking/utls/pull/58#discussion_r522354105
	// https://tools.ietf.org/html/draft-ietf-tls-grease-01#section-2
	 := []uint8{}
	if !readUint8LengthPrefixed(&, &) {
		return 0, errors.New("unable to read PSK extension data")
	}
	.Modes = 
	return , nil
}

func ( *PSKKeyExchangeModesExtension) ( *UConn) error {
	.HandshakeState.Hello.PskModes = .Modes
	return nil
}

func ( *PSKKeyExchangeModesExtension) ( []byte) error {
	var  struct {
		 []string `json:"ke_modes"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	for ,  := range . {
		if ,  := dicttls.DictPSKKeyExchangeModeNameIndexed[];  {
			.Modes = append(.Modes, )
		} else {
			return fmt.Errorf("unknown PSK Key Exchange Mode %s", )
		}
	}
	return nil
}

// SupportedVersionsExtension implements supported_versions (43).
type SupportedVersionsExtension struct {
	Versions []uint16
}

func ( *SupportedVersionsExtension) ( *UConn) error {
	.HandshakeState.Hello.SupportedVersions = .Versions
	return nil
}

func ( *SupportedVersionsExtension) () int {
	return 4 + 1 + (2 * len(.Versions))
}

func ( *SupportedVersionsExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	 := 2 * len(.Versions)
	if  > 255 {
		return 0, errors.New("too many supported versions")
	}

	[0] = byte(extensionSupportedVersions >> 8)
	[1] = byte(extensionSupportedVersions)
	[2] = byte(( + 1) >> 8)
	[3] = byte( + 1)
	[4] = byte()

	 := 5
	for ,  := range .Versions {
		[] = byte( >> 8)
		[+1] = byte()
		 += 2
	}
	return .Len(), io.EOF
}

func ( *SupportedVersionsExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	// RFC 8446, Section 4.2.1
	var  cryptobyte.String
	if !.ReadUint8LengthPrefixed(&) || .Empty() {
		return 0, errors.New("unable to read supported versions extension data")
	}
	 := []uint16{}
	for !.Empty() {
		var  uint16
		if !.ReadUint16(&) {
			return 0, errors.New("unable to read supported versions extension data")
		}
		 = append(, unGREASEUint16())
	}
	.Versions = 
	return , nil
}

func ( *SupportedVersionsExtension) ( []byte) error {
	var  struct {
		 []string `json:"versions"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	for ,  := range . {
		switch  {
		case "GREASE":
			.Versions = append(.Versions, GREASE_PLACEHOLDER)
		case "TLS 1.3":
			.Versions = append(.Versions, VersionTLS13)
		case "TLS 1.2":
			.Versions = append(.Versions, VersionTLS12)
		case "TLS 1.1":
			.Versions = append(.Versions, VersionTLS11)
		case "TLS 1.0":
			.Versions = append(.Versions, VersionTLS10)
		case "SSL 3.0": // deprecated
			// 	e.Versions = append(e.Versions, VersionSSL30)
			return fmt.Errorf("SSL 3.0 is deprecated")
		default:
			return fmt.Errorf("unknown version %s", )
		}
	}
	return nil
}

// CookieExtension implements cookie (44).
// MUST NOT be part of initial ClientHello
type CookieExtension struct {
	Cookie []byte
}

func ( *CookieExtension) ( *UConn) error {
	return nil
}

func ( *CookieExtension) () int {
	// The total length of the Cookie extension is:
	// 2 bytes for ExtensionType (extensionCookie)
	// 2 bytes for OuterExtensionDataLength
	// 2 bytes for InnerCookieLength (len(e.Cookie))
	// N bytes for the Cookie data itself (e.Cookie)
	// So, total = 6 + len(e.Cookie)
	return 6 + len(.Cookie)
}

func ( *CookieExtension) ( []byte) (int, error) {
	 := len(.Cookie)

	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}

	// Extension type
	[0] = byte(extensionCookie >> 8)
	[1] = byte(extensionCookie)

	// Copied from BoringSSL https://boringssl.googlesource.com/boringssl.git/%2B/chromium-stable/ssl/extensions.cc#2465
	// Total extension_data length
	 := 2 +  // 2 bytes for cookie length + cookie
	[2] = byte( >> 8)
	[3] = byte()

	// Cookie length
	[4] = byte( >> 8)
	[5] = byte()

	// Cookie value
	copy([6:], .Cookie)

	return .Len(), io.EOF
}

func ( *CookieExtension) ( []byte) error {
	var  struct {
		 []uint8 `json:"cookie"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}
	.Cookie = []byte(.)
	return nil
}

// NPNExtension implements next_protocol_negotiation (Not IANA assigned)
type NPNExtension struct {
	NextProtos []string
}

func ( *NPNExtension) ( *UConn) error {
	.config.NextProtos = .NextProtos
	.HandshakeState.Hello.NextProtoNeg = true
	return nil
}

func ( *NPNExtension) () int {
	return 4
}

func ( *NPNExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	[0] = byte(extensionNextProtoNeg >> 8)
	[1] = byte(extensionNextProtoNeg & 0xff)
	// The length is always 0
	return .Len(), io.EOF
}

// Write is a no-op for NPNExtension. NextProtos are not included in the
// ClientHello.
func ( *NPNExtension) ( []byte) (int, error) {
	return 0, nil
}

// draft-agl-tls-nextprotoneg-04:
// The "extension_data" field of a "next_protocol_negotiation" extension
// in a "ClientHello" MUST be empty.
func ( *NPNExtension) ( []byte) error {
	return nil
}

// RenegotiationInfoExtension implements renegotiation_info (65281)
type RenegotiationInfoExtension struct {
	// Renegotiation field limits how many times client will perform renegotiation: no limit, once, or never.
	// The extension still will be sent, even if Renegotiation is set to RenegotiateNever.
	Renegotiation RenegotiationSupport // [UTLS] added for internal use only

	// RenegotiatedConnection is not yet properly handled, now we
	// are just copying it to the client hello.
	//
	// If this is the initial handshake for a connection, then the
	// "renegotiated_connection" field is of zero length in both the
	// ClientHello and the ServerHello.
	RenegotiatedConnection []byte
}

func ( *RenegotiationInfoExtension) () int {
	return 5 + len(.RenegotiatedConnection)
}

func ( *RenegotiationInfoExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}

	 := len(.RenegotiatedConnection)
	 := 1 + 

	[0] = byte(extensionRenegotiationInfo >> 8)
	[1] = byte(extensionRenegotiationInfo & 0xff)
	[2] = byte( >> 8)
	[3] = byte()
	[4] = byte()
	copy([5:], .RenegotiatedConnection)

	return .Len(), io.EOF
}

func ( *RenegotiationInfoExtension) ( []byte) error {
	.Renegotiation = RenegotiateOnceAsClient
	return nil
}

func ( *RenegotiationInfoExtension) ( []byte) (int, error) {
	.Renegotiation = RenegotiateOnceAsClient // none empty or other modes are unsupported
	// extData := cryptobyte.String(b)
	// var renegotiatedConnection cryptobyte.String
	// if !extData.ReadUint8LengthPrefixed(&renegotiatedConnection) || !extData.Empty() {
	// 	return 0, errors.New("unable to read renegotiation info extension data")
	// }
	// e.RenegotiatedConnection = make([]byte, len(renegotiatedConnection))
	// copy(e.RenegotiatedConnection, renegotiatedConnection)

	// we don't really want to parse it at all.

	return len(), nil
}

func ( *RenegotiationInfoExtension) ( *UConn) error {
	.config.Renegotiation = .Renegotiation
	switch .Renegotiation {
	case RenegotiateOnceAsClient:
		fallthrough
	case RenegotiateFreelyAsClient:
		.HandshakeState.Hello.SecureRenegotiationSupported = true
		// TODO: don't do backward propagation here
		if .handshakes > 0 {
			.RenegotiatedConnection = .clientFinished[:]
		}
	case RenegotiateNever:
	default:
	}
	return nil
}

/*
FAKE EXTENSIONS
*/

type FakeChannelIDExtension struct {
	// The extension ID changed from 30031 to 30032. Set to true to use the old extension ID.
	OldExtensionID bool
}

func ( *FakeChannelIDExtension) ( *UConn) error {
	return nil
}

func ( *FakeChannelIDExtension) () int {
	return 4
}

func ( *FakeChannelIDExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	 := fakeExtensionChannelID
	if .OldExtensionID {
		 = fakeOldExtensionChannelID
	}
	// https://tools.ietf.org/html/draft-balfanz-tls-channelid-00
	[0] = byte( >> 8)
	[1] = byte( & 0xff)
	// The length is 0
	return .Len(), io.EOF
}

func ( *FakeChannelIDExtension) ( []byte) (int, error) {
	return 0, nil
}

func ( *FakeChannelIDExtension) ( []byte) error {
	return nil
}

// FakeRecordSizeLimitExtension implements record_size_limit (28)
// but with no support.
type FakeRecordSizeLimitExtension struct {
	Limit uint16
}

func ( *FakeRecordSizeLimitExtension) ( *UConn) error {
	return nil
}

func ( *FakeRecordSizeLimitExtension) () int {
	return 6
}

func ( *FakeRecordSizeLimitExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// https://tools.ietf.org/html/draft-balfanz-tls-channelid-00
	[0] = byte(fakeRecordSizeLimit >> 8)
	[1] = byte(fakeRecordSizeLimit & 0xff)

	[2] = byte(0)
	[3] = byte(2)

	[4] = byte(.Limit >> 8)
	[5] = byte(.Limit & 0xff)
	return .Len(), io.EOF
}

func ( *FakeRecordSizeLimitExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	if !.ReadUint16(&.Limit) {
		return 0, errors.New("unable to read record size limit extension data")
	}
	return , nil
}

func ( *FakeRecordSizeLimitExtension) ( []byte) error {
	var  struct {
		 uint16 `json:"record_size_limit"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	.Limit = .
	return nil
}

type DelegatedCredentialsExtension = FakeDelegatedCredentialsExtension

// https://tools.ietf.org/html/rfc8472#section-2
type FakeTokenBindingExtension struct {
	MajorVersion, MinorVersion uint8
	KeyParameters              []uint8
}

func ( *FakeTokenBindingExtension) ( *UConn) error {
	return nil
}

func ( *FakeTokenBindingExtension) () int {
	// extension ID + data length + versions + key parameters length + key parameters
	return 2 + 2 + 2 + 1 + len(.KeyParameters)
}

func ( *FakeTokenBindingExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	 := .Len() - 4
	[0] = byte(fakeExtensionTokenBinding >> 8)
	[1] = byte(fakeExtensionTokenBinding & 0xff)
	[2] = byte( >> 8)
	[3] = byte( & 0xff)
	[4] = .MajorVersion
	[5] = .MinorVersion
	[6] = byte(len(.KeyParameters))
	if len(.KeyParameters) > 0 {
		copy([7:], .KeyParameters)
	}
	return .Len(), io.EOF
}

func ( *FakeTokenBindingExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	var  cryptobyte.String
	if !.ReadUint8(&.MajorVersion) ||
		!.ReadUint8(&.MinorVersion) ||
		!.ReadUint8LengthPrefixed(&) {
		return 0, errors.New("unable to read token binding extension data")
	}
	.KeyParameters = 
	return , nil
}

func ( *FakeTokenBindingExtension) ( []byte) error {
	var  struct {
		 struct {
			 uint8 `json:"major"`
			 uint8 `json:"minor"`
		} `json:"token_binding_version"`
		 []string `json:"key_parameters_list"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	.MajorVersion = ..
	.MinorVersion = ..
	for ,  := range . {
		switch  {
		case "rsa2048_pkcs1.5":
			.KeyParameters = append(.KeyParameters, 0)
		case "rsa2048_pss":
			.KeyParameters = append(.KeyParameters, 1)
		case "ecdsap256":
			.KeyParameters = append(.KeyParameters, 2)
		default:
			return fmt.Errorf("unknown token binding key parameter: %s", )
		}
	}
	return nil
}

// https://datatracker.ietf.org/doc/html/draft-ietf-tls-subcerts-15#section-4.1.1

type FakeDelegatedCredentialsExtension struct {
	SupportedSignatureAlgorithms []SignatureScheme
}

func ( *FakeDelegatedCredentialsExtension) ( *UConn) error {
	return nil
}

func ( *FakeDelegatedCredentialsExtension) () int {
	return 6 + 2*len(.SupportedSignatureAlgorithms)
}

func ( *FakeDelegatedCredentialsExtension) ( []byte) (int, error) {
	if len() < .Len() {
		return 0, io.ErrShortBuffer
	}
	// https://datatracker.ietf.org/doc/html/draft-ietf-tls-subcerts-15#section-4.1.1
	[0] = byte(fakeExtensionDelegatedCredentials >> 8)
	[1] = byte(fakeExtensionDelegatedCredentials)
	[2] = byte((2 + 2*len(.SupportedSignatureAlgorithms)) >> 8)
	[3] = byte((2 + 2*len(.SupportedSignatureAlgorithms)))
	[4] = byte((2 * len(.SupportedSignatureAlgorithms)) >> 8)
	[5] = byte((2 * len(.SupportedSignatureAlgorithms)))
	for ,  := range .SupportedSignatureAlgorithms {
		[6+2*] = byte( >> 8)
		[7+2*] = byte()
	}
	return .Len(), io.EOF
}

func ( *FakeDelegatedCredentialsExtension) ( []byte) (int, error) {
	 := len()
	 := cryptobyte.String()
	//https://datatracker.ietf.org/doc/html/draft-ietf-tls-subcerts-15#section-4.1.1
	var  cryptobyte.String
	if !.ReadUint16LengthPrefixed(&) || .Empty() {
		return 0, errors.New("unable to read signature algorithms extension data")
	}
	 := []SignatureScheme{}
	for !.Empty() {
		var  uint16
		if !.ReadUint16(&) {
			return 0, errors.New("unable to read signature algorithms extension data")
		}
		 = append(
			, SignatureScheme())
	}
	.SupportedSignatureAlgorithms = 
	return , nil
}

// Implementation copied from SignatureAlgorithmsExtension.UnmarshalJSON
func ( *FakeDelegatedCredentialsExtension) ( []byte) error {
	var  struct {
		 []string `json:"supported_signature_algorithms"`
	}
	if  := json.Unmarshal(, &);  != nil {
		return 
	}

	for ,  := range . {
		if  == "GREASE" {
			.SupportedSignatureAlgorithms = append(.SupportedSignatureAlgorithms, GREASE_PLACEHOLDER)
			continue
		}

		if ,  := dicttls.DictSignatureSchemeNameIndexed[];  {
			.SupportedSignatureAlgorithms = append(.SupportedSignatureAlgorithms, SignatureScheme())
		} else {
			return fmt.Errorf("unknown delegated credentials signature scheme: %s", )
		}
	}
	return nil
}