Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion client/client_db/migrations/02-denim/up.sql
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ CREATE TABLE DeniableDeviceSessionStore (

CREATE TABLE DeniablePayload (
id INTEGER PRIMARY KEY,
content BLOB NOT NULL
content BLOB NOT NULL,
chunk_count INTEGER NOT NULL
);

CREATE TABLE DeniableKeyRequestsSent (
Expand Down
8 changes: 5 additions & 3 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ impl<T: ClientDB, U: SignalServerAPI> Client<T, U> {
.device
.lock()
.await
.store_deniable_payload(None, deniable_payload_serialized)
.store_deniable_payload(None, 0, deniable_payload_serialized)
.await
.map_err(DatabaseError::from)?;
}
Expand Down Expand Up @@ -583,15 +583,17 @@ impl<T: ClientDB, U: SignalServerAPI> Client<T, U> {

let mut deniable_payloads = Vec::new();
for chunk in new_chunks {
chunks.push(chunk.clone());
if chunk.is_final() {
chunks.sort();
chunks.push(chunk.clone());
let deniable_bytes: Vec<u8> = chunks.into_iter().flat_map(|c| c.chunk).collect();
let deniable_payload =
deserialize(&deniable_bytes).expect("Should be deniable payload");
deniable_payloads.push(deniable_payload);

chunks = Vec::new();
} else {
chunks.push(chunk.clone());
}
}

Expand Down Expand Up @@ -682,7 +684,7 @@ impl<T: ClientDB, U: SignalServerAPI> Client<T, U> {
.device
.lock()
.await
.store_deniable_payload(None, deniable_payload_serialized)
.store_deniable_payload(None, 0, deniable_payload_serialized)
.await
.map_err(DatabaseError::from)?;
self.storage
Expand Down
13 changes: 9 additions & 4 deletions client/src/storage/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,15 @@ pub trait ClientDB {
async fn get_aci(&self) -> Result<Aci, Self::Error>;
async fn set_pni(&mut self, new_pni: Pni) -> Result<(), Self::Error>;
async fn get_pni(&self) -> Result<Pni, Self::Error>;
async fn get_deniable_payload(&self) -> Result<(u32, Vec<u8>), Self::Error>;
async fn get_deniable_payload_by_id(&self, payload_id: u32) -> Result<Vec<u8>, Self::Error>;
async fn get_deniable_payload(&self) -> Result<(u32, Vec<u8>, i32), Self::Error>;
async fn get_deniable_payload_by_id(
&self,
payload_id: u32,
) -> Result<(Vec<u8>, i32), Self::Error>;
async fn store_deniable_payload(
&self,
payload_id: Option<u32>,
chunk_count: i32,
payload: Vec<u8>,
) -> Result<(), Self::Error>;
async fn remove_deniable_payload(&self, payload_id: u32) -> Result<(), Self::Error>;
Expand Down Expand Up @@ -470,7 +474,7 @@ impl<T: ClientDB> SessionStore for DeniableStore<T> {

#[async_trait(?Send)]
impl<T: ClientDB> DeniableSendingBuffer for DeniableStore<T> {
async fn get_outgoing_message(&mut self) -> Result<(u32, Vec<u8>), SignalProtocolError> {
async fn get_outgoing_message(&mut self) -> Result<(u32, Vec<u8>, i32), SignalProtocolError> {
self.db
.lock()
.await
Expand All @@ -482,12 +486,13 @@ impl<T: ClientDB> DeniableSendingBuffer for DeniableStore<T> {
async fn set_outgoing_message(
&mut self,
message_id: Option<u32>,
chunk_count: i32,
outgoing_message: Vec<u8>,
) -> Result<(), SignalProtocolError> {
self.db
.lock()
.await
.store_deniable_payload(message_id, outgoing_message)
.store_deniable_payload(message_id, chunk_count, outgoing_message)
.await
.map_err(|err| SignalProtocolError::InvalidArgument(format!("{err}")))
}
Expand Down
30 changes: 17 additions & 13 deletions client/src/storage/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -965,32 +965,35 @@ impl ClientDB for Device {
)?)
}

async fn get_deniable_payload(&self) -> Result<(u32, Vec<u8>), Self::Error> {
async fn get_deniable_payload(&self) -> Result<(u32, Vec<u8>, i32), Self::Error> {
let mut stmt = self
.conn
.prepare(
r#"
SELECT
id, content
id, content, chunk_count
FROM
DeniablePayload
"#,
)
.map_err(|err| SignalProtocolError::InvalidArgument(format!("{}", err)))?;

let row: (u32, Vec<u8>) = stmt
.query_row([], |row| Ok((row.get(0)?, row.get(1)?)))
let row: (u32, Vec<u8>, i32) = stmt
.query_row([], |row| Ok((row.get(0)?, row.get(1)?, row.get(2)?)))
.map_err(|err| SignalProtocolError::InvalidArgument(format!("{}", err)))?;
Ok(row)
}

async fn get_deniable_payload_by_id(&self, payload_id: u32) -> Result<Vec<u8>, Self::Error> {
async fn get_deniable_payload_by_id(
&self,
payload_id: u32,
) -> Result<(Vec<u8>, i32), Self::Error> {
let mut stmt = self
.conn
.prepare(
r#"
SELECT
content
content, chunk_count
FROM
DeniablePayload
WHERE
Expand All @@ -999,15 +1002,16 @@ impl ClientDB for Device {
)
.map_err(|err| SignalProtocolError::InvalidArgument(format!("{}", err)))?;

let row: Vec<u8> = stmt
.query_row([payload_id], |row| Ok(row.get(0)?))
let row: (Vec<u8>, i32) = stmt
.query_row([payload_id], |row| Ok((row.get(0)?, row.get(1)?)))
.map_err(|err| SignalProtocolError::InvalidArgument(format!("{}", err)))?;
Ok(row)
}

async fn store_deniable_payload(
&self,
payload_id: Option<u32>,
chunk_count: i32,
payload: Vec<u8>,
) -> Result<(), Self::Error> {
if let Some(id) = payload_id {
Expand All @@ -1016,21 +1020,21 @@ impl ClientDB for Device {
.prepare(
r#"
UPDATE DeniablePayload
SET content = ?1
WHERE id = ?2
SET content = ?1, chunk_count = ?2
WHERE id = ?3
"#,
)
.map_err(|err| SignalProtocolError::InvalidArgument(format!("{}", err)))?;

stmt.execute(params![payload, id])
stmt.execute(params![payload, chunk_count, id])
.map_err(|err| SignalProtocolError::InvalidArgument(format!("{}", err)))?;
} else {
let mut stmt = self
.conn
.prepare(
r#"
INSERT INTO DeniablePayload (content)
VALUES (?1)
INSERT INTO DeniablePayload (content, chunk_count)
VALUES (?1, 0)
"#,
)
.map_err(|err| SignalProtocolError::InvalidArgument(format!("{}", err)))?;
Expand Down
11 changes: 8 additions & 3 deletions client/src/storage/in_memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,14 +267,19 @@ impl ClientDB for InMemory {
Ok(self.pni)
}

async fn get_deniable_payload(&self) -> Result<(u32, Vec<u8>), Self::Error> {
async fn get_deniable_payload(&self) -> Result<(u32, Vec<u8>, i32), Self::Error> {
todo!()
}

async fn get_deniable_payload_by_id(&self, _: u32) -> Result<Vec<u8>, Self::Error> {
async fn get_deniable_payload_by_id(&self, _: u32) -> Result<(Vec<u8>, i32), Self::Error> {
todo!()
}
async fn store_deniable_payload(&self, _: Option<u32>, _: Vec<u8>) -> Result<(), Self::Error> {
async fn store_deniable_payload(
&self,
_: Option<u32>,
_: i32,
_: Vec<u8>,
) -> Result<(), Self::Error> {
todo!()
}

Expand Down
10 changes: 7 additions & 3 deletions common/src/deniable/chunk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,14 @@ impl Chunker {
} else {
new_chunk = DenimChunk {
chunk: current_outgoing_message.1[..chunk_size].to_vec(),
flags: ChunkType::Data(0).into(),
flags: ChunkType::Data(current_outgoing_message.2).into(),
};
let remaining_current_outgoing_message =
current_outgoing_message.1[chunk_size..].to_vec();
buffer
.set_outgoing_message(
Some(current_outgoing_message.0),
current_outgoing_message.2 - 1,
remaining_current_outgoing_message,
)
.await
Expand Down Expand Up @@ -157,13 +158,16 @@ mod test {

#[async_trait(?Send)]
impl DeniableSendingBuffer for MockDeniableSendingBuffer {
async fn get_outgoing_message(&mut self) -> Result<(u32, Vec<u8>), SignalProtocolError> {
async fn get_outgoing_message(
&mut self,
) -> Result<(u32, Vec<u8>, i32), SignalProtocolError> {
let message: [u8; 32] = rand::random();
Ok((1, message.to_vec()))
Ok((1, message.to_vec(), 0))
}
async fn set_outgoing_message(
&mut self,
_: Option<u32>,
_: i32,
_: Vec<u8>,
) -> Result<(), SignalProtocolError> {
Ok(())
Expand Down
3 changes: 2 additions & 1 deletion common/src/deniable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ pub mod constants;

#[async_trait(?Send)]
pub trait DeniableSendingBuffer {
async fn get_outgoing_message(&mut self) -> Result<(u32, Vec<u8>), SignalProtocolError>;
async fn get_outgoing_message(&mut self) -> Result<(u32, Vec<u8>, i32), SignalProtocolError>;
async fn set_outgoing_message(
&mut self,
message_id: Option<u32>,
chunk_count: i32,
outgoing_message: Vec<u8>,
) -> Result<(), SignalProtocolError>;
async fn remove_outgoing_message(&mut self, message_id: u32)
Expand Down
4 changes: 2 additions & 2 deletions common/src/web_api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,11 @@ pub struct DenimChunk {

impl DenimChunk {
pub fn is_dummy(&self) -> bool {
self.flags & 1 == 1
self.flags == 1
}

pub fn is_final(&self) -> bool {
self.flags & 2 == 2
self.flags == 2
}
}

Expand Down