// SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
// SPDX-License-Identifier: MIT

// Package extension implements the extension values in the ClientHello/ServerHello
package extension import // TypeValue is the 2 byte value for a TLS Extension as registered in the IANA // // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml type TypeValue uint16 // TypeValue constants const ( ServerNameTypeValue TypeValue = 0 SupportedEllipticCurvesTypeValue TypeValue = 10 SupportedPointFormatsTypeValue TypeValue = 11 SupportedSignatureAlgorithmsTypeValue TypeValue = 13 UseSRTPTypeValue TypeValue = 14 ALPNTypeValue TypeValue = 16 UseExtendedMasterSecretTypeValue TypeValue = 23 RenegotiationInfoTypeValue TypeValue = 65281 ) // Extension represents a single TLS extension type Extension interface { Marshal() ([]byte, error) Unmarshal(data []byte) error TypeValue() TypeValue } // Unmarshal many extensions at once func ( []byte) ([]Extension, error) { switch { case len() == 0: return []Extension{}, nil case len() < 2: return nil, errBufferTooSmall } := binary.BigEndian.Uint16() if len()-2 != int() { return nil, errLengthMismatch } := []Extension{} := func( []byte, Extension) error { := .Unmarshal() if != nil { return } = append(, ) return nil } for := 2; < len(); { if len() < ( + 2) { return nil, errBufferTooSmall } var error switch TypeValue(binary.BigEndian.Uint16([:])) { case ServerNameTypeValue: = ([:], &ServerName{}) case SupportedEllipticCurvesTypeValue: = ([:], &SupportedEllipticCurves{}) case UseSRTPTypeValue: = ([:], &UseSRTP{}) case ALPNTypeValue: = ([:], &ALPN{}) case UseExtendedMasterSecretTypeValue: = ([:], &UseExtendedMasterSecret{}) case RenegotiationInfoTypeValue: = ([:], &RenegotiationInfo{}) default: } if != nil { return nil, } if len() < ( + 4) { return nil, errBufferTooSmall } := binary.BigEndian.Uint16([+2:]) += (4 + int()) } return , nil } // Marshal many extensions at once func ( []Extension) ([]byte, error) { := []byte{} for , := range { , := .Marshal() if != nil { return nil, } = append(, ...) } := []byte{0x00, 0x00} binary.BigEndian.PutUint16(, uint16(len())) return append(, ...), nil }