mirror of
https://github.com/bjdgyc/anylink.git
synced 2025-08-08 22:08:19 +08:00
添加 github.com/pion/dtls 代码
This commit is contained in:
100
dtls-2.0.9/pkg/protocol/handshake/message_certificate_request.go
Normal file
100
dtls-2.0.9/pkg/protocol/handshake/message_certificate_request.go
Normal file
@@ -0,0 +1,100 @@
|
||||
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"
|
||||
)
|
||||
|
||||
/*
|
||||
MessageCertificateRequest is so a non-anonymous server can optionally
|
||||
request a certificate from the client, if appropriate for the selected cipher
|
||||
suite. This message, if sent, will immediately follow the ServerKeyExchange
|
||||
message (if it is sent; otherwise, this message follows the
|
||||
server's Certificate message).
|
||||
|
||||
https://tools.ietf.org/html/rfc5246#section-7.4.4
|
||||
*/
|
||||
type MessageCertificateRequest struct {
|
||||
CertificateTypes []clientcertificate.Type
|
||||
SignatureHashAlgorithms []signaturehash.Algorithm
|
||||
}
|
||||
|
||||
const (
|
||||
messageCertificateRequestMinLength = 5
|
||||
)
|
||||
|
||||
// Type returns the Handshake Type
|
||||
func (m MessageCertificateRequest) Type() Type {
|
||||
return TypeCertificateRequest
|
||||
}
|
||||
|
||||
// Marshal encodes the Handshake
|
||||
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))
|
||||
}
|
||||
|
||||
out = append(out, []byte{0x00, 0x00}...) // Distinguished Names Length
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Unmarshal populates the message from encoded data
|
||||
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})
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user