github.com/pion/dtls/v2@v2.2.12/pkg/protocol/handshake/message_client_key_exchange.go (about) 1 // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly> 2 // SPDX-License-Identifier: MIT 3 4 package handshake 5 6 import ( 7 "encoding/binary" 8 9 "github.com/pion/dtls/v2/internal/ciphersuite/types" 10 ) 11 12 // MessageClientKeyExchange is a DTLS Handshake Message 13 // With this message, the premaster secret is set, either by direct 14 // transmission of the RSA-encrypted secret or by the transmission of 15 // Diffie-Hellman parameters that will allow each side to agree upon 16 // the same premaster secret. 17 // 18 // https://tools.ietf.org/html/rfc5246#section-7.4.7 19 type MessageClientKeyExchange struct { 20 IdentityHint []byte 21 PublicKey []byte 22 23 // for unmarshaling 24 KeyExchangeAlgorithm types.KeyExchangeAlgorithm 25 } 26 27 // Type returns the Handshake Type 28 func (m MessageClientKeyExchange) Type() Type { 29 return TypeClientKeyExchange 30 } 31 32 // Marshal encodes the Handshake 33 func (m *MessageClientKeyExchange) Marshal() (out []byte, err error) { 34 if m.IdentityHint == nil && m.PublicKey == nil { 35 return nil, errInvalidClientKeyExchange 36 } 37 38 if m.IdentityHint != nil { 39 out = append([]byte{0x00, 0x00}, m.IdentityHint...) 40 binary.BigEndian.PutUint16(out, uint16(len(out)-2)) 41 } 42 43 if m.PublicKey != nil { 44 out = append(out, byte(len(m.PublicKey))) 45 out = append(out, m.PublicKey...) 46 } 47 48 return out, nil 49 } 50 51 // Unmarshal populates the message from encoded data 52 func (m *MessageClientKeyExchange) Unmarshal(data []byte) error { 53 switch { 54 case len(data) < 2: 55 return errBufferTooSmall 56 case m.KeyExchangeAlgorithm == types.KeyExchangeAlgorithmNone: 57 return errCipherSuiteUnset 58 } 59 60 offset := 0 61 if m.KeyExchangeAlgorithm.Has(types.KeyExchangeAlgorithmPsk) { 62 pskLength := int(binary.BigEndian.Uint16(data)) 63 if pskLength > len(data)-2 { 64 return errBufferTooSmall 65 } 66 67 m.IdentityHint = append([]byte{}, data[2:pskLength+2]...) 68 offset += pskLength + 2 69 } 70 71 if m.KeyExchangeAlgorithm.Has(types.KeyExchangeAlgorithmEcdhe) { 72 publicKeyLength := int(data[offset]) 73 if publicKeyLength > len(data)-1-offset { 74 return errBufferTooSmall 75 } 76 77 m.PublicKey = append([]byte{}, data[offset+1:]...) 78 } 79 80 return nil 81 }