Protect crypto initialization checks

This commit is contained in:
Brandon McGinty (chatgpt)
2026-08-10 04:28:38 -04:00
committed by Brandon McGinty
parent fa84373a81
commit d399650198
+11 -4
View File
@@ -270,6 +270,12 @@ func (cs *cryptState) nonceForPacket(counter uint32) [12]byte {
return n 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) { func (cs *cryptState) encrypt(counter uint32, plaintext []byte) ([]byte, error) {
cs.mu.Lock() cs.mu.Lock()
defer cs.mu.Unlock() defer cs.mu.Unlock()
@@ -301,7 +307,7 @@ func (c *Client) handleCryptSetup(buffer []byte) error {
defer c.volatile.Unlock() defer c.volatile.Unlock()
if packet.Key != nil && packet.ClientNonce != nil && packet.ServerNonce != nil { 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.cryptOut.setup(packet.Key, packet.ClientNonce)
c.cryptIn.setup(packet.Key, packet.ServerNonce) 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", log.Info("received CryptSetup: key_len=%d client_nonce_len=%d server_nonce_len=%d",
len(packet.Key), len(packet.ClientNonce), len(packet.ServerNonce)) 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 // Only log incomplete once before crypto is set up
log.Debug("received CryptSetup with incomplete fields, waiting for full key exchange") log.Debug("received CryptSetup with incomplete fields, waiting for full key exchange")
} }
cryptoReady := c.cryptOut.isInitialized()
c.udpMu.Lock() c.udpMu.Lock()
udpReady := c.udpCryptoOut != nil udpReady := c.udpCryptoOut != nil
startUDP := c.cryptOut.initialized && c.udpConn != nil && !c.udpStarted && udpReady startUDP := cryptoReady && c.udpConn != nil && !c.udpStarted && udpReady
if startUDP { if startUDP {
// Keep TCP tunnelling enabled until an authenticated UDP packet proves // Keep TCP tunnelling enabled until an authenticated UDP packet proves
// that the inbound path works. // 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") log.Info("UDP crypto ready (1.5 native), starting UDP reader and pinger")
go c.udpReadRoutine() go c.udpReadRoutine()
go c.udpPingRoutine() 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") log.Warn("crypto ready but no UDP socket — audio will use TCP tunnel")
} }