diff --git a/app/src/main/java/com/bitchat/android/mesh/BluetoothMeshService.kt b/app/src/main/java/com/bitchat/android/mesh/BluetoothMeshService.kt index 24b37610..8c848dc8 100644 --- a/app/src/main/java/com/bitchat/android/mesh/BluetoothMeshService.kt +++ b/app/src/main/java/com/bitchat/android/mesh/BluetoothMeshService.kt @@ -219,6 +219,10 @@ class BluetoothMeshService(private val context: Context) { return securityManager.decryptFromPeer(encryptedData, senderPeerID) } + override fun verifyEd25519Signature(signature: ByteArray, data: ByteArray, publicKey: ByteArray): Boolean { + return encryptionService.verifyEd25519Signature(signature, data, publicKey) + } + // Noise protocol operations override fun hasNoiseSession(peerID: String): Boolean { return encryptionService.hasEstablishedSession(peerID) @@ -976,6 +980,40 @@ class BluetoothMeshService(private val context: Context) { return result } + + // MARK: - Panic Mode Support + + /** + * Clear all internal mesh service data (for panic mode) + */ + fun clearAllInternalData() { + Log.w(TAG, "🚨 Clearing all mesh service internal data") + try { + // Clear all managers + fragmentManager.clearAllFragments() + storeForwardManager.clearAllCache() + securityManager.clearAllData() + peerManager.clearAllPeers() + peerManager.clearAllFingerprints() + Log.d(TAG, "✅ Cleared all mesh service internal data") + } catch (e: Exception) { + Log.e(TAG, "❌ Error clearing mesh service internal data: ${e.message}") + } + } + + /** + * Clear all encryption and cryptographic data (for panic mode) + */ + fun clearAllEncryptionData() { + Log.w(TAG, "🚨 Clearing all encryption data") + try { + // Clear encryption service persistent identity (includes Ed25519 signing keys) + encryptionService.clearPersistentIdentity() + Log.d(TAG, "✅ Cleared all encryption data") + } catch (e: Exception) { + Log.e(TAG, "❌ Error clearing encryption data: ${e.message}") + } + } } /** diff --git a/app/src/main/java/com/bitchat/android/mesh/MessageHandler.kt b/app/src/main/java/com/bitchat/android/mesh/MessageHandler.kt index 87e266cc..6e4e6ff6 100644 --- a/app/src/main/java/com/bitchat/android/mesh/MessageHandler.kt +++ b/app/src/main/java/com/bitchat/android/mesh/MessageHandler.kt @@ -120,13 +120,27 @@ class MessageHandler(private val myPeerID: String) { Log.d(TAG, "Parsed identity announcement: peerID=${announcement.peerID}, " + "nickname=${announcement.nickname}, fingerprint=${announcement.fingerprint?.take(16)}...") - // Verify the announcement signature (basic validation) - // In a full implementation, this would use cryptographic verification + // Verify the announcement signature using Ed25519 (iOS compatibility) if (announcement.signature.isEmpty()) { - Log.w(TAG, "Identity announcement from $peerID has no signature") + Log.w(TAG, "❌ Identity announcement from $peerID has no signature - rejecting") return } + // Verify signature using the same format as iOS + val timestampMs = announcement.timestamp.time + val bindingData = announcement.peerID.toByteArray(Charsets.UTF_8) + + announcement.publicKey + + timestampMs.toString().toByteArray(Charsets.UTF_8) + + val isSignatureValid = delegate?.verifyEd25519Signature(announcement.signature, bindingData, announcement.signingPublicKey) ?: false + + if (!isSignatureValid) { + Log.w(TAG, "❌ Signature verification failed for identity announcement from $peerID - rejecting") + return + } + + Log.d(TAG, "✅ Signature verification successful for identity announcement from $peerID") + // Update peer binding in the delegate (ChatViewModel/BluetoothMeshService) delegate?.updatePeerIDBinding( newPeerID = announcement.peerID, @@ -377,6 +391,7 @@ interface MessageHandlerDelegate { fun verifySignature(packet: BitchatPacket, peerID: String): Boolean fun encryptForPeer(data: ByteArray, recipientPeerID: String): ByteArray? fun decryptFromPeer(encryptedData: ByteArray, senderPeerID: String): ByteArray? + fun verifyEd25519Signature(signature: ByteArray, data: ByteArray, publicKey: ByteArray): Boolean // Noise protocol operations fun hasNoiseSession(peerID: String): Boolean diff --git a/app/src/main/java/com/bitchat/android/ui/ChatViewModel.kt b/app/src/main/java/com/bitchat/android/ui/ChatViewModel.kt index 9123eb58..ea9f3b5a 100644 --- a/app/src/main/java/com/bitchat/android/ui/ChatViewModel.kt +++ b/app/src/main/java/com/bitchat/android/ui/ChatViewModel.kt @@ -25,6 +25,10 @@ class ChatViewModel( val meshService: BluetoothMeshService ) : AndroidViewModel(application), BluetoothMeshDelegate { + companion object { + private const val TAG = "ChatViewModel" + } + // State management private val state = ChatState() @@ -394,21 +398,71 @@ class ChatViewModel( // MARK: - Emergency Clear fun panicClearAllData() { - // Clear all managers + Log.w(TAG, "🚨 PANIC MODE ACTIVATED - Clearing all sensitive data") + + // Clear all UI managers messageManager.clearAllMessages() channelManager.clearAllChannels() privateChatManager.clearAllPrivateChats() dataManager.clearAllData() + // Clear all mesh service data + clearAllMeshServiceData() + + // Clear all cryptographic data + clearAllCryptographicData() + + // Clear all notifications + notificationManager.clearAllNotifications() + // Reset nickname val newNickname = "anon${Random.nextInt(1000, 9999)}" state.setNickname(newNickname) dataManager.saveNickname(newNickname) + Log.w(TAG, "🚨 PANIC MODE COMPLETED - All sensitive data cleared") + // Note: Mesh service restart is now handled by MainActivity // This method now only clears data, not mesh service lifecycle } + /** + * Clear all mesh service related data + */ + private fun clearAllMeshServiceData() { + try { + // Request mesh service to clear all its internal data + meshService.clearAllInternalData() + + Log.d(TAG, "✅ Cleared all mesh service data") + } catch (e: Exception) { + Log.e(TAG, "❌ Error clearing mesh service data: ${e.message}") + } + } + + /** + * Clear all cryptographic data including persistent identity + */ + private fun clearAllCryptographicData() { + try { + // Clear encryption service persistent identity (Ed25519 signing keys) + meshService.clearAllEncryptionData() + + // Clear secure identity state (if used) + try { + val identityManager = com.bitchat.android.identity.SecureIdentityStateManager(getApplication()) + identityManager.clearIdentityData() + Log.d(TAG, "✅ Cleared secure identity state") + } catch (e: Exception) { + Log.d(TAG, "SecureIdentityStateManager not available or already cleared: ${e.message}") + } + + Log.d(TAG, "✅ Cleared all cryptographic data") + } catch (e: Exception) { + Log.e(TAG, "❌ Error clearing cryptographic data: ${e.message}") + } + } + // MARK: - Navigation Management fun showAppInfo() {