From cabe380244814a289e87be8e35daddad30c29448 Mon Sep 17 00:00:00 2001 From: Mikkel Krautz Date: Sat, 8 Dec 2012 22:10:21 +0100 Subject: [PATCH] grumble: add support for crypto mode negotiation. --- client.go | 32 ++++++++++++++++++++++++++++++-- pkg/cryptstate/cryptstate.go | 7 ++++++- pkg/mumbleproto/Mumble.pb.go | 11 ++++++----- pkg/mumbleproto/Mumble.proto | 1 + 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/client.go b/client.go index 0956e33..a23af29 100644 --- a/client.go +++ b/client.go @@ -71,6 +71,7 @@ type Client struct { ClientName string OSName string OSVersion string + CryptoMode string // Personal Username string @@ -483,8 +484,9 @@ func (client *Client) tlsRecvLoop() { // what version of the protocol it should speak. if client.state == StateClientConnected { version := &mumbleproto.Version{ - Version: proto.Uint32(0x10203), - Release: proto.String("Grumble"), + Version: proto.Uint32(0x10205), + Release: proto.String("Grumble"), + CryptoModes: cryptstate.SupportedModes(), } if client.server.cfg.BoolValue("SendOSInfo") { version.Os = proto.String(runtime.GOOS) @@ -529,6 +531,32 @@ func (client *Client) tlsRecvLoop() { client.OSVersion = *version.OsVersion } + // Extract the client's supported crypto mode. + // If the client does not pick a crypto mode + // itself, use an invalid mode (the empty string) + // as its requested mode. This is effectively + // a flag asking for the default crypto mode. + requestedMode := "" + if len(version.CryptoModes) > 0 { + requestedMode = version.CryptoModes[0] + } + + // Check if the requested crypto mode is supported + // by us. If not, fall back to the default crypto + // mode. + supportedModes := cryptstate.SupportedModes() + ok := false + for _, mode := range supportedModes { + if requestedMode == mode { + ok = true + break + } + } + if !ok { + requestedMode = "OCB2-AES128" + } + + client.CryptoMode = requestedMode client.state = StateClientSentVersion } } diff --git a/pkg/cryptstate/cryptstate.go b/pkg/cryptstate/cryptstate.go index 167ad0d..4d12f04 100644 --- a/pkg/cryptstate/cryptstate.go +++ b/pkg/cryptstate/cryptstate.go @@ -36,6 +36,11 @@ type CryptState struct { cipher cipher.Block } +// SupportedModes returns the list of supported CryptoModes. +func SupportedModes() []string { + return []string{"OCB2-AES128"} +} + func (cs *CryptState) GenerateKey() error { _, err := io.ReadFull(rand.Reader, cs.RawKey[0:]) if err != nil { @@ -239,4 +244,4 @@ func (cs *CryptState) Encrypt(dst, src []byte) { dst[3] = tag[2] return -} \ No newline at end of file +} diff --git a/pkg/mumbleproto/Mumble.pb.go b/pkg/mumbleproto/Mumble.pb.go index 17d5d7a..82ea32f 100644 --- a/pkg/mumbleproto/Mumble.pb.go +++ b/pkg/mumbleproto/Mumble.pb.go @@ -206,11 +206,12 @@ func (x *ContextActionModify_Operation) UnmarshalJSON(data []byte) error { } type Version struct { - Version *uint32 `protobuf:"varint,1,opt,name=version" json:"version,omitempty"` - Release *string `protobuf:"bytes,2,opt,name=release" json:"release,omitempty"` - Os *string `protobuf:"bytes,3,opt,name=os" json:"os,omitempty"` - OsVersion *string `protobuf:"bytes,4,opt,name=os_version" json:"os_version,omitempty"` - XXX_unrecognized []byte `json:"-"` + Version *uint32 `protobuf:"varint,1,opt,name=version" json:"version,omitempty"` + Release *string `protobuf:"bytes,2,opt,name=release" json:"release,omitempty"` + Os *string `protobuf:"bytes,3,opt,name=os" json:"os,omitempty"` + OsVersion *string `protobuf:"bytes,4,opt,name=os_version" json:"os_version,omitempty"` + CryptoModes []string `protobuf:"bytes,5,rep,name=crypto_modes" json:"crypto_modes,omitempty"` + XXX_unrecognized []byte `json:"-"` } func (this *Version) Reset() { *this = Version{} } diff --git a/pkg/mumbleproto/Mumble.proto b/pkg/mumbleproto/Mumble.proto index fe5638f..8d477e2 100644 --- a/pkg/mumbleproto/Mumble.proto +++ b/pkg/mumbleproto/Mumble.proto @@ -7,6 +7,7 @@ message Version { optional string release = 2; optional string os = 3; optional string os_version = 4; + repeated string crypto_modes = 5; } message UDPTunnel {