Skip to content

Commit

Permalink
Merge branch 'MarcusGrass-registration-fixes-completion' into dev3
Browse files Browse the repository at this point in the history
  • Loading branch information
nanu-c committed Aug 16, 2023
2 parents 8c6f4ee + b7e47cc commit 07d4c69
Show file tree
Hide file tree
Showing 7 changed files with 243 additions and 77 deletions.
2 changes: 1 addition & 1 deletion presage-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ enum Cmd {
group(
ArgGroup::new("list-messages")
.required(true)
.args(&["recipient-uuid", "group-master-key"])
.args(&["recipient_uuid", "group_master_key"])
)
)]
ListMessages {
Expand Down
167 changes: 117 additions & 50 deletions presage-store-sled/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,25 @@ use async_trait::async_trait;
use log::{debug, error, trace, warn};
#[cfg(feature = "encryption")]
use matrix_sdk_store_encryption::StoreCipher;
use presage::{
libsignal_service::{
self,
groups_v2::{decrypt_group, Group},
models::Contact,
prelude::{
protocol::{
Context, Direction, IdentityKey, IdentityKeyPair, IdentityKeyStore, PreKeyId,
PreKeyRecord, PreKeyStore, ProtocolAddress, ProtocolStore, SenderKeyRecord,
SenderKeyStore, SessionRecord, SessionStore, SessionStoreExt, SignalProtocolError,
SignedPreKeyId, SignedPreKeyRecord, SignedPreKeyStore,
},
Content, ProfileKey, Uuid,
use presage::libsignal_service::{
self,
groups_v2::Group,
models::Contact,
prelude::{
protocol::{
Context, Direction, GenericSignedPreKey, IdentityKey, IdentityKeyPair,
IdentityKeyStore, KyberPreKeyId, KyberPreKeyRecord, KyberPreKeyStore, PreKeyId,
PreKeyRecord, PreKeyStore, ProtocolAddress, ProtocolStore, SenderKeyRecord,
SenderKeyStore, SessionRecord, SessionStore, SessionStoreExt, SignalProtocolError,
SignedPreKeyId, SignedPreKeyRecord, SignedPreKeyStore,
},
push_service::DEFAULT_DEVICE_ID,
Profile, ServiceAddress,
Content, ProfileKey, Uuid,
},
ThreadMetadata,
prelude::proto,
push_service::DEFAULT_DEVICE_ID,
Profile, ServiceAddress,
};
use presage::ThreadMetadata;

use prost::Message;
use protobuf::ContentProto;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
Expand All @@ -49,13 +48,15 @@ const SLED_TREE_PRE_KEYS: &str = "pre_keys";
const SLED_TREE_SENDER_KEYS: &str = "sender_keys";
const SLED_TREE_SESSIONS: &str = "sessions";
const SLED_TREE_SIGNED_PRE_KEYS: &str = "signed_pre_keys";
const SLED_TREE_KYBER_PRE_KEYS: &str = "kyber_pre_keys";
const SLED_TREE_STATE: &str = "state";
const SLED_TREE_THREADS_PREFIX: &str = "threads";
const SLED_TREE_THREADS_METADATA: &str = "threads_metadata";
const SLED_TREE_PROFILES: &str = "profiles";
const SLED_TREE_PROFILE_KEYS: &str = "profile_keys";

const SLED_KEY_NEXT_SIGNED_PRE_KEY_ID: &str = "next_signed_pre_key_id";
const SLED_KEY_NEXT_PQ_PRE_KEY_ID: &str = "next_pq_pre_key_id";
const SLED_KEY_PRE_KEYS_OFFSET_ID: &str = "pre_keys_offset_id";
const SLED_KEY_REGISTRATION: &str = "registration";
const SLED_KEY_SCHEMA_VERSION: &str = "schema_version";
Expand Down Expand Up @@ -88,13 +89,13 @@ pub enum SchemaVersion {
#[default]
V0 = 0,
V1 = 1,
/// the current version
V2 = 2,
V3 = 3,
}

impl SchemaVersion {
fn current() -> SchemaVersion {
Self::V2
Self::V3
}

/// return an iterator on all the necessary migration steps from another version
Expand All @@ -106,6 +107,7 @@ impl SchemaVersion {
.map(|i| match i {
1 => SchemaVersion::V1,
2 => SchemaVersion::V2,
3 => SchemaVersion::V3,
_ => unreachable!("oops, this not supposed to happen!"),
})
}
Expand Down Expand Up @@ -300,6 +302,12 @@ fn migrate(
db.flush()?;
}
}
SchemaVersion::V3 => {
debug!("migrating from schema v2 to v3: dropping encrypted group cache");
let db = store.write();
db.drop_tree(SLED_TREE_GROUPS)?;
db.flush()?;
}
_ => return Err(SledStoreError::MigrationConflict),
}

Expand Down Expand Up @@ -421,6 +429,17 @@ impl Store for SledStore {
Ok(())
}

fn next_pq_pre_key_id(&self) -> Result<u32, SledStoreError> {
Ok(self
.get(SLED_TREE_STATE, SLED_KEY_NEXT_PQ_PRE_KEY_ID)?
.unwrap_or(0))
}

fn set_next_pq_pre_key_id(&mut self, id: u32) -> Result<(), SledStoreError> {
self.insert(SLED_TREE_STATE, SLED_KEY_NEXT_PQ_PRE_KEY_ID, id)?;
Ok(())
}

/// Contacts

fn clear_contacts(&mut self) -> Result<(), SledStoreError> {
Expand Down Expand Up @@ -476,24 +495,15 @@ impl Store for SledStore {
&self,
master_key_bytes: GroupMasterKeyBytes,
) -> Result<Option<Group>, SledStoreError> {
let val: Option<Vec<u8>> = self.get(SLED_TREE_GROUPS, master_key_bytes)?;
match val {
Some(ref v) => {
let encrypted_group = proto::Group::decode(v.as_slice())?;
let group = decrypt_group(&master_key_bytes, encrypted_group)
.map_err(|_| SledStoreError::GroupDecryption)?;
Ok(Some(group))
}
None => Ok(None),
}
self.get(SLED_TREE_GROUPS, master_key_bytes)
}

fn save_group(
&self,
master_key: GroupMasterKeyBytes,
group: proto::Group,
group: &Group,
) -> Result<(), SledStoreError> {
self.insert(SLED_TREE_GROUPS, master_key, group.encode_to_vec())?;
self.insert(SLED_TREE_GROUPS, master_key, group)?;
Ok(())
}

Expand All @@ -513,6 +523,16 @@ impl Store for SledStore {
Ok(())
}

fn clear_thread(&mut self, thread: &Thread) -> Result<(), SledStoreError> {
log::trace!("clearing thread {thread}");

let db = self.write();
db.drop_tree(self.messages_thread_tree_name(thread))?;
db.flush()?;

Ok(())
}

fn save_message(&mut self, thread: &Thread, message: Content) -> Result<(), SledStoreError> {
log::trace!(
"storing a message with thread: {thread}, timestamp: {}",
Expand Down Expand Up @@ -665,26 +685,21 @@ impl Iterator for SledGroupsIter {
type Item = Result<(GroupMasterKeyBytes, Group), SledStoreError>;

fn next(&mut self) -> Option<Self::Item> {
self.iter
.next()?
.map_err(SledStoreError::from)
.and_then(|(master_key_bytes, value)| {
let decrypted_data: Vec<u8> = self.cipher.as_ref().map_or_else(
Some(self.iter.next()?.map_err(SledStoreError::from).and_then(
|(group_master_key_bytes, value)| {
let group = self.cipher.as_ref().map_or_else(
|| serde_json::from_slice(&value).map_err(SledStoreError::from),
|c| c.decrypt_value(&value).map_err(SledStoreError::from),
)?;
Ok((master_key_bytes, decrypted_data))
})
.and_then(|(master_key_bytes, encrypted_group_data)| {
let encrypted_group = proto::Group::decode(encrypted_group_data.as_slice())?;
let master_key: GroupMasterKeyBytes = master_key_bytes[..]
.try_into()
.expect("wrong group master key length");
let decrypted_group = decrypt_group(&master_key, encrypted_group)
.map_err(|_| SledStoreError::GroupDecryption)?;
Ok((master_key, decrypted_group))
})
.into()
Ok((
group_master_key_bytes
.as_ref()
.try_into()
.map_err(|_| SledStoreError::GroupDecryption)?,
group,
))
},
))
}
}

Expand Down Expand Up @@ -764,6 +779,57 @@ impl SignedPreKeyStore for SledStore {
}
}

#[async_trait(?Send)]
impl KyberPreKeyStore for SledStore {
async fn get_kyber_pre_key(
&self,
kyber_prekey_id: KyberPreKeyId,
_ctx: Context,
) -> Result<KyberPreKeyRecord, SignalProtocolError> {
let buf: Vec<u8> = self
.get(SLED_TREE_KYBER_PRE_KEYS, kyber_prekey_id.to_string())
.ok()
.flatten()
.ok_or(SignalProtocolError::InvalidKyberPreKeyId)?;
KyberPreKeyRecord::deserialize(&buf)
}

async fn save_kyber_pre_key(
&mut self,
kyber_prekey_id: KyberPreKeyId,
record: &KyberPreKeyRecord,
_ctx: Context,
) -> Result<(), SignalProtocolError> {
self.insert(
SLED_TREE_KYBER_PRE_KEYS,
kyber_prekey_id.to_string(),
record.serialize()?,
)
.map_err(|e| {
log::error!("sled error: {}", e);
SignalProtocolError::InvalidState("save_kyber_pre_key", "sled error".into())
})?;
Ok(())
}

async fn mark_kyber_pre_key_used(
&mut self,
kyber_prekey_id: KyberPreKeyId,
_ctx: Context,
) -> Result<(), SignalProtocolError> {
if self
.remove(SLED_TREE_KYBER_PRE_KEYS, kyber_prekey_id.to_string())
.map_err(|e| {
log::error!("sled error: {}", e);
SignalProtocolError::InvalidState("mark_kyber_pre_key_used", "sled error".into())
})?
{
log::trace!("removed kyber pre-key {kyber_prekey_id}");
}
Ok(())
}
}

#[async_trait(?Send)]
impl SessionStore for SledStore {
async fn load_session(
Expand Down Expand Up @@ -1054,8 +1120,9 @@ mod tests {
content::{ContentBody, Metadata},
prelude::{
protocol::{
self, Direction, IdentityKeyStore, PreKeyRecord, PreKeyStore, SessionRecord,
SessionStore, SignedPreKeyRecord, SignedPreKeyStore,
self, Direction, GenericSignedPreKey, IdentityKeyStore, PreKeyRecord,
PreKeyStore, SessionRecord, SessionStore, SignedPreKeyRecord,
SignedPreKeyStore,
},
Uuid,
},
Expand Down
4 changes: 2 additions & 2 deletions presage/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ authors = ["Gabriel Féron <g@leirbag.net>"]
edition = "2021"

[dependencies]
libsignal-service = { git = "https://github.com/whisperfish/libsignal-service-rs", rev = "c2f70ef" }
libsignal-service-hyper = { git = "https://github.com/whisperfish/libsignal-service-rs", rev = "c2f70ef" }
libsignal-service = { git = "https://github.com/whisperfish/libsignal-service-rs", rev = "3c65765" }
libsignal-service-hyper = { git = "https://github.com/whisperfish/libsignal-service-rs", rev = "3c65765" }

base64 = "0.12"
futures = "0.3"
Expand Down
4 changes: 4 additions & 0 deletions presage/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ pub enum Error<S: std::error::Error> {
Timeout(#[from] tokio::time::error::Elapsed),
#[error("store error: {0}")]
Store(S),
#[error("unknown error: {0}")]
UnknownError(String),
#[error("verification error")]
VerificationCodeRequestError,
}

impl<S: StoreError> From<S> for Error<S> {
Expand Down
1 change: 1 addition & 0 deletions presage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub mod prelude {
self, Content, ContentBody, DataMessage, GroupContext, GroupContextV2, GroupType,
Metadata, SyncMessage,
},
groups_v2::{AccessControl, Group, GroupChange, PendingMember, RequestingMember, Timer},
models::Contact,
prelude::{
phonenumber::{self, PhoneNumber},
Expand Down

0 comments on commit 07d4c69

Please sign in to comment.