mirror of
				https://github.com/bjdgyc/anylink.git
				synced 2025-10-31 16:43:28 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			146 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Package handshake provides the DTLS wire protocol for handshakes
 | |
| package handshake
 | |
| 
 | |
| import (
 | |
| 	"github.com/pion/dtls/v2/internal/util"
 | |
| 	"github.com/pion/dtls/v2/pkg/protocol"
 | |
| )
 | |
| 
 | |
| // Type is the unique identifier for each handshake message
 | |
| // https://tools.ietf.org/html/rfc5246#section-7.4
 | |
| type Type uint8
 | |
| 
 | |
| // Types of DTLS Handshake messages we know about
 | |
| const (
 | |
| 	TypeHelloRequest       Type = 0
 | |
| 	TypeClientHello        Type = 1
 | |
| 	TypeServerHello        Type = 2
 | |
| 	TypeHelloVerifyRequest Type = 3
 | |
| 	TypeCertificate        Type = 11
 | |
| 	TypeServerKeyExchange  Type = 12
 | |
| 	TypeCertificateRequest Type = 13
 | |
| 	TypeServerHelloDone    Type = 14
 | |
| 	TypeCertificateVerify  Type = 15
 | |
| 	TypeClientKeyExchange  Type = 16
 | |
| 	TypeFinished           Type = 20
 | |
| )
 | |
| 
 | |
| // String returns the string representation of this type
 | |
| func (t Type) String() string {
 | |
| 	switch t {
 | |
| 	case TypeHelloRequest:
 | |
| 		return "HelloRequest"
 | |
| 	case TypeClientHello:
 | |
| 		return "ClientHello"
 | |
| 	case TypeServerHello:
 | |
| 		return "ServerHello"
 | |
| 	case TypeHelloVerifyRequest:
 | |
| 		return "HelloVerifyRequest"
 | |
| 	case TypeCertificate:
 | |
| 		return "TypeCertificate"
 | |
| 	case TypeServerKeyExchange:
 | |
| 		return "ServerKeyExchange"
 | |
| 	case TypeCertificateRequest:
 | |
| 		return "CertificateRequest"
 | |
| 	case TypeServerHelloDone:
 | |
| 		return "ServerHelloDone"
 | |
| 	case TypeCertificateVerify:
 | |
| 		return "CertificateVerify"
 | |
| 	case TypeClientKeyExchange:
 | |
| 		return "ClientKeyExchange"
 | |
| 	case TypeFinished:
 | |
| 		return "Finished"
 | |
| 	}
 | |
| 	return ""
 | |
| }
 | |
| 
 | |
| // Message is the body of a Handshake datagram
 | |
| type Message interface {
 | |
| 	Marshal() ([]byte, error)
 | |
| 	Unmarshal(data []byte) error
 | |
| 
 | |
| 	Type() Type
 | |
| }
 | |
| 
 | |
| // Handshake protocol is responsible for selecting a cipher spec and
 | |
| // generating a master secret, which together comprise the primary
 | |
| // cryptographic parameters associated with a secure session.  The
 | |
| // handshake protocol can also optionally authenticate parties who have
 | |
| // certificates signed by a trusted certificate authority.
 | |
| // https://tools.ietf.org/html/rfc5246#section-7.3
 | |
| type Handshake struct {
 | |
| 	Header  Header
 | |
| 	Message Message
 | |
| }
 | |
| 
 | |
| // ContentType returns what kind of content this message is carying
 | |
| func (h Handshake) ContentType() protocol.ContentType {
 | |
| 	return protocol.ContentTypeHandshake
 | |
| }
 | |
| 
 | |
| // Marshal encodes a handshake into a binary message
 | |
| func (h *Handshake) Marshal() ([]byte, error) {
 | |
| 	if h.Message == nil {
 | |
| 		return nil, errHandshakeMessageUnset
 | |
| 	} else if h.Header.FragmentOffset != 0 {
 | |
| 		return nil, errUnableToMarshalFragmented
 | |
| 	}
 | |
| 
 | |
| 	msg, err := h.Message.Marshal()
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	h.Header.Length = uint32(len(msg))
 | |
| 	h.Header.FragmentLength = h.Header.Length
 | |
| 	h.Header.Type = h.Message.Type()
 | |
| 	header, err := h.Header.Marshal()
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return append(header, msg...), nil
 | |
| }
 | |
| 
 | |
| // Unmarshal decodes a handshake from a binary message
 | |
| func (h *Handshake) Unmarshal(data []byte) error {
 | |
| 	if err := h.Header.Unmarshal(data); err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 
 | |
| 	reportedLen := util.BigEndianUint24(data[1:])
 | |
| 	if uint32(len(data)-HeaderLength) != reportedLen {
 | |
| 		return errLengthMismatch
 | |
| 	} else if reportedLen != h.Header.FragmentLength {
 | |
| 		return errLengthMismatch
 | |
| 	}
 | |
| 
 | |
| 	switch Type(data[0]) {
 | |
| 	case TypeHelloRequest:
 | |
| 		return errNotImplemented
 | |
| 	case TypeClientHello:
 | |
| 		h.Message = &MessageClientHello{}
 | |
| 	case TypeHelloVerifyRequest:
 | |
| 		h.Message = &MessageHelloVerifyRequest{}
 | |
| 	case TypeServerHello:
 | |
| 		h.Message = &MessageServerHello{}
 | |
| 	case TypeCertificate:
 | |
| 		h.Message = &MessageCertificate{}
 | |
| 	case TypeServerKeyExchange:
 | |
| 		h.Message = &MessageServerKeyExchange{}
 | |
| 	case TypeCertificateRequest:
 | |
| 		h.Message = &MessageCertificateRequest{}
 | |
| 	case TypeServerHelloDone:
 | |
| 		h.Message = &MessageServerHelloDone{}
 | |
| 	case TypeClientKeyExchange:
 | |
| 		h.Message = &MessageClientKeyExchange{}
 | |
| 	case TypeFinished:
 | |
| 		h.Message = &MessageFinished{}
 | |
| 	case TypeCertificateVerify:
 | |
| 		h.Message = &MessageCertificateVerify{}
 | |
| 	default:
 | |
| 		return errNotImplemented
 | |
| 	}
 | |
| 	return h.Message.Unmarshal(data[HeaderLength:])
 | |
| }
 |