From d3996501982f0c8e37bf59f422ad8fddd53ba253 Mon Sep 17 00:00:00 2001 From: "Brandon McGinty (chatgpt)" Date: Mon, 10 Aug 2026 04:28:38 -0400 Subject: [PATCH] Protect crypto initialization checks --- gumble/gumble/crypt.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/gumble/gumble/crypt.go b/gumble/gumble/crypt.go index 5b1d4b6..4abedc5 100644 --- a/gumble/gumble/crypt.go +++ b/gumble/gumble/crypt.go @@ -270,6 +270,12 @@ func (cs *cryptState) nonceForPacket(counter uint32) [12]byte { return n } +func (cs *cryptState) isInitialized() bool { + cs.mu.Lock() + defer cs.mu.Unlock() + return cs.initialized +} + func (cs *cryptState) encrypt(counter uint32, plaintext []byte) ([]byte, error) { cs.mu.Lock() defer cs.mu.Unlock() @@ -301,7 +307,7 @@ func (c *Client) handleCryptSetup(buffer []byte) error { defer c.volatile.Unlock() if packet.Key != nil && packet.ClientNonce != nil && packet.ServerNonce != nil { - wasInit := c.cryptOut.initialized + wasInit := c.cryptOut.isInitialized() c.cryptOut.setup(packet.Key, packet.ClientNonce) c.cryptIn.setup(packet.Key, packet.ServerNonce) @@ -316,14 +322,15 @@ func (c *Client) handleCryptSetup(buffer []byte) error { log.Info("received CryptSetup: key_len=%d client_nonce_len=%d server_nonce_len=%d", len(packet.Key), len(packet.ClientNonce), len(packet.ServerNonce)) } - } else if !c.cryptOut.initialized { + } else if !c.cryptOut.isInitialized() { // Only log incomplete once before crypto is set up log.Debug("received CryptSetup with incomplete fields, waiting for full key exchange") } + cryptoReady := c.cryptOut.isInitialized() c.udpMu.Lock() udpReady := c.udpCryptoOut != nil - startUDP := c.cryptOut.initialized && c.udpConn != nil && !c.udpStarted && udpReady + startUDP := cryptoReady && c.udpConn != nil && !c.udpStarted && udpReady if startUDP { // Keep TCP tunnelling enabled until an authenticated UDP packet proves // that the inbound path works. @@ -335,7 +342,7 @@ func (c *Client) handleCryptSetup(buffer []byte) error { log.Info("UDP crypto ready (1.5 native), starting UDP reader and pinger") go c.udpReadRoutine() go c.udpPingRoutine() - } else if c.cryptOut.initialized && noUDPConn { + } else if cryptoReady && noUDPConn { log.Warn("crypto ready but no UDP socket — audio will use TCP tunnel") }