mirror of
				https://github.com/bjdgyc/anylink.git
				synced 2025-11-04 11:06:22 +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:])
 | 
						|
}
 |