diff options
Diffstat (limited to 'vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go')
-rw-r--r-- | vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go new file mode 100644 index 0000000..4aa493e --- /dev/null +++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/handshake/handshake.go @@ -0,0 +1,145 @@ +// 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:]) +} |