mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-02-11 09:23:26 +00:00
fix: make ci checks pass
This commit is contained in:
parent
c5f9994c9e
commit
cd737ea058
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
@ -13,13 +13,9 @@ jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
toolchain:
|
||||
- stable
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
|
||||
- run: rustup update stable && rustup default stable
|
||||
- run: cargo build --verbose
|
||||
- run: cargo test --verbose
|
||||
|
||||
@ -28,7 +24,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
|
||||
- run: rustup update stable && rustup default stable
|
||||
- run: rustup component add clippy
|
||||
- run: cargo clippy --all-targets --all-features -- -D warnings
|
||||
|
||||
@ -37,6 +33,6 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
|
||||
- run: rustup update stable && rustup default stable
|
||||
- run: rustup component add rustfmt
|
||||
- run: cargo fmt --all -- --check
|
||||
|
||||
@ -44,7 +44,7 @@ impl Context {
|
||||
let remote_id = Inbox::inbox_identifier_for_key(remote_bundle.installation_key);
|
||||
let payload_bytes = payloads
|
||||
.into_iter()
|
||||
.map(|p| p.to_envelope(remote_id.clone()))
|
||||
.map(|p| p.into_envelope(remote_id.clone()))
|
||||
.collect();
|
||||
|
||||
let convo_id = self.add_convo(Box::new(convo));
|
||||
@ -65,16 +65,13 @@ impl Context {
|
||||
// Attach conversation_ids to Envelopes
|
||||
Ok(payloads
|
||||
.into_iter()
|
||||
.map(|p| p.to_envelope(convo.remote_id()))
|
||||
.map(|p| p.into_envelope(convo.remote_id()))
|
||||
.collect())
|
||||
}
|
||||
|
||||
// Decode bytes and send to protocol for processing.
|
||||
pub fn handle_payload(&mut self, payload: &[u8]) -> Result<Option<ContentData>, ChatError> {
|
||||
let env = match EnvelopeV1::decode(payload) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
let env = EnvelopeV1::decode(payload)?;
|
||||
|
||||
// TODO: Impl Conversation hinting
|
||||
let convo_id = env.conversation_hint;
|
||||
@ -102,7 +99,7 @@ impl Context {
|
||||
convo_id: ConversationId,
|
||||
enc_payload: EncryptedPayload,
|
||||
) -> Result<Option<ContentData>, ChatError> {
|
||||
let Some(convo) = self.store.get_mut(&convo_id) else {
|
||||
let Some(convo) = self.store.get_mut(convo_id) else {
|
||||
return Err(ChatError::Protocol("convo id not found".into()));
|
||||
};
|
||||
|
||||
@ -115,21 +112,18 @@ impl Context {
|
||||
}
|
||||
|
||||
fn add_convo(&mut self, convo: Box<dyn Convo>) -> ConversationIdOwned {
|
||||
let convo_id = self.store.insert_convo(convo);
|
||||
|
||||
convo_id
|
||||
self.store.insert_convo(convo)
|
||||
}
|
||||
|
||||
// Returns a mutable reference to a Convo for a given ConvoId
|
||||
fn get_convo_mut(&mut self, convo_id: ConversationId) -> Result<&mut dyn Convo, ChatError> {
|
||||
self.store
|
||||
.get_mut(&convo_id)
|
||||
.get_mut(convo_id)
|
||||
.ok_or_else(|| ChatError::NoConvo(convo_id.into()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::conversation::GroupTestConvo;
|
||||
@ -141,7 +135,7 @@ mod tests {
|
||||
let new_convo = GroupTestConvo::new();
|
||||
let convo_id = store.insert_convo(Box::new(new_convo));
|
||||
|
||||
let convo = store.get_mut(&convo_id).ok_or_else(|| 0);
|
||||
let convo = store.get_mut(&convo_id).ok_or(0);
|
||||
convo.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ pub type ConversationId<'a> = &'a str;
|
||||
pub type ConversationIdOwned = Arc<str>;
|
||||
|
||||
pub trait Id: Debug {
|
||||
fn id(&self) -> ConversationId;
|
||||
fn id(&self) -> ConversationId<'_>;
|
||||
}
|
||||
|
||||
pub trait Convo: Id + Debug {
|
||||
@ -54,14 +54,17 @@ impl ConversationStore {
|
||||
Some(self.conversations.get_mut(id)?.as_mut())
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn conversation_ids(&self) -> Vec<ConversationIdOwned> {
|
||||
self.conversations.keys().cloned().collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod group_test;
|
||||
mod privatev1;
|
||||
|
||||
use chat_proto::logoschat::encryption::EncryptedPayload;
|
||||
pub use group_test::GroupTestConvo;
|
||||
#[cfg(test)]
|
||||
pub(crate) use group_test::GroupTestConvo;
|
||||
pub use privatev1::PrivateV1Convo;
|
||||
|
||||
@ -14,7 +14,7 @@ impl GroupTestConvo {
|
||||
}
|
||||
|
||||
impl Id for GroupTestConvo {
|
||||
fn id(&self) -> ConversationId {
|
||||
fn id(&self) -> ConversationId<'_> {
|
||||
// implementation
|
||||
"grouptest"
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ impl PrivateV1Convo {
|
||||
}
|
||||
|
||||
impl Id for PrivateV1Convo {
|
||||
fn id(&self) -> ConversationId {
|
||||
fn id(&self) -> ConversationId<'_> {
|
||||
// TODO: implementation
|
||||
"private_v1_convo_id"
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
mod handler;
|
||||
mod handshake;
|
||||
mod inbox;
|
||||
mod introduction;
|
||||
|
||||
pub use inbox::Inbox;
|
||||
pub use handler::Inbox;
|
||||
pub use introduction::Introduction;
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
use blake2::{Blake2b512, Digest};
|
||||
use chat_proto::logoschat::encryption::EncryptedPayload;
|
||||
use hex;
|
||||
use prost::Message;
|
||||
use prost::bytes::Bytes;
|
||||
use rand_core::OsRng;
|
||||
@ -29,7 +28,7 @@ pub struct Inbox {
|
||||
ephemeral_keys: HashMap<String, StaticSecret>,
|
||||
}
|
||||
|
||||
impl<'a> std::fmt::Debug for Inbox {
|
||||
impl std::fmt::Debug for Inbox {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Inbox")
|
||||
.field("ident", &self.ident)
|
||||
@ -61,7 +60,7 @@ impl Inbox {
|
||||
|
||||
PrekeyBundle {
|
||||
identity_key: self.ident.public_key(),
|
||||
signed_prekey: signed_prekey,
|
||||
signed_prekey,
|
||||
signature: [0u8; 64],
|
||||
onetime_prekey: None,
|
||||
}
|
||||
@ -83,7 +82,7 @@ impl Inbox {
|
||||
};
|
||||
|
||||
let (seed_key, ephemeral_pub) =
|
||||
InboxHandshake::perform_as_initiator(&self.ident.secret(), &pkb, &mut rng);
|
||||
InboxHandshake::perform_as_initiator(self.ident.secret(), &pkb, &mut rng);
|
||||
|
||||
let mut convo = PrivateV1Convo::new_initiator(seed_key, remote_bundle.ephemeral_key);
|
||||
|
||||
@ -218,7 +217,7 @@ impl Inbox {
|
||||
fn lookup_ephemeral_key(&self, key: &str) -> Result<&StaticSecret, ChatError> {
|
||||
self.ephemeral_keys
|
||||
.get(key)
|
||||
.ok_or_else(|| return ChatError::UnknownEphemeralKey())
|
||||
.ok_or(ChatError::UnknownEphemeralKey())
|
||||
}
|
||||
|
||||
pub fn inbox_identifier_for_key(pubkey: PublicKey) -> String {
|
||||
@ -228,7 +227,7 @@ impl Inbox {
|
||||
}
|
||||
|
||||
impl Id for Inbox {
|
||||
fn id(&self) -> ConversationId {
|
||||
fn id(&self) -> ConversationId<'_> {
|
||||
&self.local_convo_id
|
||||
}
|
||||
}
|
||||
@ -85,12 +85,12 @@ mod tests {
|
||||
let mut rng = OsRng;
|
||||
|
||||
// Alice (initiator) generates her identity key
|
||||
let alice_identity = StaticSecret::random_from_rng(&mut rng);
|
||||
let alice_identity = StaticSecret::random_from_rng(rng);
|
||||
let alice_identity_pub = PublicKey::from(&alice_identity);
|
||||
|
||||
// Bob (responder) generates his keys
|
||||
let bob_identity = StaticSecret::random_from_rng(&mut rng);
|
||||
let bob_signed_prekey = StaticSecret::random_from_rng(&mut rng);
|
||||
let bob_identity = StaticSecret::random_from_rng(rng);
|
||||
let bob_signed_prekey = StaticSecret::random_from_rng(rng);
|
||||
let bob_signed_prekey_pub = PublicKey::from(&bob_signed_prekey);
|
||||
|
||||
// Create Bob's prekey bundle
|
||||
|
||||
@ -18,13 +18,13 @@ impl From<PrekeyBundle> for Introduction {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<Vec<u8>> for Introduction {
|
||||
fn into(self) -> Vec<u8> {
|
||||
impl From<Introduction> for Vec<u8> {
|
||||
fn from(val: Introduction) -> Self {
|
||||
// TODO: avoid copies, via writing directly to slice
|
||||
let link = format!(
|
||||
"Bundle:{}:{}",
|
||||
hex::encode(self.installation_key.as_bytes()),
|
||||
hex::encode(self.ephemeral_key.as_bytes()),
|
||||
hex::encode(val.installation_key.as_bytes()),
|
||||
hex::encode(val.ephemeral_key.as_bytes()),
|
||||
);
|
||||
|
||||
link.into_bytes()
|
||||
|
||||
@ -15,7 +15,6 @@ pub use api::*;
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn test_ffi() {}
|
||||
|
||||
@ -27,7 +27,7 @@ pub(crate) struct AddressedEncryptedPayload {
|
||||
|
||||
impl AddressedEncryptedPayload {
|
||||
// Wrap in an envelope and prepare for transmission
|
||||
pub fn to_envelope(self, convo_id: String) -> AddressedEnvelope {
|
||||
pub fn into_envelope(self, convo_id: String) -> AddressedEnvelope {
|
||||
let envelope = proto::EnvelopeV1 {
|
||||
// TODO: conversation_id should be obscured
|
||||
conversation_hint: convo_id,
|
||||
|
||||
@ -134,17 +134,17 @@ mod tests {
|
||||
let mut rng = OsRng;
|
||||
|
||||
// Alice (initiator) generates her identity key
|
||||
let alice_identity = StaticSecret::random_from_rng(&mut rng);
|
||||
let alice_identity = StaticSecret::random_from_rng(rng);
|
||||
let alice_identity_pub = PublicKey::from(&alice_identity);
|
||||
|
||||
// Bob (responder) generates his keys
|
||||
let bob_identity = StaticSecret::random_from_rng(&mut rng);
|
||||
let bob_identity = StaticSecret::random_from_rng(rng);
|
||||
let bob_identity_pub = PublicKey::from(&bob_identity);
|
||||
|
||||
let bob_signed_prekey = StaticSecret::random_from_rng(&mut rng);
|
||||
let bob_signed_prekey = StaticSecret::random_from_rng(rng);
|
||||
let bob_signed_prekey_pub = PublicKey::from(&bob_signed_prekey);
|
||||
|
||||
let bob_onetime_prekey = StaticSecret::random_from_rng(&mut rng);
|
||||
let bob_onetime_prekey = StaticSecret::random_from_rng(rng);
|
||||
let bob_onetime_prekey_pub = PublicKey::from(&bob_onetime_prekey);
|
||||
|
||||
// Create Bob's prekey bundle (with one-time prekey)
|
||||
@ -177,14 +177,14 @@ mod tests {
|
||||
let mut rng = OsRng;
|
||||
|
||||
// Alice (initiator) generates her identity key
|
||||
let alice_identity = StaticSecret::random_from_rng(&mut rng);
|
||||
let alice_identity = StaticSecret::random_from_rng(rng);
|
||||
let alice_identity_pub = PublicKey::from(&alice_identity);
|
||||
|
||||
// Bob (responder) generates his keys
|
||||
let bob_identity = StaticSecret::random_from_rng(&mut rng);
|
||||
let bob_identity = StaticSecret::random_from_rng(rng);
|
||||
let bob_identity_pub = PublicKey::from(&bob_identity);
|
||||
|
||||
let bob_signed_prekey = StaticSecret::random_from_rng(&mut rng);
|
||||
let bob_signed_prekey = StaticSecret::random_from_rng(rng);
|
||||
let bob_signed_prekey_pub = PublicKey::from(&bob_signed_prekey);
|
||||
|
||||
// Create Bob's prekey bundle (without one-time prekey)
|
||||
|
||||
@ -6,7 +6,7 @@ fn main() {
|
||||
|
||||
let bob_dh = InstallationKeyPair::generate();
|
||||
|
||||
let mut alice: RatchetState = RatchetState::init_sender(shared_secret, bob_dh.public().clone());
|
||||
let mut alice: RatchetState = RatchetState::init_sender(shared_secret, *bob_dh.public());
|
||||
let mut bob: RatchetState = RatchetState::init_receiver(shared_secret, bob_dh);
|
||||
|
||||
let (ciphertext, header) = alice.encrypt_message(b"Hello Bob!");
|
||||
|
||||
@ -15,7 +15,7 @@ fn main() {
|
||||
|
||||
let shared_secret = [0x42u8; 32];
|
||||
let bob_keypair = InstallationKeyPair::generate();
|
||||
let bob_public = bob_keypair.public().clone();
|
||||
let bob_public = *bob_keypair.public();
|
||||
|
||||
let conv_id = "out_of_order_conv";
|
||||
let encryption_key = "super-secret-key-123!";
|
||||
|
||||
@ -6,7 +6,7 @@ fn main() {
|
||||
|
||||
let bob_dh = InstallationKeyPair::generate();
|
||||
|
||||
let mut alice: RatchetState = RatchetState::init_sender(shared_secret, bob_dh.public().clone());
|
||||
let mut alice: RatchetState = RatchetState::init_sender(shared_secret, *bob_dh.public());
|
||||
let mut bob: RatchetState = RatchetState::init_receiver(shared_secret, bob_dh);
|
||||
|
||||
let (ciphertext, header) = alice.encrypt_message(b"Hello Bob!");
|
||||
|
||||
@ -55,7 +55,7 @@ fn run_conversation(alice_storage: &mut RatchetStorage, bob_storage: &mut Ratche
|
||||
alice_storage,
|
||||
conv_id,
|
||||
shared_secret,
|
||||
bob_keypair.public().clone(),
|
||||
*bob_keypair.public(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
@ -122,9 +122,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_sequential_reads() {
|
||||
let mut data = vec![0x01]; // version
|
||||
data.extend_from_slice(&[0xAA; 32]); // 32-byte array
|
||||
data.extend_from_slice(&[0x00, 0x00, 0x00, 0x10]); // u32 = 16
|
||||
let mut data = vec![0x01]; // version
|
||||
data.extend_from_slice(&[0xAA; 32]); // 32-byte array
|
||||
data.extend_from_slice(&[0x00, 0x00, 0x00, 0x10]); // u32 = 16
|
||||
|
||||
let mut reader = Reader::new(&data);
|
||||
|
||||
|
||||
@ -345,7 +345,7 @@ impl<D: HkdfInfo> RatchetState<D> {
|
||||
*chain = next_chain;
|
||||
|
||||
let header = Header {
|
||||
dh_pub: self.dh_self.public().clone(),
|
||||
dh_pub: *self.dh_self.public(),
|
||||
msg_num: self.msg_send,
|
||||
prev_chain_len: self.prev_chain_len,
|
||||
};
|
||||
@ -481,7 +481,7 @@ mod tests {
|
||||
let bob_keypair = InstallationKeyPair::generate();
|
||||
|
||||
// Alice initializes as sender, knowing Bob's public key
|
||||
let alice = RatchetState::init_sender(shared_secret, bob_keypair.public().clone());
|
||||
let alice = RatchetState::init_sender(shared_secret, *bob_keypair.public());
|
||||
|
||||
// Bob initializes as receiver with his private key
|
||||
let bob = RatchetState::init_receiver(shared_secret, bob_keypair);
|
||||
@ -554,7 +554,7 @@ mod tests {
|
||||
bob.decrypt_message(&ct, header).unwrap();
|
||||
|
||||
// Bob performs DH ratchet by trying to send
|
||||
let old_bob_pub = bob.dh_self.public().clone();
|
||||
let old_bob_pub = *bob.dh_self.public();
|
||||
let (bob_ct, bob_header) = {
|
||||
let mut b = bob.clone();
|
||||
b.encrypt_message(b"reply")
|
||||
@ -562,7 +562,7 @@ mod tests {
|
||||
assert_ne!(bob_header.dh_pub, old_bob_pub);
|
||||
|
||||
// Alice receives Bob's message with new DH pub → ratchets
|
||||
let old_alice_pub = alice.dh_self.public().clone();
|
||||
let old_alice_pub = *alice.dh_self.public();
|
||||
let old_root = alice.root_key;
|
||||
|
||||
// Even if decrypt fails (wrong key), ratchet should happen
|
||||
|
||||
@ -280,7 +280,7 @@ mod tests {
|
||||
fn create_test_state() -> (RatchetState, SharedSecret) {
|
||||
let shared_secret = [0x42u8; 32];
|
||||
let bob_keypair = InstallationKeyPair::generate();
|
||||
let state = RatchetState::init_sender(shared_secret, bob_keypair.public().clone());
|
||||
let state = RatchetState::init_sender(shared_secret, *bob_keypair.public());
|
||||
(state, shared_secret)
|
||||
}
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ impl<'a, D: HkdfInfo + Clone> RatchetSession<'a, D> {
|
||||
return Err(SessionError::ConvAlreadyExists(conversation_id.to_string()));
|
||||
}
|
||||
let state = RatchetState::<D>::init_sender(shared_secret, remote_pub);
|
||||
Ok(Self::create(storage, conversation_id, state)?)
|
||||
Self::create(storage, conversation_id, state)
|
||||
}
|
||||
|
||||
/// Initializes a new session as a receiver and persists the initial state.
|
||||
@ -75,7 +75,7 @@ impl<'a, D: HkdfInfo + Clone> RatchetSession<'a, D> {
|
||||
}
|
||||
|
||||
let state = RatchetState::<D>::init_receiver(shared_secret, dh_self);
|
||||
Ok(Self::create(storage, conversation_id, state)?)
|
||||
Self::create(storage, conversation_id, state)
|
||||
}
|
||||
|
||||
/// Encrypts a message and persists the updated state.
|
||||
@ -169,7 +169,7 @@ mod tests {
|
||||
let shared_secret = [0x42; 32];
|
||||
let bob_keypair = InstallationKeyPair::generate();
|
||||
let alice: RatchetState<DefaultDomain> =
|
||||
RatchetState::init_sender(shared_secret, bob_keypair.public().clone());
|
||||
RatchetState::init_sender(shared_secret, *bob_keypair.public());
|
||||
|
||||
// Create session
|
||||
{
|
||||
@ -192,7 +192,7 @@ mod tests {
|
||||
let shared_secret = [0x42; 32];
|
||||
let bob_keypair = InstallationKeyPair::generate();
|
||||
let alice: RatchetState<DefaultDomain> =
|
||||
RatchetState::init_sender(shared_secret, bob_keypair.public().clone());
|
||||
RatchetState::init_sender(shared_secret, *bob_keypair.public());
|
||||
|
||||
// Create and encrypt
|
||||
{
|
||||
@ -216,7 +216,7 @@ mod tests {
|
||||
let shared_secret = [0x42; 32];
|
||||
let bob_keypair = InstallationKeyPair::generate();
|
||||
let alice: RatchetState<DefaultDomain> =
|
||||
RatchetState::init_sender(shared_secret, bob_keypair.public().clone());
|
||||
RatchetState::init_sender(shared_secret, *bob_keypair.public());
|
||||
let bob: RatchetState<DefaultDomain> =
|
||||
RatchetState::init_receiver(shared_secret, bob_keypair);
|
||||
|
||||
@ -255,7 +255,7 @@ mod tests {
|
||||
|
||||
let shared_secret = [0x42; 32];
|
||||
let bob_keypair = InstallationKeyPair::generate();
|
||||
let bob_pub = bob_keypair.public().clone();
|
||||
let bob_pub = *bob_keypair.public();
|
||||
|
||||
// First call creates
|
||||
{
|
||||
@ -263,7 +263,7 @@ mod tests {
|
||||
&mut storage,
|
||||
"conv1",
|
||||
shared_secret,
|
||||
bob_pub.clone(),
|
||||
bob_pub,
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(session.state().msg_send, 0);
|
||||
@ -290,7 +290,7 @@ mod tests {
|
||||
|
||||
let shared_secret = [0x42; 32];
|
||||
let bob_keypair = InstallationKeyPair::generate();
|
||||
let bob_pub = bob_keypair.public().clone();
|
||||
let bob_pub = *bob_keypair.public();
|
||||
|
||||
// First creation succeeds
|
||||
{
|
||||
@ -298,7 +298,7 @@ mod tests {
|
||||
&mut storage,
|
||||
"conv1",
|
||||
shared_secret,
|
||||
bob_pub.clone(),
|
||||
bob_pub,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
@ -310,7 +310,7 @@ mod tests {
|
||||
&mut storage,
|
||||
"conv1",
|
||||
shared_secret,
|
||||
bob_pub.clone(),
|
||||
bob_pub,
|
||||
);
|
||||
|
||||
assert!(matches!(result, Err(SessionError::ConvAlreadyExists(_))));
|
||||
|
||||
@ -56,10 +56,7 @@ impl SqliteDb {
|
||||
}
|
||||
|
||||
pub fn sqlcipher(path: String, key: String) -> Result<Self, StorageError> {
|
||||
Self::new(StorageConfig::Encrypted {
|
||||
path: path,
|
||||
key: key,
|
||||
})
|
||||
Self::new(StorageConfig::Encrypted { path, key })
|
||||
}
|
||||
|
||||
/// Returns a reference to the underlying connection.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user