github.com/pion/dtls/v2@v2.2.12/pkg/protocol/handshake/message_certificate_verify.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/pkg/crypto/hash"
    10  	"github.com/pion/dtls/v2/pkg/crypto/signature"
    11  )
    12  
    13  // MessageCertificateVerify provide explicit verification of a
    14  // client certificate.
    15  //
    16  // https://tools.ietf.org/html/rfc5246#section-7.4.8
    17  type MessageCertificateVerify struct {
    18  	HashAlgorithm      hash.Algorithm
    19  	SignatureAlgorithm signature.Algorithm
    20  	Signature          []byte
    21  }
    22  
    23  const handshakeMessageCertificateVerifyMinLength = 4
    24  
    25  // Type returns the Handshake Type
    26  func (m MessageCertificateVerify) Type() Type {
    27  	return TypeCertificateVerify
    28  }
    29  
    30  // Marshal encodes the Handshake
    31  func (m *MessageCertificateVerify) Marshal() ([]byte, error) {
    32  	out := make([]byte, 1+1+2+len(m.Signature))
    33  
    34  	out[0] = byte(m.HashAlgorithm)
    35  	out[1] = byte(m.SignatureAlgorithm)
    36  	binary.BigEndian.PutUint16(out[2:], uint16(len(m.Signature)))
    37  	copy(out[4:], m.Signature)
    38  	return out, nil
    39  }
    40  
    41  // Unmarshal populates the message from encoded data
    42  func (m *MessageCertificateVerify) Unmarshal(data []byte) error {
    43  	if len(data) < handshakeMessageCertificateVerifyMinLength {
    44  		return errBufferTooSmall
    45  	}
    46  
    47  	m.HashAlgorithm = hash.Algorithm(data[0])
    48  	if _, ok := hash.Algorithms()[m.HashAlgorithm]; !ok {
    49  		return errInvalidHashAlgorithm
    50  	}
    51  
    52  	m.SignatureAlgorithm = signature.Algorithm(data[1])
    53  	if _, ok := signature.Algorithms()[m.SignatureAlgorithm]; !ok {
    54  		return errInvalidSignatureAlgorithm
    55  	}
    56  
    57  	signatureLength := int(binary.BigEndian.Uint16(data[2:]))
    58  	if (signatureLength + 4) != len(data) {
    59  		return errBufferTooSmall
    60  	}
    61  
    62  	m.Signature = append([]byte{}, data[4:]...)
    63  	return nil
    64  }