package handshake
import (
"encoding/binary"
"github.com/pion/dtls/v2/pkg/crypto/clientcertificate"
"github.com/pion/dtls/v2/pkg/crypto/hash"
"github.com/pion/dtls/v2/pkg/crypto/signature"
"github.com/pion/dtls/v2/pkg/crypto/signaturehash"
)
type MessageCertificateRequest struct {
CertificateTypes []clientcertificate .Type
SignatureHashAlgorithms []signaturehash .Algorithm
CertificateAuthoritiesNames [][]byte
}
const (
messageCertificateRequestMinLength = 5
)
func (m MessageCertificateRequest ) Type () Type {
return TypeCertificateRequest
}
func (m *MessageCertificateRequest ) Marshal () ([]byte , error ) {
out := []byte {byte (len (m .CertificateTypes ))}
for _ , v := range m .CertificateTypes {
out = append (out , byte (v ))
}
out = append (out , []byte {0x00 , 0x00 }...)
binary .BigEndian .PutUint16 (out [len (out )-2 :], uint16 (len (m .SignatureHashAlgorithms )*2 ))
for _ , v := range m .SignatureHashAlgorithms {
out = append (out , byte (v .Hash ))
out = append (out , byte (v .Signature ))
}
casLength := 0
for _ , ca := range m .CertificateAuthoritiesNames {
casLength += len (ca ) + 2
}
out = append (out , []byte {0x00 , 0x00 }...)
binary .BigEndian .PutUint16 (out [len (out )-2 :], uint16 (casLength ))
if casLength > 0 {
for _ , ca := range m .CertificateAuthoritiesNames {
out = append (out , []byte {0x00 , 0x00 }...)
binary .BigEndian .PutUint16 (out [len (out )-2 :], uint16 (len (ca )))
out = append (out , ca ...)
}
}
return out , nil
}
func (m *MessageCertificateRequest ) Unmarshal (data []byte ) error {
if len (data ) < messageCertificateRequestMinLength {
return errBufferTooSmall
}
offset := 0
certificateTypesLength := int (data [0 ])
offset ++
if (offset + certificateTypesLength ) > len (data ) {
return errBufferTooSmall
}
for i := 0 ; i < certificateTypesLength ; i ++ {
certType := clientcertificate .Type (data [offset +i ])
if _ , ok := clientcertificate .Types ()[certType ]; ok {
m .CertificateTypes = append (m .CertificateTypes , certType )
}
}
offset += certificateTypesLength
if len (data ) < offset +2 {
return errBufferTooSmall
}
signatureHashAlgorithmsLength := int (binary .BigEndian .Uint16 (data [offset :]))
offset += 2
if (offset + signatureHashAlgorithmsLength ) > len (data ) {
return errBufferTooSmall
}
for i := 0 ; i < signatureHashAlgorithmsLength ; i += 2 {
if len (data ) < (offset + i + 2 ) {
return errBufferTooSmall
}
h := hash .Algorithm (data [offset +i ])
s := signature .Algorithm (data [offset +i +1 ])
if _ , ok := hash .Algorithms ()[h ]; !ok {
continue
} else if _ , ok := signature .Algorithms ()[s ]; !ok {
continue
}
m .SignatureHashAlgorithms = append (m .SignatureHashAlgorithms , signaturehash .Algorithm {Signature : s , Hash : h })
}
offset += signatureHashAlgorithmsLength
if len (data ) < offset +2 {
return errBufferTooSmall
}
casLength := int (binary .BigEndian .Uint16 (data [offset :]))
offset += 2
if (offset + casLength ) > len (data ) {
return errBufferTooSmall
}
cas := make ([]byte , casLength )
copy (cas , data [offset :offset +casLength ])
m .CertificateAuthoritiesNames = nil
for len (cas ) > 0 {
if len (cas ) < 2 {
return errBufferTooSmall
}
caLen := binary .BigEndian .Uint16 (cas )
cas = cas [2 :]
if len (cas ) < int (caLen ) {
return errBufferTooSmall
}
m .CertificateAuthoritiesNames = append (m .CertificateAuthoritiesNames , cas [:caLen ])
cas = cas [caLen :]
}
return nil
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .