diff --git a/native/native_rust_library/Cargo.lock b/native/native_rust_library/Cargo.lock --- a/native/native_rust_library/Cargo.lock +++ b/native/native_rust_library/Cargo.lock @@ -1418,6 +1418,7 @@ name = "native_rust_library" version = "0.1.0" dependencies = [ + "anyhow", "argon2", "backup_client", "base64 0.21.7", @@ -1431,6 +1432,7 @@ "regex", "serde", "serde_json", + "sha2", "siwe", "tokio", "tokio-util", @@ -2870,7 +2872,7 @@ [[package]] name = "vodozemac" version = "0.9.0" -source = "git+https://github.com/CommE2E/vodozemac#3c142a35f114fcc9edb9dc766b051716c5160150" +source = "git+https://github.com/CommE2E/vodozemac?branch=x3dh-test#5a4c8ed45d6a2aa1c91f9bcdb2e567895b76a2f5" dependencies = [ "aes", "arrayvec", diff --git a/native/native_rust_library/Cargo.toml b/native/native_rust_library/Cargo.toml --- a/native/native_rust_library/Cargo.toml +++ b/native/native_rust_library/Cargo.toml @@ -21,7 +21,9 @@ grpc_clients = { path = "../../shared/grpc_clients" } base64 = "0.21" regex = "1.10" -vodozemac = { git = "https://github.com/CommE2E/vodozemac", features = ["libolm-compat"] } +vodozemac = { git = "https://github.com/CommE2E/vodozemac", branch = "x3dh-test", features = ["libolm-compat"] } +anyhow = "1.0.97" +sha2 = "0.10" [target.'cfg(target_os = "android")'.dependencies] backup_client = { path = "../../shared/backup_client", default-features = false, features = [ diff --git a/native/native_rust_library/build.rs b/native/native_rust_library/build.rs --- a/native/native_rust_library/build.rs +++ b/native/native_rust_library/build.rs @@ -197,7 +197,7 @@ .expect("Couldn't write backup service config"); println!("cargo:rerun-if-changed=src/lib.rs"); - println!("cargo:rerun-if-changed=src/session.rs"); + println!("cargo:rerun-if-changed=src/vodozemac.rs"); println!("cargo:rerun-if-changed={}", IdentityServiceConfig::FILEPATH); println!("cargo:rerun-if-changed={}", BackupServiceConfig::FILEPATH); } diff --git a/native/native_rust_library/src/lib.rs b/native/native_rust_library/src/lib.rs --- a/native/native_rust_library/src/lib.rs +++ b/native/native_rust_library/src/lib.rs @@ -10,12 +10,16 @@ mod backup; mod constants; mod identity; -mod session; mod utils; +mod vodozemac; use crate::argon2_tools::compute_backup_key_str; use crate::utils::jsi_callbacks::handle_string_result_as_callback; -use session::{session_from_pickle, EncryptResult, VodozemacSession}; +use vodozemac::{ + account_from_pickle, account_new, encrypt_result_new, session_from_pickle, + sha256, verify_ed25519_signature, EncryptResult, InboundCreationResult, + VodozemacAccount, VodozemacSession, +}; mod generated { // We get the CODE_VERSION from this generated file @@ -571,16 +575,25 @@ extern "Rust" { // NOTE: Keep in sync with Vodozemac crypto functions block // in native/vodozemac_bindings/src/lib.rs. - #[cfg(target_os = "android")] - type VodozemacSession; + + // EncryptResult type #[cfg(target_os = "android")] type EncryptResult; #[cfg(target_os = "android")] - fn pickle(self: &VodozemacSession, pickle_key: &[u8; 32]) -> String; + fn encrypt_result_new( + encrypted_message: String, + message_type: u32, + ) -> Box; #[cfg(target_os = "android")] fn encrypted_message(self: &EncryptResult) -> String; #[cfg(target_os = "android")] fn message_type(self: &EncryptResult) -> u32; + + // VodozemacSession type + #[cfg(target_os = "android")] + type VodozemacSession; + #[cfg(target_os = "android")] + fn pickle(self: &VodozemacSession, pickle_key: &[u8; 32]) -> String; #[cfg(target_os = "android")] fn encrypt( self: &mut VodozemacSession, @@ -592,12 +605,93 @@ encrypted_message: String, message_type: u32, ) -> Result; + #[cfg(target_os = "android")] + fn has_received_message(self: &VodozemacSession) -> bool; + #[cfg(target_os = "android")] + fn is_sender_chain_empty(self: &VodozemacSession) -> bool; #[cfg(target_os = "android")] pub fn session_from_pickle( session_state: String, session_key: String, ) -> Result>; + + // VodozemacAccount type + #[cfg(target_os = "android")] + type VodozemacAccount; + #[cfg(target_os = "android")] + fn pickle(self: &VodozemacAccount, pickle_key: &[u8; 32]) -> String; + #[cfg(target_os = "android")] + fn ed25519_key(self: &VodozemacAccount) -> String; + #[cfg(target_os = "android")] + fn curve25519_key(self: &VodozemacAccount) -> String; + #[cfg(target_os = "android")] + fn sign(self: &VodozemacAccount, message: &str) -> String; + #[cfg(target_os = "android")] + fn generate_one_time_keys(self: &mut VodozemacAccount, count: usize); + #[cfg(target_os = "android")] + fn one_time_keys(self: &VodozemacAccount) -> Vec; + #[cfg(target_os = "android")] + fn mark_keys_as_published(self: &mut VodozemacAccount); + #[cfg(target_os = "android")] + fn max_number_of_one_time_keys(self: &VodozemacAccount) -> usize; + #[cfg(target_os = "android")] + fn mark_prekey_as_published(self: &mut VodozemacAccount) -> bool; + #[cfg(target_os = "android")] + fn generate_prekey(self: &mut VodozemacAccount) -> bool; + #[cfg(target_os = "android")] + fn forget_old_prekey(self: &mut VodozemacAccount); + #[cfg(target_os = "android")] + fn last_prekey_publish_time(self: &mut VodozemacAccount) -> u64; + #[cfg(target_os = "android")] + fn prekey(self: &VodozemacAccount) -> String; + #[cfg(target_os = "android")] + fn unpublished_prekey(self: &VodozemacAccount) -> String; + #[cfg(target_os = "android")] + fn prekey_signature(self: &VodozemacAccount) -> String; + #[cfg(target_os = "android")] + fn create_outbound_session( + self: &VodozemacAccount, + identity_key: &str, + signing_key: &str, + one_time_key: &str, + pre_key: &str, + pre_key_signature: &str, + olm_compatibility_mode: bool, + ) -> Result>; + #[cfg(target_os = "android")] + fn create_inbound_session( + self: &mut VodozemacAccount, + identity_key: &str, + message: &EncryptResult, + ) -> Result>; + + #[cfg(target_os = "android")] + pub fn account_new() -> Box; + + #[cfg(target_os = "android")] + pub fn account_from_pickle( + account_state: String, + session_key: String, + ) -> Result>; + + #[cfg(target_os = "android")] + pub fn verify_ed25519_signature( + public_key: &str, + message: &str, + signature: &str, + ) -> Result<()>; + + #[cfg(target_os = "android")] + pub fn sha256(input: &[u8]) -> String; + + // InboundCreationResult type + #[cfg(target_os = "android")] + type InboundCreationResult; + #[cfg(target_os = "android")] + fn plaintext(self: &InboundCreationResult) -> String; + #[cfg(target_os = "android")] + fn take_session(self: &mut InboundCreationResult) -> Box; } } diff --git a/native/native_rust_library/src/session.rs b/native/native_rust_library/src/session.rs deleted file mode 100644 --- a/native/native_rust_library/src/session.rs +++ /dev/null @@ -1,114 +0,0 @@ -use vodozemac::olm::{Session, SessionPickle}; -use vodozemac::{olm, PickleError}; - -pub struct VodozemacSession(pub(crate) vodozemac::olm::Session); - -impl From for VodozemacSession { - fn from(session: Session) -> Self { - VodozemacSession(session) - } -} - -pub struct EncryptResult { - pub encrypted_message: String, - pub message_type: u32, -} - -impl EncryptResult { - pub fn encrypted_message(&self) -> String { - self.encrypted_message.clone() - } - - pub fn message_type(&self) -> u32 { - self.message_type - } -} - -impl VodozemacSession { - pub fn pickle(&self, pickle_key: &[u8; 32]) -> String { - self.0.pickle().encrypt(pickle_key) - } - - pub fn encrypt( - &mut self, - plaintext: &str, - ) -> Result, String> { - let olm_message = self.0.encrypt(plaintext.as_bytes()); - - let (message_type, encrypted_message) = match olm_message { - olm::OlmMessage::Normal(msg) => (1, msg.to_base64()), - olm::OlmMessage::PreKey(msg) => (0, msg.to_base64()), - }; - - Ok(Box::from(EncryptResult { - encrypted_message, - message_type: message_type as u32, - })) - } - - pub fn decrypt( - &mut self, - encrypted_message: String, - message_type: u32, - ) -> Result { - let olm_message: vodozemac::olm::OlmMessage = match message_type { - 0 => olm::PreKeyMessage::from_base64(encrypted_message.as_str()) - .map_err(|e| e.to_string())? - .into(), - 1 => olm::Message::from_base64(encrypted_message.as_str()) - .map_err(|e| e.to_string())? - .into(), - _ => return Err("wrong message type".to_string()), - }; - - let result = self.0.decrypt(&olm_message).map_err(|e| e.to_string())?; - let plaintext = String::from_utf8(result).expect("Invalid UTF-8"); - - Ok(plaintext) - } -} - -pub fn session_from_pickle( - session_state: String, - session_key: String, -) -> Result, String> { - let key_bytes = session_key.as_bytes(); - - //NOTE: vvodozemac works only with 32-byte keys. - // We have sessions pickled with 64-byte keys. Additionally, this key - // is used in backup, so it can't simply be migrated. Instead, we're going - // to just use the first 32 bytes of the existing secret key. - let key: &[u8; 32] = &key_bytes[0..32] - .try_into() - .expect("String must be at least 32 bytes"); - - let session_pickle = - match SessionPickle::from_encrypted(session_state.as_str(), key) { - Ok(pickle) => Some(pickle), - Err(e) => { - match e { - PickleError::Base64(base64_error) => { - return Err(base64_error.to_string()); - } - //TODO: Use only specific error type - PickleError::Decryption(_) => { - println!("Decryption error, will try from_libolm_pickle"); - None - } - PickleError::Serialization(serialization_error) => { - return Err(serialization_error.to_string()); - } - } - } - }; - - let session: VodozemacSession = if let Some(pickle) = session_pickle { - Session::from_pickle(pickle).into() - } else { - Session::from_libolm_pickle(&session_state, session_key.as_bytes()) - .map_err(|e| e.to_string())? - .into() - }; - - Ok(Box::from(session)) -} diff --git a/native/native_rust_library/src/vodozemac.rs b/native/native_rust_library/src/vodozemac.rs new file mode 100644 --- /dev/null +++ b/native/native_rust_library/src/vodozemac.rs @@ -0,0 +1,395 @@ +use sha2::{Digest, Sha256}; +use vodozemac::olm::{Account, AccountPickle, Session, SessionPickle}; +use vodozemac::{olm, PickleError}; + +pub struct VodozemacSession(pub(crate) vodozemac::olm::Session); + +impl From for VodozemacSession { + fn from(session: Session) -> Self { + VodozemacSession(session) + } +} + +pub struct EncryptResult { + pub encrypted_message: String, + pub message_type: u32, +} + +pub fn encrypt_result_new( + encrypted_message: String, + message_type: u32, +) -> Box { + Box::new(EncryptResult { + encrypted_message, + message_type, + }) +} + +impl EncryptResult { + pub fn encrypted_message(&self) -> String { + self.encrypted_message.clone() + } + + pub fn message_type(&self) -> u32 { + self.message_type + } +} + +impl TryFrom<&EncryptResult> for olm::OlmMessage { + type Error = anyhow::Error; + + fn try_from(message: &EncryptResult) -> Result { + match message.message_type { + 0 => { + let prekey = + olm::PreKeyMessage::from_base64(&message.encrypted_message)?; + Ok(prekey.into()) + } + 1 => { + let msg = olm::Message::from_base64(&message.encrypted_message)?; + Ok(msg.into()) + } + _ => anyhow::bail!("Invalid message type: {}", message.message_type), + } + } +} + +impl VodozemacSession { + pub fn pickle(&self, pickle_key: &[u8; 32]) -> String { + self.0.pickle().encrypt(pickle_key) + } + + pub fn encrypt( + &mut self, + plaintext: &str, + ) -> Result, String> { + let olm_message = self.0.encrypt(plaintext.as_bytes()); + + let (message_type, encrypted_message) = match olm_message { + olm::OlmMessage::Normal(msg) => (1, msg.to_base64()), + olm::OlmMessage::PreKey(msg) => (0, msg.to_base64()), + }; + + Ok(Box::from(EncryptResult { + encrypted_message, + message_type: message_type as u32, + })) + } + + pub fn decrypt( + &mut self, + encrypted_message: String, + message_type: u32, + ) -> Result { + let olm_message: vodozemac::olm::OlmMessage = match message_type { + 0 => olm::PreKeyMessage::from_base64(encrypted_message.as_str()) + .map_err(|e| e.to_string())? + .into(), + 1 => olm::Message::from_base64(encrypted_message.as_str()) + .map_err(|e| e.to_string())? + .into(), + _ => return Err("wrong message type".to_string()), + }; + + let result = self.0.decrypt(&olm_message).map_err(|e| e.to_string())?; + let plaintext = String::from_utf8(result).expect("Invalid UTF-8"); + + Ok(plaintext) + } + + pub fn has_received_message(&self) -> bool { + self.0.has_received_message() + } + + pub fn is_sender_chain_empty(&self) -> bool { + self.0.is_sender_chain_empty() + } +} + +pub fn session_from_pickle( + session_state: String, + session_key: String, +) -> Result, String> { + let key_bytes = session_key.as_bytes(); + + //NOTE: vvodozemac works only with 32-byte keys. + // We have sessions pickled with 64-byte keys. Additionally, this key + // is used in backup, so it can't simply be migrated. Instead, we're going + // to just use the first 32 bytes of the existing secret key. + let key: &[u8; 32] = &key_bytes[0..32] + .try_into() + .expect("String must be at least 32 bytes"); + + let session_pickle = + match SessionPickle::from_encrypted(session_state.as_str(), key) { + Ok(pickle) => Some(pickle), + Err(e) => match e { + PickleError::Base64(base64_error) => { + return Err(base64_error.to_string()); + } + PickleError::Decryption(_) => { + println!("Decryption error, will try from_libolm_pickle"); + None + } + PickleError::Serialization(serialization_error) => { + return Err(serialization_error.to_string()); + } + }, + }; + + let session: VodozemacSession = if let Some(pickle) = session_pickle { + Session::from_pickle(pickle).into() + } else { + Session::from_libolm_pickle(&session_state, session_key.as_bytes()) + .map_err(|e| e.to_string())? + .into() + }; + + Ok(Box::from(session)) +} + +pub struct VodozemacAccount(pub(crate) vodozemac::olm::Account); + +impl From for VodozemacAccount { + fn from(account: Account) -> Self { + VodozemacAccount(account) + } +} + +pub struct InboundCreationResult { + session: Option, + plaintext: String, +} + +impl From for InboundCreationResult { + fn from(result: vodozemac::olm::InboundCreationResult) -> Self { + InboundCreationResult { + session: Some(VodozemacSession(result.session)), + plaintext: String::from_utf8(result.plaintext) + .expect("Invalid UTF-8 in plaintext"), + } + } +} + +impl InboundCreationResult { + pub fn plaintext(&self) -> String { + self.plaintext.clone() + } + + pub fn take_session(&mut self) -> Box { + Box::new(self.session.take().expect("Session has already been taken")) + } +} + +impl VodozemacAccount { + pub fn pickle(&self, pickle_key: &[u8; 32]) -> String { + self.0.pickle().encrypt(pickle_key) + } + + pub fn ed25519_key(&self) -> String { + self.0.ed25519_key().to_base64() + } + + pub fn curve25519_key(&self) -> String { + self.0.curve25519_key().to_base64() + } + + pub fn sign(&self, message: &str) -> String { + self.0.sign(message).to_base64() + } + + pub fn generate_one_time_keys(&mut self, count: usize) { + self.0.generate_one_time_keys(count); + } + + pub fn one_time_keys(&self) -> Vec { + self + .0 + .one_time_keys() + .into_values() + .map(|v| v.to_base64()) + .collect() + } + + pub fn mark_keys_as_published(&mut self) { + self.0.mark_keys_as_published() + } + + pub fn max_number_of_one_time_keys(&self) -> usize { + self.0.max_number_of_one_time_keys() + } + + pub fn mark_prekey_as_published(&mut self) -> bool { + self.0.mark_prekey_as_published() + } + + pub fn generate_prekey(&mut self) -> bool { + self.0.generate_prekey() + } + + pub fn forget_old_prekey(&mut self) { + self.0.forget_old_prekey() + } + + pub fn last_prekey_publish_time(&mut self) -> u64 { + self.0.get_last_prekey_publish_time() + } + + pub fn prekey(&self) -> String { + self + .0 + .prekey() + .map(|key| key.to_base64()) + .unwrap_or_default() + } + + pub fn unpublished_prekey(&self) -> String { + self + .0 + .unpublished_prekey() + .map(|key| key.to_base64()) + .unwrap_or_default() + } + + pub fn prekey_signature(&self) -> String { + self.0.get_prekey_signature().unwrap_or_default() + } + + pub fn create_outbound_session( + &self, + identity_key: &str, + signing_key: &str, + one_time_key: &str, + pre_key: &str, + pre_key_signature: &str, + olm_compatibility_mode: bool, + ) -> Result, String> { + let session_config = vodozemac::olm::SessionConfig::version_1(); + let identity_key = + vodozemac::Curve25519PublicKey::from_base64(identity_key) + .map_err(|e| e.to_string())?; + let signing_key = vodozemac::Ed25519PublicKey::from_base64(signing_key) + .map_err(|e| e.to_string())?; + let one_time_key = if one_time_key.is_empty() { + None + } else { + Some( + vodozemac::Curve25519PublicKey::from_base64(one_time_key) + .map_err(|e| e.to_string())?, + ) + }; + let pre_key = vodozemac::Curve25519PublicKey::from_base64(pre_key) + .map_err(|e| e.to_string())?; + + let session = self + .0 + .create_outbound_session( + session_config, + identity_key, + signing_key, + one_time_key, + pre_key, + pre_key_signature.to_string(), + olm_compatibility_mode, + ) + .map_err(|e| e.to_string())?; + + Ok(Box::new(VodozemacSession(session))) + } + + pub fn create_inbound_session( + &mut self, + identity_key: &str, + message: &EncryptResult, + ) -> Result, String> { + let identity_key = + vodozemac::Curve25519PublicKey::from_base64(identity_key) + .map_err(|e| e.to_string())?; + let olm_message: olm::OlmMessage = message + .try_into() + .map_err(|e: anyhow::Error| e.to_string())?; + + if let olm::OlmMessage::PreKey(message) = olm_message { + Ok(Box::new( + self + .0 + .create_inbound_session(identity_key, &message) + .map_err(|e| e.to_string())? + .into(), + )) + } else { + Err("Invalid message type, a pre-key message is required".to_string()) + } + } +} + +pub fn account_new() -> Box { + let account = Account::new(); + Box::new(VodozemacAccount(account)) +} + +pub fn account_from_pickle( + account_state: String, + account_key: String, +) -> Result, String> { + let key_bytes = account_key.as_bytes(); + + //NOTE: vodozemac works only with 32-byte keys. + // We have sessions pickled with 64-byte keys. Additionally, this key + // is used in backup, so it can't simply be migrated. Instead, we're going + // to just use the first 32 bytes of the existing secret key. + let key: &[u8; 32] = &key_bytes[0..32] + .try_into() + .expect("String must be at least 32 bytes"); + + let account_pickle = + match AccountPickle::from_encrypted(account_state.as_str(), key) { + Ok(pickle) => Some(pickle), + Err(e) => match e { + PickleError::Base64(base64_error) => { + return Err(base64_error.to_string()); + } + PickleError::Decryption(_) => { + println!("Decryption error, will try from_libolm_pickle"); + None + } + PickleError::Serialization(serialization_error) => { + return Err(serialization_error.to_string()); + } + }, + }; + + let account: VodozemacAccount = if let Some(pickle) = account_pickle { + Account::from_pickle(pickle).into() + } else { + Account::from_libolm_pickle(&account_state, account_key.as_bytes()) + .map_err(|e| e.to_string())? + .into() + }; + + Ok(Box::from(account)) +} + +pub fn verify_ed25519_signature( + public_key: &str, + message: &str, + signature: &str, +) -> Result<(), String> { + let public_key = vodozemac::Ed25519PublicKey::from_base64(public_key) + .map_err(|e| e.to_string())?; + + let signature = vodozemac::Ed25519Signature::from_base64(signature) + .map_err(|e| e.to_string())?; + + public_key + .verify(message.as_bytes(), &signature) + .map_err(|e| e.to_string()) +} + +pub fn sha256(input: &[u8]) -> String { + let mut hasher = Sha256::new(); + hasher.update(&input); + let hash = hasher.finalize(); + + vodozemac::base64_encode(hash) +} diff --git a/native/vodozemac_bindings/Cargo.lock b/native/vodozemac_bindings/Cargo.lock --- a/native/vodozemac_bindings/Cargo.lock +++ b/native/vodozemac_bindings/Cargo.lock @@ -897,7 +897,7 @@ [[package]] name = "vodozemac" version = "0.9.0" -source = "git+https://github.com/CommE2E/vodozemac#3c142a35f114fcc9edb9dc766b051716c5160150" +source = "git+https://github.com/CommE2E/vodozemac?branch=x3dh-test#5a4c8ed45d6a2aa1c91f9bcdb2e567895b76a2f5" dependencies = [ "aes", "arrayvec", @@ -934,6 +934,7 @@ "regex", "serde", "serde_json", + "sha2", "vodozemac", ] diff --git a/native/vodozemac_bindings/Cargo.toml b/native/vodozemac_bindings/Cargo.toml --- a/native/vodozemac_bindings/Cargo.toml +++ b/native/vodozemac_bindings/Cargo.toml @@ -5,11 +5,12 @@ [dependencies] cxx = "=1.0.75" -vodozemac = { git = "https://github.com/CommE2E/vodozemac", features = ["libolm-compat"] } +vodozemac = { git = "https://github.com/CommE2E/vodozemac", branch = "x3dh-test", features = ["libolm-compat"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" derive_more = "0.99" anyhow = "1.0.97" +sha2 = "0.10" [build-dependencies] cxx-build = "=1.0.75" diff --git a/native/vodozemac_bindings/build.rs b/native/vodozemac_bindings/build.rs --- a/native/vodozemac_bindings/build.rs +++ b/native/vodozemac_bindings/build.rs @@ -3,4 +3,5 @@ cxx_build::bridge("src/lib.rs").flag_if_supported("-std=c++17"); println!("cargo:rerun-if-changed=src/lib.rs"); + println!("cargo:rerun-if-changed=src/vodozemac.rs"); } diff --git a/native/vodozemac_bindings/src/lib.rs b/native/vodozemac_bindings/src/lib.rs --- a/native/vodozemac_bindings/src/lib.rs +++ b/native/vodozemac_bindings/src/lib.rs @@ -1,10 +1,10 @@ use std::error::Error as StdError; -mod session; +mod vodozemac; -use session::{session_from_pickle, VodozemacSession}; +use vodozemac::{session_from_pickle, VodozemacSession}; -use crate::session::*; +use crate::vodozemac::*; #[cxx::bridge] pub mod ffi { @@ -13,11 +13,18 @@ // NOTE: Keep in sync with Vodozemac crypto functions block // in native/native_rust_library/src/lib.rs extern "Rust" { - type VodozemacSession; + // EncryptResult type type EncryptResult; - fn pickle(self: &VodozemacSession, pickle_key: &[u8; 32]) -> String; + fn encrypt_result_new( + encrypted_message: String, + message_type: u32, + ) -> Box; fn encrypted_message(self: &EncryptResult) -> String; fn message_type(self: &EncryptResult) -> u32; + + // VodozemacSession type + type VodozemacSession; + fn pickle(self: &VodozemacSession, pickle_key: &[u8; 32]) -> String; fn encrypt( self: &mut VodozemacSession, plaintext: &str, @@ -27,11 +34,65 @@ encrypted_message: String, message_type: u32, ) -> Result; + fn has_received_message(self: &VodozemacSession) -> bool; + fn is_sender_chain_empty(self: &VodozemacSession) -> bool; pub fn session_from_pickle( session_state: String, session_key: String, ) -> Result>; + + // VodozemacAccount type + type VodozemacAccount; + fn pickle(self: &VodozemacAccount, pickle_key: &[u8; 32]) -> String; + fn ed25519_key(self: &VodozemacAccount) -> String; + fn curve25519_key(self: &VodozemacAccount) -> String; + fn sign(self: &VodozemacAccount, message: &str) -> String; + fn generate_one_time_keys(self: &mut VodozemacAccount, count: usize); + fn one_time_keys(self: &VodozemacAccount) -> Vec; + fn mark_keys_as_published(self: &mut VodozemacAccount); + fn max_number_of_one_time_keys(self: &VodozemacAccount) -> usize; + fn mark_prekey_as_published(self: &mut VodozemacAccount) -> bool; + fn generate_prekey(self: &mut VodozemacAccount) -> bool; + fn forget_old_prekey(self: &mut VodozemacAccount); + fn last_prekey_publish_time(self: &mut VodozemacAccount) -> u64; + fn prekey(self: &VodozemacAccount) -> String; + fn unpublished_prekey(self: &VodozemacAccount) -> String; + fn prekey_signature(self: &VodozemacAccount) -> String; + fn create_outbound_session( + self: &VodozemacAccount, + identity_key: &str, + signing_key: &str, + one_time_key: &str, + pre_key: &str, + pre_key_signature: &str, + olm_compatibility_mode: bool, + ) -> Result>; + fn create_inbound_session( + self: &mut VodozemacAccount, + identity_key: &str, + message: &EncryptResult, + ) -> Result>; + + pub fn account_new() -> Box; + + pub fn account_from_pickle( + account_state: String, + session_key: String, + ) -> Result>; + + pub fn verify_ed25519_signature( + public_key: &str, + message: &str, + signature: &str, + ) -> Result<()>; + + pub fn sha256(input: &[u8]) -> String; + + // InboundCreationResult type + type InboundCreationResult; + fn plaintext(self: &InboundCreationResult) -> String; + fn take_session(self: &mut InboundCreationResult) -> Box; } } diff --git a/native/vodozemac_bindings/src/session.rs b/native/vodozemac_bindings/src/session.rs deleted file mode 120000 --- a/native/vodozemac_bindings/src/session.rs +++ /dev/null @@ -1 +0,0 @@ -../../native_rust_library/src/session.rs \ No newline at end of file diff --git a/native/vodozemac_bindings/src/vodozemac.rs b/native/vodozemac_bindings/src/vodozemac.rs new file mode 120000 --- /dev/null +++ b/native/vodozemac_bindings/src/vodozemac.rs @@ -0,0 +1 @@ +../../native_rust_library/src/vodozemac.rs \ No newline at end of file