diff options
Diffstat (limited to 'vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go')
-rw-r--r-- | vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go new file mode 100644 index 0000000..a08033f --- /dev/null +++ b/vendor/github.com/pion/dtls/v2/pkg/protocol/extension/server_name.go @@ -0,0 +1,78 @@ +package extension + +import ( + "strings" + + "golang.org/x/crypto/cryptobyte" +) + +const serverNameTypeDNSHostName = 0 + +// ServerName allows the client to inform the server the specific +// name it wishs to contact. Useful if multiple DNS names resolve +// to one IP +// +// https://tools.ietf.org/html/rfc6066#section-3 +type ServerName struct { + ServerName string +} + +// TypeValue returns the extension TypeValue +func (s ServerName) TypeValue() TypeValue { + return ServerNameTypeValue +} + +// Marshal encodes the extension +func (s *ServerName) Marshal() ([]byte, error) { + var b cryptobyte.Builder + b.AddUint16(uint16(s.TypeValue())) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddUint8(serverNameTypeDNSHostName) + b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) { + b.AddBytes([]byte(s.ServerName)) + }) + }) + }) + return b.Bytes() +} + +// Unmarshal populates the extension from encoded data +func (s *ServerName) Unmarshal(data []byte) error { + val := cryptobyte.String(data) + var extension uint16 + val.ReadUint16(&extension) + if TypeValue(extension) != s.TypeValue() { + return errInvalidExtensionType + } + + var extData cryptobyte.String + val.ReadUint16LengthPrefixed(&extData) + + var nameList cryptobyte.String + if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() { + return errInvalidSNIFormat + } + for !nameList.Empty() { + var nameType uint8 + var serverName cryptobyte.String + if !nameList.ReadUint8(&nameType) || + !nameList.ReadUint16LengthPrefixed(&serverName) || + serverName.Empty() { + return errInvalidSNIFormat + } + if nameType != serverNameTypeDNSHostName { + continue + } + if len(s.ServerName) != 0 { + // Multiple names of the same name_type are prohibited. + return errInvalidSNIFormat + } + s.ServerName = string(serverName) + // An SNI value may not include a trailing dot. + if strings.HasSuffix(s.ServerName, ".") { + return errInvalidSNIFormat + } + } + return nil +} |