mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-26 14:05:22 +00:00
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).
36 lines
1.2 KiB
Swift
36 lines
1.2 KiB
Swift
import Foundation
|
|
|
|
enum BLENoisePayloadFactory {
|
|
static func privateMessage(content: String, messageID: String) -> Data? {
|
|
guard let payload = PrivateMessagePacket(messageID: messageID, content: content).encode() else {
|
|
return nil
|
|
}
|
|
|
|
return typedPayload(.privateMessage, payload: payload)
|
|
}
|
|
|
|
static func readReceipt(originalMessageID: String) -> Data {
|
|
typedPayload(.readReceipt, payload: Data(originalMessageID.utf8))
|
|
}
|
|
|
|
static func delivered(messageID: String) -> Data {
|
|
typedPayload(.delivered, payload: Data(messageID.utf8))
|
|
}
|
|
|
|
static func privateFile(_ filePacket: BitchatFilePacket) -> Data? {
|
|
guard let payload = filePacket.encode() else { return nil }
|
|
return typedPayload(.privateFile, payload: payload)
|
|
}
|
|
|
|
static func authenticatedPeerState(_ state: AuthenticatedPeerStatePacket) -> Data? {
|
|
guard let payload = state.encode() else { return nil }
|
|
return typedPayload(.authenticatedPeerState, payload: payload)
|
|
}
|
|
|
|
static func typedPayload(_ type: NoisePayloadType, payload: Data) -> Data {
|
|
var typed = Data([type.rawValue])
|
|
typed.append(payload)
|
|
return typed
|
|
}
|
|
}
|