mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-24 23:45:19 +00:00
@@ -134,9 +134,15 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
payload = response,
|
payload = response,
|
||||||
ttl = MAX_TTL
|
ttl = MAX_TTL
|
||||||
)
|
)
|
||||||
connectionManager.broadcastPacket(RoutedPacket(responsePacket))
|
// Sign the handshake response
|
||||||
|
val signedPacket = signPacketBeforeBroadcast(responsePacket)
|
||||||
|
connectionManager.broadcastPacket(RoutedPacket(signedPacket))
|
||||||
Log.d(TAG, "Sent Noise handshake response to $peerID (${response.size} bytes)")
|
Log.d(TAG, "Sent Noise handshake response to $peerID (${response.size} bytes)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getPeerInfo(peerID: String): PeerInfo? {
|
||||||
|
return peerManager.getPeerInfo(peerID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreForwardManager delegates
|
// StoreForwardManager delegates
|
||||||
@@ -191,7 +197,9 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
|
|
||||||
// Packet operations
|
// Packet operations
|
||||||
override fun sendPacket(packet: BitchatPacket) {
|
override fun sendPacket(packet: BitchatPacket) {
|
||||||
connectionManager.broadcastPacket(RoutedPacket(packet))
|
// Sign the packet before broadcasting
|
||||||
|
val signedPacket = signPacketBeforeBroadcast(packet)
|
||||||
|
connectionManager.broadcastPacket(RoutedPacket(signedPacket))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun relayPacket(routed: RoutedPacket) {
|
override fun relayPacket(routed: RoutedPacket) {
|
||||||
@@ -240,7 +248,9 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
ttl = MAX_TTL
|
ttl = MAX_TTL
|
||||||
)
|
)
|
||||||
|
|
||||||
connectionManager.broadcastPacket(RoutedPacket(packet))
|
// Sign the handshake packet before broadcasting
|
||||||
|
val signedPacket = signPacketBeforeBroadcast(packet)
|
||||||
|
connectionManager.broadcastPacket(RoutedPacket(signedPacket))
|
||||||
Log.d(TAG, "Initiated Noise handshake with $peerID (${handshakeData.size} bytes)")
|
Log.d(TAG, "Initiated Noise handshake with $peerID (${handshakeData.size} bytes)")
|
||||||
} else {
|
} else {
|
||||||
Log.w(TAG, "Failed to generate Noise handshake data for $peerID")
|
Log.w(TAG, "Failed to generate Noise handshake data for $peerID")
|
||||||
@@ -456,7 +466,9 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
ttl = MAX_TTL
|
ttl = MAX_TTL
|
||||||
)
|
)
|
||||||
|
|
||||||
connectionManager.broadcastPacket(RoutedPacket(packet))
|
// Sign the packet before broadcasting
|
||||||
|
val signedPacket = signPacketBeforeBroadcast(packet)
|
||||||
|
connectionManager.broadcastPacket(RoutedPacket(signedPacket))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,7 +533,9 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
ttl = MAX_TTL
|
ttl = MAX_TTL
|
||||||
)
|
)
|
||||||
|
|
||||||
connectionManager.broadcastPacket(RoutedPacket(packet))
|
// Sign the packet before broadcasting
|
||||||
|
val signedPacket = signPacketBeforeBroadcast(packet)
|
||||||
|
connectionManager.broadcastPacket(RoutedPacket(signedPacket))
|
||||||
Log.d(TAG, "📤 Sent encrypted private message to $recipientPeerID (${encrypted.size} bytes)")
|
Log.d(TAG, "📤 Sent encrypted private message to $recipientPeerID (${encrypted.size} bytes)")
|
||||||
|
|
||||||
// FIXED: Don't send didReceiveMessage for our own sent messages
|
// FIXED: Don't send didReceiveMessage for our own sent messages
|
||||||
@@ -584,7 +598,9 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
ttl = 7u // Same TTL as iOS messageTTL
|
ttl = 7u // Same TTL as iOS messageTTL
|
||||||
)
|
)
|
||||||
|
|
||||||
connectionManager.broadcastPacket(RoutedPacket(packet))
|
// Sign the packet before broadcasting
|
||||||
|
val signedPacket = signPacketBeforeBroadcast(packet)
|
||||||
|
connectionManager.broadcastPacket(RoutedPacket(signedPacket))
|
||||||
Log.d(TAG, "📤 Sent read receipt to $recipientPeerID for message $messageID")
|
Log.d(TAG, "📤 Sent read receipt to $recipientPeerID for message $messageID")
|
||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@@ -699,7 +715,9 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
payload = nickname.toByteArray()
|
payload = nickname.toByteArray()
|
||||||
)
|
)
|
||||||
|
|
||||||
connectionManager.broadcastPacket(RoutedPacket(packet))
|
// Sign the packet before broadcasting
|
||||||
|
val signedPacket = signPacketBeforeBroadcast(packet)
|
||||||
|
connectionManager.broadcastPacket(RoutedPacket(signedPacket))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -861,6 +879,33 @@ class BluetoothMeshService(private val context: Context) {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sign packet before broadcasting using our signing private key
|
||||||
|
*/
|
||||||
|
private fun signPacketBeforeBroadcast(packet: BitchatPacket): BitchatPacket {
|
||||||
|
return try {
|
||||||
|
// Get the canonical packet data for signing (without signature)
|
||||||
|
val packetDataForSigning = packet.toBinaryDataForSigning()
|
||||||
|
if (packetDataForSigning == null) {
|
||||||
|
Log.w(TAG, "Failed to encode packet type ${packet.type} for signing, sending unsigned")
|
||||||
|
return packet
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sign the packet data using our signing key
|
||||||
|
val signature = encryptionService.signData(packetDataForSigning)
|
||||||
|
if (signature != null) {
|
||||||
|
Log.d(TAG, "✅ Signed packet type ${packet.type} (signature ${signature.size} bytes)")
|
||||||
|
packet.copy(signature = signature)
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "Failed to sign packet type ${packet.type}, sending unsigned")
|
||||||
|
packet
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "Error signing packet type ${packet.type}: ${e.message}, sending unsigned")
|
||||||
|
packet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Panic Mode Support
|
// MARK: - Panic Mode Support
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class SecurityManager(private val encryptionService: EncryptionService, private
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate packet security (timestamp, replay attacks, duplicates)
|
* Validate packet security (timestamp, replay attacks, duplicates, signatures)
|
||||||
*/
|
*/
|
||||||
fun validatePacket(packet: BitchatPacket, peerID: String): Boolean {
|
fun validatePacket(packet: BitchatPacket, peerID: String): Boolean {
|
||||||
// Skip validation for our own packets
|
// Skip validation for our own packets
|
||||||
@@ -83,6 +83,9 @@ class SecurityManager(private val encryptionService: EncryptionService, private
|
|||||||
processedMessages.add(messageID)
|
processedMessages.add(messageID)
|
||||||
messageTimestamps[messageID] = currentTime
|
messageTimestamps[messageID] = currentTime
|
||||||
|
|
||||||
|
// NEW: Signature verification logging (not rejecting yet)
|
||||||
|
verifyPacketSignatureWithLogging(packet, peerID)
|
||||||
|
|
||||||
Log.d(TAG, "Packet validation passed for $peerID, messageID: $messageID")
|
Log.d(TAG, "Packet validation passed for $peerID, messageID: $messageID")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -225,6 +228,52 @@ class SecurityManager(private val encryptionService: EncryptionService, private
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify packet signature using peer's signing public key and log the result
|
||||||
|
*/
|
||||||
|
private fun verifyPacketSignatureWithLogging(packet: BitchatPacket, peerID: String) {
|
||||||
|
try {
|
||||||
|
// Check if packet has a signature
|
||||||
|
if (packet.signature == null) {
|
||||||
|
Log.d(TAG, "📝 Signature check for $peerID: NO_SIGNATURE (packet type ${packet.type})")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get peer's signing public key from peer info
|
||||||
|
val peerInfo = delegate?.getPeerInfo(peerID)
|
||||||
|
val signingPublicKey = peerInfo?.signingPublicKey
|
||||||
|
|
||||||
|
if (signingPublicKey == null) {
|
||||||
|
Log.d(TAG, "📝 Signature check for $peerID: NO_SIGNING_KEY (packet type ${packet.type})")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the canonical packet data for signature verification (without signature)
|
||||||
|
val packetDataForSigning = packet.toBinaryDataForSigning()
|
||||||
|
if (packetDataForSigning == null) {
|
||||||
|
Log.w(TAG, "📝 Signature check for $peerID: ENCODING_ERROR (packet type ${packet.type})")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the signature using the peer's signing public key
|
||||||
|
val signature = packet.signature!! // We already checked for null above
|
||||||
|
val isSignatureValid = encryptionService.verifyEd25519Signature(
|
||||||
|
signature,
|
||||||
|
packetDataForSigning,
|
||||||
|
signingPublicKey
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isSignatureValid) {
|
||||||
|
Log.d(TAG, "📝 Signature check for $peerID: ✅ VALID (packet type ${packet.type})")
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "📝 Signature check for $peerID: ❌ INVALID (packet type ${packet.type})")
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.w(TAG, "📝 Signature check for $peerID: ERROR - ${e.message} (packet type ${packet.type})")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if we have encryption keys for a peer
|
* Check if we have encryption keys for a peer
|
||||||
*/
|
*/
|
||||||
@@ -339,4 +388,5 @@ class SecurityManager(private val encryptionService: EncryptionService, private
|
|||||||
interface SecurityManagerDelegate {
|
interface SecurityManagerDelegate {
|
||||||
fun onKeyExchangeCompleted(peerID: String, peerPublicKeyData: ByteArray)
|
fun onKeyExchangeCompleted(peerID: String, peerPublicKeyData: ByteArray)
|
||||||
fun sendHandshakeResponse(peerID: String, response: ByteArray)
|
fun sendHandshakeResponse(peerID: String, response: ByteArray)
|
||||||
|
fun getPeerInfo(peerID: String): PeerInfo? // NEW: For signature verification
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user