mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 18:25:21 +00:00
Encrypt private media before BLE fragmentation (#1434)
Closes the last cleartext private-content path over BLE: private DM images/voice were sent as plaintext signed fileTransfer packets, TTL-relayed across the mesh, so every relay saw the full bytes. Now the complete BitchatFilePacket is encrypted as a single Noise AEAD message (inner type 0x20, matching Android) and the opaque ciphertext is fragmented. Adds an authenticated in-session capability proof (0x21 TLV: capabilities + Ed25519 key), TOFU-style downgrade pinning, a per-send consent dialog for the signed-cleartext fallback to legacy peers, and a cancellation/admission registry so cancel/delete cannot race a deferred cleartext send. Android wire constants (0x20 / 0x21 / capability bit 8) confirmed shipping. The 256-fragment preflight cap applies only to the directed fileTransfer migration fallback; encrypted media to capable peers uses the full receiver ceiling. Rebased over #1428/#1349: identity reads go through BLELocalIdentityStateStore; the session-bound authenticated signing-key check and the announce-path TOFU pin are kept as complementary checks. Full local suite green (1744+197 tests).
This commit is contained in:
@@ -10,6 +10,7 @@ struct BLENoisePacketHandlerTests {
|
||||
var handshakeResult: Result<Data?, Error> = .success(nil)
|
||||
var handshakeAuthenticated = false
|
||||
var hasSession = false
|
||||
let sessionGeneration = UUID()
|
||||
var decryptResult: Result<Data, Error> = .success(Data())
|
||||
|
||||
var processedHandshakes: [(peerID: PeerID, message: Data)] = []
|
||||
@@ -19,6 +20,7 @@ struct BLENoisePacketHandlerTests {
|
||||
var lastSeenUpdates: [PeerID] = []
|
||||
var decryptCalls: [(payload: Data, peerID: PeerID)] = []
|
||||
var clearedSessions: [PeerID] = []
|
||||
var authenticatedPeerStates: [(peerID: PeerID, payload: Data, generation: UUID)] = []
|
||||
var deliveries: [(peerID: PeerID, type: NoisePayloadType, payload: Data, timestamp: Date)] = []
|
||||
/// Ordered side-effect log to assert recovery sequencing.
|
||||
var events: [String] = []
|
||||
@@ -61,12 +63,18 @@ struct BLENoisePacketHandlerTests {
|
||||
},
|
||||
decrypt: { payload, peerID in
|
||||
recorder.decryptCalls.append((payload, peerID))
|
||||
return try recorder.decryptResult.get()
|
||||
return BLENoiseDecryptionResult(
|
||||
plaintext: try recorder.decryptResult.get(),
|
||||
sessionGeneration: recorder.sessionGeneration
|
||||
)
|
||||
},
|
||||
clearSession: { peerID in
|
||||
recorder.clearedSessions.append(peerID)
|
||||
recorder.events.append("clearSession")
|
||||
},
|
||||
handleAuthenticatedPeerState: { peerID, payload, generation in
|
||||
recorder.authenticatedPeerStates.append((peerID, payload, generation))
|
||||
},
|
||||
deliverNoisePayload: { peerID, type, payload, timestamp in
|
||||
recorder.deliveries.append((peerID, type, payload, timestamp))
|
||||
}
|
||||
@@ -244,6 +252,25 @@ struct BLENoisePacketHandlerTests {
|
||||
#expect(recorder.initiatedHandshakes.isEmpty)
|
||||
}
|
||||
|
||||
@Test
|
||||
func authenticatedPeerStateIsConsumedByTransportNotDeliveredToUI() {
|
||||
let recorder = Recorder()
|
||||
recorder.decryptResult = .success(Data([
|
||||
NoisePayloadType.authenticatedPeerState.rawValue,
|
||||
0x01, 0x02, 0x03
|
||||
]))
|
||||
let handler = makeHandler(recorder: recorder)
|
||||
let packet = makeEncryptedPacket(recipientID: Data(hexString: localPeerID.id))
|
||||
|
||||
handler.handleEncrypted(packet, from: remotePeerID)
|
||||
|
||||
#expect(recorder.authenticatedPeerStates.count == 1)
|
||||
#expect(recorder.authenticatedPeerStates.first?.peerID == remotePeerID)
|
||||
#expect(recorder.authenticatedPeerStates.first?.payload == Data([0x01, 0x02, 0x03]))
|
||||
#expect(recorder.authenticatedPeerStates.first?.generation == recorder.sessionGeneration)
|
||||
#expect(recorder.deliveries.isEmpty)
|
||||
}
|
||||
|
||||
@Test
|
||||
func emptyDecryptedPayloadIsIgnored() {
|
||||
let recorder = Recorder()
|
||||
|
||||
Reference in New Issue
Block a user