github.com/pion/dtls/v2@v2.2.12/pkg/protocol/extension/supported_elliptic_curves.go (about) 1 // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly> 2 // SPDX-License-Identifier: MIT 3 4 package extension 5 6 import ( 7 "encoding/binary" 8 9 "github.com/pion/dtls/v2/pkg/crypto/elliptic" 10 ) 11 12 const ( 13 supportedGroupsHeaderSize = 6 14 ) 15 16 // SupportedEllipticCurves allows a Client/Server to communicate 17 // what curves they both support 18 // 19 // https://tools.ietf.org/html/rfc8422#section-5.1.1 20 type SupportedEllipticCurves struct { 21 EllipticCurves []elliptic.Curve 22 } 23 24 // TypeValue returns the extension TypeValue 25 func (s SupportedEllipticCurves) TypeValue() TypeValue { 26 return SupportedEllipticCurvesTypeValue 27 } 28 29 // Marshal encodes the extension 30 func (s *SupportedEllipticCurves) Marshal() ([]byte, error) { 31 out := make([]byte, supportedGroupsHeaderSize) 32 33 binary.BigEndian.PutUint16(out, uint16(s.TypeValue())) 34 binary.BigEndian.PutUint16(out[2:], uint16(2+(len(s.EllipticCurves)*2))) 35 binary.BigEndian.PutUint16(out[4:], uint16(len(s.EllipticCurves)*2)) 36 37 for _, v := range s.EllipticCurves { 38 out = append(out, []byte{0x00, 0x00}...) 39 binary.BigEndian.PutUint16(out[len(out)-2:], uint16(v)) 40 } 41 42 return out, nil 43 } 44 45 // Unmarshal populates the extension from encoded data 46 func (s *SupportedEllipticCurves) Unmarshal(data []byte) error { 47 if len(data) <= supportedGroupsHeaderSize { 48 return errBufferTooSmall 49 } else if TypeValue(binary.BigEndian.Uint16(data)) != s.TypeValue() { 50 return errInvalidExtensionType 51 } 52 53 groupCount := int(binary.BigEndian.Uint16(data[4:]) / 2) 54 if supportedGroupsHeaderSize+(groupCount*2) > len(data) { 55 return errLengthMismatch 56 } 57 58 for i := 0; i < groupCount; i++ { 59 supportedGroupID := elliptic.Curve(binary.BigEndian.Uint16(data[(supportedGroupsHeaderSize + (i * 2)):])) 60 if _, ok := elliptic.Curves()[supportedGroupID]; ok { 61 s.EllipticCurves = append(s.EllipticCurves, supportedGroupID) 62 } 63 } 64 return nil 65 }