Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F32088492
D15549.1765007492.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
D15549.1765007492.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D15549: [native] implement CXX bindings to Vodozemac
Attached
Detach File
Event Timeline
Log In to Comment