This commit is contained in:
callebtc
2025-07-23 01:02:27 +02:00
parent 4a512f51bf
commit d05476757f
2 changed files with 34 additions and 12 deletions
@@ -5,6 +5,7 @@ import com.bitchat.android.crypto.EncryptionService
import com.bitchat.android.protocol.BitchatPacket import com.bitchat.android.protocol.BitchatPacket
import com.bitchat.android.protocol.MessageType import com.bitchat.android.protocol.MessageType
import com.bitchat.android.model.RoutedPacket import com.bitchat.android.model.RoutedPacket
import com.bitchat.android.util.toHexString
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.util.* import java.util.*
import kotlin.collections.mutableSetOf import kotlin.collections.mutableSetOf
@@ -93,7 +94,11 @@ class SecurityManager(private val encryptionService: EncryptionService, private
val packet = routed.packet val packet = routed.packet
val peerID = routed.peerID ?: "unknown" val peerID = routed.peerID ?: "unknown"
Log.d(TAG, "Processing Noise handshake step $step from $peerID (${packet.payload.size} bytes)") // Skip handshakes not addressed to us
if (packet.recipientID?.toHexString() != myPeerID) {
Log.d(TAG, "Skipping handshake not addressed to us: $peerID")
return false
}
// Skip our own handshake messages // Skip our own handshake messages
if (peerID == myPeerID) return false if (peerID == myPeerID) return false
@@ -115,7 +120,7 @@ class SecurityManager(private val encryptionService: EncryptionService, private
Log.d(TAG, "Already processed handshake: $exchangeKey") Log.d(TAG, "Already processed handshake: $exchangeKey")
return false return false
} }
Log.d(TAG, "Processing Noise handshake step $step from $peerID (${packet.payload.size} bytes)")
processedKeyExchanges.add(exchangeKey) processedKeyExchanges.add(exchangeKey)
try { try {
@@ -304,20 +304,32 @@ class NoiseSession(
} }
/** /**
* Complete handshake and derive real transport keys * Complete handshake and derive transport keys
*/ */
@Synchronized
private fun completeHandshake() { private fun completeHandshake() {
if (currentPattern < NOISE_XX_PATTERN_LENGTH) { if (currentPattern < NOISE_XX_PATTERN_LENGTH) {
return return
} }
Log.d(TAG, "Completing real XX handshake with $peerID") Log.d(TAG, "Completing XX handshake with $peerID")
try { try {
// Split handshake state into transport ciphers // Split handshake state into transport ciphers
val cipherPair = handshakeState?.split() val cipherPair = handshakeState?.split()
// CRITICAL FIX: Assign ciphers based on role to match iOS implementation
// Initiator uses getSender() for sending, getReceiver() for receiving
// Responder uses getReceiver() for sending, getSender() for receiving
if (isInitiator) {
sendCipher = cipherPair?.getSender() sendCipher = cipherPair?.getSender()
receiveCipher = cipherPair?.getReceiver() receiveCipher = cipherPair?.getReceiver()
Log.d(TAG, "INITIATOR: sendCipher = getSender(), receiveCipher = getReceiver()")
} else {
sendCipher = cipherPair?.getReceiver()
receiveCipher = cipherPair?.getSender()
Log.d(TAG, "RESPONDER: sendCipher = getReceiver(), receiveCipher = getSender()")
}
// Extract remote static key if available // Extract remote static key if available
if (handshakeState?.hasRemotePublicKey() == true) { if (handshakeState?.hasRemotePublicKey() == true) {
@@ -325,6 +337,7 @@ class NoiseSession(
if (remoteDH != null) { if (remoteDH != null) {
remoteStaticPublicKey = ByteArray(32) remoteStaticPublicKey = ByteArray(32)
remoteDH.getPublicKey(remoteStaticPublicKey!!, 0) remoteDH.getPublicKey(remoteStaticPublicKey!!, 0)
Log.d(TAG, "Remote static public key: ${remoteStaticPublicKey!!.joinToString("") { "%02x".format(it) }}")
} }
} }
@@ -349,7 +362,7 @@ class NoiseSession(
} }
} }
// MARK: - Real Transport Encryption // MARK: - Transport Encryption
/** /**
* Encrypt data in transport mode using real ChaCha20-Poly1305 * Encrypt data in transport mode using real ChaCha20-Poly1305
@@ -372,13 +385,17 @@ class NoiseSession(
} }
try { try {
val ciphertext = ByteArray(data.size + 16) // Add space for MAC tag // assert that sendCipher!!.macLengt is 16:
val ciphertextLength = sendCipher!!.encryptWithAd(null, data, 0, ciphertext, 0, data.size) if (sendCipher!!.macLength != 16) {
throw IllegalStateException("Send cipher MAC length is not 16")
}
val ciphertext = ByteArray(data.size + sendCipher!!.macLength) // Add space for MAC tag
val ciphertextLength = sendCipher!!.encryptWithAd(null, data, 0, ciphertext, 0, data.size)
messagesSent++ messagesSent++
val result = ciphertext.copyOf(ciphertextLength) val result = ciphertext.copyOf(ciphertextLength)
Log.d(TAG, "Real encrypted ${data.size} bytes to ${result.size} bytes for $peerID (msg #$messagesSent)") Log.d(TAG, "✅ ANDROID ENCRYPT: ${data.size} ${result.size} bytes for $peerID (msg #$messagesSent, role: ${if (isInitiator) "INITIATOR" else "RESPONDER"})")
return result return result
} catch (e: Exception) { } catch (e: Exception) {
@@ -420,7 +437,7 @@ class NoiseSession(
messagesReceived++ messagesReceived++
val result = plaintext.copyOf(plaintextLength) val result = plaintext.copyOf(plaintextLength)
Log.d(TAG, "Decrypted ${encryptedData.size} bytes to ${result.size} bytes from $peerID (msg #$messagesReceived)") Log.d(TAG, "✅ ANDROID DECRYPT: ${encryptedData.size} ${result.size} bytes from $peerID (msg #$messagesReceived, role: ${if (isInitiator) "INITIATOR" else "RESPONDER"})")
return result return result
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Decryption failed - exception: ${e.message}") Log.e(TAG, "Decryption failed - exception: ${e.message}")