Page MenuHomePhorge

D15549.1765007492.diff
No OneTemporary

Size
26 KB
Referenced Files
None
Subscribers
None

D15549.1765007492.diff

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<EncryptResult>;
#[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<String>;
+ #[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<Box<VodozemacSession>>;
+
+ // 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<String>;
+ #[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<Box<VodozemacSession>>;
+ #[cfg(target_os = "android")]
+ fn create_inbound_session(
+ self: &mut VodozemacAccount,
+ identity_key: &str,
+ message: &EncryptResult,
+ ) -> Result<Box<InboundCreationResult>>;
+
+ #[cfg(target_os = "android")]
+ pub fn account_new() -> Box<VodozemacAccount>;
+
+ #[cfg(target_os = "android")]
+ pub fn account_from_pickle(
+ account_state: String,
+ session_key: String,
+ ) -> Result<Box<VodozemacAccount>>;
+
+ #[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<VodozemacSession>;
}
}
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<Session> 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<Box<EncryptResult>, 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<String, String> {
- 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<Box<VodozemacSession>, 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<Session> 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<EncryptResult> {
+ 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<Self, Self::Error> {
+ 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<Box<EncryptResult>, 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<String, String> {
+ 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<Box<VodozemacSession>, 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<Account> for VodozemacAccount {
+ fn from(account: Account) -> Self {
+ VodozemacAccount(account)
+ }
+}
+
+pub struct InboundCreationResult {
+ session: Option<VodozemacSession>,
+ plaintext: String,
+}
+
+impl From<vodozemac::olm::InboundCreationResult> 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<VodozemacSession> {
+ 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<String> {
+ 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<Box<VodozemacSession>, 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<Box<InboundCreationResult>, 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<VodozemacAccount> {
+ let account = Account::new();
+ Box::new(VodozemacAccount(account))
+}
+
+pub fn account_from_pickle(
+ account_state: String,
+ account_key: String,
+) -> Result<Box<VodozemacAccount>, 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<EncryptResult>;
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<String>;
+ 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<Box<VodozemacSession>>;
+
+ // 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<String>;
+ 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<Box<VodozemacSession>>;
+ fn create_inbound_session(
+ self: &mut VodozemacAccount,
+ identity_key: &str,
+ message: &EncryptResult,
+ ) -> Result<Box<InboundCreationResult>>;
+
+ pub fn account_new() -> Box<VodozemacAccount>;
+
+ pub fn account_from_pickle(
+ account_state: String,
+ session_key: String,
+ ) -> Result<Box<VodozemacAccount>>;
+
+ 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<VodozemacSession>;
}
}
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

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 6, 7:51 AM (22 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5834069
Default Alt Text
D15549.1765007492.diff (26 KB)

Event Timeline