From b158ff7ab6470211ee041591c6264d8f2112d26f Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 11 Aug 2020 18:20:35 -0400 Subject: [PATCH 01/19] Initialize repository --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..7335050452 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# libsignal-jni From b03ce6bf01b757c6657867dee1a3264b5acbe570 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 11 Aug 2020 18:33:52 -0400 Subject: [PATCH 02/19] Initial commit --- .gitignore | 2 + Cargo.toml | 17 ++ src/lib.rs | 819 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/util.rs | 407 ++++++++++++++++++++++++++ 4 files changed, 1245 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 src/lib.rs create mode 100644 src/util.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..96ef6c0b94 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000000..4cce622f70 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "libsignal-jni" +version = "0.1.0" +authors = ["Jack Lloyd "] +edition = "2018" + +[lib] +name = "signal_jni" +crate-type = ["dylib"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +libsignal-protocol-rust = { path = "../libsignal-protocol-rust" } +#libsignal-protocol-rust = { git = "https://github.com/signalapp/libsignal-protocol-rust" } +jni = "0.17" +rand = "0.7.3" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000000..388e91f504 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,819 @@ +#![allow(clippy::missing_safety_doc)] + +use jni::objects::{JClass, JString}; +use jni::sys::{jboolean, jbyteArray, jint, jlong, jstring}; +use jni::JNIEnv; +use libsignal_protocol_rust::*; +use std::convert::TryFrom; + +mod util; + +use crate::util::*; + +struct SeedAndIteration { + seed: Vec, + iteration: u32 +} + +impl SeedAndIteration { + fn new(seed: Vec, iteration: u32) -> Self { + Self { seed, iteration } + } + + fn seed(&self) -> Result, SignalProtocolError> { + Ok(self.seed.clone()) + } + + fn iteration(&self) -> Result { + Ok(self.iteration) + } +} + +/* SeedAndIteration (utility class) */ +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_util_SeedAndIteration_New( + env: JNIEnv, + _class: JClass, + seed: jbyteArray, + iteration: jint +) -> ObjectHandle { + run_ffi_safe(&env, || { + let seed = env.convert_byte_array(seed)?; + let iteration = jint_to_u32(iteration)?; + box_object::(Ok(SeedAndIteration::new(seed, iteration))) + }) +} + +jni_fn_destroy!(Java_org_signal_libsignal_util_SeedAndIteration_Destroy destroys SeedAndIteration); + +jni_fn_get_jint!(Java_org_signal_libsignal_util_SeedAndIteration_GetIteration(SeedAndIteration) using + |si: &SeedAndIteration| si.iteration()); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_util_SeedAndIteration_GetSeed(SeedAndIteration) using + |si: &SeedAndIteration| si.seed()); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_SignalProtocolAddress_New( + env: JNIEnv, + _class: JClass, + name: JString, + device_id: jint, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let name: String = env.get_string(name)?.into(); + let device_id = jint_to_u32(device_id)?; + let address = ProtocolAddress::new(name, device_id); + box_object::(Ok(address)) + }) +} + +jni_fn_destroy!(Java_org_signal_libsignal_SignalProtocolAddress_Destroy destroys ProtocolAddress); + +jni_fn_get_jstring!(Java_org_signal_libsignal_SignalProtocolAddress_Name(ProtocolAddress) using + |p: &ProtocolAddress| Ok(p.name().to_string())); + +jni_fn_get_jint!(Java_org_signal_libsignal_SignalProtocolAddress_DeviceId(ProtocolAddress) using + |obj: &ProtocolAddress| { Ok(obj.device_id()) }); + +jni_fn_deserialize!(Java_org_signal_libsignal_ecc_ECPublicKey_Deserialize is PublicKey::deserialize); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_ecc_ECPublicKey_Serialize(PublicKey) using + |k: &PublicKey| Ok(k.serialize())); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_ecc_ECPublicKey_Verify( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + message: jbyteArray, + signature: jbyteArray, +) -> jboolean { + run_ffi_safe(&env, || { + let key = native_handle_cast::(handle)?; + let message = env.convert_byte_array(message)?; + let signature = env.convert_byte_array(signature)?; + Ok(key.verify_signature(&message, &signature)? as jboolean) + }) +} + +jni_fn_destroy!(Java_org_signal_libsignal_ecc_ECPublicKey_Destroy destroys PublicKey); + +jni_fn_deserialize!(Java_org_signal_libsignal_ecc_ECPrivateKey_Deserialize is PrivateKey::deserialize); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_ecc_ECPrivateKey_Serialize(PrivateKey) using + |k: &PrivateKey| Ok(k.serialize())); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_ecc_ECPrivateKey_Sign( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + message: jbyteArray, +) -> jbyteArray { + run_ffi_safe(&env, || { + let message = env.convert_byte_array(message)?; + let key = native_handle_cast::(handle)?; + let mut rng = rand::rngs::OsRng; + let sig = key.calculate_signature(&message, &mut rng)?; + to_jbytearray(&env, Ok(sig)) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_ecc_ECPrivateKey_Agree( + env: JNIEnv, + _class: JClass, + private_key_handle: ObjectHandle, + public_key_handle: ObjectHandle, +) -> jbyteArray { + run_ffi_safe(&env, || { + let private_key = native_handle_cast::(private_key_handle)?; + let public_key = native_handle_cast::(public_key_handle)?; + let shared_secret = private_key.calculate_agreement(&public_key)?; + to_jbytearray(&env, Ok(shared_secret)) + }) +} + +jni_fn_destroy!(Java_org_signal_libsignal_ecc_ECPrivateKey_Destroy destroys PrivateKey); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_fingerprint_DisplayableFingerprint_Format( + env: JNIEnv, + _class: JClass, + local: jbyteArray, + remote: jbyteArray, +) -> jstring { + run_ffi_safe(&env, || { + let local = env.convert_byte_array(local)?; + let remote = env.convert_byte_array(remote)?; + let fingerprint = DisplayableFingerprint::new(&local, &remote)?; + let result = env.new_string(format!("{}", fingerprint))?; + Ok(result.into_inner()) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_fingerprint_NumericFingerprintGenerator_New( + env: JNIEnv, + _class: JClass, + iterations: jint, + version: jint, + local_identifier: jbyteArray, + local_key: jbyteArray, + remote_identifier: jbyteArray, + remote_key: jbyteArray, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let version = jint_to_u32(version)?; + let iterations = jint_to_u32(iterations)?; + + let local_identifier = env.convert_byte_array(local_identifier)?; + let local_key = env.convert_byte_array(local_key)?; + + let remote_identifier = env.convert_byte_array(remote_identifier)?; + let remote_key = env.convert_byte_array(remote_key)?; + + let local_key = IdentityKey::decode(&local_key)?; + let remote_key = IdentityKey::decode(&remote_key)?; + let fprint = Fingerprint::new( + version, + iterations, + &local_identifier, + &local_key, + &remote_identifier, + &remote_key, + )?; + + box_object::(Ok(fprint)) + }) +} + +jni_fn_destroy!(Java_org_signal_libsignal_fingerprint_NumericFingerprintGenerator_Destroy destroys Fingerprint); + +jni_fn_get_jstring!(Java_org_signal_libsignal_fingerprint_NumericFingerprintGenerator_GetDisplayString(Fingerprint) using + Fingerprint::display_string); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_fingerprint_NumericFingerprintGenerator_GetScannableEncoding(Fingerprint) using + |f: &Fingerprint| f.scannable.serialize()); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_fingerprint_ScannableFingerprint_Compare( + env: JNIEnv, + _class: JClass, + fprint1: jbyteArray, + fprint2: jbyteArray, +) -> jboolean { + run_ffi_safe(&env, || { + let fprint1 = env.convert_byte_array(fprint1)?; + let fprint2 = env.convert_byte_array(fprint2)?; + + let fprint1 = ScannableFingerprint::deserialize(&fprint1)?; + Ok(fprint1.compare(&fprint2)? as jboolean) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_kdf_HKDF_DeriveSecrets( + env: JNIEnv, + _class: JClass, + version: jint, + input_key_material: jbyteArray, + salt: jbyteArray, + info: jbyteArray, + output_length: jint, +) -> jbyteArray { + run_ffi_safe(&env, || { + let version = jint_to_u32(version)?; + let output_length = output_length as usize; + + let input_key_material = env.convert_byte_array(input_key_material)?; + + let salt = if salt.is_null() { + None + } else { + Some(env.convert_byte_array(salt)?) + }; + + let info = env.convert_byte_array(info)?; + + let hkdf = HKDF::new(version)?; + let derived = if let Some(salt) = salt { + hkdf.derive_salted_secrets(&input_key_material, &salt, &info, output_length) + } else { + hkdf.derive_secrets(&input_key_material, &info, output_length) + }; + + to_jbytearray(&env, derived) + }) +} + +jni_fn_deserialize!(Java_org_signal_libsignal_protocol_SignalMessage_Deserialize is SignalMessage::try_from); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SignalMessage_New( + env: JNIEnv, + _class: JClass, + message_version: jint, + mac_key: jbyteArray, + sender_ratchet_key: ObjectHandle, + counter: jint, + previous_counter: jint, + ciphertext: jbyteArray, + sender_identity_key: ObjectHandle, + receiver_identity_key: ObjectHandle, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let message_version = jint_to_u8(message_version)?; + let mac_key = env.convert_byte_array(mac_key)?; + let sender_ratchet_key = native_handle_cast::(sender_ratchet_key)?; + let counter = jint_to_u32(counter)?; + let previous_counter = jint_to_u32(previous_counter)?; + let ciphertext = env.convert_byte_array(ciphertext)?; + + let sender_identity_key = native_handle_cast::(sender_identity_key)?; + let receiver_identity_key = native_handle_cast::(receiver_identity_key)?; + + let msg = SignalMessage::new( + message_version, + &mac_key, + *sender_ratchet_key, + counter, + previous_counter, + &ciphertext, + &IdentityKey::new(*sender_identity_key), + &IdentityKey::new(*receiver_identity_key), + )?; + + box_object::(Ok(msg)) + }) +} + +jni_fn_destroy!(Java_org_signal_libsignal_protocol_SignalMessage_Destroy destroys SignalMessage); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SignalMessage_GetSenderRatchetKey(SignalMessage) using + |m: &SignalMessage| Ok(m.sender_ratchet_key().serialize())); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SignalMessage_GetBody(SignalMessage) using + |m: &SignalMessage| Ok(m.body().to_vec())); +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SignalMessage_GetSerialized(SignalMessage) using + |m: &SignalMessage| Ok(m.serialized().to_vec())); + +jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SignalMessage_GetMessageVersion(SignalMessage) using + |msg: &SignalMessage| { Ok(msg.message_version() as u32) }); + +jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SignalMessage_GetCounter(SignalMessage) using + |msg: &SignalMessage| { Ok(msg.counter()) }); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SignalMessage_VerifyMac( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + sender_identity_key: ObjectHandle, + receiver_identity_key: ObjectHandle, + mac_key: jbyteArray, +) -> jboolean { + run_ffi_safe(&env, || { + let msg = native_handle_cast::(handle)?; + let sender_identity_key = native_handle_cast::(sender_identity_key)?; + let receiver_identity_key = native_handle_cast::(receiver_identity_key)?; + let mac_key = env.convert_byte_array(mac_key)?; + + let valid = msg.verify_mac( + &IdentityKey::new(*sender_identity_key), + &IdentityKey::new(*receiver_identity_key), + &mac_key, + )?; + + Ok(valid as jboolean) + }) +} + +jni_fn_deserialize!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_Deserialize is PreKeySignalMessage::try_from); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_PreKeySignalMessage_New( + env: JNIEnv, + _class: JClass, + message_version: jint, + registration_id: jint, + pre_key_id: jint, + signed_pre_key_id: jint, + base_key_handle: ObjectHandle, + identity_key_handle: ObjectHandle, + signal_message_handle: ObjectHandle, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let message_version = message_version as u8; + let registration_id = jint_to_u32(registration_id)?; + let pre_key_id = if pre_key_id < 0 { + None + } else { + Some(jint_to_u32(pre_key_id)?) + }; + let signed_pre_key_id = jint_to_u32(signed_pre_key_id)?; + let base_key = native_handle_cast::(base_key_handle)?; + let identity_key = native_handle_cast::(identity_key_handle)?; + let signal_message = native_handle_cast::(signal_message_handle)?; + + let msg = PreKeySignalMessage::new( + message_version, + registration_id, + pre_key_id, + signed_pre_key_id, + *base_key, + IdentityKey::new(*identity_key), + signal_message.clone(), + ); + box_object::(msg) + }) +} + +jni_fn_destroy!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_Destroy destroys PreKeySignalMessage); + +jni_fn_get_jint!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetVersion(PreKeySignalMessage) using + |m: &PreKeySignalMessage| Ok(m.message_version() as u32)); + +jni_fn_get_jint!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetRegistrationId(PreKeySignalMessage) using + |m: &PreKeySignalMessage| Ok(m.registration_id())); + +// Special logic to handle optionality: +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetPreKeyId( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, +) -> jint { + run_ffi_safe(&env, || { + let pksm = native_handle_cast::(handle)?; + match pksm.pre_key_id() { + Some(id) => jint_from_u32(Ok(id)), + None => Ok(-1 as jint), + } + }) +} + +jni_fn_get_jint!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetSignedPreKeyId(PreKeySignalMessage) using + |m: &PreKeySignalMessage| Ok(m.signed_pre_key_id())); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetBaseKey(PreKeySignalMessage) using + |m: &PreKeySignalMessage| Ok(m.base_key().serialize())); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetIdentityKey(PreKeySignalMessage) using + |m: &PreKeySignalMessage| Ok(m.identity_key().serialize())); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetSignalMessage(PreKeySignalMessage) using + |m: &PreKeySignalMessage| Ok(m.message().serialized().to_vec())); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetSerialized(PreKeySignalMessage) using + |m: &PreKeySignalMessage| Ok(m.serialized().to_vec())); + +jni_fn_deserialize!(Java_org_signal_libsignal_protocol_SenderKeyMessage_Deserialize is SenderKeyMessage::try_from); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SenderKeyMessage_New( + env: JNIEnv, + _class: JClass, + key_id: jint, + iteration: jint, + ciphertext: jbyteArray, + pk_handle: ObjectHandle, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let key_id = jint_to_u32(key_id)?; + let iteration = jint_to_u32(iteration)?; + let ciphertext = env.convert_byte_array(ciphertext)?; + let signature_key = native_handle_cast::(pk_handle)?; + let mut csprng = rand::rngs::OsRng; + let skm = SenderKeyMessage::new(key_id, iteration, &ciphertext, &mut csprng, signature_key); + box_object::(skm) + }) +} + +jni_fn_deserialize!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_Deserialize is SenderKeyDistributionMessage::try_from); + +jni_fn_destroy!(Java_org_signal_libsignal_protocol_SenderKeyMessage_Destroy destroys SenderKeyMessage); + +jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SenderKeyMessage_GetKeyId(SenderKeyMessage) using + |m: &SenderKeyMessage| Ok(m.key_id())); + +jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SenderKeyMessage_GetIteration(SenderKeyMessage) using + |m: &SenderKeyMessage| Ok(m.iteration())); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SenderKeyMessage_GetCipherText(SenderKeyMessage) using + |m: &SenderKeyMessage| Ok(m.ciphertext().to_vec())); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SenderKeyMessage_GetSerialized(SenderKeyMessage) using + |m: &SenderKeyMessage| Ok(m.serialized().to_vec())); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SenderKeyMessage_VerifySignature( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + pubkey_handle: ObjectHandle, +) -> jboolean { + run_ffi_safe(&env, || { + let skm = native_handle_cast::(handle)?; + let pubkey = native_handle_cast::(pubkey_handle)?; + let valid = skm.verify_signature(pubkey)?; + Ok(valid as jboolean) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_New( + env: JNIEnv, + _class: JClass, + key_id: jint, + iteration: jint, + chainkey: jbyteArray, + pk_handle: ObjectHandle, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let key_id = jint_to_u32(key_id)?; + let iteration = jint_to_u32(iteration)?; + let chainkey = env.convert_byte_array(chainkey)?; + let signature_key = native_handle_cast::(pk_handle)?; + let skdm = SenderKeyDistributionMessage::new(key_id, iteration, &chainkey, *signature_key); + box_object::(skdm) + }) +} + +jni_fn_destroy!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_Destroy destroys SenderKeyDistributionMessage); + +jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_GetId(SenderKeyDistributionMessage) using + |m: &SenderKeyDistributionMessage| m.id()); + +jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_GetIteration(SenderKeyDistributionMessage) using + |m: &SenderKeyDistributionMessage| m.iteration()); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_GetChainKey(SenderKeyDistributionMessage) using + |m: &SenderKeyDistributionMessage| Ok(m.chain_key()?.to_vec())); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_GetSignatureKey(SenderKeyDistributionMessage) using + |m: &SenderKeyDistributionMessage| Ok(m.signing_key()?.serialize())); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_GetSerialized(SenderKeyDistributionMessage) using + |m: &SenderKeyDistributionMessage| Ok(m.serialized().to_vec())); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_state_PreKeyBundle_New( + env: JNIEnv, + _class: JClass, + registration_id: jint, + device_id: jint, + prekey_id: jint, + prekey_handle: ObjectHandle, + signed_prekey_id: jint, + signed_prekey_handle: ObjectHandle, + signed_prekey_signature: jbyteArray, + identity_key_handle: ObjectHandle, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let registration_id = jint_to_u32(registration_id)?; + let device_id = jint_to_u32(device_id)?; + let signed_prekey_id = jint_to_u32(signed_prekey_id)?; + let signed_prekey = native_handle_cast::(signed_prekey_handle)?; + let signed_prekey_signature = env.convert_byte_array(signed_prekey_signature)?; + + let prekey = native_handle_cast_optional::(prekey_handle)?.map(|k| *k); + + let prekey_id = if prekey_id < 0 { + None + } else { + Some(jint_to_u32(prekey_id)?) + }; + + let identity_key = IdentityKey::new(*(identity_key_handle as *mut PublicKey)); + + let bundle = PreKeyBundle::new( + registration_id, + device_id, + prekey_id, + prekey, + signed_prekey_id, + *signed_prekey, + signed_prekey_signature, + identity_key, + ); + + box_object::(bundle) + }) +} + +jni_fn_destroy!(Java_org_signal_libsignal_state_PreKeyBundle_Destroy destroys PreKeyBundle); + +jni_fn_get_jint!(Java_org_signal_libsignal_state_PreKeyBundle_GetRegistrationId(PreKeyBundle) using + |m: &PreKeyBundle| m.registration_id()); + +jni_fn_get_jint!(Java_org_signal_libsignal_state_PreKeyBundle_GetDeviceId(PreKeyBundle) using + |m: &PreKeyBundle| m.device_id()); + +jni_fn_get_jint!(Java_org_signal_libsignal_state_PreKeyBundle_GetSignedPreKeyId(PreKeyBundle) using + |m: &PreKeyBundle| m.signed_pre_key_id()); + +// Special logic for optional here: +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_state_PreKeyBundle_GetPreKeyId( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, +) -> jint { + run_ffi_safe(&env, || { + let bundle = native_handle_cast::(handle)?; + match bundle.pre_key_id()? { + Some(prekey_id) => jint_from_u32(Ok(prekey_id)), + None => Ok(-1), + } + }) +} + +jni_fn_get_new_boxed_optional_obj!(Java_org_signal_libsignal_state_PreKeyBundle_GetPreKeyPublic(PublicKey) from PreKeyBundle, + |p: &PreKeyBundle| p.pre_key_public()); + +jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_PreKeyBundle_GetSignedPreKeyPublic(PublicKey) from PreKeyBundle, + |p: &PreKeyBundle| Ok(p.signed_pre_key_public()?)); + +jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_PreKeyBundle_GetIdentityKey(PublicKey) from PreKeyBundle, + |p: &PreKeyBundle| Ok(*p.identity_key()?.public_key())); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_state_PreKeyBundle_GetSignedPreKeySignature(PreKeyBundle) using + |m: &PreKeyBundle| Ok(m.signed_pre_key_signature()?.to_vec())); + +/* SignedPreKeyRecord */ + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_state_SignedPreKeyRecord_New( + env: JNIEnv, + _class: JClass, + id: jint, + timestamp: jlong, + pub_key_handle: ObjectHandle, + priv_key_handle: ObjectHandle, + signature: jbyteArray, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let pub_key = native_handle_cast::(pub_key_handle)?; + let priv_key = native_handle_cast::(priv_key_handle)?; + let id = jint_to_u32(id)?; + let timestamp = timestamp as u64; + let keypair = KeyPair::new(*pub_key, *priv_key); + let signature = env.convert_byte_array(signature)?; + + let spkr = SignedPreKeyRecord::new(id, timestamp, &keypair, &signature); + + box_object::(Ok(spkr)) + }) +} + +jni_fn_deserialize!(Java_org_signal_libsignal_state_SignedPreKeyRecord_Deserialize is SignedPreKeyRecord::deserialize); + +jni_fn_get_jint!(Java_org_signal_libsignal_state_SignedPreKeyRecord_GetId(SignedPreKeyRecord) using + |m: &SignedPreKeyRecord| m.id()); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_state_SignedPreKeyRecord_GetTimestamp( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, +) -> jlong { + run_ffi_safe(&env, || { + let spkr = native_handle_cast::(handle)?; + jlong_from_u64(spkr.timestamp()) + }) +} + +jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_SignedPreKeyRecord_GetPublicKey(PublicKey) from SignedPreKeyRecord, + |p: &SignedPreKeyRecord| p.public_key()); + +jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_SignedPreKeyRecord_GetPrivateKey(PrivateKey) from SignedPreKeyRecord, + |p: &SignedPreKeyRecord| p.private_key()); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_state_SignedPreKeyRecord_GetSignature(SignedPreKeyRecord) using + |m: &SignedPreKeyRecord| m.signature()); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_state_SignedPreKeyRecord_GetSerialized(SignedPreKeyRecord) using + |m: &SignedPreKeyRecord| m.serialize()); + +jni_fn_destroy!(Java_org_signal_libsignal_state_SignedPreKeyRecord_Destroy destroys SignedPreKeyRecord); + +/* PreKeyRecord */ + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_state_PreKeyRecord_New( + env: JNIEnv, + _class: JClass, + id: jint, + pub_key_handle: ObjectHandle, + priv_key_handle: ObjectHandle, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let id = jint_to_u32(id)?; + let pub_key = native_handle_cast::(pub_key_handle)?; + let priv_key = native_handle_cast::(priv_key_handle)?; + let keypair = KeyPair::new(*pub_key, *priv_key); + + let pkr = PreKeyRecord::new(id, &keypair); + + box_object::(Ok(pkr)) + }) +} + +jni_fn_deserialize!(Java_org_signal_libsignal_state_PreKeyRecord_Deserialize is PreKeyRecord::deserialize); + +jni_fn_get_jint!(Java_org_signal_libsignal_state_PreKeyRecord_GetId(PreKeyRecord) using + |m: &PreKeyRecord| m.id()); + +jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_PreKeyRecord_GetPublicKey(PublicKey) from PreKeyRecord, + |p: &PreKeyRecord| p.public_key()); + +jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_PreKeyRecord_GetPrivateKey(PrivateKey) from PreKeyRecord, + |p: &PreKeyRecord| p.private_key()); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_state_PreKeyRecord_GetSerialized(PreKeyRecord) using + |m: &PreKeyRecord| m.serialize()); + +jni_fn_destroy!(Java_org_signal_libsignal_state_PreKeyRecord_Destroy destroys PreKeyRecord); + +/* SenderKeyName */ + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_groups_SenderKeyName_New( + env: JNIEnv, + _class: JClass, + group_id: JString, + sender_name: JString, + sender_device_id: jint, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let group_id: String = env.get_string(group_id)?.into(); + let sender_name = env.get_string(sender_name)?.into(); + let sender_id = jint_to_u32(sender_device_id)?; + let name = SenderKeyName::new(group_id, ProtocolAddress::new(sender_name, sender_id)); + box_object::(name) + }) +} + +jni_fn_destroy!(Java_org_signal_libsignal_groups_SenderKeyName_Destroy destroys SenderKeyName); + +jni_fn_get_jstring!(Java_org_signal_libsignal_groups_SenderKeyName_GetGroupId(SenderKeyName) using + SenderKeyName::group_id); + +jni_fn_get_jstring!(Java_org_signal_libsignal_groups_SenderKeyName_GetSenderName(SenderKeyName) using + |skn: &SenderKeyName| { Ok(skn.sender()?.name().to_string()) }); + +jni_fn_get_jint!(Java_org_signal_libsignal_groups_SenderKeyName_GetSenderDeviceId(SenderKeyName) using + |m: &SenderKeyName| Ok(m.sender()?.device_id())); + + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeyState_New( + env: JNIEnv, + _class: JClass, + id: jint, + iteration: jint, + chain_key: jbyteArray, + signature_public: ObjectHandle, + signature_private: ObjectHandle, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let id = jint_to_u32(id)?; + let iteration = jint_to_u32(iteration)?; + let chain_key = env.convert_byte_array(chain_key)?; + let signature_public = native_handle_cast::(signature_public)?; + let signature_private = native_handle_cast_optional::(signature_private)?.map(|k| *k); + + let sks = SenderKeyState::new(id, iteration, &chain_key, *signature_public, signature_private); + box_object::(sks) + }) +} + +jni_fn_destroy!(Java_org_signal_libsignal_groups_state_SenderKeyState_Destroy destroys SenderKeyState); + +jni_fn_deserialize!(Java_org_signal_libsignal_groups_state_SenderKeyState_Deserialize is SenderKeyState::deserialize); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetSerialized(SenderKeyState) using + |sks: &SenderKeyState| sks.serialize()); + +jni_fn_get_jint!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetKeyId(SenderKeyState) using + |sks: &SenderKeyState| sks.sender_key_id()); + +jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetSigningKeyPublic(PublicKey) from SenderKeyState, + |sks: &SenderKeyState| sks.signing_key_public()); + +jni_fn_get_new_boxed_optional_obj!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetSigningKeyPrivate(PrivateKey) from SenderKeyState, + |sks: &SenderKeyState| sks.signing_key_private()); + +jni_fn_get_jbytearray!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetSenderChainKeySeed(SenderKeyState) using + |sks: &SenderKeyState| sks.sender_chain_key()?.seed()); + +jni_fn_get_jint!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetSenderChainKeyIteration(SenderKeyState) using + |sks: &SenderKeyState| sks.sender_chain_key()?.iteration()); + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeyState_SetSenderChainKey( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + iteration: jint, + seed: jbyteArray) { + run_ffi_safe(&env, || { + let sender_key_state = native_handle_cast::(handle)?; + let iteration = jint_to_u32(iteration)?; + let seed = env.convert_byte_array(seed)?; + + let sender_chain = SenderChainKey::new(iteration, seed)?; + sender_key_state.set_sender_chain_key(sender_chain)?; + Ok(()) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeyState_AddSenderMessageKey( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + iteration: jint, + seed: jbyteArray) { + run_ffi_safe(&env, || { + let sender_key_state = native_handle_cast::(handle)?; + let iteration = jint_to_u32(iteration)?; + let seed = env.convert_byte_array(seed)?; + let sender_message_key = SenderMessageKey::new(iteration, seed)?; + sender_key_state.add_sender_message_key(&sender_message_key)?; + Ok(()) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeyState_HasSenderMessageKey( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + iteration: jint) -> jboolean { + run_ffi_safe(&env, || { + let sender_key_state = native_handle_cast::(handle)?; + let iteration = jint_to_u32(iteration)?; + Ok(sender_key_state.has_sender_message_key(iteration)? as jboolean) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeyState_RemoveSenderMessageKey( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + iteration: jint) -> ObjectHandle { + run_ffi_safe(&env, || { + let sender_key_state = native_handle_cast::(handle)?; + let iteration = jint_to_u32(iteration)?; + + if let Some(sender_key) = sender_key_state.remove_sender_message_key(iteration)? { + let sai = SeedAndIteration::new(sender_key.seed()?, sender_key.iteration()?); + box_object::(Ok(sai)) + } else { + Ok(0 as ObjectHandle) + } + }) +} diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000000..912a0cdb89 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,407 @@ +use jni::sys::{_jobject, jboolean, jbyteArray, jint, jlong, jstring}; +use jni::JNIEnv; +use libsignal_protocol_rust::*; +use std::fmt; + +#[derive(Debug)] +pub enum SignalJniError { + Signal(SignalProtocolError), + Jni(jni::errors::Error), + BadJniParameter(&'static str), + NullHandle, + IntegerOverflow(String), + UnexpectedPanic(std::boxed::Box), +} + +impl fmt::Display for SignalJniError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + SignalJniError::Signal(s) => write!(f, "{}", s), + SignalJniError::Jni(s) => write!(f, "{}", s), + SignalJniError::NullHandle => write!(f, "null handle"), + SignalJniError::BadJniParameter(m) => write!(f, "bad parameter type {}", m), + SignalJniError::IntegerOverflow(m) => { + write!(f, "integer overflow during conversion of {}", m) + } + SignalJniError::UnexpectedPanic(e) => match e.downcast_ref::<&'static str>() { + Some(s) => write!(f, "unexpected panic: {}", s), + None => write!(f, "unknown unexpected panic"), + }, + } + } +} + +impl From for SignalJniError { + fn from(e: SignalProtocolError) -> SignalJniError { + SignalJniError::Signal(e) + } +} + +impl From for SignalJniError { + fn from(e: jni::errors::Error) -> SignalJniError { + SignalJniError::Jni(e) + } +} + +pub fn throw_error(env: &JNIEnv, error: SignalJniError) { + let error_string = format!("{}", error); + + let exception_type = match error { + SignalJniError::NullHandle => "java/lang/NullPointerException", + SignalJniError::UnexpectedPanic(_) => "java/lang/AssertionError", + SignalJniError::BadJniParameter(_) => "java/lang/AssertionError", + SignalJniError::IntegerOverflow(_) => "java/lang/RuntimeException", + + SignalJniError::Signal(SignalProtocolError::DuplicatedMessage(_, _)) => { + "org/signal/libsignal/DuplicatedMessageException" + } + + SignalJniError::Signal(SignalProtocolError::InvalidPreKeyId) + | SignalJniError::Signal(SignalProtocolError::InvalidSignedPreKeyId) + | SignalJniError::Signal(SignalProtocolError::InvalidSenderKeyId) => { + "org/signal/libsignal/InvalidKeyIdException" + } + + SignalJniError::Signal(SignalProtocolError::NoKeyTypeIdentifier) + | SignalJniError::Signal(SignalProtocolError::BadKeyType(_)) + | SignalJniError::Signal(SignalProtocolError::BadKeyLength(_, _)) => { + "org/signal/libsignal/InvalidKeyException" + } + + SignalJniError::Signal(SignalProtocolError::SessionNotFound) => { + "org/signal/libsignal/NoSessionException" + } + + SignalJniError::Signal(SignalProtocolError::InvalidMessage(_)) + | SignalJniError::Signal(SignalProtocolError::CiphertextMessageTooShort(_)) + | SignalJniError::Signal(SignalProtocolError::UnrecognizedCiphertextVersion(_)) + | SignalJniError::Signal(SignalProtocolError::UnrecognizedMessageVersion(_)) + | SignalJniError::Signal(SignalProtocolError::InvalidCiphertext) + | SignalJniError::Signal(SignalProtocolError::InvalidProtobufEncoding) => { + "org/signal/libsignal/InvalidMessageException" + } + + SignalJniError::Signal(SignalProtocolError::LegacyCiphertextVersion(_)) => { + "org/signal/libsignal/LegacyMessageException" + } + + SignalJniError::Signal(SignalProtocolError::InvalidState(_, _)) + | SignalJniError::Signal(SignalProtocolError::NoSenderKeyState) + | SignalJniError::Signal(SignalProtocolError::InvalidSessionStructure) => { + "java/lang/IllegalStateException" + } + + SignalJniError::Signal(SignalProtocolError::InvalidArgument(_)) => { + "java/lang/IllegalArgumentException" + } + + SignalJniError::Signal(_) => "java/lang/RuntimeException", + + SignalJniError::Jni(_) => "java/lang/RuntimeException", + }; + + let _ = env.throw_new(exception_type, error_string); +} + +pub type ObjectHandle = jlong; + +pub unsafe fn native_handle_cast( + handle: ObjectHandle, +) -> Result<&'static mut T, SignalJniError> { + /* + Should we try testing the encoded pointer for sanity here, beyond + being null? For example verifying that lowest bits are zero, + highest bits are zero, greater than 64K, etc? + */ + if handle == 0 { + return Err(SignalJniError::NullHandle); + } + + Ok(&mut *(handle as *mut T)) +} + +pub unsafe fn native_handle_cast_optional( + handle: ObjectHandle, +) -> Result, SignalJniError> { + if handle == 0 { + return Ok(None); + } + + Ok(Some(&mut *(handle as *mut T))) +} + +// A dummy value to return when we are throwing an exception +pub trait JniDummyValue { + fn dummy_value() -> Self; +} + +impl JniDummyValue for ObjectHandle { + fn dummy_value() -> Self { + 0 + } +} + +impl JniDummyValue for jint { + fn dummy_value() -> Self { + 0 as jint + } +} + +impl JniDummyValue for *mut _jobject { + fn dummy_value() -> Self { + 0 as jstring + } +} + +impl JniDummyValue for jboolean { + fn dummy_value() -> Self { + 0 as jboolean + } +} + +impl JniDummyValue for () { + fn dummy_value() -> Self { + } +} + +pub fn run_ffi_safe Result + std::panic::UnwindSafe, R>( + env: &JNIEnv, + f: F, +) -> R +where + R: JniDummyValue, +{ + match std::panic::catch_unwind(f) { + Ok(Ok(r)) => r, + Ok(Err(e)) => { + throw_error(env, e); + R::dummy_value() + } + Err(r) => { + throw_error(env, SignalJniError::UnexpectedPanic(r)); + R::dummy_value() + } + } +} + +pub fn box_object(t: Result) -> Result { + match t { + Ok(t) => Ok(Box::into_raw(Box::new(t)) as ObjectHandle), + Err(e) => Err(SignalJniError::Signal(e)), + } +} + +pub fn to_jbytearray>( + env: &JNIEnv, + data: Result, +) -> Result { + let data = data?; + let data: &[u8] = data.as_ref(); + let out = env.new_byte_array(data.len() as i32)?; + let buf: Vec = data.iter().map(|i| *i as i8).collect(); + env.set_byte_array_region(out, 0, buf.as_slice())?; + Ok(out) +} + +pub fn jint_to_u32(v: jint) -> Result { + if v < 0 { + return Err(SignalJniError::IntegerOverflow(format!("{} to u32", v))); + } + Ok(v as u32) +} + +pub fn jint_to_u8(v: jint) -> Result { + if v < 0 || v > 255 { + return Err(SignalJniError::IntegerOverflow(format!("{} to u8", v))); + } + Ok(v as u8) +} + +pub fn jint_from_u32(value: Result) -> Result { + match value { + Ok(value) => { + let result = value as jint; + if result as u32 != value { + return Err(SignalJniError::IntegerOverflow(format!( + "{} to jint", + value + ))); + } + Ok(result) + } + Err(e) => Err(SignalJniError::Signal(e)), + } +} + +pub fn jlong_from_u64(value: Result) -> Result { + match value { + Ok(value) => { + let result = value as jlong; + if result as u64 != value { + return Err(SignalJniError::IntegerOverflow(format!( + "{} to jlong", + value + ))); + } + Ok(result) + } + Err(e) => Err(SignalJniError::Signal(e)), + } +} + +#[macro_export] +macro_rules! jni_fn_deserialize { + ( $nm:ident is $func:path ) => { + #[no_mangle] + pub unsafe extern "system" fn $nm( + env: JNIEnv, + _class: JClass, + data: jbyteArray, + ) -> ObjectHandle { + run_ffi_safe(&env, || { + let data = env.convert_byte_array(data)?; + box_object($func(data.as_ref())) + }) + } + }; +} + +#[macro_export] +macro_rules! jni_fn_get_new_boxed_obj { + ( $nm:ident($rt:ty) from $typ:ty, $body:expr ) => { + #[no_mangle] + pub unsafe extern "system" fn $nm( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + ) -> ObjectHandle { + run_ffi_safe(&env, || { + let obj = native_handle_cast::<$typ>(handle)?; + return box_object::<$rt>($body(obj)); + }) + } + }; +} + +#[macro_export] +macro_rules! jni_fn_get_new_boxed_optional_obj { + ( $nm:ident($rt:ty) from $typ:ty, $body:expr ) => { + #[no_mangle] + pub unsafe extern "system" fn $nm( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + ) -> ObjectHandle { + run_ffi_safe(&env, || { + let obj = native_handle_cast::<$typ>(handle)?; + let result : Option<$rt> = $body(obj)?; + if let Some(result) = result { + box_object::<$rt>(Ok(result)) + } else { + Ok(0 as ObjectHandle) + } + }) + } + }; +} + +#[macro_export] +macro_rules! jni_fn_get_jint { + ( $nm:ident($typ:ty) using $body:expr ) => { + #[no_mangle] + pub unsafe extern "system" fn $nm( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + ) -> jint { + run_ffi_safe(&env, || { + let obj = native_handle_cast::<$typ>(handle)?; + return jint_from_u32($body(obj)); + }) + } + }; +} + +#[macro_export] +macro_rules! jni_fn_get_jboolean { + ( $nm:ident($typ:ty) using $body:expr ) => { + #[no_mangle] + pub unsafe extern "system" fn $nm( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + ) -> jboolean { + run_ffi_safe(&env, || { + let obj = native_handle_cast::<$typ>(handle)?; + let r : bool = $body(obj)?; + Ok(r as jboolean) + }) + } + }; +} + +/* +Without the indirection of inner_get, rust can't deduce the Error type +if the provided lambda just returns Ok(something) +*/ +#[macro_export] +macro_rules! jni_fn_get_jstring { + ( $nm:ident($typ:ty) using $body:expr ) => { + #[no_mangle] + pub unsafe extern "system" fn $nm( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + ) -> jstring { + fn inner_get(t: &$typ) -> Result { + $body(&t) + } + run_ffi_safe(&env, || { + let obj : &mut $typ = native_handle_cast::<$typ>(handle)?; + return Ok(env.new_string(inner_get(&obj)?)?.into_inner()); + }) + } + }; + ( $nm:ident($typ:ty) using $func:path ) => { + #[no_mangle] + pub unsafe extern "system" fn $nm( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + ) -> jstring { + run_ffi_safe(&env, || { + let obj : &mut $typ = native_handle_cast::<$typ>(handle)?; + return Ok(env.new_string($func(&obj)?)?.into_inner()); + }) + } + }; +} + +#[macro_export] +macro_rules! jni_fn_get_jbytearray { + ( $nm:ident($typ:ty) using $body:expr ) => { + #[no_mangle] + pub unsafe extern "system" fn $nm( + env: JNIEnv, + _class: JClass, + handle: ObjectHandle, + ) -> jbyteArray { + run_ffi_safe(&env, || { + let obj = native_handle_cast::<$typ>(handle)?; + return to_jbytearray(&env, $body(obj)); + }) + } + }; +} + +#[macro_export] +macro_rules! jni_fn_destroy { + ( $nm:ident destroys $typ:ty ) => { + #[no_mangle] + pub unsafe extern "system" fn $nm(_env: JNIEnv, _class: JClass, handle: ObjectHandle) { + if handle != 0 { + let _boxed_value = Box::from_raw(handle as *mut $typ); + } + } + }; +} From 8e9d0352bc84a99094a8b196113c39653c665586 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 11 Aug 2020 19:17:49 -0400 Subject: [PATCH 03/19] Rename to org.whispersystems Makes the diff against libsignal-protocol-java easier to read --- src/lib.rs | 208 ++++++++++++++++++++++++++-------------------------- src/util.rs | 12 +-- 2 files changed, 110 insertions(+), 110 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 388e91f504..b02872b397 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,7 +31,7 @@ impl SeedAndIteration { /* SeedAndIteration (utility class) */ #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_util_SeedAndIteration_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_util_SeedAndIteration_New( env: JNIEnv, _class: JClass, seed: jbyteArray, @@ -44,16 +44,16 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_util_SeedAndIteration_Ne }) } -jni_fn_destroy!(Java_org_signal_libsignal_util_SeedAndIteration_Destroy destroys SeedAndIteration); +jni_fn_destroy!(Java_org_whispersystems_libsignal_util_SeedAndIteration_Destroy destroys SeedAndIteration); -jni_fn_get_jint!(Java_org_signal_libsignal_util_SeedAndIteration_GetIteration(SeedAndIteration) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_util_SeedAndIteration_GetIteration(SeedAndIteration) using |si: &SeedAndIteration| si.iteration()); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_util_SeedAndIteration_GetSeed(SeedAndIteration) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_util_SeedAndIteration_GetSeed(SeedAndIteration) using |si: &SeedAndIteration| si.seed()); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_SignalProtocolAddress_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SignalProtocolAddress_New( env: JNIEnv, _class: JClass, name: JString, @@ -67,21 +67,21 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_SignalProtocolAddress_Ne }) } -jni_fn_destroy!(Java_org_signal_libsignal_SignalProtocolAddress_Destroy destroys ProtocolAddress); +jni_fn_destroy!(Java_org_whispersystems_libsignal_SignalProtocolAddress_Destroy destroys ProtocolAddress); -jni_fn_get_jstring!(Java_org_signal_libsignal_SignalProtocolAddress_Name(ProtocolAddress) using +jni_fn_get_jstring!(Java_org_whispersystems_libsignal_SignalProtocolAddress_Name(ProtocolAddress) using |p: &ProtocolAddress| Ok(p.name().to_string())); -jni_fn_get_jint!(Java_org_signal_libsignal_SignalProtocolAddress_DeviceId(ProtocolAddress) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_SignalProtocolAddress_DeviceId(ProtocolAddress) using |obj: &ProtocolAddress| { Ok(obj.device_id()) }); -jni_fn_deserialize!(Java_org_signal_libsignal_ecc_ECPublicKey_Deserialize is PublicKey::deserialize); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_Deserialize is PublicKey::deserialize); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_ecc_ECPublicKey_Serialize(PublicKey) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_Serialize(PublicKey) using |k: &PublicKey| Ok(k.serialize())); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_ecc_ECPublicKey_Verify( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPublicKey_Verify( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -96,15 +96,15 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_ecc_ECPublicKey_Verify( }) } -jni_fn_destroy!(Java_org_signal_libsignal_ecc_ECPublicKey_Destroy destroys PublicKey); +jni_fn_destroy!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_Destroy destroys PublicKey); -jni_fn_deserialize!(Java_org_signal_libsignal_ecc_ECPrivateKey_Deserialize is PrivateKey::deserialize); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Deserialize is PrivateKey::deserialize); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_ecc_ECPrivateKey_Serialize(PrivateKey) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Serialize(PrivateKey) using |k: &PrivateKey| Ok(k.serialize())); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_ecc_ECPrivateKey_Sign( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Sign( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -120,7 +120,7 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_ecc_ECPrivateKey_Sign( } #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_ecc_ECPrivateKey_Agree( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Agree( env: JNIEnv, _class: JClass, private_key_handle: ObjectHandle, @@ -134,10 +134,10 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_ecc_ECPrivateKey_Agree( }) } -jni_fn_destroy!(Java_org_signal_libsignal_ecc_ECPrivateKey_Destroy destroys PrivateKey); +jni_fn_destroy!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Destroy destroys PrivateKey); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_fingerprint_DisplayableFingerprint_Format( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_DisplayableFingerprint_Format( env: JNIEnv, _class: JClass, local: jbyteArray, @@ -153,7 +153,7 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_fingerprint_DisplayableF } #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_fingerprint_NumericFingerprintGenerator_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_New( env: JNIEnv, _class: JClass, iterations: jint, @@ -188,16 +188,16 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_fingerprint_NumericFinge }) } -jni_fn_destroy!(Java_org_signal_libsignal_fingerprint_NumericFingerprintGenerator_Destroy destroys Fingerprint); +jni_fn_destroy!(Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_Destroy destroys Fingerprint); -jni_fn_get_jstring!(Java_org_signal_libsignal_fingerprint_NumericFingerprintGenerator_GetDisplayString(Fingerprint) using +jni_fn_get_jstring!(Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_GetDisplayString(Fingerprint) using Fingerprint::display_string); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_fingerprint_NumericFingerprintGenerator_GetScannableEncoding(Fingerprint) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_GetScannableEncoding(Fingerprint) using |f: &Fingerprint| f.scannable.serialize()); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_fingerprint_ScannableFingerprint_Compare( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_ScannableFingerprint_Compare( env: JNIEnv, _class: JClass, fprint1: jbyteArray, @@ -213,7 +213,7 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_fingerprint_ScannableFin } #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_kdf_HKDF_DeriveSecrets( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_kdf_HKDF_DeriveSecrets( env: JNIEnv, _class: JClass, version: jint, @@ -247,10 +247,10 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_kdf_HKDF_DeriveSecrets( }) } -jni_fn_deserialize!(Java_org_signal_libsignal_protocol_SignalMessage_Deserialize is SignalMessage::try_from); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_SignalMessage_Deserialize is SignalMessage::try_from); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SignalMessage_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SignalMessage_New( env: JNIEnv, _class: JClass, message_version: jint, @@ -288,24 +288,24 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SignalMessage_N }) } -jni_fn_destroy!(Java_org_signal_libsignal_protocol_SignalMessage_Destroy destroys SignalMessage); +jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_SignalMessage_Destroy destroys SignalMessage); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SignalMessage_GetSenderRatchetKey(SignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SignalMessage_GetSenderRatchetKey(SignalMessage) using |m: &SignalMessage| Ok(m.sender_ratchet_key().serialize())); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SignalMessage_GetBody(SignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SignalMessage_GetBody(SignalMessage) using |m: &SignalMessage| Ok(m.body().to_vec())); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SignalMessage_GetSerialized(SignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SignalMessage_GetSerialized(SignalMessage) using |m: &SignalMessage| Ok(m.serialized().to_vec())); -jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SignalMessage_GetMessageVersion(SignalMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SignalMessage_GetMessageVersion(SignalMessage) using |msg: &SignalMessage| { Ok(msg.message_version() as u32) }); -jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SignalMessage_GetCounter(SignalMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SignalMessage_GetCounter(SignalMessage) using |msg: &SignalMessage| { Ok(msg.counter()) }); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SignalMessage_VerifyMac( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SignalMessage_VerifyMac( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -329,10 +329,10 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SignalMessage_V }) } -jni_fn_deserialize!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_Deserialize is PreKeySignalMessage::try_from); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_Deserialize is PreKeySignalMessage::try_from); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_PreKeySignalMessage_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_New( env: JNIEnv, _class: JClass, message_version: jint, @@ -369,17 +369,17 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_PreKeySignalMes }) } -jni_fn_destroy!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_Destroy destroys PreKeySignalMessage); +jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_Destroy destroys PreKeySignalMessage); -jni_fn_get_jint!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetVersion(PreKeySignalMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetVersion(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.message_version() as u32)); -jni_fn_get_jint!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetRegistrationId(PreKeySignalMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetRegistrationId(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.registration_id())); // Special logic to handle optionality: #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetPreKeyId( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetPreKeyId( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -393,25 +393,25 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_PreKeySignalMes }) } -jni_fn_get_jint!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetSignedPreKeyId(PreKeySignalMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetSignedPreKeyId(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.signed_pre_key_id())); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetBaseKey(PreKeySignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetBaseKey(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.base_key().serialize())); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetIdentityKey(PreKeySignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetIdentityKey(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.identity_key().serialize())); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetSignalMessage(PreKeySignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetSignalMessage(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.message().serialized().to_vec())); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_PreKeySignalMessage_GetSerialized(PreKeySignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetSerialized(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.serialized().to_vec())); -jni_fn_deserialize!(Java_org_signal_libsignal_protocol_SenderKeyMessage_Deserialize is SenderKeyMessage::try_from); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_Deserialize is SenderKeyMessage::try_from); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SenderKeyMessage_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_New( env: JNIEnv, _class: JClass, key_id: jint, @@ -430,24 +430,24 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SenderKeyMessag }) } -jni_fn_deserialize!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_Deserialize is SenderKeyDistributionMessage::try_from); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_Deserialize is SenderKeyDistributionMessage::try_from); -jni_fn_destroy!(Java_org_signal_libsignal_protocol_SenderKeyMessage_Destroy destroys SenderKeyMessage); +jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_Destroy destroys SenderKeyMessage); -jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SenderKeyMessage_GetKeyId(SenderKeyMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_GetKeyId(SenderKeyMessage) using |m: &SenderKeyMessage| Ok(m.key_id())); -jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SenderKeyMessage_GetIteration(SenderKeyMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_GetIteration(SenderKeyMessage) using |m: &SenderKeyMessage| Ok(m.iteration())); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SenderKeyMessage_GetCipherText(SenderKeyMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_GetCipherText(SenderKeyMessage) using |m: &SenderKeyMessage| Ok(m.ciphertext().to_vec())); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SenderKeyMessage_GetSerialized(SenderKeyMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_GetSerialized(SenderKeyMessage) using |m: &SenderKeyMessage| Ok(m.serialized().to_vec())); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SenderKeyMessage_VerifySignature( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_VerifySignature( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -462,7 +462,7 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SenderKeyMessag } #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_New( env: JNIEnv, _class: JClass, key_id: jint, @@ -480,25 +480,25 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_protocol_SenderKeyDistri }) } -jni_fn_destroy!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_Destroy destroys SenderKeyDistributionMessage); +jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_Destroy destroys SenderKeyDistributionMessage); -jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_GetId(SenderKeyDistributionMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_GetId(SenderKeyDistributionMessage) using |m: &SenderKeyDistributionMessage| m.id()); -jni_fn_get_jint!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_GetIteration(SenderKeyDistributionMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_GetIteration(SenderKeyDistributionMessage) using |m: &SenderKeyDistributionMessage| m.iteration()); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_GetChainKey(SenderKeyDistributionMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_GetChainKey(SenderKeyDistributionMessage) using |m: &SenderKeyDistributionMessage| Ok(m.chain_key()?.to_vec())); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_GetSignatureKey(SenderKeyDistributionMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_GetSignatureKey(SenderKeyDistributionMessage) using |m: &SenderKeyDistributionMessage| Ok(m.signing_key()?.serialize())); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_protocol_SenderKeyDistributionMessage_GetSerialized(SenderKeyDistributionMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_GetSerialized(SenderKeyDistributionMessage) using |m: &SenderKeyDistributionMessage| Ok(m.serialized().to_vec())); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_state_PreKeyBundle_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyBundle_New( env: JNIEnv, _class: JClass, registration_id: jint, @@ -542,20 +542,20 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_state_PreKeyBundle_New( }) } -jni_fn_destroy!(Java_org_signal_libsignal_state_PreKeyBundle_Destroy destroys PreKeyBundle); +jni_fn_destroy!(Java_org_whispersystems_libsignal_state_PreKeyBundle_Destroy destroys PreKeyBundle); -jni_fn_get_jint!(Java_org_signal_libsignal_state_PreKeyBundle_GetRegistrationId(PreKeyBundle) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetRegistrationId(PreKeyBundle) using |m: &PreKeyBundle| m.registration_id()); -jni_fn_get_jint!(Java_org_signal_libsignal_state_PreKeyBundle_GetDeviceId(PreKeyBundle) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetDeviceId(PreKeyBundle) using |m: &PreKeyBundle| m.device_id()); -jni_fn_get_jint!(Java_org_signal_libsignal_state_PreKeyBundle_GetSignedPreKeyId(PreKeyBundle) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetSignedPreKeyId(PreKeyBundle) using |m: &PreKeyBundle| m.signed_pre_key_id()); // Special logic for optional here: #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_state_PreKeyBundle_GetPreKeyId( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyBundle_GetPreKeyId( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -569,22 +569,22 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_state_PreKeyBundle_GetPr }) } -jni_fn_get_new_boxed_optional_obj!(Java_org_signal_libsignal_state_PreKeyBundle_GetPreKeyPublic(PublicKey) from PreKeyBundle, +jni_fn_get_new_boxed_optional_obj!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetPreKeyPublic(PublicKey) from PreKeyBundle, |p: &PreKeyBundle| p.pre_key_public()); -jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_PreKeyBundle_GetSignedPreKeyPublic(PublicKey) from PreKeyBundle, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetSignedPreKeyPublic(PublicKey) from PreKeyBundle, |p: &PreKeyBundle| Ok(p.signed_pre_key_public()?)); -jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_PreKeyBundle_GetIdentityKey(PublicKey) from PreKeyBundle, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetIdentityKey(PublicKey) from PreKeyBundle, |p: &PreKeyBundle| Ok(*p.identity_key()?.public_key())); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_state_PreKeyBundle_GetSignedPreKeySignature(PreKeyBundle) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetSignedPreKeySignature(PreKeyBundle) using |m: &PreKeyBundle| Ok(m.signed_pre_key_signature()?.to_vec())); /* SignedPreKeyRecord */ #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_state_SignedPreKeyRecord_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_New( env: JNIEnv, _class: JClass, id: jint, @@ -607,13 +607,13 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_state_SignedPreKeyRecord }) } -jni_fn_deserialize!(Java_org_signal_libsignal_state_SignedPreKeyRecord_Deserialize is SignedPreKeyRecord::deserialize); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_Deserialize is SignedPreKeyRecord::deserialize); -jni_fn_get_jint!(Java_org_signal_libsignal_state_SignedPreKeyRecord_GetId(SignedPreKeyRecord) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetId(SignedPreKeyRecord) using |m: &SignedPreKeyRecord| m.id()); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_state_SignedPreKeyRecord_GetTimestamp( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetTimestamp( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -624,24 +624,24 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_state_SignedPreKeyRecord }) } -jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_SignedPreKeyRecord_GetPublicKey(PublicKey) from SignedPreKeyRecord, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetPublicKey(PublicKey) from SignedPreKeyRecord, |p: &SignedPreKeyRecord| p.public_key()); -jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_SignedPreKeyRecord_GetPrivateKey(PrivateKey) from SignedPreKeyRecord, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetPrivateKey(PrivateKey) from SignedPreKeyRecord, |p: &SignedPreKeyRecord| p.private_key()); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_state_SignedPreKeyRecord_GetSignature(SignedPreKeyRecord) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetSignature(SignedPreKeyRecord) using |m: &SignedPreKeyRecord| m.signature()); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_state_SignedPreKeyRecord_GetSerialized(SignedPreKeyRecord) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetSerialized(SignedPreKeyRecord) using |m: &SignedPreKeyRecord| m.serialize()); -jni_fn_destroy!(Java_org_signal_libsignal_state_SignedPreKeyRecord_Destroy destroys SignedPreKeyRecord); +jni_fn_destroy!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_Destroy destroys SignedPreKeyRecord); /* PreKeyRecord */ #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_state_PreKeyRecord_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyRecord_New( env: JNIEnv, _class: JClass, id: jint, @@ -660,26 +660,26 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_state_PreKeyRecord_New( }) } -jni_fn_deserialize!(Java_org_signal_libsignal_state_PreKeyRecord_Deserialize is PreKeyRecord::deserialize); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_state_PreKeyRecord_Deserialize is PreKeyRecord::deserialize); -jni_fn_get_jint!(Java_org_signal_libsignal_state_PreKeyRecord_GetId(PreKeyRecord) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyRecord_GetId(PreKeyRecord) using |m: &PreKeyRecord| m.id()); -jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_PreKeyRecord_GetPublicKey(PublicKey) from PreKeyRecord, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyRecord_GetPublicKey(PublicKey) from PreKeyRecord, |p: &PreKeyRecord| p.public_key()); -jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_state_PreKeyRecord_GetPrivateKey(PrivateKey) from PreKeyRecord, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyRecord_GetPrivateKey(PrivateKey) from PreKeyRecord, |p: &PreKeyRecord| p.private_key()); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_state_PreKeyRecord_GetSerialized(PreKeyRecord) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_PreKeyRecord_GetSerialized(PreKeyRecord) using |m: &PreKeyRecord| m.serialize()); -jni_fn_destroy!(Java_org_signal_libsignal_state_PreKeyRecord_Destroy destroys PreKeyRecord); +jni_fn_destroy!(Java_org_whispersystems_libsignal_state_PreKeyRecord_Destroy destroys PreKeyRecord); /* SenderKeyName */ #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_groups_SenderKeyName_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_SenderKeyName_New( env: JNIEnv, _class: JClass, group_id: JString, @@ -695,20 +695,20 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_groups_SenderKeyName_New }) } -jni_fn_destroy!(Java_org_signal_libsignal_groups_SenderKeyName_Destroy destroys SenderKeyName); +jni_fn_destroy!(Java_org_whispersystems_libsignal_groups_SenderKeyName_Destroy destroys SenderKeyName); -jni_fn_get_jstring!(Java_org_signal_libsignal_groups_SenderKeyName_GetGroupId(SenderKeyName) using +jni_fn_get_jstring!(Java_org_whispersystems_libsignal_groups_SenderKeyName_GetGroupId(SenderKeyName) using SenderKeyName::group_id); -jni_fn_get_jstring!(Java_org_signal_libsignal_groups_SenderKeyName_GetSenderName(SenderKeyName) using +jni_fn_get_jstring!(Java_org_whispersystems_libsignal_groups_SenderKeyName_GetSenderName(SenderKeyName) using |skn: &SenderKeyName| { Ok(skn.sender()?.name().to_string()) }); -jni_fn_get_jint!(Java_org_signal_libsignal_groups_SenderKeyName_GetSenderDeviceId(SenderKeyName) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_groups_SenderKeyName_GetSenderDeviceId(SenderKeyName) using |m: &SenderKeyName| Ok(m.sender()?.device_id())); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeyState_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_New( env: JNIEnv, _class: JClass, id: jint, @@ -729,30 +729,30 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeySt }) } -jni_fn_destroy!(Java_org_signal_libsignal_groups_state_SenderKeyState_Destroy destroys SenderKeyState); +jni_fn_destroy!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_Destroy destroys SenderKeyState); -jni_fn_deserialize!(Java_org_signal_libsignal_groups_state_SenderKeyState_Deserialize is SenderKeyState::deserialize); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_Deserialize is SenderKeyState::deserialize); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetSerialized(SenderKeyState) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetSerialized(SenderKeyState) using |sks: &SenderKeyState| sks.serialize()); -jni_fn_get_jint!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetKeyId(SenderKeyState) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetKeyId(SenderKeyState) using |sks: &SenderKeyState| sks.sender_key_id()); -jni_fn_get_new_boxed_obj!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetSigningKeyPublic(PublicKey) from SenderKeyState, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetSigningKeyPublic(PublicKey) from SenderKeyState, |sks: &SenderKeyState| sks.signing_key_public()); -jni_fn_get_new_boxed_optional_obj!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetSigningKeyPrivate(PrivateKey) from SenderKeyState, +jni_fn_get_new_boxed_optional_obj!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetSigningKeyPrivate(PrivateKey) from SenderKeyState, |sks: &SenderKeyState| sks.signing_key_private()); -jni_fn_get_jbytearray!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetSenderChainKeySeed(SenderKeyState) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetSenderChainKeySeed(SenderKeyState) using |sks: &SenderKeyState| sks.sender_chain_key()?.seed()); -jni_fn_get_jint!(Java_org_signal_libsignal_groups_state_SenderKeyState_GetSenderChainKeyIteration(SenderKeyState) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetSenderChainKeyIteration(SenderKeyState) using |sks: &SenderKeyState| sks.sender_chain_key()?.iteration()); #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeyState_SetSenderChainKey( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_SetSenderChainKey( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -770,7 +770,7 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeySt } #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeyState_AddSenderMessageKey( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_AddSenderMessageKey( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -787,7 +787,7 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeySt } #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeyState_HasSenderMessageKey( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_HasSenderMessageKey( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -800,7 +800,7 @@ pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeySt } #[no_mangle] -pub unsafe extern "system" fn Java_org_signal_libsignal_groups_state_SenderKeyState_RemoveSenderMessageKey( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_RemoveSenderMessageKey( env: JNIEnv, _class: JClass, handle: ObjectHandle, diff --git a/src/util.rs b/src/util.rs index 912a0cdb89..176fe4bb79 100644 --- a/src/util.rs +++ b/src/util.rs @@ -53,23 +53,23 @@ pub fn throw_error(env: &JNIEnv, error: SignalJniError) { SignalJniError::IntegerOverflow(_) => "java/lang/RuntimeException", SignalJniError::Signal(SignalProtocolError::DuplicatedMessage(_, _)) => { - "org/signal/libsignal/DuplicatedMessageException" + "org/whispersystems/libsignal/DuplicatedMessageException" } SignalJniError::Signal(SignalProtocolError::InvalidPreKeyId) | SignalJniError::Signal(SignalProtocolError::InvalidSignedPreKeyId) | SignalJniError::Signal(SignalProtocolError::InvalidSenderKeyId) => { - "org/signal/libsignal/InvalidKeyIdException" + "org/whispersystems/libsignal/InvalidKeyIdException" } SignalJniError::Signal(SignalProtocolError::NoKeyTypeIdentifier) | SignalJniError::Signal(SignalProtocolError::BadKeyType(_)) | SignalJniError::Signal(SignalProtocolError::BadKeyLength(_, _)) => { - "org/signal/libsignal/InvalidKeyException" + "org/whispersystems/libsignal/InvalidKeyException" } SignalJniError::Signal(SignalProtocolError::SessionNotFound) => { - "org/signal/libsignal/NoSessionException" + "org/whispersystems/libsignal/NoSessionException" } SignalJniError::Signal(SignalProtocolError::InvalidMessage(_)) @@ -78,11 +78,11 @@ pub fn throw_error(env: &JNIEnv, error: SignalJniError) { | SignalJniError::Signal(SignalProtocolError::UnrecognizedMessageVersion(_)) | SignalJniError::Signal(SignalProtocolError::InvalidCiphertext) | SignalJniError::Signal(SignalProtocolError::InvalidProtobufEncoding) => { - "org/signal/libsignal/InvalidMessageException" + "org/whispersystems/libsignal/InvalidMessageException" } SignalJniError::Signal(SignalProtocolError::LegacyCiphertextVersion(_)) => { - "org/signal/libsignal/LegacyMessageException" + "org/whispersystems/libsignal/LegacyMessageException" } SignalJniError::Signal(SignalProtocolError::InvalidState(_, _)) From 420ba84bbdf6d4040a73cdb8239588ea35f5555b Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 12 Aug 2020 17:49:23 -0400 Subject: [PATCH 04/19] Add key generation JNI funcs --- src/lib.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index b02872b397..6d13456da0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,6 +103,21 @@ jni_fn_deserialize!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Deseriali jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Serialize(PrivateKey) using |k: &PrivateKey| Ok(k.serialize())); +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Generate( + env: JNIEnv, + _class: JClass, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let mut rng = rand::rngs::OsRng; + let keypair = KeyPair::generate(&mut rng); + box_object::(Ok(keypair.private_key)) + }) +} + +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_GetPublicKey(PublicKey) from PrivateKey, + |k: &PrivateKey| k.public_key()); + #[no_mangle] pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Sign( env: JNIEnv, From 32a6933d30cf12b7d2ab227b1590f76fd20c9c7a Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 14 Aug 2020 16:05:32 -0400 Subject: [PATCH 05/19] Add SenderKeyStore handling --- src/lib.rs | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/util.rs | 25 +++++- 2 files changed, 253 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6d13456da0..07b6bdc5eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ #![allow(clippy::missing_safety_doc)] -use jni::objects::{JClass, JString}; -use jni::sys::{jboolean, jbyteArray, jint, jlong, jstring}; +use jni::objects::{JClass, JString, JValue, JObject}; +use jni::sys::{jboolean, jbyteArray, jint, jlong, jstring, jobject}; use jni::JNIEnv; use libsignal_protocol_rust::*; use std::convert::TryFrom; @@ -832,3 +832,231 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_Sen } }) } + +pub struct JniSenderKeyStore<'a> { + env: &'a JNIEnv<'a>, + obj: jobject, +} + +impl<'a> JniSenderKeyStore<'a> { + fn new(env: &'a JNIEnv, obj: jobject) -> Self { + Self { env, obj } + } +} + +fn jobject_from_sender_key_name<'a>(env: &'a JNIEnv, sender_key_name: &SenderKeyName) -> Result, SignalJniError> { + let sender_key_name_class = env.find_class("org/whispersystems/libsignal/groups/SenderKeyName")?; + let sender_key_name_ctor_args = [ + JObject::from(env.new_string(sender_key_name.group_id()?)?).into(), + JObject::from(env.new_string(sender_key_name.sender_name()?)?).into(), + JValue::from(jint_from_u32(sender_key_name.sender_device_id())?) + ]; + + let sender_key_name_ctor_sig = "(Ljava/lang/String;Ljava/lang/String;I)V"; + let sender_key_name_jobject = env.new_object(sender_key_name_class, sender_key_name_ctor_sig, &sender_key_name_ctor_args)?; + Ok(sender_key_name_jobject) +} + +fn jobject_from_sender_key_record<'a>(env: &'a JNIEnv, sender_key_record: &SenderKeyRecord) -> Result, SignalJniError> { + let sender_key_record_class = env.find_class("org/whispersystems/libsignal/groups/state/SenderKeyRecord")?; + let sender_key_record_ctor_sig = "([B)V"; + let sender_key_record_ctor_args = [ + JValue::from(to_jbytearray(env, sender_key_record.serialize())?), + ]; + let sender_key_record_jobject = env.new_object(sender_key_record_class, sender_key_record_ctor_sig, &sender_key_record_ctor_args)?; + Ok(sender_key_record_jobject) +} + +fn exception_check(env: &JNIEnv) -> Result<(), SignalJniError> { + if env.exception_check()? { + let throwable = env.exception_occurred()?; + env.exception_clear()?; + + let getmessage_sig = "()Ljava/lang/String;"; + + let jmessage = env.call_method(throwable, "getMessage", getmessage_sig, &[])?; + + if let JValue::Object(o) = jmessage { + let message: String = env.get_string(JString::from(o))?.into(); + return Err(SignalJniError::ExceptionDuringCallback(message)); + } else { + return Err(SignalJniError::ExceptionDuringCallback("Exception that didn't implement getMessage".to_string())); + } + } + + Ok(()) +} + +impl<'a> JniSenderKeyStore<'a> { + fn do_store_sender_key( + &mut self, + sender_key_name: &SenderKeyName, + record: &SenderKeyRecord, + ) -> Result<(), SignalJniError> { + + let sender_key_name_jobject = jobject_from_sender_key_name(self.env, sender_key_name)?; + let sender_key_record_jobject = jobject_from_sender_key_record(self.env, record)?; + + let callback_args = [ + sender_key_name_jobject.into(), + sender_key_record_jobject.into(), + ]; + let callback_sig = "(Lorg/whispersystems/libsignal/groups/SenderKeyName;Lorg/whispersystems/libsignal/groups/state/SenderKeyRecord;)V"; + self.env.call_method(self.obj, "storeSenderKey", callback_sig, &callback_args[..])?; + exception_check(self.env)?; + + Ok(()) + } + + fn do_load_sender_key( + &mut self, + sender_key_name: &SenderKeyName, + ) -> Result, SignalJniError> { + + let sender_key_name_jobject = jobject_from_sender_key_name(self.env, sender_key_name)?; + let callback_args = [ + sender_key_name_jobject.into(), + ]; + let callback_sig = "(Lorg/whispersystems/libsignal/groups/SenderKeyName;)Lorg/whispersystems/libsignal/groups/state/SenderKeyRecord;"; + + let skr_obj = self.env.call_method(self.obj, "loadSenderKey", callback_sig, &callback_args[..])?; + exception_check(self.env)?; + + let skr_obj = match skr_obj { + JValue::Object(o) => *o, + _ => { + return Err(SignalJniError::BadJniParameter("loadSenderKey returned non-object")) + } + }; + + let serialized_bytes = self.env.call_method(skr_obj, "serialize", "()[B", &[])?; + exception_check(self.env)?; + + match serialized_bytes { + JValue::Object(o) => { + let bytes = self.env.convert_byte_array(*o)?; + let skr = SenderKeyRecord::deserialize(&bytes)?; + Ok(Some(skr)) + } + _ => { + Err(SignalJniError::BadJniParameter("SenderKeyRecord::serialize returned unexpected type")) + } + } + } + +} + +impl<'a> SenderKeyStore for JniSenderKeyStore<'a> { + fn store_sender_key( + &mut self, + sender_key_name: &SenderKeyName, + record: &SenderKeyRecord, + ) -> Result<(), SignalProtocolError> { + self.do_store_sender_key(sender_key_name, record).map_err(|e| e.to_signal_protocol_error()) + } + + fn load_sender_key( + &mut self, + sender_key_name: &SenderKeyName, + ) -> Result, SignalProtocolError> { + self.do_load_sender_key(sender_key_name).map_err(|e| e.to_signal_protocol_error()) + } +} + +fn check_jobject_type(env: &JNIEnv, obj: jobject, class_name: &str) -> Result { + if obj == std::ptr::null_mut() { + return Err(SignalJniError::NullHandle); + } + + let class = env.find_class(class_name)?; + + if !env.is_instance_of(obj, class)? { + return Err(SignalJniError::BadJniParameter("SenderKeyStore")); + } + + Ok(obj) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSessionBuilder_CreateSenderKeyDistributionMessage( + env: JNIEnv, + _class: JClass, + sender_key_name: ObjectHandle, + store: jobject) -> ObjectHandle { + + run_ffi_safe(&env, || { + let sender_key_name = native_handle_cast::(sender_key_name)?; + let store = check_jobject_type(&env, store, "org/whispersystems/libsignal/groups/state/SenderKeyStore")?; + + let mut sender_key_store = JniSenderKeyStore::new(&env, store); + let mut csprng = rand::rngs::OsRng; + + let skdm = create_sender_key_distribution_message(&sender_key_name, &mut sender_key_store, &mut csprng)?; + box_object::(Ok(skdm)) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSessionBuilder_ProcessSenderKeyDistributionMessage( + env: JNIEnv, + _class: JClass, + sender_key_name: ObjectHandle, + sender_key_distribution_message: ObjectHandle, + store: jobject) { + + run_ffi_safe(&env, || { + let sender_key_name = native_handle_cast::(sender_key_name)?; + let sender_key_distribution_message = native_handle_cast::(sender_key_distribution_message)?; + let store = check_jobject_type(&env, store, "org/whispersystems/libsignal/groups/state/SenderKeyStore")?; + + let mut sender_key_store = JniSenderKeyStore::new(&env, store); + + process_sender_key_distribution_message(sender_key_name, sender_key_distribution_message, &mut sender_key_store)?; + Ok(()) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCipher_EncryptMessage( + env: JNIEnv, + _class: JClass, + sender_key_name: ObjectHandle, + message: jbyteArray, + store: jobject) -> jbyteArray { + + run_ffi_safe(&env, || { + let sender_key_name = native_handle_cast::(sender_key_name)?; + let message = env.convert_byte_array(message)?; + let store = check_jobject_type(&env, store, "org/whispersystems/libsignal/groups/state/SenderKeyStore")?; + + let mut sender_key_store = JniSenderKeyStore::new(&env, store); + + let mut rng = rand::rngs::OsRng; + + let ctext = group_encrypt(&mut sender_key_store, &sender_key_name, &message, &mut rng)?; + + to_jbytearray(&env, Ok(ctext)) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCipher_DecryptMessage( + env: JNIEnv, + _class: JClass, + sender_key_name: ObjectHandle, + message: jbyteArray, + store: jobject) -> jbyteArray { + + run_ffi_safe(&env, || { + let sender_key_name = native_handle_cast::(sender_key_name)?; + let message = env.convert_byte_array(message)?; + let store = check_jobject_type(&env, store, "org/whispersystems/libsignal/groups/state/SenderKeyStore")?; + + let mut sender_key_store = JniSenderKeyStore::new(&env, store); + + let ptext = group_decrypt(&message, &mut sender_key_store, &sender_key_name)?; + + to_jbytearray(&env, Ok(ptext)) + }) +} + diff --git a/src/util.rs b/src/util.rs index 176fe4bb79..15ae4528cb 100644 --- a/src/util.rs +++ b/src/util.rs @@ -11,13 +11,32 @@ pub enum SignalJniError { NullHandle, IntegerOverflow(String), UnexpectedPanic(std::boxed::Box), + ExceptionDuringCallback(String), +} + +impl SignalJniError { + pub fn to_signal_protocol_error(&self) -> SignalProtocolError { + match self { + SignalJniError::Signal(e) => e.clone(), + SignalJniError::Jni(e) => { + SignalProtocolError::FfiBindingError(e.to_string()) + } + SignalJniError::BadJniParameter(m) => { + SignalProtocolError::InvalidArgument(m.to_string()) + } + _ => { + SignalProtocolError::FfiBindingError(format!("{}", self)) + } + } + } } impl fmt::Display for SignalJniError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { SignalJniError::Signal(s) => write!(f, "{}", s), - SignalJniError::Jni(s) => write!(f, "{}", s), + SignalJniError::Jni(s) => write!(f, "JNI error {}", s), + SignalJniError::ExceptionDuringCallback(s) => write!(f, "exception recieved during callback {}", s), SignalJniError::NullHandle => write!(f, "null handle"), SignalJniError::BadJniParameter(m) => write!(f, "bad parameter type {}", m), SignalJniError::IntegerOverflow(m) => { @@ -52,8 +71,10 @@ pub fn throw_error(env: &JNIEnv, error: SignalJniError) { SignalJniError::BadJniParameter(_) => "java/lang/AssertionError", SignalJniError::IntegerOverflow(_) => "java/lang/RuntimeException", + SignalJniError::ExceptionDuringCallback(_) => "java/lang/RuntimeException", + SignalJniError::Signal(SignalProtocolError::DuplicatedMessage(_, _)) => { - "org/whispersystems/libsignal/DuplicatedMessageException" + "org/whispersystems/libsignal/DuplicateMessageException" } SignalJniError::Signal(SignalProtocolError::InvalidPreKeyId) From f2d5978250ea4efa1c0d1e838ff936f035e70239 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 17 Aug 2020 18:51:30 -0400 Subject: [PATCH 06/19] Stubs for all the storage interfaces --- src/lib.rs | 226 ++++++++++++++++++++++++++++++++++++++++------------ src/util.rs | 61 +++++++++++++- 2 files changed, 235 insertions(+), 52 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 07b6bdc5eb..d0f128d7c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -833,17 +833,6 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_Sen }) } -pub struct JniSenderKeyStore<'a> { - env: &'a JNIEnv<'a>, - obj: jobject, -} - -impl<'a> JniSenderKeyStore<'a> { - fn new(env: &'a JNIEnv, obj: jobject) -> Self { - Self { env, obj } - } -} - fn jobject_from_sender_key_name<'a>(env: &'a JNIEnv, sender_key_name: &SenderKeyName) -> Result, SignalJniError> { let sender_key_name_class = env.find_class("org/whispersystems/libsignal/groups/SenderKeyName")?; let sender_key_name_ctor_args = [ @@ -858,33 +847,185 @@ fn jobject_from_sender_key_name<'a>(env: &'a JNIEnv, sender_key_name: &SenderKey } fn jobject_from_sender_key_record<'a>(env: &'a JNIEnv, sender_key_record: &SenderKeyRecord) -> Result, SignalJniError> { - let sender_key_record_class = env.find_class("org/whispersystems/libsignal/groups/state/SenderKeyRecord")?; - let sender_key_record_ctor_sig = "([B)V"; - let sender_key_record_ctor_args = [ - JValue::from(to_jbytearray(env, sender_key_record.serialize())?), - ]; - let sender_key_record_jobject = env.new_object(sender_key_record_class, sender_key_record_ctor_sig, &sender_key_record_ctor_args)?; - Ok(sender_key_record_jobject) + jobject_from_serialized(env, "org/whispersystems/libsignal/groups/state/SenderKeyRecord", &sender_key_record.serialize()?) } -fn exception_check(env: &JNIEnv) -> Result<(), SignalJniError> { - if env.exception_check()? { - let throwable = env.exception_occurred()?; - env.exception_clear()?; +pub struct JniIdentityKeyStore<'a> { + env: &'a JNIEnv<'a>, + obj: jobject, +} - let getmessage_sig = "()Ljava/lang/String;"; +impl<'a> JniIdentityKeyStore<'a> { + fn new(env: &'a JNIEnv, obj: jobject) -> Self { + Self { env, obj } + } +} + +impl<'a> JniIdentityKeyStore<'a> { + fn do_get_identity_key_pair(&self) -> Result { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } - let jmessage = env.call_method(throwable, "getMessage", getmessage_sig, &[])?; + fn do_get_local_registration_id(&self) -> Result { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } - if let JValue::Object(o) = jmessage { - let message: String = env.get_string(JString::from(o))?.into(); - return Err(SignalJniError::ExceptionDuringCallback(message)); - } else { - return Err(SignalJniError::ExceptionDuringCallback("Exception that didn't implement getMessage".to_string())); - } + fn do_save_identity(&mut self, address: &ProtocolAddress, identity: &IdentityKey) -> Result { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } + + fn do_is_trusted_identity( + &self, + address: &ProtocolAddress, + identity: &IdentityKey, + direction: Direction, + ) -> Result { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } + + fn do_get_identity(&self, address: &ProtocolAddress) -> Result, SignalJniError> { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } +} + +impl<'a> IdentityKeyStore for JniIdentityKeyStore<'a> { + + fn get_identity_key_pair(&self) -> Result { + Ok(self.do_get_identity_key_pair()?) + } + + fn get_local_registration_id(&self) -> Result { + Ok(self.do_get_local_registration_id()?) + } + + fn save_identity(&mut self, address: &ProtocolAddress, identity: &IdentityKey) -> Result { + Ok(self.do_save_identity(address, identity)?) + } + + fn is_trusted_identity( + &self, + address: &ProtocolAddress, + identity: &IdentityKey, + direction: Direction, + ) -> Result { + Ok(self.do_is_trusted_identity(address, identity, direction)?) + } + + fn get_identity(&self, address: &ProtocolAddress) -> Result, SignalProtocolError> { + Ok(self.do_get_identity(address)?) + } +} + +pub struct JniPreKeyStore<'a> { + env: &'a JNIEnv<'a>, + obj: jobject, +} + +impl<'a> JniPreKeyStore<'a> { + fn new(env: &'a JNIEnv, obj: jobject) -> Self { + Self { env, obj } + } +} + +impl<'a> JniPreKeyStore<'a> { + fn do_get_pre_key(&self, prekey_id: u32) -> Result { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } + + fn do_save_pre_key(&mut self, prekey_id: u32, record: &PreKeyRecord) -> Result<(), SignalJniError> { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } + + fn do_remove_pre_key(&mut self, prekey_id: u32) -> Result<(), SignalJniError> { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } +} + +impl<'a> PreKeyStore for JniPreKeyStore<'a> { + fn get_pre_key(&self, prekey_id: u32) -> Result { + Ok(self.do_get_pre_key(prekey_id)?) + } + + fn save_pre_key(&mut self, prekey_id: u32, record: &PreKeyRecord) -> Result<(), SignalProtocolError> { + Ok(self.do_save_pre_key(prekey_id, record)?) } - Ok(()) + fn remove_pre_key(&mut self, prekey_id: u32) -> Result<(), SignalProtocolError> { + Ok(self.do_remove_pre_key(prekey_id)?) + } +} + +pub struct JniSignedPreKeyStore<'a> { + env: &'a JNIEnv<'a>, + obj: jobject, +} + +impl<'a> JniSignedPreKeyStore<'a> { + fn new(env: &'a JNIEnv, obj: jobject) -> Self { + Self { env, obj } + } +} + +impl<'a> JniSignedPreKeyStore<'a> { + fn do_get_signed_pre_key(&self, prekey_id: u32) -> Result { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } + + fn do_save_signed_pre_key(&mut self, prekey_id: u32, record: &SignedPreKeyRecord) -> Result<(), SignalJniError> { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } +} + +impl<'a> SignedPreKeyStore for JniSignedPreKeyStore<'a> { + fn get_signed_pre_key(&self, prekey_id: u32) -> Result { + Ok(self.do_get_signed_pre_key(prekey_id)?) + } + + fn save_signed_pre_key(&mut self, prekey_id: u32, record: &SignedPreKeyRecord) -> Result<(), SignalProtocolError> { + Ok(self.do_save_signed_pre_key(prekey_id, record)?) + } +} + +pub struct JniSessionStore<'a> { + env: &'a JNIEnv<'a>, + obj: jobject, +} + +impl<'a> JniSessionStore<'a> { + fn new(env: &'a JNIEnv, obj: jobject) -> Self { + Self { env, obj } + } +} + +impl<'a> JniSessionStore<'a> { + fn do_load_session(&self, address: &ProtocolAddress) -> Result, SignalJniError> { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } + + fn do_store_session(&mut self, address: &ProtocolAddress, record: &SessionRecord) -> Result<(), SignalJniError> { + Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + } +} + +impl<'a> SessionStore for JniSessionStore<'a> { + fn load_session(&self, address: &ProtocolAddress) -> Result, SignalProtocolError> { + Ok(self.do_load_session(address)?) + } + + fn store_session(&mut self, address: &ProtocolAddress, record: &SessionRecord) -> Result<(), SignalProtocolError> { + Ok(self.do_store_session(address, record)?) + } +} + +pub struct JniSenderKeyStore<'a> { + env: &'a JNIEnv<'a>, + obj: jobject, +} + +impl<'a> JniSenderKeyStore<'a> { + fn new(env: &'a JNIEnv, obj: jobject) -> Self { + Self { env, obj } + } } impl<'a> JniSenderKeyStore<'a> { @@ -914,9 +1055,7 @@ impl<'a> JniSenderKeyStore<'a> { ) -> Result, SignalJniError> { let sender_key_name_jobject = jobject_from_sender_key_name(self.env, sender_key_name)?; - let callback_args = [ - sender_key_name_jobject.into(), - ]; + let callback_args = [sender_key_name_jobject.into()]; let callback_sig = "(Lorg/whispersystems/libsignal/groups/SenderKeyName;)Lorg/whispersystems/libsignal/groups/state/SenderKeyRecord;"; let skr_obj = self.env.call_method(self.obj, "loadSenderKey", callback_sig, &callback_args[..])?; @@ -943,7 +1082,6 @@ impl<'a> JniSenderKeyStore<'a> { } } } - } impl<'a> SenderKeyStore for JniSenderKeyStore<'a> { @@ -952,31 +1090,17 @@ impl<'a> SenderKeyStore for JniSenderKeyStore<'a> { sender_key_name: &SenderKeyName, record: &SenderKeyRecord, ) -> Result<(), SignalProtocolError> { - self.do_store_sender_key(sender_key_name, record).map_err(|e| e.to_signal_protocol_error()) + Ok(self.do_store_sender_key(sender_key_name, record)?) } fn load_sender_key( &mut self, sender_key_name: &SenderKeyName, ) -> Result, SignalProtocolError> { - self.do_load_sender_key(sender_key_name).map_err(|e| e.to_signal_protocol_error()) + Ok(self.do_load_sender_key(sender_key_name)?) } } -fn check_jobject_type(env: &JNIEnv, obj: jobject, class_name: &str) -> Result { - if obj == std::ptr::null_mut() { - return Err(SignalJniError::NullHandle); - } - - let class = env.find_class(class_name)?; - - if !env.is_instance_of(obj, class)? { - return Err(SignalJniError::BadJniParameter("SenderKeyStore")); - } - - Ok(obj) -} - #[no_mangle] pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSessionBuilder_CreateSenderKeyDistributionMessage( env: JNIEnv, diff --git a/src/util.rs b/src/util.rs index 15ae4528cb..27a6fed9ef 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,4 +1,5 @@ -use jni::sys::{_jobject, jboolean, jbyteArray, jint, jlong, jstring}; +use jni::sys::{_jobject, jobject, jboolean, jbyteArray, jint, jlong, jstring}; +use jni::objects::{JString, JValue, JObject}; use jni::JNIEnv; use libsignal_protocol_rust::*; use std::fmt; @@ -62,6 +63,23 @@ impl From for SignalJniError { } } +impl From for SignalProtocolError { + fn from(err: SignalJniError) -> SignalProtocolError { + match err { + SignalJniError::Signal(e) => e.clone(), + SignalJniError::Jni(e) => { + SignalProtocolError::FfiBindingError(e.to_string()) + } + SignalJniError::BadJniParameter(m) => { + SignalProtocolError::InvalidArgument(m.to_string()) + } + _ => { + SignalProtocolError::FfiBindingError(format!("{}", err)) + } + } + } +} + pub fn throw_error(env: &JNIEnv, error: SignalJniError) { let error_string = format!("{}", error); @@ -270,6 +288,47 @@ pub fn jlong_from_u64(value: Result) -> Result Result<(), SignalJniError> { + if env.exception_check()? { + let throwable = env.exception_occurred()?; + env.exception_clear()?; + + let getmessage_sig = "()Ljava/lang/String;"; + + let jmessage = env.call_method(throwable, "getMessage", getmessage_sig, &[])?; + + if let JValue::Object(o) = jmessage { + let message: String = env.get_string(JString::from(o))?.into(); + return Err(SignalJniError::ExceptionDuringCallback(message)); + } else { + return Err(SignalJniError::ExceptionDuringCallback("Exception that didn't implement getMessage".to_string())); + } + } + + Ok(()) +} + +pub fn check_jobject_type(env: &JNIEnv, obj: jobject, class_name: &'static str) -> Result { + if obj == std::ptr::null_mut() { + return Err(SignalJniError::NullHandle); + } + + let class = env.find_class(class_name)?; + + if !env.is_instance_of(obj, class)? { + return Err(SignalJniError::BadJniParameter(class_name)); + } + + Ok(obj) +} + +pub fn jobject_from_serialized<'a>(env: &'a JNIEnv, class_name: &str, serialized: &[u8]) -> Result, SignalJniError> { + let class_type = env.find_class(class_name)?; + let ctor_sig = "([B)V"; + let ctor_args = [JValue::from(to_jbytearray(env, Ok(serialized))?)]; + Ok(env.new_object(class_type, ctor_sig, &ctor_args)?) +} + #[macro_export] macro_rules! jni_fn_deserialize { ( $nm:ident is $func:path ) => { From d1f421c4bea7e2b84d0cad5f14acd32d3f83c092 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 18 Aug 2020 14:29:09 -0400 Subject: [PATCH 07/19] PreKey and SignedPreKey storage --- Cargo.toml | 4 +- src/lib.rs | 114 +++++++++++++++++++++++++++++++++++++++------------- src/util.rs | 3 ++ 3 files changed, 90 insertions(+), 31 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4cce622f70..3e7de35363 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,6 @@ crate-type = ["dylib"] [dependencies] libsignal-protocol-rust = { path = "../libsignal-protocol-rust" } -#libsignal-protocol-rust = { git = "https://github.com/signalapp/libsignal-protocol-rust" } +#libsignal-protocol-rust = { git = "ssh://git@github.com/signalapp/libsignal-protocol-rust.git" } jni = "0.17" -rand = "0.7.3" \ No newline at end of file +rand = "0.7.3" diff --git a/src/lib.rs b/src/lib.rs index d0f128d7c1..423bebc8e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -833,7 +833,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_Sen }) } -fn jobject_from_sender_key_name<'a>(env: &'a JNIEnv, sender_key_name: &SenderKeyName) -> Result, SignalJniError> { +fn sender_key_name_to_jobject<'a>(env: &'a JNIEnv, sender_key_name: &SenderKeyName) -> Result, SignalJniError> { let sender_key_name_class = env.find_class("org/whispersystems/libsignal/groups/SenderKeyName")?; let sender_key_name_ctor_args = [ JObject::from(env.new_string(sender_key_name.group_id()?)?).into(), @@ -846,18 +846,26 @@ fn jobject_from_sender_key_name<'a>(env: &'a JNIEnv, sender_key_name: &SenderKey Ok(sender_key_name_jobject) } -fn jobject_from_sender_key_record<'a>(env: &'a JNIEnv, sender_key_record: &SenderKeyRecord) -> Result, SignalJniError> { - jobject_from_serialized(env, "org/whispersystems/libsignal/groups/state/SenderKeyRecord", &sender_key_record.serialize()?) +fn protocol_address_to_jobject<'a>(env: &'a JNIEnv, address: &ProtocolAddress) -> Result, SignalJniError> { + let address_class = env.find_class("org/whispersystems/libsignal/ProtocolAddress")?; + let address_ctor_args = [ + JObject::from(env.new_string(address.name())?).into(), + JValue::from(jint_from_u32(Ok(address.device_id()))?) + ]; + + let address_ctor_sig = "(Ljava/lang/String;I)V"; + let address_jobject = env.new_object(address_class, address_ctor_sig, &address_ctor_args)?; + Ok(address_jobject) } pub struct JniIdentityKeyStore<'a> { env: &'a JNIEnv<'a>, - obj: jobject, + store: jobject, } impl<'a> JniIdentityKeyStore<'a> { - fn new(env: &'a JNIEnv, obj: jobject) -> Self { - Self { env, obj } + fn new(env: &'a JNIEnv, store: jobject) -> Self { + Self { env, store } } } @@ -867,7 +875,15 @@ impl<'a> JniIdentityKeyStore<'a> { } fn do_get_local_registration_id(&self) -> Result { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let callback_sig = "()I"; + + let rvalue = self.env.call_method(self.store, "getLocalRegistrationId", callback_sig, &[])?; + exception_check(self.env)?; + + match rvalue { + JValue::Int(i) => jint_to_u32(i), + _ => Err(SignalJniError::BadJniParameter("Unexpected return type from getLocalRegistrationId")) + } } fn do_save_identity(&mut self, address: &ProtocolAddress, identity: &IdentityKey) -> Result { @@ -918,26 +934,59 @@ impl<'a> IdentityKeyStore for JniIdentityKeyStore<'a> { pub struct JniPreKeyStore<'a> { env: &'a JNIEnv<'a>, - obj: jobject, + store: jobject, } impl<'a> JniPreKeyStore<'a> { - fn new(env: &'a JNIEnv, obj: jobject) -> Self { - Self { env, obj } + fn new(env: &'a JNIEnv, store: jobject) -> Self { + Self { env, store } } } +fn get_object_with_native_handle(env: &JNIEnv, + store_obj: jobject, + callback_args: &[JValue], + callback_sig: &'static str, + callback_fn: &'static str) -> Result { + let rvalue = env.call_method(store_obj, callback_fn, callback_sig, &callback_args)?; + exception_check(env)?; + + let obj = match rvalue { + JValue::Object(o) => *o, + _ => return Err(SignalJniError::UnexpectedJniResultType(callback_fn, rvalue.type_name())) + }; + + let handle = env.call_method(obj, "nativeHandle", "()J", &[])?; + match handle { + JValue::Long(handle) => { + let object = unsafe { native_handle_cast::(handle)? }; + Ok(object.clone()) + } + _ => Err(SignalJniError::UnexpectedJniResultType("nativeHandle", handle.type_name())) + } +} + + impl<'a> JniPreKeyStore<'a> { fn do_get_pre_key(&self, prekey_id: u32) -> Result { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let callback_sig = "(I)Lorg/whispersystems/libsignal/state/PreKeyRecord;"; + let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?)]; + get_object_with_native_handle::(self.env, self.store, &callback_args, callback_sig, "loadPreKey") } fn do_save_pre_key(&mut self, prekey_id: u32, record: &PreKeyRecord) -> Result<(), SignalJniError> { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let jobject_record = jobject_from_serialized(self.env, "org/whispersystems/libsignal/state/PreKeyRecord", &record.serialize()?)?; + let callback_sig = "(I,Lorg/whispersystems/libsignal/state/PreKeyRecord;)V"; + let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?), jobject_record.into()]; + self.env.call_method(self.store, "storePreKey", callback_sig, &callback_args)?; + Ok(()) } fn do_remove_pre_key(&mut self, prekey_id: u32) -> Result<(), SignalJniError> { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let callback_sig = "(I)V"; + let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?)]; + self.env.call_method(self.store, "removePreKey", callback_sig, &callback_args)?; + Ok(()) } } @@ -957,22 +1006,28 @@ impl<'a> PreKeyStore for JniPreKeyStore<'a> { pub struct JniSignedPreKeyStore<'a> { env: &'a JNIEnv<'a>, - obj: jobject, + store: jobject, } impl<'a> JniSignedPreKeyStore<'a> { - fn new(env: &'a JNIEnv, obj: jobject) -> Self { - Self { env, obj } + fn new(env: &'a JNIEnv, store: jobject) -> Self { + Self { env, store } } } impl<'a> JniSignedPreKeyStore<'a> { fn do_get_signed_pre_key(&self, prekey_id: u32) -> Result { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let callback_sig = "(I)Lorg/whispersystems/libsignal/state/SignedPreKeyRecord;"; + let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?)]; + get_object_with_native_handle::(self.env, self.store, &callback_args, callback_sig, "loadSignedPreKey") } fn do_save_signed_pre_key(&mut self, prekey_id: u32, record: &SignedPreKeyRecord) -> Result<(), SignalJniError> { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let jobject_record = jobject_from_serialized(self.env, "org/whispersystems/libsignal/state/SignedPreKeyRecord", &record.serialize()?)?; + let callback_sig = "(I,Lorg/whispersystems/libsignal/state/SignedPreKeyRecord;)V"; + let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?), jobject_record.into()]; + self.env.call_method(self.store, "storeSignedPreKey", callback_sig, &callback_args)?; + Ok(()) } } @@ -988,12 +1043,12 @@ impl<'a> SignedPreKeyStore for JniSignedPreKeyStore<'a> { pub struct JniSessionStore<'a> { env: &'a JNIEnv<'a>, - obj: jobject, + store: jobject, } impl<'a> JniSessionStore<'a> { - fn new(env: &'a JNIEnv, obj: jobject) -> Self { - Self { env, obj } + fn new(env: &'a JNIEnv, store: jobject) -> Self { + Self { env, store } } } @@ -1019,12 +1074,12 @@ impl<'a> SessionStore for JniSessionStore<'a> { pub struct JniSenderKeyStore<'a> { env: &'a JNIEnv<'a>, - obj: jobject, + store: jobject, } impl<'a> JniSenderKeyStore<'a> { - fn new(env: &'a JNIEnv, obj: jobject) -> Self { - Self { env, obj } + fn new(env: &'a JNIEnv, store: jobject) -> Self { + Self { env, store } } } @@ -1035,15 +1090,16 @@ impl<'a> JniSenderKeyStore<'a> { record: &SenderKeyRecord, ) -> Result<(), SignalJniError> { - let sender_key_name_jobject = jobject_from_sender_key_name(self.env, sender_key_name)?; - let sender_key_record_jobject = jobject_from_sender_key_record(self.env, record)?; + let sender_key_name_jobject = sender_key_name_to_jobject(self.env, sender_key_name)?; + let sender_key_record_jobject = + jobject_from_serialized(self.env, "org/whispersystems/libsignal/groups/state/SenderKeyRecord", &record.serialize()?)?; let callback_args = [ sender_key_name_jobject.into(), sender_key_record_jobject.into(), ]; let callback_sig = "(Lorg/whispersystems/libsignal/groups/SenderKeyName;Lorg/whispersystems/libsignal/groups/state/SenderKeyRecord;)V"; - self.env.call_method(self.obj, "storeSenderKey", callback_sig, &callback_args[..])?; + self.env.call_method(self.store, "storeSenderKey", callback_sig, &callback_args[..])?; exception_check(self.env)?; Ok(()) @@ -1054,11 +1110,11 @@ impl<'a> JniSenderKeyStore<'a> { sender_key_name: &SenderKeyName, ) -> Result, SignalJniError> { - let sender_key_name_jobject = jobject_from_sender_key_name(self.env, sender_key_name)?; + let sender_key_name_jobject = sender_key_name_to_jobject(self.env, sender_key_name)?; let callback_args = [sender_key_name_jobject.into()]; let callback_sig = "(Lorg/whispersystems/libsignal/groups/SenderKeyName;)Lorg/whispersystems/libsignal/groups/state/SenderKeyRecord;"; - let skr_obj = self.env.call_method(self.obj, "loadSenderKey", callback_sig, &callback_args[..])?; + let skr_obj = self.env.call_method(self.store, "loadSenderKey", callback_sig, &callback_args[..])?; exception_check(self.env)?; let skr_obj = match skr_obj { diff --git a/src/util.rs b/src/util.rs index 27a6fed9ef..3e22a62f09 100644 --- a/src/util.rs +++ b/src/util.rs @@ -9,6 +9,7 @@ pub enum SignalJniError { Signal(SignalProtocolError), Jni(jni::errors::Error), BadJniParameter(&'static str), + UnexpectedJniResultType(&'static str, &'static str), NullHandle, IntegerOverflow(String), UnexpectedPanic(std::boxed::Box), @@ -40,6 +41,7 @@ impl fmt::Display for SignalJniError { SignalJniError::ExceptionDuringCallback(s) => write!(f, "exception recieved during callback {}", s), SignalJniError::NullHandle => write!(f, "null handle"), SignalJniError::BadJniParameter(m) => write!(f, "bad parameter type {}", m), + SignalJniError::UnexpectedJniResultType(m, t) => write!(f, "calling {} returned unexpected type {}", m, t), SignalJniError::IntegerOverflow(m) => { write!(f, "integer overflow during conversion of {}", m) } @@ -87,6 +89,7 @@ pub fn throw_error(env: &JNIEnv, error: SignalJniError) { SignalJniError::NullHandle => "java/lang/NullPointerException", SignalJniError::UnexpectedPanic(_) => "java/lang/AssertionError", SignalJniError::BadJniParameter(_) => "java/lang/AssertionError", + SignalJniError::UnexpectedJniResultType(_,_) => "java/lang/AssertionError", SignalJniError::IntegerOverflow(_) => "java/lang/RuntimeException", SignalJniError::ExceptionDuringCallback(_) => "java/lang/RuntimeException", From 7badc342a9e335cb38aad8249e3f47883c951513 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 18 Aug 2020 18:35:34 -0400 Subject: [PATCH 08/19] Add the other storage layer types --- src/lib.rs | 352 ++++++++++++++++++++++++++++++++++++++++++++-------- src/util.rs | 70 ++++++++++- 2 files changed, 365 insertions(+), 57 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 423bebc8e0..1f29e8ae1d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -847,7 +847,7 @@ fn sender_key_name_to_jobject<'a>(env: &'a JNIEnv, sender_key_name: &SenderKeyNa } fn protocol_address_to_jobject<'a>(env: &'a JNIEnv, address: &ProtocolAddress) -> Result, SignalJniError> { - let address_class = env.find_class("org/whispersystems/libsignal/ProtocolAddress")?; + let address_class = env.find_class("org/whispersystems/libsignal/SignalProtocolAddress")?; let address_ctor_args = [ JObject::from(env.new_string(address.name())?).into(), JValue::from(jint_from_u32(Ok(address.device_id()))?) @@ -871,7 +871,13 @@ impl<'a> JniIdentityKeyStore<'a> { impl<'a> JniIdentityKeyStore<'a> { fn do_get_identity_key_pair(&self) -> Result { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let callback_sig = "()Lorg/whispersystems/libsignal/IdentityKeyPair;"; + let bits = get_object_with_serialization(self.env, self.store, &[], callback_sig, "getIdentityKeyPair")?; + + match bits { + None => Err(SignalJniError::Signal(SignalProtocolError::InternalError("getIdentityKeyPair returned null"))), + Some(k) => Ok(IdentityKeyPair::try_from(k.as_ref())?), + } } fn do_get_local_registration_id(&self) -> Result { @@ -882,12 +888,22 @@ impl<'a> JniIdentityKeyStore<'a> { match rvalue { JValue::Int(i) => jint_to_u32(i), - _ => Err(SignalJniError::BadJniParameter("Unexpected return type from getLocalRegistrationId")) + _ => Err(SignalJniError::UnexpectedJniResultType("getLocalRegistrationId", rvalue.type_name())) } } fn do_save_identity(&mut self, address: &ProtocolAddress, identity: &IdentityKey) -> Result { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let address_jobject = protocol_address_to_jobject(self.env, address)?; + let key_jobject = jobject_from_serialized(self.env, "org/whispersystems/libsignal/IdentityKey", identity.serialize().as_ref())?; + let callback_sig = "(Lorg/whispersystems/libsignal/SignalProtocolAddress;Lorg/whispersystems/libsignal/IdentityKey;)Z"; + let callback_args = [address_jobject.into(), key_jobject.into()]; + let result = self.env.call_method(self.store, "saveIdentity", callback_sig, &callback_args)?; + exception_check(self.env)?; + + match result { + JValue::Bool(b) => Ok(b != 0), + _ => Err(SignalJniError::UnexpectedJniResultType("saveIdentity", result.type_name())) + } } fn do_is_trusted_identity( @@ -896,11 +912,24 @@ impl<'a> JniIdentityKeyStore<'a> { identity: &IdentityKey, direction: Direction, ) -> Result { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let address_jobject = protocol_address_to_jobject(self.env, address)?; + let key_jobject = jobject_from_serialized(self.env, "org/whispersystems/libsignal/IdentityKey", identity.serialize().as_ref())?; + + Ok(true) + //Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) } fn do_get_identity(&self, address: &ProtocolAddress) -> Result, SignalJniError> { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let address_jobject = protocol_address_to_jobject(self.env, address)?; + let callback_sig = "(Lorg/whispersystems/libsignal/SignalProtocolAddress;)Lorg/whispersystems/libsignal/IdentityKey;"; + let callback_args = [address_jobject.into()]; + + let bits = get_object_with_serialization(self.env, self.store, &callback_args, callback_sig, "getIdentity")?; + + match bits { + None => Ok(None), + Some(k) => Ok(Some(IdentityKey::decode(&k)?)), + } } } @@ -943,35 +972,15 @@ impl<'a> JniPreKeyStore<'a> { } } -fn get_object_with_native_handle(env: &JNIEnv, - store_obj: jobject, - callback_args: &[JValue], - callback_sig: &'static str, - callback_fn: &'static str) -> Result { - let rvalue = env.call_method(store_obj, callback_fn, callback_sig, &callback_args)?; - exception_check(env)?; - - let obj = match rvalue { - JValue::Object(o) => *o, - _ => return Err(SignalJniError::UnexpectedJniResultType(callback_fn, rvalue.type_name())) - }; - - let handle = env.call_method(obj, "nativeHandle", "()J", &[])?; - match handle { - JValue::Long(handle) => { - let object = unsafe { native_handle_cast::(handle)? }; - Ok(object.clone()) - } - _ => Err(SignalJniError::UnexpectedJniResultType("nativeHandle", handle.type_name())) - } -} - - impl<'a> JniPreKeyStore<'a> { fn do_get_pre_key(&self, prekey_id: u32) -> Result { let callback_sig = "(I)Lorg/whispersystems/libsignal/state/PreKeyRecord;"; let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?)]; - get_object_with_native_handle::(self.env, self.store, &callback_args, callback_sig, "loadPreKey") + let pk = get_object_with_native_handle::(self.env, self.store, &callback_args, callback_sig, "loadPreKey")?; + match pk { + Some(pk) => Ok(pk), + None => Err(SignalJniError::Signal(SignalProtocolError::InvalidPreKeyId)), + } } fn do_save_pre_key(&mut self, prekey_id: u32, record: &PreKeyRecord) -> Result<(), SignalJniError> { @@ -979,6 +988,7 @@ impl<'a> JniPreKeyStore<'a> { let callback_sig = "(I,Lorg/whispersystems/libsignal/state/PreKeyRecord;)V"; let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?), jobject_record.into()]; self.env.call_method(self.store, "storePreKey", callback_sig, &callback_args)?; + exception_check(self.env)?; Ok(()) } @@ -986,6 +996,7 @@ impl<'a> JniPreKeyStore<'a> { let callback_sig = "(I)V"; let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?)]; self.env.call_method(self.store, "removePreKey", callback_sig, &callback_args)?; + exception_check(self.env)?; Ok(()) } } @@ -1019,7 +1030,11 @@ impl<'a> JniSignedPreKeyStore<'a> { fn do_get_signed_pre_key(&self, prekey_id: u32) -> Result { let callback_sig = "(I)Lorg/whispersystems/libsignal/state/SignedPreKeyRecord;"; let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?)]; - get_object_with_native_handle::(self.env, self.store, &callback_args, callback_sig, "loadSignedPreKey") + let spk = get_object_with_native_handle::(self.env, self.store, &callback_args, callback_sig, "loadSignedPreKey")?; + match spk { + Some(spk) => Ok(spk), + None => Err(SignalJniError::Signal(SignalProtocolError::InvalidSignedPreKeyId)), + } } fn do_save_signed_pre_key(&mut self, prekey_id: u32, record: &SignedPreKeyRecord) -> Result<(), SignalJniError> { @@ -1027,6 +1042,7 @@ impl<'a> JniSignedPreKeyStore<'a> { let callback_sig = "(I,Lorg/whispersystems/libsignal/state/SignedPreKeyRecord;)V"; let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?), jobject_record.into()]; self.env.call_method(self.store, "storeSignedPreKey", callback_sig, &callback_args)?; + exception_check(self.env)?; Ok(()) } } @@ -1054,11 +1070,28 @@ impl<'a> JniSessionStore<'a> { impl<'a> JniSessionStore<'a> { fn do_load_session(&self, address: &ProtocolAddress) -> Result, SignalJniError> { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let address_jobject = protocol_address_to_jobject(self.env, address)?; + + let callback_sig = "(Lorg/whispersystems/libsignal/SignalProtocolAddress;)Lorg/whispersystems/libsignal/state/SessionRecord;"; + let callback_args = [address_jobject.into()]; + let session = get_object_with_serialization(self.env, self.store, &callback_args, callback_sig, "loadSession")?; + + match session { + None => Ok(None), + Some(s) => Ok(Some(SessionRecord::deserialize(&s)?)) + } } fn do_store_session(&mut self, address: &ProtocolAddress, record: &SessionRecord) -> Result<(), SignalJniError> { - Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let address_jobject = protocol_address_to_jobject(self.env, address)?; + let session_jobject = + jobject_from_serialized(self.env, "org/whispersystems/libsignal/state/SessionRecord", &record.serialize()?)?; + + let callback_sig = "(Lorg/whispersystems/libsignal/SignalProtocolAddress;Lorg/whispersystems/libsignal/state/SessionRecord;)V"; + let callback_args = [address_jobject.into(), session_jobject.into()]; + self.env.call_method(self.store, "storeSession", callback_sig, &callback_args)?; + exception_check(self.env)?; + Ok(()) } } @@ -1072,6 +1105,141 @@ impl<'a> SessionStore for JniSessionStore<'a> { } } +fn create_identity_store<'a>(env: &'a JNIEnv, obj: jobject) -> Result, SignalJniError> { + let identity_key_store = check_jobject_type(&env, obj, "org/whispersystems/libsignal/state/IdentityKeyStore")?; + Ok(JniIdentityKeyStore::new(&env, identity_key_store)) +} + +fn create_session_store<'a>(env: &'a JNIEnv, obj: jobject) -> Result, SignalJniError> { + let session_store = check_jobject_type(&env, obj, "org/whispersystems/libsignal/state/SessionStore")?; + Ok(JniSessionStore::new(&env, session_store)) +} + +fn create_prekey_store<'a>(env: &'a JNIEnv, obj: jobject) -> Result, SignalJniError> { + let prekey_store = check_jobject_type(&env, obj, "org/whispersystems/libsignal/state/PreKeyStore")?; + Ok(JniPreKeyStore::new(&env, prekey_store)) +} + +fn create_signed_prekey_store<'a>(env: &'a JNIEnv, obj: jobject) -> Result, SignalJniError> { + let signed_prekey_store = check_jobject_type(&env, obj, "org/whispersystems/libsignal/state/SignedPreKeyStore")?; + Ok(JniSignedPreKeyStore::new(&env, signed_prekey_store)) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionBuilder_ProcessPreKeyBundle( + env: JNIEnv, + _class: JClass, + bundle: ObjectHandle, + protocol_address: ObjectHandle, + session_store: jobject, + identity_key_store: jobject) { + + run_ffi_safe(&env, || { + let bundle = native_handle_cast::(bundle)?; + let protocol_address = native_handle_cast::(protocol_address)?; + + let mut identity_key_store = create_identity_store(&env, identity_key_store)?; + let mut session_store = create_session_store(&env, session_store)?; + + let mut csprng = rand::rngs::OsRng; + process_prekey_bundle(&protocol_address, &mut session_store, &mut identity_key_store, + bundle, &mut csprng)?; + + Ok(()) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_EncryptMessage( + env: JNIEnv, + _class: JClass, + message: jbyteArray, + protocol_address: ObjectHandle, + session_store: jobject, + identity_key_store: jobject) -> jobject { + + run_ffi_safe(&env, || { + let message = env.convert_byte_array(message)?; + let protocol_address = native_handle_cast::(protocol_address)?; + + let mut identity_key_store = create_identity_store(&env, identity_key_store)?; + let mut session_store = create_session_store(&env, session_store)?; + + let ctext = message_encrypt(&message, &protocol_address, &mut session_store, &mut identity_key_store)?; + + let obj = match ctext { + CiphertextMessage::SignalMessage(m) => { + jobject_from_native_handle(&env, + "org/whispersystems/libsignal/protocol/SignalMessage", + box_object::(Ok(m))?) + } + CiphertextMessage::PreKeySignalMessage(m) => { + jobject_from_native_handle(&env, + "org/whispersystems/libsignal/protocol/PreKeySignalMessage", + box_object::(Ok(m))?) + } + _ => Err(SignalJniError::Signal(SignalProtocolError::InternalError("Unexpected result type from message_encrypt"))) + }; + + Ok(obj?.into_inner()) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_DecryptSignalMessage( + env: JNIEnv, + _class: JClass, + message: ObjectHandle, + protocol_address: ObjectHandle, + session_store: jobject, + identity_key_store: jobject) -> jbyteArray { + + run_ffi_safe(&env, || { + let message = native_handle_cast::(message)?; + let protocol_address = native_handle_cast::(protocol_address)?; + + let mut identity_key_store = create_identity_store(&env, identity_key_store)?; + let mut session_store = create_session_store(&env, session_store)?; + + let mut csprng = rand::rngs::OsRng; + let ptext = message_decrypt_signal(&message, &protocol_address, &mut session_store, &mut identity_key_store, &mut csprng)?; + + to_jbytearray(&env, Ok(ptext)) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_DecryptPreKeySignalMessage( + env: JNIEnv, + _class: JClass, + message: ObjectHandle, + protocol_address: ObjectHandle, + session_store: jobject, + identity_key_store: jobject, + prekey_store: jobject, + signed_prekey_store: jobject) -> jbyteArray { + + run_ffi_safe(&env, || { + let message = native_handle_cast::(message)?; + let protocol_address = native_handle_cast::(protocol_address)?; + let mut identity_key_store = create_identity_store(&env, identity_key_store)?; + let mut session_store = create_session_store(&env, session_store)?; + let mut prekey_store = create_prekey_store(&env, prekey_store)?; + let mut signed_prekey_store = create_signed_prekey_store(&env, signed_prekey_store)?; + + let mut csprng = rand::rngs::OsRng; + let ptext = message_decrypt_prekey(&message, + &protocol_address, + &mut session_store, + &mut identity_key_store, + &mut prekey_store, + &mut signed_prekey_store, + &mut csprng)?; + + to_jbytearray(&env, Ok(ptext)) + }) +} + pub struct JniSenderKeyStore<'a> { env: &'a JNIEnv<'a>, store: jobject, @@ -1114,28 +1282,11 @@ impl<'a> JniSenderKeyStore<'a> { let callback_args = [sender_key_name_jobject.into()]; let callback_sig = "(Lorg/whispersystems/libsignal/groups/SenderKeyName;)Lorg/whispersystems/libsignal/groups/state/SenderKeyRecord;"; - let skr_obj = self.env.call_method(self.store, "loadSenderKey", callback_sig, &callback_args[..])?; - exception_check(self.env)?; - - let skr_obj = match skr_obj { - JValue::Object(o) => *o, - _ => { - return Err(SignalJniError::BadJniParameter("loadSenderKey returned non-object")) - } - }; - - let serialized_bytes = self.env.call_method(skr_obj, "serialize", "()[B", &[])?; - exception_check(self.env)?; + let skr = get_object_with_serialization(self.env, self.store, &callback_args, callback_sig, "loadSenderKey")?; - match serialized_bytes { - JValue::Object(o) => { - let bytes = self.env.convert_byte_array(*o)?; - let skr = SenderKeyRecord::deserialize(&bytes)?; - Ok(Some(skr)) - } - _ => { - Err(SignalJniError::BadJniParameter("SenderKeyRecord::serialize returned unexpected type")) - } + match skr { + None => Ok(None), + Some(k) => Ok(Some(SenderKeyRecord::deserialize(&k)?)) } } } @@ -1240,3 +1391,94 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCiph }) } +// The following are just exposed to make it possible to retain some of the Java tests: + +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionState_InitializeAliceSession( + env: JNIEnv, + _class: JClass, + identity_key_private: ObjectHandle, + identity_key_public: ObjectHandle, + base_private: ObjectHandle, + base_public: ObjectHandle, + their_identity_key: ObjectHandle, + their_signed_prekey: ObjectHandle, + their_ratchet_key: ObjectHandle) -> jbyteArray { + + run_ffi_safe(&env, || { + let identity_key_private = native_handle_cast::(identity_key_private)?; + let identity_key_public = native_handle_cast::(identity_key_public)?; + let base_private = native_handle_cast::(base_private)?; + let base_public = native_handle_cast::(base_public)?; + let their_identity_key = native_handle_cast::(their_identity_key)?; + let their_signed_prekey = native_handle_cast::(their_signed_prekey)?; + let their_ratchet_key = native_handle_cast::(their_ratchet_key)?; + + let our_identity_key_pair = IdentityKeyPair::new( + IdentityKey::new(*identity_key_public), *identity_key_private); + + let our_base_key_pair = KeyPair::new(*base_public, *base_private); + + let their_identity_key = IdentityKey::new(*their_identity_key); + + let mut csprng = rand::rngs::OsRng; + + let parameters = AliceSignalProtocolParameters::new( + our_identity_key_pair, + our_base_key_pair, + their_identity_key, + *their_signed_prekey, + None, + *their_ratchet_key); + + let session = initialize_alice_session(¶meters, &mut csprng)?; + + to_jbytearray(&env, session.serialize()) + }) +} + +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionState_InitializeBobSession( + env: JNIEnv, + _class: JClass, + identity_key_private: ObjectHandle, + identity_key_public: ObjectHandle, + signed_prekey_private: ObjectHandle, + signed_prekey_public: ObjectHandle, + eph_private: ObjectHandle, + eph_public: ObjectHandle, + their_identity_key: ObjectHandle, + their_base_key: ObjectHandle) -> jbyteArray { + + run_ffi_safe(&env, || { + let identity_key_private = native_handle_cast::(identity_key_private)?; + let identity_key_public = native_handle_cast::(identity_key_public)?; + let signed_prekey_private = native_handle_cast::(signed_prekey_private)?; + let signed_prekey_public = native_handle_cast::(signed_prekey_public)?; + let eph_private = native_handle_cast::(eph_private)?; + let eph_public = native_handle_cast::(eph_public)?; + let their_identity_key = native_handle_cast::(their_identity_key)?; + let their_base_key = native_handle_cast::(their_base_key)?; + + let our_identity_key_pair = IdentityKeyPair::new( + IdentityKey::new(*identity_key_public), *identity_key_private); + + let our_signed_pre_key_pair = KeyPair::new(*signed_prekey_public, *signed_prekey_private); + + let our_ratchet_key_pair = KeyPair::new(*eph_public, *eph_private); + + let their_identity_key = IdentityKey::new(*their_identity_key); + + let parameters = BobSignalProtocolParameters::new( + our_identity_key_pair, + our_signed_pre_key_pair, + None, + our_ratchet_key_pair, + their_identity_key, + *their_base_key); + + let session = initialize_bob_session(¶meters)?; + + to_jbytearray(&env, session.serialize()) + }) +} diff --git a/src/util.rs b/src/util.rs index 3e22a62f09..3e0984e154 100644 --- a/src/util.rs +++ b/src/util.rs @@ -68,7 +68,7 @@ impl From for SignalJniError { impl From for SignalProtocolError { fn from(err: SignalJniError) -> SignalProtocolError { match err { - SignalJniError::Signal(e) => e.clone(), + SignalJniError::Signal(e) => e, SignalJniError::Jni(e) => { SignalProtocolError::FfiBindingError(e.to_string()) } @@ -105,6 +105,7 @@ pub fn throw_error(env: &JNIEnv, error: SignalJniError) { } SignalJniError::Signal(SignalProtocolError::NoKeyTypeIdentifier) + | SignalJniError::Signal(SignalProtocolError::SignatureValidationFailed) | SignalJniError::Signal(SignalProtocolError::BadKeyType(_)) | SignalJniError::Signal(SignalProtocolError::BadKeyLength(_, _)) => { "org/whispersystems/libsignal/InvalidKeyException" @@ -312,7 +313,7 @@ pub fn exception_check(env: &JNIEnv) -> Result<(), SignalJniError> { } pub fn check_jobject_type(env: &JNIEnv, obj: jobject, class_name: &'static str) -> Result { - if obj == std::ptr::null_mut() { + if obj.is_null() { return Err(SignalJniError::NullHandle); } @@ -325,6 +326,64 @@ pub fn check_jobject_type(env: &JNIEnv, obj: jobject, class_name: &'static str) Ok(obj) } +pub fn get_object_with_native_handle(env: &JNIEnv, + store_obj: jobject, + callback_args: &[JValue], + callback_sig: &'static str, + callback_fn: &'static str) -> Result, SignalJniError> { + let rvalue = env.call_method(store_obj, callback_fn, callback_sig, &callback_args)?; + exception_check(env)?; + + let obj = match rvalue { + JValue::Object(o) => *o, + _ => return Err(SignalJniError::UnexpectedJniResultType(callback_fn, rvalue.type_name())) + }; + + if obj.is_null() { + return Ok(None); + } + + let handle = env.call_method(obj, "nativeHandle", "()J", &[])?; + exception_check(env)?; + match handle { + JValue::Long(handle) => { + let object = unsafe { native_handle_cast::(handle)? }; + Ok(Some(object.clone())) + } + _ => Err(SignalJniError::UnexpectedJniResultType("nativeHandle", handle.type_name())) + } +} + +pub fn get_object_with_serialization(env: &JNIEnv, + store_obj: jobject, + callback_args: &[JValue], + callback_sig: &'static str, + callback_fn: &'static str) -> Result>, SignalJniError> { + let rvalue = env.call_method(store_obj, callback_fn, callback_sig, &callback_args)?; + exception_check(env)?; + + let obj = match rvalue { + JValue::Object(o) => *o, + _ => return Err(SignalJniError::UnexpectedJniResultType(callback_fn, rvalue.type_name())) + }; + + if obj.is_null() { + return Ok(None); + } + + let bytes = env.call_method(obj, "serialize", "()[B", &[])?; + exception_check(env)?; + + match bytes { + JValue::Object(o) => { + Ok(Some(env.convert_byte_array(*o)?)) + } + _ => { + return Err(SignalJniError::UnexpectedJniResultType("serialize", bytes.type_name())) + } + } +} + pub fn jobject_from_serialized<'a>(env: &'a JNIEnv, class_name: &str, serialized: &[u8]) -> Result, SignalJniError> { let class_type = env.find_class(class_name)?; let ctor_sig = "([B)V"; @@ -332,6 +391,13 @@ pub fn jobject_from_serialized<'a>(env: &'a JNIEnv, class_name: &str, serialized Ok(env.new_object(class_type, ctor_sig, &ctor_args)?) } +pub fn jobject_from_native_handle<'a>(env: &'a JNIEnv, class_name: &str, boxed_handle: ObjectHandle) -> Result, SignalJniError> { + let class_type = env.find_class(class_name)?; + let ctor_sig = "(J)V"; + let ctor_args = [JValue::from(boxed_handle)]; + Ok(env.new_object(class_type, ctor_sig, &ctor_args)?) +} + #[macro_export] macro_rules! jni_fn_deserialize { ( $nm:ident is $func:path ) => { From 380356fba0499bb2ad8c4b65f0dce43084b18836 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 20 Aug 2020 14:11:07 -0400 Subject: [PATCH 09/19] Remove unused endpoints Also fix isTrustedIdentity which was still just a stub Fix some bugs around error reporting and choice of exception --- src/lib.rs | 135 +++++++--------------------------------------------- src/util.rs | 14 ++++-- 2 files changed, 29 insertions(+), 120 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1f29e8ae1d..c4a0a70f1c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,5 @@ #![allow(clippy::missing_safety_doc)] +#![deny(warnings)] use jni::objects::{JClass, JString, JValue, JObject}; use jni::sys::{jboolean, jbyteArray, jint, jlong, jstring, jobject}; @@ -10,48 +11,6 @@ mod util; use crate::util::*; -struct SeedAndIteration { - seed: Vec, - iteration: u32 -} - -impl SeedAndIteration { - fn new(seed: Vec, iteration: u32) -> Self { - Self { seed, iteration } - } - - fn seed(&self) -> Result, SignalProtocolError> { - Ok(self.seed.clone()) - } - - fn iteration(&self) -> Result { - Ok(self.iteration) - } -} - -/* SeedAndIteration (utility class) */ -#[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_util_SeedAndIteration_New( - env: JNIEnv, - _class: JClass, - seed: jbyteArray, - iteration: jint -) -> ObjectHandle { - run_ffi_safe(&env, || { - let seed = env.convert_byte_array(seed)?; - let iteration = jint_to_u32(iteration)?; - box_object::(Ok(SeedAndIteration::new(seed, iteration))) - }) -} - -jni_fn_destroy!(Java_org_whispersystems_libsignal_util_SeedAndIteration_Destroy destroys SeedAndIteration); - -jni_fn_get_jint!(Java_org_whispersystems_libsignal_util_SeedAndIteration_GetIteration(SeedAndIteration) using - |si: &SeedAndIteration| si.iteration()); - -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_util_SeedAndIteration_GetSeed(SeedAndIteration) using - |si: &SeedAndIteration| si.seed()); - #[no_mangle] pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SignalProtocolAddress_New( env: JNIEnv, @@ -760,79 +719,6 @@ jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_groups_state_SenderK jni_fn_get_new_boxed_optional_obj!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetSigningKeyPrivate(PrivateKey) from SenderKeyState, |sks: &SenderKeyState| sks.signing_key_private()); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetSenderChainKeySeed(SenderKeyState) using - |sks: &SenderKeyState| sks.sender_chain_key()?.seed()); - -jni_fn_get_jint!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetSenderChainKeyIteration(SenderKeyState) using - |sks: &SenderKeyState| sks.sender_chain_key()?.iteration()); - -#[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_SetSenderChainKey( - env: JNIEnv, - _class: JClass, - handle: ObjectHandle, - iteration: jint, - seed: jbyteArray) { - run_ffi_safe(&env, || { - let sender_key_state = native_handle_cast::(handle)?; - let iteration = jint_to_u32(iteration)?; - let seed = env.convert_byte_array(seed)?; - - let sender_chain = SenderChainKey::new(iteration, seed)?; - sender_key_state.set_sender_chain_key(sender_chain)?; - Ok(()) - }) -} - -#[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_AddSenderMessageKey( - env: JNIEnv, - _class: JClass, - handle: ObjectHandle, - iteration: jint, - seed: jbyteArray) { - run_ffi_safe(&env, || { - let sender_key_state = native_handle_cast::(handle)?; - let iteration = jint_to_u32(iteration)?; - let seed = env.convert_byte_array(seed)?; - let sender_message_key = SenderMessageKey::new(iteration, seed)?; - sender_key_state.add_sender_message_key(&sender_message_key)?; - Ok(()) - }) -} - -#[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_HasSenderMessageKey( - env: JNIEnv, - _class: JClass, - handle: ObjectHandle, - iteration: jint) -> jboolean { - run_ffi_safe(&env, || { - let sender_key_state = native_handle_cast::(handle)?; - let iteration = jint_to_u32(iteration)?; - Ok(sender_key_state.has_sender_message_key(iteration)? as jboolean) - }) -} - -#[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_RemoveSenderMessageKey( - env: JNIEnv, - _class: JClass, - handle: ObjectHandle, - iteration: jint) -> ObjectHandle { - run_ffi_safe(&env, || { - let sender_key_state = native_handle_cast::(handle)?; - let iteration = jint_to_u32(iteration)?; - - if let Some(sender_key) = sender_key_state.remove_sender_message_key(iteration)? { - let sai = SeedAndIteration::new(sender_key.seed()?, sender_key.iteration()?); - box_object::(Ok(sai)) - } else { - Ok(0 as ObjectHandle) - } - }) -} - fn sender_key_name_to_jobject<'a>(env: &'a JNIEnv, sender_key_name: &SenderKeyName) -> Result, SignalJniError> { let sender_key_name_class = env.find_class("org/whispersystems/libsignal/groups/SenderKeyName")?; let sender_key_name_ctor_args = [ @@ -915,8 +801,23 @@ impl<'a> JniIdentityKeyStore<'a> { let address_jobject = protocol_address_to_jobject(self.env, address)?; let key_jobject = jobject_from_serialized(self.env, "org/whispersystems/libsignal/IdentityKey", identity.serialize().as_ref())?; - Ok(true) - //Err(SignalJniError::Signal(SignalProtocolError::InternalError("todo"))) + let direction_class = self.env.find_class("org/whispersystems/libsignal/state/IdentityKeyStore$Direction")?; + let field_name = match direction { + Direction::Sending => "SENDING", + Direction::Receiving => "RECEIVING", + }; + + let field_value = self.env.get_static_field(direction_class, field_name, "Lorg/whispersystems/libsignal/state/IdentityKeyStore$Direction;")?; + + let callback_sig = "(Lorg/whispersystems/libsignal/SignalProtocolAddress;Lorg/whispersystems/libsignal/IdentityKey;Lorg/whispersystems/libsignal/state/IdentityKeyStore$Direction;)Z"; + let callback_args = [address_jobject.into(), key_jobject.into(), field_value]; + let result = self.env.call_method(self.store, "isTrustedIdentity", callback_sig, &callback_args)?; + exception_check(self.env)?; + + match result { + JValue::Bool(b) => Ok(b != 0), + _ => Err(SignalJniError::UnexpectedJniResultType("isTrustedIdentity", result.type_name())) + } } fn do_get_identity(&self, address: &ProtocolAddress) -> Result, SignalJniError> { diff --git a/src/util.rs b/src/util.rs index 3e0984e154..c8e61cec7f 100644 --- a/src/util.rs +++ b/src/util.rs @@ -83,8 +83,6 @@ impl From for SignalProtocolError { } pub fn throw_error(env: &JNIEnv, error: SignalJniError) { - let error_string = format!("{}", error); - let exception_type = match error { SignalJniError::NullHandle => "java/lang/NullPointerException", SignalJniError::UnexpectedPanic(_) => "java/lang/AssertionError", @@ -128,6 +126,10 @@ pub fn throw_error(env: &JNIEnv, error: SignalJniError) { "org/whispersystems/libsignal/LegacyMessageException" } + SignalJniError::Signal(SignalProtocolError::UntrustedIdentity(_)) => { + "org/whispersystems/libsignal/UntrustedIdentityException" + } + SignalJniError::Signal(SignalProtocolError::InvalidState(_, _)) | SignalJniError::Signal(SignalProtocolError::NoSenderKeyState) | SignalJniError::Signal(SignalProtocolError::InvalidSessionStructure) => { @@ -143,6 +145,12 @@ pub fn throw_error(env: &JNIEnv, error: SignalJniError) { SignalJniError::Jni(_) => "java/lang/RuntimeException", }; + + let error_string = match error { + SignalJniError::Signal(SignalProtocolError::UntrustedIdentity(addr)) => addr.name().to_string(), + e => format!("{}", e) + }; + let _ = env.throw_new(exception_type, error_string); } @@ -379,7 +387,7 @@ pub fn get_object_with_serialization(env: &JNIEnv, Ok(Some(env.convert_byte_array(*o)?)) } _ => { - return Err(SignalJniError::UnexpectedJniResultType("serialize", bytes.type_name())) + Err(SignalJniError::UnexpectedJniResultType("serialize", bytes.type_name())) } } } From 944bc9987f339f9393fba3aef4d9e4716f59a2e3 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 24 Aug 2020 15:50:46 -0400 Subject: [PATCH 10/19] add 'native' prefix to all JNI functions The current uppercase leading char is unusual for Java, and having a `native` prefix makes it more clear what is happening on the Java side. --- src/lib.rs | 212 ++++++++++++++++++++++++++--------------------------- 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c4a0a70f1c..955a911f4a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,7 +12,7 @@ mod util; use crate::util::*; #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SignalProtocolAddress_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SignalProtocolAddress_nativeNew( env: JNIEnv, _class: JClass, name: JString, @@ -26,21 +26,21 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SignalProtocolAd }) } -jni_fn_destroy!(Java_org_whispersystems_libsignal_SignalProtocolAddress_Destroy destroys ProtocolAddress); +jni_fn_destroy!(Java_org_whispersystems_libsignal_SignalProtocolAddress_nativeDestroy destroys ProtocolAddress); -jni_fn_get_jstring!(Java_org_whispersystems_libsignal_SignalProtocolAddress_Name(ProtocolAddress) using +jni_fn_get_jstring!(Java_org_whispersystems_libsignal_SignalProtocolAddress_nativeName(ProtocolAddress) using |p: &ProtocolAddress| Ok(p.name().to_string())); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_SignalProtocolAddress_DeviceId(ProtocolAddress) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_SignalProtocolAddress_nativeDeviceId(ProtocolAddress) using |obj: &ProtocolAddress| { Ok(obj.device_id()) }); -jni_fn_deserialize!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_Deserialize is PublicKey::deserialize); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_nativeDeserialize is PublicKey::deserialize); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_Serialize(PublicKey) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_nativeSerialize(PublicKey) using |k: &PublicKey| Ok(k.serialize())); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPublicKey_Verify( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPublicKey_nativeVerify( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -55,15 +55,15 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPublicKey_ }) } -jni_fn_destroy!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_Destroy destroys PublicKey); +jni_fn_destroy!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_nativeDestroy destroys PublicKey); -jni_fn_deserialize!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Deserialize is PrivateKey::deserialize); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_nativeDeserialize is PrivateKey::deserialize); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Serialize(PrivateKey) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_nativeSerialize(PrivateKey) using |k: &PrivateKey| Ok(k.serialize())); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Generate( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey_nativeGenerate( env: JNIEnv, _class: JClass, ) -> ObjectHandle { @@ -74,11 +74,11 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey }) } -jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_GetPublicKey(PublicKey) from PrivateKey, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_nativeGetPublicKey(PublicKey) from PrivateKey, |k: &PrivateKey| k.public_key()); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Sign( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey_nativeSign( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -94,7 +94,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey } #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Agree( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey_nativeAgree( env: JNIEnv, _class: JClass, private_key_handle: ObjectHandle, @@ -108,10 +108,10 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPrivateKey }) } -jni_fn_destroy!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_Destroy destroys PrivateKey); +jni_fn_destroy!(Java_org_whispersystems_libsignal_ecc_ECPrivateKey_nativeDestroy destroys PrivateKey); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_DisplayableFingerprint_Format( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_DisplayableFingerprint_nativeFormat( env: JNIEnv, _class: JClass, local: jbyteArray, @@ -127,7 +127,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_Disp } #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_nativeNew( env: JNIEnv, _class: JClass, iterations: jint, @@ -162,16 +162,16 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_Nume }) } -jni_fn_destroy!(Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_Destroy destroys Fingerprint); +jni_fn_destroy!(Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_nativeDestroy destroys Fingerprint); -jni_fn_get_jstring!(Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_GetDisplayString(Fingerprint) using +jni_fn_get_jstring!(Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_nativeGetDisplayString(Fingerprint) using Fingerprint::display_string); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_GetScannableEncoding(Fingerprint) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_fingerprint_NumericFingerprintGenerator_nativeGetScannableEncoding(Fingerprint) using |f: &Fingerprint| f.scannable.serialize()); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_ScannableFingerprint_Compare( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_ScannableFingerprint_nativeCompare( env: JNIEnv, _class: JClass, fprint1: jbyteArray, @@ -187,7 +187,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_fingerprint_Scan } #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_kdf_HKDF_DeriveSecrets( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_kdf_HKDF_nativeDeriveSecrets( env: JNIEnv, _class: JClass, version: jint, @@ -221,10 +221,10 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_kdf_HKDF_DeriveS }) } -jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_SignalMessage_Deserialize is SignalMessage::try_from); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_SignalMessage_nativeDeserialize is SignalMessage::try_from); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SignalMessage_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SignalMessage_nativeNew( env: JNIEnv, _class: JClass, message_version: jint, @@ -262,24 +262,24 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SignalM }) } -jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_SignalMessage_Destroy destroys SignalMessage); +jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_SignalMessage_nativeDestroy destroys SignalMessage); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SignalMessage_GetSenderRatchetKey(SignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SignalMessage_nativeGetSenderRatchetKey(SignalMessage) using |m: &SignalMessage| Ok(m.sender_ratchet_key().serialize())); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SignalMessage_GetBody(SignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SignalMessage_nativeGetBody(SignalMessage) using |m: &SignalMessage| Ok(m.body().to_vec())); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SignalMessage_GetSerialized(SignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SignalMessage_nativeGetSerialized(SignalMessage) using |m: &SignalMessage| Ok(m.serialized().to_vec())); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SignalMessage_GetMessageVersion(SignalMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SignalMessage_nativeGetMessageVersion(SignalMessage) using |msg: &SignalMessage| { Ok(msg.message_version() as u32) }); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SignalMessage_GetCounter(SignalMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SignalMessage_nativeGetCounter(SignalMessage) using |msg: &SignalMessage| { Ok(msg.counter()) }); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SignalMessage_VerifyMac( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SignalMessage_nativeVerifyMac( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -303,10 +303,10 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SignalM }) } -jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_Deserialize is PreKeySignalMessage::try_from); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_nativeDeserialize is PreKeySignalMessage::try_from); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_nativeNew( env: JNIEnv, _class: JClass, message_version: jint, @@ -343,17 +343,17 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_PreKeyS }) } -jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_Destroy destroys PreKeySignalMessage); +jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_nativeDestroy destroys PreKeySignalMessage); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetVersion(PreKeySignalMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_nativeGetVersion(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.message_version() as u32)); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetRegistrationId(PreKeySignalMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_nativeGetRegistrationId(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.registration_id())); // Special logic to handle optionality: #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetPreKeyId( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_nativeGetPreKeyId( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -367,25 +367,25 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_PreKeyS }) } -jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetSignedPreKeyId(PreKeySignalMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_nativeGetSignedPreKeyId(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.signed_pre_key_id())); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetBaseKey(PreKeySignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_nativeGetBaseKey(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.base_key().serialize())); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetIdentityKey(PreKeySignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_nativeGetIdentityKey(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.identity_key().serialize())); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetSignalMessage(PreKeySignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_nativeGetSignalMessage(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.message().serialized().to_vec())); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_GetSerialized(PreKeySignalMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_PreKeySignalMessage_nativeGetSerialized(PreKeySignalMessage) using |m: &PreKeySignalMessage| Ok(m.serialized().to_vec())); -jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_Deserialize is SenderKeyMessage::try_from); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_nativeDeserialize is SenderKeyMessage::try_from); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_nativeNew( env: JNIEnv, _class: JClass, key_id: jint, @@ -404,24 +404,24 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderK }) } -jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_Deserialize is SenderKeyDistributionMessage::try_from); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_nativeDeserialize is SenderKeyDistributionMessage::try_from); -jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_Destroy destroys SenderKeyMessage); +jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_nativeDestroy destroys SenderKeyMessage); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_GetKeyId(SenderKeyMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_nativeGetKeyId(SenderKeyMessage) using |m: &SenderKeyMessage| Ok(m.key_id())); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_GetIteration(SenderKeyMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_nativeGetIteration(SenderKeyMessage) using |m: &SenderKeyMessage| Ok(m.iteration())); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_GetCipherText(SenderKeyMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_nativeGetCipherText(SenderKeyMessage) using |m: &SenderKeyMessage| Ok(m.ciphertext().to_vec())); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_GetSerialized(SenderKeyMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_nativeGetSerialized(SenderKeyMessage) using |m: &SenderKeyMessage| Ok(m.serialized().to_vec())); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_VerifySignature( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderKeyMessage_nativeVerifySignature( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -436,7 +436,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderK } #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_nativeNew( env: JNIEnv, _class: JClass, key_id: jint, @@ -454,25 +454,25 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_protocol_SenderK }) } -jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_Destroy destroys SenderKeyDistributionMessage); +jni_fn_destroy!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_nativeDestroy destroys SenderKeyDistributionMessage); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_GetId(SenderKeyDistributionMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_nativeGetId(SenderKeyDistributionMessage) using |m: &SenderKeyDistributionMessage| m.id()); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_GetIteration(SenderKeyDistributionMessage) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_nativeGetIteration(SenderKeyDistributionMessage) using |m: &SenderKeyDistributionMessage| m.iteration()); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_GetChainKey(SenderKeyDistributionMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_nativeGetChainKey(SenderKeyDistributionMessage) using |m: &SenderKeyDistributionMessage| Ok(m.chain_key()?.to_vec())); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_GetSignatureKey(SenderKeyDistributionMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_nativeGetSignatureKey(SenderKeyDistributionMessage) using |m: &SenderKeyDistributionMessage| Ok(m.signing_key()?.serialize())); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_GetSerialized(SenderKeyDistributionMessage) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_protocol_SenderKeyDistributionMessage_nativeGetSerialized(SenderKeyDistributionMessage) using |m: &SenderKeyDistributionMessage| Ok(m.serialized().to_vec())); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyBundle_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyBundle_nativeNew( env: JNIEnv, _class: JClass, registration_id: jint, @@ -516,20 +516,20 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyBund }) } -jni_fn_destroy!(Java_org_whispersystems_libsignal_state_PreKeyBundle_Destroy destroys PreKeyBundle); +jni_fn_destroy!(Java_org_whispersystems_libsignal_state_PreKeyBundle_nativeDestroy destroys PreKeyBundle); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetRegistrationId(PreKeyBundle) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyBundle_nativeGetRegistrationId(PreKeyBundle) using |m: &PreKeyBundle| m.registration_id()); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetDeviceId(PreKeyBundle) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyBundle_nativeGetDeviceId(PreKeyBundle) using |m: &PreKeyBundle| m.device_id()); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetSignedPreKeyId(PreKeyBundle) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyBundle_nativeGetSignedPreKeyId(PreKeyBundle) using |m: &PreKeyBundle| m.signed_pre_key_id()); // Special logic for optional here: #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyBundle_GetPreKeyId( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyBundle_nativeGetPreKeyId( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -543,22 +543,22 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyBund }) } -jni_fn_get_new_boxed_optional_obj!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetPreKeyPublic(PublicKey) from PreKeyBundle, +jni_fn_get_new_boxed_optional_obj!(Java_org_whispersystems_libsignal_state_PreKeyBundle_nativeGetPreKeyPublic(PublicKey) from PreKeyBundle, |p: &PreKeyBundle| p.pre_key_public()); -jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetSignedPreKeyPublic(PublicKey) from PreKeyBundle, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyBundle_nativeGetSignedPreKeyPublic(PublicKey) from PreKeyBundle, |p: &PreKeyBundle| Ok(p.signed_pre_key_public()?)); -jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetIdentityKey(PublicKey) from PreKeyBundle, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyBundle_nativeGetIdentityKey(PublicKey) from PreKeyBundle, |p: &PreKeyBundle| Ok(*p.identity_key()?.public_key())); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_PreKeyBundle_GetSignedPreKeySignature(PreKeyBundle) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_PreKeyBundle_nativeGetSignedPreKeySignature(PreKeyBundle) using |m: &PreKeyBundle| Ok(m.signed_pre_key_signature()?.to_vec())); /* SignedPreKeyRecord */ #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_nativeNew( env: JNIEnv, _class: JClass, id: jint, @@ -581,13 +581,13 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SignedPreK }) } -jni_fn_deserialize!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_Deserialize is SignedPreKeyRecord::deserialize); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_nativeDeserialize is SignedPreKeyRecord::deserialize); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetId(SignedPreKeyRecord) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_nativeGetId(SignedPreKeyRecord) using |m: &SignedPreKeyRecord| m.id()); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetTimestamp( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_nativeGetTimestamp( env: JNIEnv, _class: JClass, handle: ObjectHandle, @@ -598,24 +598,24 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SignedPreK }) } -jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetPublicKey(PublicKey) from SignedPreKeyRecord, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_nativeGetPublicKey(PublicKey) from SignedPreKeyRecord, |p: &SignedPreKeyRecord| p.public_key()); -jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetPrivateKey(PrivateKey) from SignedPreKeyRecord, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_nativeGetPrivateKey(PrivateKey) from SignedPreKeyRecord, |p: &SignedPreKeyRecord| p.private_key()); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetSignature(SignedPreKeyRecord) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_nativeGetSignature(SignedPreKeyRecord) using |m: &SignedPreKeyRecord| m.signature()); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_GetSerialized(SignedPreKeyRecord) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_nativeGetSerialized(SignedPreKeyRecord) using |m: &SignedPreKeyRecord| m.serialize()); -jni_fn_destroy!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_Destroy destroys SignedPreKeyRecord); +jni_fn_destroy!(Java_org_whispersystems_libsignal_state_SignedPreKeyRecord_nativeDestroy destroys SignedPreKeyRecord); /* PreKeyRecord */ #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyRecord_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyRecord_nativeNew( env: JNIEnv, _class: JClass, id: jint, @@ -634,26 +634,26 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_PreKeyReco }) } -jni_fn_deserialize!(Java_org_whispersystems_libsignal_state_PreKeyRecord_Deserialize is PreKeyRecord::deserialize); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_state_PreKeyRecord_nativeDeserialize is PreKeyRecord::deserialize); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyRecord_GetId(PreKeyRecord) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_state_PreKeyRecord_nativeGetId(PreKeyRecord) using |m: &PreKeyRecord| m.id()); -jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyRecord_GetPublicKey(PublicKey) from PreKeyRecord, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyRecord_nativeGetPublicKey(PublicKey) from PreKeyRecord, |p: &PreKeyRecord| p.public_key()); -jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyRecord_GetPrivateKey(PrivateKey) from PreKeyRecord, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_state_PreKeyRecord_nativeGetPrivateKey(PrivateKey) from PreKeyRecord, |p: &PreKeyRecord| p.private_key()); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_PreKeyRecord_GetSerialized(PreKeyRecord) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_state_PreKeyRecord_nativeGetSerialized(PreKeyRecord) using |m: &PreKeyRecord| m.serialize()); -jni_fn_destroy!(Java_org_whispersystems_libsignal_state_PreKeyRecord_Destroy destroys PreKeyRecord); +jni_fn_destroy!(Java_org_whispersystems_libsignal_state_PreKeyRecord_nativeDestroy destroys PreKeyRecord); /* SenderKeyName */ #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_SenderKeyName_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_SenderKeyName_nativeNew( env: JNIEnv, _class: JClass, group_id: JString, @@ -669,20 +669,20 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_SenderKey }) } -jni_fn_destroy!(Java_org_whispersystems_libsignal_groups_SenderKeyName_Destroy destroys SenderKeyName); +jni_fn_destroy!(Java_org_whispersystems_libsignal_groups_SenderKeyName_nativeDestroy destroys SenderKeyName); -jni_fn_get_jstring!(Java_org_whispersystems_libsignal_groups_SenderKeyName_GetGroupId(SenderKeyName) using +jni_fn_get_jstring!(Java_org_whispersystems_libsignal_groups_SenderKeyName_nativeGetGroupId(SenderKeyName) using SenderKeyName::group_id); -jni_fn_get_jstring!(Java_org_whispersystems_libsignal_groups_SenderKeyName_GetSenderName(SenderKeyName) using +jni_fn_get_jstring!(Java_org_whispersystems_libsignal_groups_SenderKeyName_nativeGetSenderName(SenderKeyName) using |skn: &SenderKeyName| { Ok(skn.sender()?.name().to_string()) }); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_groups_SenderKeyName_GetSenderDeviceId(SenderKeyName) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_groups_SenderKeyName_nativeGetSenderDeviceId(SenderKeyName) using |m: &SenderKeyName| Ok(m.sender()?.device_id())); #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_New( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_nativeNew( env: JNIEnv, _class: JClass, id: jint, @@ -703,20 +703,20 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_Sen }) } -jni_fn_destroy!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_Destroy destroys SenderKeyState); +jni_fn_destroy!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_nativeDestroy destroys SenderKeyState); -jni_fn_deserialize!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_Deserialize is SenderKeyState::deserialize); +jni_fn_deserialize!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_nativeDeserialize is SenderKeyState::deserialize); -jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetSerialized(SenderKeyState) using +jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_nativeGetSerialized(SenderKeyState) using |sks: &SenderKeyState| sks.serialize()); -jni_fn_get_jint!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetKeyId(SenderKeyState) using +jni_fn_get_jint!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_nativeGetKeyId(SenderKeyState) using |sks: &SenderKeyState| sks.sender_key_id()); -jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetSigningKeyPublic(PublicKey) from SenderKeyState, +jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_nativeGetSigningKeyPublic(PublicKey) from SenderKeyState, |sks: &SenderKeyState| sks.signing_key_public()); -jni_fn_get_new_boxed_optional_obj!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_GetSigningKeyPrivate(PrivateKey) from SenderKeyState, +jni_fn_get_new_boxed_optional_obj!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_nativeGetSigningKeyPrivate(PrivateKey) from SenderKeyState, |sks: &SenderKeyState| sks.signing_key_private()); fn sender_key_name_to_jobject<'a>(env: &'a JNIEnv, sender_key_name: &SenderKeyName) -> Result, SignalJniError> { @@ -1027,7 +1027,7 @@ fn create_signed_prekey_store<'a>(env: &'a JNIEnv, obj: jobject) -> Result SenderKeyStore for JniSenderKeyStore<'a> { } #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSessionBuilder_CreateSenderKeyDistributionMessage( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSessionBuilder_nativeCreateSenderKeyDistributionMessage( env: JNIEnv, _class: JClass, sender_key_name: ObjectHandle, @@ -1229,7 +1229,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSess } #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSessionBuilder_ProcessSenderKeyDistributionMessage( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSessionBuilder_nativeProcessSenderKeyDistributionMessage( env: JNIEnv, _class: JClass, sender_key_name: ObjectHandle, @@ -1249,7 +1249,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSess } #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCipher_EncryptMessage( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCipher_nativeEncryptMessage( env: JNIEnv, _class: JClass, sender_key_name: ObjectHandle, @@ -1272,7 +1272,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCiph } #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCipher_DecryptMessage( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCipher_nativeDecryptMessage( env: JNIEnv, _class: JClass, sender_key_name: ObjectHandle, @@ -1295,7 +1295,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCiph // The following are just exposed to make it possible to retain some of the Java tests: #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionState_InitializeAliceSession( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionState_nativeInitializeAliceSession( env: JNIEnv, _class: JClass, identity_key_private: ObjectHandle, @@ -1339,7 +1339,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionSta } #[no_mangle] -pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionState_InitializeBobSession( +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionState_nativeInitializeBobSession( env: JNIEnv, _class: JClass, identity_key_private: ObjectHandle, From d72b12643e917649e7cf01bfe67b3adb0349c9c5 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Mon, 24 Aug 2020 16:17:50 -0400 Subject: [PATCH 11/19] Add offset argument for PublicKey deserialization Allows simplifying some of the Java-side logic --- src/lib.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 955a911f4a..5d63a485de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,7 +34,20 @@ jni_fn_get_jstring!(Java_org_whispersystems_libsignal_SignalProtocolAddress_nati jni_fn_get_jint!(Java_org_whispersystems_libsignal_SignalProtocolAddress_nativeDeviceId(ProtocolAddress) using |obj: &ProtocolAddress| { Ok(obj.device_id()) }); -jni_fn_deserialize!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_nativeDeserialize is PublicKey::deserialize); +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPublicKey_nativeDeserialize( + env: JNIEnv, + _class: JClass, + data: jbyteArray, + offset: jint, +) -> ObjectHandle { + run_ffi_safe(&env, || { + let offset = jint_to_u32(offset)? as usize; + let data = env.convert_byte_array(data)?; + let key = PublicKey::deserialize(&data[offset..])?; + box_object::(Ok(key)) + }) +} jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_nativeSerialize(PublicKey) using |k: &PublicKey| Ok(k.serialize())); From eee7f6c055371a531b2207d4e72aa5a4cdd52f53 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 25 Aug 2020 13:24:33 -0400 Subject: [PATCH 12/19] Update libsignal-protocol-rust reference --- Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3e7de35363..a1c4c6175a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,6 @@ crate-type = ["dylib"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -libsignal-protocol-rust = { path = "../libsignal-protocol-rust" } -#libsignal-protocol-rust = { git = "ssh://git@github.com/signalapp/libsignal-protocol-rust.git" } +libsignal-protocol-rust = { git = "ssh://git@github.com/signalapp/libsignal-protocol-rust.git" } jni = "0.17" rand = "0.7.3" From 4935c95f9dcd3924f6421a72387c0c3c60ff19d2 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 25 Aug 2020 13:20:57 -0400 Subject: [PATCH 13/19] Add CI using Github actions Cannot build due to needing to reference the private libsignal-protocol-rust --- .github/workflows/rust.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/workflows/rust.yml diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000000..6aff1a32ed --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,26 @@ +name: Rust + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Rustfmt check + run: cargo fmt -- --check +# - name: Build +# run: cargo build --verbose +# - name: Run tests +# run: cargo test --verbose +# - name: Clippy +# run: cargo clippy From a64c893d88265aa111169f1aadb9975f0aece6eb Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 25 Aug 2020 13:23:12 -0400 Subject: [PATCH 14/19] cargo fmt --- .rustfmt.toml | 1 + src/lib.rs | 483 +++++++++++++++++++++++++++++++++++++------------- src/util.rs | 124 ++++++++----- 3 files changed, 437 insertions(+), 171 deletions(-) create mode 100644 .rustfmt.toml diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index 0000000000..32a9786fa1 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1 @@ +edition = "2018" diff --git a/src/lib.rs b/src/lib.rs index 5d63a485de..1495c0baae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,8 @@ #![allow(clippy::missing_safety_doc)] #![deny(warnings)] -use jni::objects::{JClass, JString, JValue, JObject}; -use jni::sys::{jboolean, jbyteArray, jint, jlong, jstring, jobject}; +use jni::objects::{JClass, JObject, JString, JValue}; +use jni::sys::{jboolean, jbyteArray, jint, jlong, jobject, jstring}; use jni::JNIEnv; use libsignal_protocol_rust::*; use std::convert::TryFrom; @@ -693,7 +693,6 @@ jni_fn_get_jstring!(Java_org_whispersystems_libsignal_groups_SenderKeyName_nativ jni_fn_get_jint!(Java_org_whispersystems_libsignal_groups_SenderKeyName_nativeGetSenderDeviceId(SenderKeyName) using |m: &SenderKeyName| Ok(m.sender()?.device_id())); - #[no_mangle] pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_SenderKeyState_nativeNew( env: JNIEnv, @@ -709,9 +708,16 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_state_Sen let iteration = jint_to_u32(iteration)?; let chain_key = env.convert_byte_array(chain_key)?; let signature_public = native_handle_cast::(signature_public)?; - let signature_private = native_handle_cast_optional::(signature_private)?.map(|k| *k); - - let sks = SenderKeyState::new(id, iteration, &chain_key, *signature_public, signature_private); + let signature_private = + native_handle_cast_optional::(signature_private)?.map(|k| *k); + + let sks = SenderKeyState::new( + id, + iteration, + &chain_key, + *signature_public, + signature_private, + ); box_object::(sks) }) } @@ -732,24 +738,35 @@ jni_fn_get_new_boxed_obj!(Java_org_whispersystems_libsignal_groups_state_SenderK jni_fn_get_new_boxed_optional_obj!(Java_org_whispersystems_libsignal_groups_state_SenderKeyState_nativeGetSigningKeyPrivate(PrivateKey) from SenderKeyState, |sks: &SenderKeyState| sks.signing_key_private()); -fn sender_key_name_to_jobject<'a>(env: &'a JNIEnv, sender_key_name: &SenderKeyName) -> Result, SignalJniError> { - let sender_key_name_class = env.find_class("org/whispersystems/libsignal/groups/SenderKeyName")?; +fn sender_key_name_to_jobject<'a>( + env: &'a JNIEnv, + sender_key_name: &SenderKeyName, +) -> Result, SignalJniError> { + let sender_key_name_class = + env.find_class("org/whispersystems/libsignal/groups/SenderKeyName")?; let sender_key_name_ctor_args = [ JObject::from(env.new_string(sender_key_name.group_id()?)?).into(), JObject::from(env.new_string(sender_key_name.sender_name()?)?).into(), - JValue::from(jint_from_u32(sender_key_name.sender_device_id())?) + JValue::from(jint_from_u32(sender_key_name.sender_device_id())?), ]; let sender_key_name_ctor_sig = "(Ljava/lang/String;Ljava/lang/String;I)V"; - let sender_key_name_jobject = env.new_object(sender_key_name_class, sender_key_name_ctor_sig, &sender_key_name_ctor_args)?; + let sender_key_name_jobject = env.new_object( + sender_key_name_class, + sender_key_name_ctor_sig, + &sender_key_name_ctor_args, + )?; Ok(sender_key_name_jobject) } -fn protocol_address_to_jobject<'a>(env: &'a JNIEnv, address: &ProtocolAddress) -> Result, SignalJniError> { +fn protocol_address_to_jobject<'a>( + env: &'a JNIEnv, + address: &ProtocolAddress, +) -> Result, SignalJniError> { let address_class = env.find_class("org/whispersystems/libsignal/SignalProtocolAddress")?; let address_ctor_args = [ JObject::from(env.new_string(address.name())?).into(), - JValue::from(jint_from_u32(Ok(address.device_id()))?) + JValue::from(jint_from_u32(Ok(address.device_id()))?), ]; let address_ctor_sig = "(Ljava/lang/String;I)V"; @@ -771,10 +788,18 @@ impl<'a> JniIdentityKeyStore<'a> { impl<'a> JniIdentityKeyStore<'a> { fn do_get_identity_key_pair(&self) -> Result { let callback_sig = "()Lorg/whispersystems/libsignal/IdentityKeyPair;"; - let bits = get_object_with_serialization(self.env, self.store, &[], callback_sig, "getIdentityKeyPair")?; + let bits = get_object_with_serialization( + self.env, + self.store, + &[], + callback_sig, + "getIdentityKeyPair", + )?; match bits { - None => Err(SignalJniError::Signal(SignalProtocolError::InternalError("getIdentityKeyPair returned null"))), + None => Err(SignalJniError::Signal(SignalProtocolError::InternalError( + "getIdentityKeyPair returned null", + ))), Some(k) => Ok(IdentityKeyPair::try_from(k.as_ref())?), } } @@ -782,26 +807,44 @@ impl<'a> JniIdentityKeyStore<'a> { fn do_get_local_registration_id(&self) -> Result { let callback_sig = "()I"; - let rvalue = self.env.call_method(self.store, "getLocalRegistrationId", callback_sig, &[])?; + let rvalue = + self.env + .call_method(self.store, "getLocalRegistrationId", callback_sig, &[])?; exception_check(self.env)?; match rvalue { JValue::Int(i) => jint_to_u32(i), - _ => Err(SignalJniError::UnexpectedJniResultType("getLocalRegistrationId", rvalue.type_name())) + _ => Err(SignalJniError::UnexpectedJniResultType( + "getLocalRegistrationId", + rvalue.type_name(), + )), } } - fn do_save_identity(&mut self, address: &ProtocolAddress, identity: &IdentityKey) -> Result { + fn do_save_identity( + &mut self, + address: &ProtocolAddress, + identity: &IdentityKey, + ) -> Result { let address_jobject = protocol_address_to_jobject(self.env, address)?; - let key_jobject = jobject_from_serialized(self.env, "org/whispersystems/libsignal/IdentityKey", identity.serialize().as_ref())?; + let key_jobject = jobject_from_serialized( + self.env, + "org/whispersystems/libsignal/IdentityKey", + identity.serialize().as_ref(), + )?; let callback_sig = "(Lorg/whispersystems/libsignal/SignalProtocolAddress;Lorg/whispersystems/libsignal/IdentityKey;)Z"; let callback_args = [address_jobject.into(), key_jobject.into()]; - let result = self.env.call_method(self.store, "saveIdentity", callback_sig, &callback_args)?; + let result = + self.env + .call_method(self.store, "saveIdentity", callback_sig, &callback_args)?; exception_check(self.env)?; match result { JValue::Bool(b) => Ok(b != 0), - _ => Err(SignalJniError::UnexpectedJniResultType("saveIdentity", result.type_name())) + _ => Err(SignalJniError::UnexpectedJniResultType( + "saveIdentity", + result.type_name(), + )), } } @@ -812,33 +855,60 @@ impl<'a> JniIdentityKeyStore<'a> { direction: Direction, ) -> Result { let address_jobject = protocol_address_to_jobject(self.env, address)?; - let key_jobject = jobject_from_serialized(self.env, "org/whispersystems/libsignal/IdentityKey", identity.serialize().as_ref())?; + let key_jobject = jobject_from_serialized( + self.env, + "org/whispersystems/libsignal/IdentityKey", + identity.serialize().as_ref(), + )?; - let direction_class = self.env.find_class("org/whispersystems/libsignal/state/IdentityKeyStore$Direction")?; + let direction_class = self + .env + .find_class("org/whispersystems/libsignal/state/IdentityKeyStore$Direction")?; let field_name = match direction { Direction::Sending => "SENDING", Direction::Receiving => "RECEIVING", }; - let field_value = self.env.get_static_field(direction_class, field_name, "Lorg/whispersystems/libsignal/state/IdentityKeyStore$Direction;")?; + let field_value = self.env.get_static_field( + direction_class, + field_name, + "Lorg/whispersystems/libsignal/state/IdentityKeyStore$Direction;", + )?; let callback_sig = "(Lorg/whispersystems/libsignal/SignalProtocolAddress;Lorg/whispersystems/libsignal/IdentityKey;Lorg/whispersystems/libsignal/state/IdentityKeyStore$Direction;)Z"; let callback_args = [address_jobject.into(), key_jobject.into(), field_value]; - let result = self.env.call_method(self.store, "isTrustedIdentity", callback_sig, &callback_args)?; + let result = self.env.call_method( + self.store, + "isTrustedIdentity", + callback_sig, + &callback_args, + )?; exception_check(self.env)?; match result { JValue::Bool(b) => Ok(b != 0), - _ => Err(SignalJniError::UnexpectedJniResultType("isTrustedIdentity", result.type_name())) + _ => Err(SignalJniError::UnexpectedJniResultType( + "isTrustedIdentity", + result.type_name(), + )), } } - fn do_get_identity(&self, address: &ProtocolAddress) -> Result, SignalJniError> { + fn do_get_identity( + &self, + address: &ProtocolAddress, + ) -> Result, SignalJniError> { let address_jobject = protocol_address_to_jobject(self.env, address)?; let callback_sig = "(Lorg/whispersystems/libsignal/SignalProtocolAddress;)Lorg/whispersystems/libsignal/IdentityKey;"; let callback_args = [address_jobject.into()]; - let bits = get_object_with_serialization(self.env, self.store, &callback_args, callback_sig, "getIdentity")?; + let bits = get_object_with_serialization( + self.env, + self.store, + &callback_args, + callback_sig, + "getIdentity", + )?; match bits { None => Ok(None), @@ -848,7 +918,6 @@ impl<'a> JniIdentityKeyStore<'a> { } impl<'a> IdentityKeyStore for JniIdentityKeyStore<'a> { - fn get_identity_key_pair(&self) -> Result { Ok(self.do_get_identity_key_pair()?) } @@ -857,7 +926,11 @@ impl<'a> IdentityKeyStore for JniIdentityKeyStore<'a> { Ok(self.do_get_local_registration_id()?) } - fn save_identity(&mut self, address: &ProtocolAddress, identity: &IdentityKey) -> Result { + fn save_identity( + &mut self, + address: &ProtocolAddress, + identity: &IdentityKey, + ) -> Result { Ok(self.do_save_identity(address, identity)?) } @@ -870,7 +943,10 @@ impl<'a> IdentityKeyStore for JniIdentityKeyStore<'a> { Ok(self.do_is_trusted_identity(address, identity, direction)?) } - fn get_identity(&self, address: &ProtocolAddress) -> Result, SignalProtocolError> { + fn get_identity( + &self, + address: &ProtocolAddress, + ) -> Result, SignalProtocolError> { Ok(self.do_get_identity(address)?) } } @@ -890,18 +966,36 @@ impl<'a> JniPreKeyStore<'a> { fn do_get_pre_key(&self, prekey_id: u32) -> Result { let callback_sig = "(I)Lorg/whispersystems/libsignal/state/PreKeyRecord;"; let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?)]; - let pk = get_object_with_native_handle::(self.env, self.store, &callback_args, callback_sig, "loadPreKey")?; + let pk = get_object_with_native_handle::( + self.env, + self.store, + &callback_args, + callback_sig, + "loadPreKey", + )?; match pk { Some(pk) => Ok(pk), None => Err(SignalJniError::Signal(SignalProtocolError::InvalidPreKeyId)), } } - fn do_save_pre_key(&mut self, prekey_id: u32, record: &PreKeyRecord) -> Result<(), SignalJniError> { - let jobject_record = jobject_from_serialized(self.env, "org/whispersystems/libsignal/state/PreKeyRecord", &record.serialize()?)?; + fn do_save_pre_key( + &mut self, + prekey_id: u32, + record: &PreKeyRecord, + ) -> Result<(), SignalJniError> { + let jobject_record = jobject_from_serialized( + self.env, + "org/whispersystems/libsignal/state/PreKeyRecord", + &record.serialize()?, + )?; let callback_sig = "(I,Lorg/whispersystems/libsignal/state/PreKeyRecord;)V"; - let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?), jobject_record.into()]; - self.env.call_method(self.store, "storePreKey", callback_sig, &callback_args)?; + let callback_args = [ + JValue::from(jint_from_u32(Ok(prekey_id))?), + jobject_record.into(), + ]; + self.env + .call_method(self.store, "storePreKey", callback_sig, &callback_args)?; exception_check(self.env)?; Ok(()) } @@ -909,7 +1003,8 @@ impl<'a> JniPreKeyStore<'a> { fn do_remove_pre_key(&mut self, prekey_id: u32) -> Result<(), SignalJniError> { let callback_sig = "(I)V"; let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?)]; - self.env.call_method(self.store, "removePreKey", callback_sig, &callback_args)?; + self.env + .call_method(self.store, "removePreKey", callback_sig, &callback_args)?; exception_check(self.env)?; Ok(()) } @@ -920,7 +1015,11 @@ impl<'a> PreKeyStore for JniPreKeyStore<'a> { Ok(self.do_get_pre_key(prekey_id)?) } - fn save_pre_key(&mut self, prekey_id: u32, record: &PreKeyRecord) -> Result<(), SignalProtocolError> { + fn save_pre_key( + &mut self, + prekey_id: u32, + record: &PreKeyRecord, + ) -> Result<(), SignalProtocolError> { Ok(self.do_save_pre_key(prekey_id, record)?) } @@ -944,29 +1043,60 @@ impl<'a> JniSignedPreKeyStore<'a> { fn do_get_signed_pre_key(&self, prekey_id: u32) -> Result { let callback_sig = "(I)Lorg/whispersystems/libsignal/state/SignedPreKeyRecord;"; let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?)]; - let spk = get_object_with_native_handle::(self.env, self.store, &callback_args, callback_sig, "loadSignedPreKey")?; + let spk = get_object_with_native_handle::( + self.env, + self.store, + &callback_args, + callback_sig, + "loadSignedPreKey", + )?; match spk { Some(spk) => Ok(spk), - None => Err(SignalJniError::Signal(SignalProtocolError::InvalidSignedPreKeyId)), + None => Err(SignalJniError::Signal( + SignalProtocolError::InvalidSignedPreKeyId, + )), } } - fn do_save_signed_pre_key(&mut self, prekey_id: u32, record: &SignedPreKeyRecord) -> Result<(), SignalJniError> { - let jobject_record = jobject_from_serialized(self.env, "org/whispersystems/libsignal/state/SignedPreKeyRecord", &record.serialize()?)?; + fn do_save_signed_pre_key( + &mut self, + prekey_id: u32, + record: &SignedPreKeyRecord, + ) -> Result<(), SignalJniError> { + let jobject_record = jobject_from_serialized( + self.env, + "org/whispersystems/libsignal/state/SignedPreKeyRecord", + &record.serialize()?, + )?; let callback_sig = "(I,Lorg/whispersystems/libsignal/state/SignedPreKeyRecord;)V"; - let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?), jobject_record.into()]; - self.env.call_method(self.store, "storeSignedPreKey", callback_sig, &callback_args)?; + let callback_args = [ + JValue::from(jint_from_u32(Ok(prekey_id))?), + jobject_record.into(), + ]; + self.env.call_method( + self.store, + "storeSignedPreKey", + callback_sig, + &callback_args, + )?; exception_check(self.env)?; Ok(()) } } impl<'a> SignedPreKeyStore for JniSignedPreKeyStore<'a> { - fn get_signed_pre_key(&self, prekey_id: u32) -> Result { + fn get_signed_pre_key( + &self, + prekey_id: u32, + ) -> Result { Ok(self.do_get_signed_pre_key(prekey_id)?) } - fn save_signed_pre_key(&mut self, prekey_id: u32, record: &SignedPreKeyRecord) -> Result<(), SignalProtocolError> { + fn save_signed_pre_key( + &mut self, + prekey_id: u32, + record: &SignedPreKeyRecord, + ) -> Result<(), SignalProtocolError> { Ok(self.do_save_signed_pre_key(prekey_id, record)?) } } @@ -983,59 +1113,105 @@ impl<'a> JniSessionStore<'a> { } impl<'a> JniSessionStore<'a> { - fn do_load_session(&self, address: &ProtocolAddress) -> Result, SignalJniError> { + fn do_load_session( + &self, + address: &ProtocolAddress, + ) -> Result, SignalJniError> { let address_jobject = protocol_address_to_jobject(self.env, address)?; let callback_sig = "(Lorg/whispersystems/libsignal/SignalProtocolAddress;)Lorg/whispersystems/libsignal/state/SessionRecord;"; let callback_args = [address_jobject.into()]; - let session = get_object_with_serialization(self.env, self.store, &callback_args, callback_sig, "loadSession")?; + let session = get_object_with_serialization( + self.env, + self.store, + &callback_args, + callback_sig, + "loadSession", + )?; match session { None => Ok(None), - Some(s) => Ok(Some(SessionRecord::deserialize(&s)?)) + Some(s) => Ok(Some(SessionRecord::deserialize(&s)?)), } } - fn do_store_session(&mut self, address: &ProtocolAddress, record: &SessionRecord) -> Result<(), SignalJniError> { + fn do_store_session( + &mut self, + address: &ProtocolAddress, + record: &SessionRecord, + ) -> Result<(), SignalJniError> { let address_jobject = protocol_address_to_jobject(self.env, address)?; - let session_jobject = - jobject_from_serialized(self.env, "org/whispersystems/libsignal/state/SessionRecord", &record.serialize()?)?; + let session_jobject = jobject_from_serialized( + self.env, + "org/whispersystems/libsignal/state/SessionRecord", + &record.serialize()?, + )?; let callback_sig = "(Lorg/whispersystems/libsignal/SignalProtocolAddress;Lorg/whispersystems/libsignal/state/SessionRecord;)V"; let callback_args = [address_jobject.into(), session_jobject.into()]; - self.env.call_method(self.store, "storeSession", callback_sig, &callback_args)?; + self.env + .call_method(self.store, "storeSession", callback_sig, &callback_args)?; exception_check(self.env)?; Ok(()) } } impl<'a> SessionStore for JniSessionStore<'a> { - fn load_session(&self, address: &ProtocolAddress) -> Result, SignalProtocolError> { + fn load_session( + &self, + address: &ProtocolAddress, + ) -> Result, SignalProtocolError> { Ok(self.do_load_session(address)?) } - fn store_session(&mut self, address: &ProtocolAddress, record: &SessionRecord) -> Result<(), SignalProtocolError> { + fn store_session( + &mut self, + address: &ProtocolAddress, + record: &SessionRecord, + ) -> Result<(), SignalProtocolError> { Ok(self.do_store_session(address, record)?) } } -fn create_identity_store<'a>(env: &'a JNIEnv, obj: jobject) -> Result, SignalJniError> { - let identity_key_store = check_jobject_type(&env, obj, "org/whispersystems/libsignal/state/IdentityKeyStore")?; +fn create_identity_store<'a>( + env: &'a JNIEnv, + obj: jobject, +) -> Result, SignalJniError> { + let identity_key_store = check_jobject_type( + &env, + obj, + "org/whispersystems/libsignal/state/IdentityKeyStore", + )?; Ok(JniIdentityKeyStore::new(&env, identity_key_store)) } -fn create_session_store<'a>(env: &'a JNIEnv, obj: jobject) -> Result, SignalJniError> { - let session_store = check_jobject_type(&env, obj, "org/whispersystems/libsignal/state/SessionStore")?; +fn create_session_store<'a>( + env: &'a JNIEnv, + obj: jobject, +) -> Result, SignalJniError> { + let session_store = + check_jobject_type(&env, obj, "org/whispersystems/libsignal/state/SessionStore")?; Ok(JniSessionStore::new(&env, session_store)) } -fn create_prekey_store<'a>(env: &'a JNIEnv, obj: jobject) -> Result, SignalJniError> { - let prekey_store = check_jobject_type(&env, obj, "org/whispersystems/libsignal/state/PreKeyStore")?; +fn create_prekey_store<'a>( + env: &'a JNIEnv, + obj: jobject, +) -> Result, SignalJniError> { + let prekey_store = + check_jobject_type(&env, obj, "org/whispersystems/libsignal/state/PreKeyStore")?; Ok(JniPreKeyStore::new(&env, prekey_store)) } -fn create_signed_prekey_store<'a>(env: &'a JNIEnv, obj: jobject) -> Result, SignalJniError> { - let signed_prekey_store = check_jobject_type(&env, obj, "org/whispersystems/libsignal/state/SignedPreKeyStore")?; +fn create_signed_prekey_store<'a>( + env: &'a JNIEnv, + obj: jobject, +) -> Result, SignalJniError> { + let signed_prekey_store = check_jobject_type( + &env, + obj, + "org/whispersystems/libsignal/state/SignedPreKeyStore", + )?; Ok(JniSignedPreKeyStore::new(&env, signed_prekey_store)) } @@ -1046,8 +1222,8 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionBuilder_n bundle: ObjectHandle, protocol_address: ObjectHandle, session_store: jobject, - identity_key_store: jobject) { - + identity_key_store: jobject, +) { run_ffi_safe(&env, || { let bundle = native_handle_cast::(bundle)?; let protocol_address = native_handle_cast::(protocol_address)?; @@ -1056,8 +1232,13 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionBuilder_n let mut session_store = create_session_store(&env, session_store)?; let mut csprng = rand::rngs::OsRng; - process_prekey_bundle(&protocol_address, &mut session_store, &mut identity_key_store, - bundle, &mut csprng)?; + process_prekey_bundle( + &protocol_address, + &mut session_store, + &mut identity_key_store, + bundle, + &mut csprng, + )?; Ok(()) }) @@ -1070,8 +1251,8 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_na message: jbyteArray, protocol_address: ObjectHandle, session_store: jobject, - identity_key_store: jobject) -> jobject { - + identity_key_store: jobject, +) -> jobject { run_ffi_safe(&env, || { let message = env.convert_byte_array(message)?; let protocol_address = native_handle_cast::(protocol_address)?; @@ -1079,20 +1260,27 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_na let mut identity_key_store = create_identity_store(&env, identity_key_store)?; let mut session_store = create_session_store(&env, session_store)?; - let ctext = message_encrypt(&message, &protocol_address, &mut session_store, &mut identity_key_store)?; + let ctext = message_encrypt( + &message, + &protocol_address, + &mut session_store, + &mut identity_key_store, + )?; let obj = match ctext { - CiphertextMessage::SignalMessage(m) => { - jobject_from_native_handle(&env, - "org/whispersystems/libsignal/protocol/SignalMessage", - box_object::(Ok(m))?) - } - CiphertextMessage::PreKeySignalMessage(m) => { - jobject_from_native_handle(&env, - "org/whispersystems/libsignal/protocol/PreKeySignalMessage", - box_object::(Ok(m))?) - } - _ => Err(SignalJniError::Signal(SignalProtocolError::InternalError("Unexpected result type from message_encrypt"))) + CiphertextMessage::SignalMessage(m) => jobject_from_native_handle( + &env, + "org/whispersystems/libsignal/protocol/SignalMessage", + box_object::(Ok(m))?, + ), + CiphertextMessage::PreKeySignalMessage(m) => jobject_from_native_handle( + &env, + "org/whispersystems/libsignal/protocol/PreKeySignalMessage", + box_object::(Ok(m))?, + ), + _ => Err(SignalJniError::Signal(SignalProtocolError::InternalError( + "Unexpected result type from message_encrypt", + ))), }; Ok(obj?.into_inner()) @@ -1106,8 +1294,8 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_na message: ObjectHandle, protocol_address: ObjectHandle, session_store: jobject, - identity_key_store: jobject) -> jbyteArray { - + identity_key_store: jobject, +) -> jbyteArray { run_ffi_safe(&env, || { let message = native_handle_cast::(message)?; let protocol_address = native_handle_cast::(protocol_address)?; @@ -1116,7 +1304,13 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_na let mut session_store = create_session_store(&env, session_store)?; let mut csprng = rand::rngs::OsRng; - let ptext = message_decrypt_signal(&message, &protocol_address, &mut session_store, &mut identity_key_store, &mut csprng)?; + let ptext = message_decrypt_signal( + &message, + &protocol_address, + &mut session_store, + &mut identity_key_store, + &mut csprng, + )?; to_jbytearray(&env, Ok(ptext)) }) @@ -1131,8 +1325,8 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_na session_store: jobject, identity_key_store: jobject, prekey_store: jobject, - signed_prekey_store: jobject) -> jbyteArray { - + signed_prekey_store: jobject, +) -> jbyteArray { run_ffi_safe(&env, || { let message = native_handle_cast::(message)?; let protocol_address = native_handle_cast::(protocol_address)?; @@ -1142,13 +1336,15 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_na let mut signed_prekey_store = create_signed_prekey_store(&env, signed_prekey_store)?; let mut csprng = rand::rngs::OsRng; - let ptext = message_decrypt_prekey(&message, - &protocol_address, - &mut session_store, - &mut identity_key_store, - &mut prekey_store, - &mut signed_prekey_store, - &mut csprng)?; + let ptext = message_decrypt_prekey( + &message, + &protocol_address, + &mut session_store, + &mut identity_key_store, + &mut prekey_store, + &mut signed_prekey_store, + &mut csprng, + )?; to_jbytearray(&env, Ok(ptext)) }) @@ -1171,17 +1367,24 @@ impl<'a> JniSenderKeyStore<'a> { sender_key_name: &SenderKeyName, record: &SenderKeyRecord, ) -> Result<(), SignalJniError> { - let sender_key_name_jobject = sender_key_name_to_jobject(self.env, sender_key_name)?; - let sender_key_record_jobject = - jobject_from_serialized(self.env, "org/whispersystems/libsignal/groups/state/SenderKeyRecord", &record.serialize()?)?; + let sender_key_record_jobject = jobject_from_serialized( + self.env, + "org/whispersystems/libsignal/groups/state/SenderKeyRecord", + &record.serialize()?, + )?; let callback_args = [ sender_key_name_jobject.into(), sender_key_record_jobject.into(), ]; let callback_sig = "(Lorg/whispersystems/libsignal/groups/SenderKeyName;Lorg/whispersystems/libsignal/groups/state/SenderKeyRecord;)V"; - self.env.call_method(self.store, "storeSenderKey", callback_sig, &callback_args[..])?; + self.env.call_method( + self.store, + "storeSenderKey", + callback_sig, + &callback_args[..], + )?; exception_check(self.env)?; Ok(()) @@ -1191,16 +1394,21 @@ impl<'a> JniSenderKeyStore<'a> { &mut self, sender_key_name: &SenderKeyName, ) -> Result, SignalJniError> { - let sender_key_name_jobject = sender_key_name_to_jobject(self.env, sender_key_name)?; let callback_args = [sender_key_name_jobject.into()]; let callback_sig = "(Lorg/whispersystems/libsignal/groups/SenderKeyName;)Lorg/whispersystems/libsignal/groups/state/SenderKeyRecord;"; - let skr = get_object_with_serialization(self.env, self.store, &callback_args, callback_sig, "loadSenderKey")?; + let skr = get_object_with_serialization( + self.env, + self.store, + &callback_args, + callback_sig, + "loadSenderKey", + )?; match skr { None => Ok(None), - Some(k) => Ok(Some(SenderKeyRecord::deserialize(&k)?)) + Some(k) => Ok(Some(SenderKeyRecord::deserialize(&k)?)), } } } @@ -1227,16 +1435,24 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSess env: JNIEnv, _class: JClass, sender_key_name: ObjectHandle, - store: jobject) -> ObjectHandle { - + store: jobject, +) -> ObjectHandle { run_ffi_safe(&env, || { let sender_key_name = native_handle_cast::(sender_key_name)?; - let store = check_jobject_type(&env, store, "org/whispersystems/libsignal/groups/state/SenderKeyStore")?; + let store = check_jobject_type( + &env, + store, + "org/whispersystems/libsignal/groups/state/SenderKeyStore", + )?; let mut sender_key_store = JniSenderKeyStore::new(&env, store); let mut csprng = rand::rngs::OsRng; - let skdm = create_sender_key_distribution_message(&sender_key_name, &mut sender_key_store, &mut csprng)?; + let skdm = create_sender_key_distribution_message( + &sender_key_name, + &mut sender_key_store, + &mut csprng, + )?; box_object::(Ok(skdm)) }) } @@ -1247,16 +1463,25 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSess _class: JClass, sender_key_name: ObjectHandle, sender_key_distribution_message: ObjectHandle, - store: jobject) { - + store: jobject, +) { run_ffi_safe(&env, || { let sender_key_name = native_handle_cast::(sender_key_name)?; - let sender_key_distribution_message = native_handle_cast::(sender_key_distribution_message)?; - let store = check_jobject_type(&env, store, "org/whispersystems/libsignal/groups/state/SenderKeyStore")?; + let sender_key_distribution_message = + native_handle_cast::(sender_key_distribution_message)?; + let store = check_jobject_type( + &env, + store, + "org/whispersystems/libsignal/groups/state/SenderKeyStore", + )?; let mut sender_key_store = JniSenderKeyStore::new(&env, store); - process_sender_key_distribution_message(sender_key_name, sender_key_distribution_message, &mut sender_key_store)?; + process_sender_key_distribution_message( + sender_key_name, + sender_key_distribution_message, + &mut sender_key_store, + )?; Ok(()) }) } @@ -1267,12 +1492,16 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCiph _class: JClass, sender_key_name: ObjectHandle, message: jbyteArray, - store: jobject) -> jbyteArray { - + store: jobject, +) -> jbyteArray { run_ffi_safe(&env, || { let sender_key_name = native_handle_cast::(sender_key_name)?; let message = env.convert_byte_array(message)?; - let store = check_jobject_type(&env, store, "org/whispersystems/libsignal/groups/state/SenderKeyStore")?; + let store = check_jobject_type( + &env, + store, + "org/whispersystems/libsignal/groups/state/SenderKeyStore", + )?; let mut sender_key_store = JniSenderKeyStore::new(&env, store); @@ -1290,12 +1519,16 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCiph _class: JClass, sender_key_name: ObjectHandle, message: jbyteArray, - store: jobject) -> jbyteArray { - + store: jobject, +) -> jbyteArray { run_ffi_safe(&env, || { let sender_key_name = native_handle_cast::(sender_key_name)?; let message = env.convert_byte_array(message)?; - let store = check_jobject_type(&env, store, "org/whispersystems/libsignal/groups/state/SenderKeyStore")?; + let store = check_jobject_type( + &env, + store, + "org/whispersystems/libsignal/groups/state/SenderKeyStore", + )?; let mut sender_key_store = JniSenderKeyStore::new(&env, store); @@ -1317,8 +1550,8 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionSta base_public: ObjectHandle, their_identity_key: ObjectHandle, their_signed_prekey: ObjectHandle, - their_ratchet_key: ObjectHandle) -> jbyteArray { - + their_ratchet_key: ObjectHandle, +) -> jbyteArray { run_ffi_safe(&env, || { let identity_key_private = native_handle_cast::(identity_key_private)?; let identity_key_public = native_handle_cast::(identity_key_public)?; @@ -1329,7 +1562,9 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionSta let their_ratchet_key = native_handle_cast::(their_ratchet_key)?; let our_identity_key_pair = IdentityKeyPair::new( - IdentityKey::new(*identity_key_public), *identity_key_private); + IdentityKey::new(*identity_key_public), + *identity_key_private, + ); let our_base_key_pair = KeyPair::new(*base_public, *base_private); @@ -1343,7 +1578,8 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionSta their_identity_key, *their_signed_prekey, None, - *their_ratchet_key); + *their_ratchet_key, + ); let session = initialize_alice_session(¶meters, &mut csprng)?; @@ -1362,8 +1598,8 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionSta eph_private: ObjectHandle, eph_public: ObjectHandle, their_identity_key: ObjectHandle, - their_base_key: ObjectHandle) -> jbyteArray { - + their_base_key: ObjectHandle, +) -> jbyteArray { run_ffi_safe(&env, || { let identity_key_private = native_handle_cast::(identity_key_private)?; let identity_key_public = native_handle_cast::(identity_key_public)?; @@ -1375,7 +1611,9 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionSta let their_base_key = native_handle_cast::(their_base_key)?; let our_identity_key_pair = IdentityKeyPair::new( - IdentityKey::new(*identity_key_public), *identity_key_private); + IdentityKey::new(*identity_key_public), + *identity_key_private, + ); let our_signed_pre_key_pair = KeyPair::new(*signed_prekey_public, *signed_prekey_private); @@ -1389,7 +1627,8 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_state_SessionSta None, our_ratchet_key_pair, their_identity_key, - *their_base_key); + *their_base_key, + ); let session = initialize_bob_session(¶meters)?; diff --git a/src/util.rs b/src/util.rs index c8e61cec7f..48350cb277 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,5 +1,5 @@ -use jni::sys::{_jobject, jobject, jboolean, jbyteArray, jint, jlong, jstring}; -use jni::objects::{JString, JValue, JObject}; +use jni::objects::{JObject, JString, JValue}; +use jni::sys::{_jobject, jboolean, jbyteArray, jint, jlong, jobject, jstring}; use jni::JNIEnv; use libsignal_protocol_rust::*; use std::fmt; @@ -20,15 +20,11 @@ impl SignalJniError { pub fn to_signal_protocol_error(&self) -> SignalProtocolError { match self { SignalJniError::Signal(e) => e.clone(), - SignalJniError::Jni(e) => { - SignalProtocolError::FfiBindingError(e.to_string()) - } + SignalJniError::Jni(e) => SignalProtocolError::FfiBindingError(e.to_string()), SignalJniError::BadJniParameter(m) => { SignalProtocolError::InvalidArgument(m.to_string()) } - _ => { - SignalProtocolError::FfiBindingError(format!("{}", self)) - } + _ => SignalProtocolError::FfiBindingError(format!("{}", self)), } } } @@ -38,10 +34,14 @@ impl fmt::Display for SignalJniError { match self { SignalJniError::Signal(s) => write!(f, "{}", s), SignalJniError::Jni(s) => write!(f, "JNI error {}", s), - SignalJniError::ExceptionDuringCallback(s) => write!(f, "exception recieved during callback {}", s), + SignalJniError::ExceptionDuringCallback(s) => { + write!(f, "exception recieved during callback {}", s) + } SignalJniError::NullHandle => write!(f, "null handle"), SignalJniError::BadJniParameter(m) => write!(f, "bad parameter type {}", m), - SignalJniError::UnexpectedJniResultType(m, t) => write!(f, "calling {} returned unexpected type {}", m, t), + SignalJniError::UnexpectedJniResultType(m, t) => { + write!(f, "calling {} returned unexpected type {}", m, t) + } SignalJniError::IntegerOverflow(m) => { write!(f, "integer overflow during conversion of {}", m) } @@ -69,15 +69,11 @@ impl From for SignalProtocolError { fn from(err: SignalJniError) -> SignalProtocolError { match err { SignalJniError::Signal(e) => e, - SignalJniError::Jni(e) => { - SignalProtocolError::FfiBindingError(e.to_string()) - } + SignalJniError::Jni(e) => SignalProtocolError::FfiBindingError(e.to_string()), SignalJniError::BadJniParameter(m) => { SignalProtocolError::InvalidArgument(m.to_string()) } - _ => { - SignalProtocolError::FfiBindingError(format!("{}", err)) - } + _ => SignalProtocolError::FfiBindingError(format!("{}", err)), } } } @@ -87,7 +83,7 @@ pub fn throw_error(env: &JNIEnv, error: SignalJniError) { SignalJniError::NullHandle => "java/lang/NullPointerException", SignalJniError::UnexpectedPanic(_) => "java/lang/AssertionError", SignalJniError::BadJniParameter(_) => "java/lang/AssertionError", - SignalJniError::UnexpectedJniResultType(_,_) => "java/lang/AssertionError", + SignalJniError::UnexpectedJniResultType(_, _) => "java/lang/AssertionError", SignalJniError::IntegerOverflow(_) => "java/lang/RuntimeException", SignalJniError::ExceptionDuringCallback(_) => "java/lang/RuntimeException", @@ -145,10 +141,11 @@ pub fn throw_error(env: &JNIEnv, error: SignalJniError) { SignalJniError::Jni(_) => "java/lang/RuntimeException", }; - let error_string = match error { - SignalJniError::Signal(SignalProtocolError::UntrustedIdentity(addr)) => addr.name().to_string(), - e => format!("{}", e) + SignalJniError::Signal(SignalProtocolError::UntrustedIdentity(addr)) => { + addr.name().to_string() + } + e => format!("{}", e), }; let _ = env.throw_new(exception_type, error_string); @@ -211,8 +208,7 @@ impl JniDummyValue for jboolean { } impl JniDummyValue for () { - fn dummy_value() -> Self { - } + fn dummy_value() -> Self {} } pub fn run_ffi_safe Result + std::panic::UnwindSafe, R>( @@ -313,14 +309,20 @@ pub fn exception_check(env: &JNIEnv) -> Result<(), SignalJniError> { let message: String = env.get_string(JString::from(o))?.into(); return Err(SignalJniError::ExceptionDuringCallback(message)); } else { - return Err(SignalJniError::ExceptionDuringCallback("Exception that didn't implement getMessage".to_string())); + return Err(SignalJniError::ExceptionDuringCallback( + "Exception that didn't implement getMessage".to_string(), + )); } } Ok(()) } -pub fn check_jobject_type(env: &JNIEnv, obj: jobject, class_name: &'static str) -> Result { +pub fn check_jobject_type( + env: &JNIEnv, + obj: jobject, + class_name: &'static str, +) -> Result { if obj.is_null() { return Err(SignalJniError::NullHandle); } @@ -334,17 +336,24 @@ pub fn check_jobject_type(env: &JNIEnv, obj: jobject, class_name: &'static str) Ok(obj) } -pub fn get_object_with_native_handle(env: &JNIEnv, - store_obj: jobject, - callback_args: &[JValue], - callback_sig: &'static str, - callback_fn: &'static str) -> Result, SignalJniError> { +pub fn get_object_with_native_handle( + env: &JNIEnv, + store_obj: jobject, + callback_args: &[JValue], + callback_sig: &'static str, + callback_fn: &'static str, +) -> Result, SignalJniError> { let rvalue = env.call_method(store_obj, callback_fn, callback_sig, &callback_args)?; exception_check(env)?; let obj = match rvalue { JValue::Object(o) => *o, - _ => return Err(SignalJniError::UnexpectedJniResultType(callback_fn, rvalue.type_name())) + _ => { + return Err(SignalJniError::UnexpectedJniResultType( + callback_fn, + rvalue.type_name(), + )) + } }; if obj.is_null() { @@ -358,21 +367,31 @@ pub fn get_object_with_native_handle(env: &JNIEnv, let object = unsafe { native_handle_cast::(handle)? }; Ok(Some(object.clone())) } - _ => Err(SignalJniError::UnexpectedJniResultType("nativeHandle", handle.type_name())) + _ => Err(SignalJniError::UnexpectedJniResultType( + "nativeHandle", + handle.type_name(), + )), } } -pub fn get_object_with_serialization(env: &JNIEnv, - store_obj: jobject, - callback_args: &[JValue], - callback_sig: &'static str, - callback_fn: &'static str) -> Result>, SignalJniError> { +pub fn get_object_with_serialization( + env: &JNIEnv, + store_obj: jobject, + callback_args: &[JValue], + callback_sig: &'static str, + callback_fn: &'static str, +) -> Result>, SignalJniError> { let rvalue = env.call_method(store_obj, callback_fn, callback_sig, &callback_args)?; exception_check(env)?; let obj = match rvalue { JValue::Object(o) => *o, - _ => return Err(SignalJniError::UnexpectedJniResultType(callback_fn, rvalue.type_name())) + _ => { + return Err(SignalJniError::UnexpectedJniResultType( + callback_fn, + rvalue.type_name(), + )) + } }; if obj.is_null() { @@ -383,23 +402,30 @@ pub fn get_object_with_serialization(env: &JNIEnv, exception_check(env)?; match bytes { - JValue::Object(o) => { - Ok(Some(env.convert_byte_array(*o)?)) - } - _ => { - Err(SignalJniError::UnexpectedJniResultType("serialize", bytes.type_name())) - } + JValue::Object(o) => Ok(Some(env.convert_byte_array(*o)?)), + _ => Err(SignalJniError::UnexpectedJniResultType( + "serialize", + bytes.type_name(), + )), } } -pub fn jobject_from_serialized<'a>(env: &'a JNIEnv, class_name: &str, serialized: &[u8]) -> Result, SignalJniError> { +pub fn jobject_from_serialized<'a>( + env: &'a JNIEnv, + class_name: &str, + serialized: &[u8], +) -> Result, SignalJniError> { let class_type = env.find_class(class_name)?; let ctor_sig = "([B)V"; let ctor_args = [JValue::from(to_jbytearray(env, Ok(serialized))?)]; Ok(env.new_object(class_type, ctor_sig, &ctor_args)?) } -pub fn jobject_from_native_handle<'a>(env: &'a JNIEnv, class_name: &str, boxed_handle: ObjectHandle) -> Result, SignalJniError> { +pub fn jobject_from_native_handle<'a>( + env: &'a JNIEnv, + class_name: &str, + boxed_handle: ObjectHandle, +) -> Result, SignalJniError> { let class_type = env.find_class(class_name)?; let ctor_sig = "(J)V"; let ctor_args = [JValue::from(boxed_handle)]; @@ -451,7 +477,7 @@ macro_rules! jni_fn_get_new_boxed_optional_obj { ) -> ObjectHandle { run_ffi_safe(&env, || { let obj = native_handle_cast::<$typ>(handle)?; - let result : Option<$rt> = $body(obj)?; + let result: Option<$rt> = $body(obj)?; if let Some(result) = result { box_object::<$rt>(Ok(result)) } else { @@ -490,7 +516,7 @@ macro_rules! jni_fn_get_jboolean { ) -> jboolean { run_ffi_safe(&env, || { let obj = native_handle_cast::<$typ>(handle)?; - let r : bool = $body(obj)?; + let r: bool = $body(obj)?; Ok(r as jboolean) }) } @@ -514,7 +540,7 @@ macro_rules! jni_fn_get_jstring { $body(&t) } run_ffi_safe(&env, || { - let obj : &mut $typ = native_handle_cast::<$typ>(handle)?; + let obj: &mut $typ = native_handle_cast::<$typ>(handle)?; return Ok(env.new_string(inner_get(&obj)?)?.into_inner()); }) } @@ -527,7 +553,7 @@ macro_rules! jni_fn_get_jstring { handle: ObjectHandle, ) -> jstring { run_ffi_safe(&env, || { - let obj : &mut $typ = native_handle_cast::<$typ>(handle)?; + let obj: &mut $typ = native_handle_cast::<$typ>(handle)?; return Ok(env.new_string($func(&obj)?)?.into_inner()); }) } From 32b5e4a7a395506e62023b2e67bb7a726ca19087 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Tue, 25 Aug 2020 17:56:21 -0400 Subject: [PATCH 15/19] Add ECPublicKey comparison --- src/lib.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 1495c0baae..f1033e0740 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,6 +49,25 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPublicKey_ }) } +#[no_mangle] +pub unsafe extern "system" fn Java_org_whispersystems_libsignal_ecc_ECPublicKey_nativeCompare( + env: JNIEnv, + _class: JClass, + key1: ObjectHandle, + key2: ObjectHandle, +) -> jint { + run_ffi_safe(&env, || { + let key1 = native_handle_cast::(key1)?; + let key2 = native_handle_cast::(key2)?; + + match key1.cmp(&key2) { + std::cmp::Ordering::Less => Ok(-1), + std::cmp::Ordering::Equal => Ok(0), + std::cmp::Ordering::Greater => Ok(1), + } + }) +} + jni_fn_get_jbytearray!(Java_org_whispersystems_libsignal_ecc_ECPublicKey_nativeSerialize(PublicKey) using |k: &PublicKey| Ok(k.serialize())); From a854bf707db0d5440a20f8ff474c4688dbd43dde Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 16 Sep 2020 18:15:55 -0400 Subject: [PATCH 16/19] Update with Context (unused) and capture more debug info (Namely the exception types and the callback which failed) --- src/lib.rs | 54 +++++++++++++++++++++++++++++++++------------ src/util.rs | 63 ++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 88 insertions(+), 29 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f1033e0740..8e55b7ee97 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -829,7 +829,7 @@ impl<'a> JniIdentityKeyStore<'a> { let rvalue = self.env .call_method(self.store, "getLocalRegistrationId", callback_sig, &[])?; - exception_check(self.env)?; + exception_check(self.env, "getLocalRegistrationId")?; match rvalue { JValue::Int(i) => jint_to_u32(i), @@ -856,7 +856,7 @@ impl<'a> JniIdentityKeyStore<'a> { let result = self.env .call_method(self.store, "saveIdentity", callback_sig, &callback_args)?; - exception_check(self.env)?; + exception_check(self.env, "saveIdentity")?; match result { JValue::Bool(b) => Ok(b != 0), @@ -902,7 +902,7 @@ impl<'a> JniIdentityKeyStore<'a> { callback_sig, &callback_args, )?; - exception_check(self.env)?; + exception_check(self.env, "isTrustedIdentity")?; match result { JValue::Bool(b) => Ok(b != 0), @@ -937,11 +937,11 @@ impl<'a> JniIdentityKeyStore<'a> { } impl<'a> IdentityKeyStore for JniIdentityKeyStore<'a> { - fn get_identity_key_pair(&self) -> Result { + fn get_identity_key_pair(&self, _ctx: Context) -> Result { Ok(self.do_get_identity_key_pair()?) } - fn get_local_registration_id(&self) -> Result { + fn get_local_registration_id(&self, _ctx: Context) -> Result { Ok(self.do_get_local_registration_id()?) } @@ -949,6 +949,7 @@ impl<'a> IdentityKeyStore for JniIdentityKeyStore<'a> { &mut self, address: &ProtocolAddress, identity: &IdentityKey, + _ctx: Context, ) -> Result { Ok(self.do_save_identity(address, identity)?) } @@ -958,6 +959,7 @@ impl<'a> IdentityKeyStore for JniIdentityKeyStore<'a> { address: &ProtocolAddress, identity: &IdentityKey, direction: Direction, + _ctx: Context, ) -> Result { Ok(self.do_is_trusted_identity(address, identity, direction)?) } @@ -965,6 +967,7 @@ impl<'a> IdentityKeyStore for JniIdentityKeyStore<'a> { fn get_identity( &self, address: &ProtocolAddress, + _ctx: Context, ) -> Result, SignalProtocolError> { Ok(self.do_get_identity(address)?) } @@ -1015,7 +1018,7 @@ impl<'a> JniPreKeyStore<'a> { ]; self.env .call_method(self.store, "storePreKey", callback_sig, &callback_args)?; - exception_check(self.env)?; + exception_check(self.env, "storePreKey")?; Ok(()) } @@ -1024,13 +1027,17 @@ impl<'a> JniPreKeyStore<'a> { let callback_args = [JValue::from(jint_from_u32(Ok(prekey_id))?)]; self.env .call_method(self.store, "removePreKey", callback_sig, &callback_args)?; - exception_check(self.env)?; + exception_check(self.env, "removePreKey")?; Ok(()) } } impl<'a> PreKeyStore for JniPreKeyStore<'a> { - fn get_pre_key(&self, prekey_id: u32) -> Result { + fn get_pre_key( + &self, + prekey_id: u32, + _ctx: Context, + ) -> Result { Ok(self.do_get_pre_key(prekey_id)?) } @@ -1038,11 +1045,12 @@ impl<'a> PreKeyStore for JniPreKeyStore<'a> { &mut self, prekey_id: u32, record: &PreKeyRecord, + _ctx: Context, ) -> Result<(), SignalProtocolError> { Ok(self.do_save_pre_key(prekey_id, record)?) } - fn remove_pre_key(&mut self, prekey_id: u32) -> Result<(), SignalProtocolError> { + fn remove_pre_key(&mut self, prekey_id: u32, _ctx: Context) -> Result<(), SignalProtocolError> { Ok(self.do_remove_pre_key(prekey_id)?) } } @@ -1098,7 +1106,7 @@ impl<'a> JniSignedPreKeyStore<'a> { callback_sig, &callback_args, )?; - exception_check(self.env)?; + exception_check(self.env, "storeSignedPreKey")?; Ok(()) } } @@ -1107,6 +1115,7 @@ impl<'a> SignedPreKeyStore for JniSignedPreKeyStore<'a> { fn get_signed_pre_key( &self, prekey_id: u32, + _ctx: Context, ) -> Result { Ok(self.do_get_signed_pre_key(prekey_id)?) } @@ -1115,6 +1124,7 @@ impl<'a> SignedPreKeyStore for JniSignedPreKeyStore<'a> { &mut self, prekey_id: u32, record: &SignedPreKeyRecord, + _ctx: Context, ) -> Result<(), SignalProtocolError> { Ok(self.do_save_signed_pre_key(prekey_id, record)?) } @@ -1170,7 +1180,7 @@ impl<'a> JniSessionStore<'a> { let callback_args = [address_jobject.into(), session_jobject.into()]; self.env .call_method(self.store, "storeSession", callback_sig, &callback_args)?; - exception_check(self.env)?; + exception_check(self.env, "storeSession")?; Ok(()) } } @@ -1179,6 +1189,7 @@ impl<'a> SessionStore for JniSessionStore<'a> { fn load_session( &self, address: &ProtocolAddress, + _ctx: Context, ) -> Result, SignalProtocolError> { Ok(self.do_load_session(address)?) } @@ -1187,6 +1198,7 @@ impl<'a> SessionStore for JniSessionStore<'a> { &mut self, address: &ProtocolAddress, record: &SessionRecord, + _ctx: Context, ) -> Result<(), SignalProtocolError> { Ok(self.do_store_session(address, record)?) } @@ -1257,6 +1269,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionBuilder_n &mut identity_key_store, bundle, &mut csprng, + None, )?; Ok(()) @@ -1284,6 +1297,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_na &protocol_address, &mut session_store, &mut identity_key_store, + None, )?; let obj = match ctext { @@ -1329,6 +1343,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_na &mut session_store, &mut identity_key_store, &mut csprng, + None, )?; to_jbytearray(&env, Ok(ptext)) @@ -1363,6 +1378,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_SessionCipher_na &mut prekey_store, &mut signed_prekey_store, &mut csprng, + None, )?; to_jbytearray(&env, Ok(ptext)) @@ -1404,7 +1420,7 @@ impl<'a> JniSenderKeyStore<'a> { callback_sig, &callback_args[..], )?; - exception_check(self.env)?; + exception_check(self.env, "storeSenderKey")?; Ok(()) } @@ -1437,6 +1453,7 @@ impl<'a> SenderKeyStore for JniSenderKeyStore<'a> { &mut self, sender_key_name: &SenderKeyName, record: &SenderKeyRecord, + _ctx: Context, ) -> Result<(), SignalProtocolError> { Ok(self.do_store_sender_key(sender_key_name, record)?) } @@ -1444,6 +1461,7 @@ impl<'a> SenderKeyStore for JniSenderKeyStore<'a> { fn load_sender_key( &mut self, sender_key_name: &SenderKeyName, + _ctx: Context, ) -> Result, SignalProtocolError> { Ok(self.do_load_sender_key(sender_key_name)?) } @@ -1471,6 +1489,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSess &sender_key_name, &mut sender_key_store, &mut csprng, + None, )?; box_object::(Ok(skdm)) }) @@ -1500,6 +1519,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupSess sender_key_name, sender_key_distribution_message, &mut sender_key_store, + None, )?; Ok(()) }) @@ -1526,7 +1546,13 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCiph let mut rng = rand::rngs::OsRng; - let ctext = group_encrypt(&mut sender_key_store, &sender_key_name, &message, &mut rng)?; + let ctext = group_encrypt( + &mut sender_key_store, + &sender_key_name, + &message, + &mut rng, + None, + )?; to_jbytearray(&env, Ok(ctext)) }) @@ -1551,7 +1577,7 @@ pub unsafe extern "system" fn Java_org_whispersystems_libsignal_groups_GroupCiph let mut sender_key_store = JniSenderKeyStore::new(&env, store); - let ptext = group_decrypt(&message, &mut sender_key_store, &sender_key_name)?; + let ptext = group_decrypt(&message, &mut sender_key_store, &sender_key_name, None)?; to_jbytearray(&env, Ok(ptext)) }) diff --git a/src/util.rs b/src/util.rs index 48350cb277..2b90f0b92b 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,7 +1,7 @@ -use jni::objects::{JObject, JString, JValue}; +use jni::objects::{JObject, JString, JThrowable, JValue}; use jni::sys::{_jobject, jboolean, jbyteArray, jint, jlong, jobject, jstring}; use jni::JNIEnv; -use libsignal_protocol_rust::*; +use libsignal_protocol_rust::SignalProtocolError; use std::fmt; #[derive(Debug)] @@ -296,23 +296,56 @@ pub fn jlong_from_u64(value: Result) -> Result Result<(), SignalJniError> { +pub fn exception_check(env: &JNIEnv, fn_name: &'static str) -> Result<(), SignalJniError> { + fn exception_class_name(env: &JNIEnv, exn: JThrowable) -> Result { + let class_type = env.call_method(exn, "getClass", "()Ljava/lang/Class;", &[])?; + if let JValue::Object(class_type) = class_type { + let class_name = + env.call_method(class_type, "getCanonicalName", "()Ljava/lang/String;", &[])?; + + if let JValue::Object(class_name) = class_name { + let class_name: String = env.get_string(JString::from(class_name))?.into(); + Ok(class_name) + } else { + Err(SignalJniError::UnexpectedJniResultType( + "getCanonicalName", + class_name.type_name(), + )) + } + } else { + Err(SignalJniError::UnexpectedJniResultType( + "getClass", + class_type.type_name(), + )) + } + } + if env.exception_check()? { let throwable = env.exception_occurred()?; env.exception_clear()?; let getmessage_sig = "()Ljava/lang/String;"; - let jmessage = env.call_method(throwable, "getMessage", getmessage_sig, &[])?; + let exn_type = exception_class_name(env, throwable).ok(); - if let JValue::Object(o) = jmessage { - let message: String = env.get_string(JString::from(o))?.into(); - return Err(SignalJniError::ExceptionDuringCallback(message)); - } else { - return Err(SignalJniError::ExceptionDuringCallback( - "Exception that didn't implement getMessage".to_string(), - )); + if let Ok(jmessage) = env.call_method(throwable, "getMessage", getmessage_sig, &[]) { + if let JValue::Object(o) = jmessage { + let message: String = env.get_string(JString::from(o))?.into(); + return Err(SignalJniError::Signal( + SignalProtocolError::ApplicationCallbackThrewException( + fn_name, exn_type, message, + ), + )); + } } + + return Err(SignalJniError::Signal( + SignalProtocolError::ApplicationCallbackThrewException( + fn_name, + exn_type, + "".to_string(), + ), + )); } Ok(()) @@ -344,7 +377,7 @@ pub fn get_object_with_native_handle( callback_fn: &'static str, ) -> Result, SignalJniError> { let rvalue = env.call_method(store_obj, callback_fn, callback_sig, &callback_args)?; - exception_check(env)?; + exception_check(env, callback_fn)?; let obj = match rvalue { JValue::Object(o) => *o, @@ -361,7 +394,7 @@ pub fn get_object_with_native_handle( } let handle = env.call_method(obj, "nativeHandle", "()J", &[])?; - exception_check(env)?; + exception_check(env, "nativeHandle")?; match handle { JValue::Long(handle) => { let object = unsafe { native_handle_cast::(handle)? }; @@ -382,7 +415,7 @@ pub fn get_object_with_serialization( callback_fn: &'static str, ) -> Result>, SignalJniError> { let rvalue = env.call_method(store_obj, callback_fn, callback_sig, &callback_args)?; - exception_check(env)?; + exception_check(env, callback_fn)?; let obj = match rvalue { JValue::Object(o) => *o, @@ -399,7 +432,7 @@ pub fn get_object_with_serialization( } let bytes = env.call_method(obj, "serialize", "()[B", &[])?; - exception_check(env)?; + exception_check(env, "serialize")?; match bytes { JValue::Object(o) => Ok(Some(env.convert_byte_array(*o)?)), From e5840644c7cab5344c2664dd953f8b7910aa8fa8 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 16 Oct 2020 18:17:21 -0400 Subject: [PATCH 17/19] Move libsignal-jni to rust/bridge/jni --- .github/workflows/rust.yml | 26 ------------------------ .gitignore | 2 -- .rustfmt.toml | 1 - Cargo.toml => rust/bridge/jni/Cargo.toml | 0 README.md => rust/bridge/jni/README.md | 0 {src => rust/bridge/jni/src}/lib.rs | 0 {src => rust/bridge/jni/src}/util.rs | 0 7 files changed, 29 deletions(-) delete mode 100644 .github/workflows/rust.yml delete mode 100644 .gitignore delete mode 100644 .rustfmt.toml rename Cargo.toml => rust/bridge/jni/Cargo.toml (100%) rename README.md => rust/bridge/jni/README.md (100%) rename {src => rust/bridge/jni/src}/lib.rs (100%) rename {src => rust/bridge/jni/src}/util.rs (100%) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml deleted file mode 100644 index 6aff1a32ed..0000000000 --- a/.github/workflows/rust.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Rust - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -env: - CARGO_TERM_COLOR: always - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Rustfmt check - run: cargo fmt -- --check -# - name: Build -# run: cargo build --verbose -# - name: Run tests -# run: cargo test --verbose -# - name: Clippy -# run: cargo clippy diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 96ef6c0b94..0000000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target -Cargo.lock diff --git a/.rustfmt.toml b/.rustfmt.toml deleted file mode 100644 index 32a9786fa1..0000000000 --- a/.rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -edition = "2018" diff --git a/Cargo.toml b/rust/bridge/jni/Cargo.toml similarity index 100% rename from Cargo.toml rename to rust/bridge/jni/Cargo.toml diff --git a/README.md b/rust/bridge/jni/README.md similarity index 100% rename from README.md rename to rust/bridge/jni/README.md diff --git a/src/lib.rs b/rust/bridge/jni/src/lib.rs similarity index 100% rename from src/lib.rs rename to rust/bridge/jni/src/lib.rs diff --git a/src/util.rs b/rust/bridge/jni/src/util.rs similarity index 100% rename from src/util.rs rename to rust/bridge/jni/src/util.rs From 3d24f94cef2e1a7340fb08c09c22fac287879c56 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 16 Oct 2020 18:26:26 -0400 Subject: [PATCH 18/19] Update paths and workspace config --- Cargo.toml | 3 ++- rust/bridge/jni/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 90d781eeef..79fbaa590f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,6 @@ [workspace] members = [ "rust/protocol", - "rust/bridge/ffi" + "rust/bridge/ffi", + "rust/bridge/jni" ] diff --git a/rust/bridge/jni/Cargo.toml b/rust/bridge/jni/Cargo.toml index a1c4c6175a..81d9503f44 100644 --- a/rust/bridge/jni/Cargo.toml +++ b/rust/bridge/jni/Cargo.toml @@ -11,6 +11,6 @@ crate-type = ["dylib"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -libsignal-protocol-rust = { git = "ssh://git@github.com/signalapp/libsignal-protocol-rust.git" } +libsignal-protocol-rust = { path = "../../protocol" } jni = "0.17" rand = "0.7.3" From c1331eb42f71184996e3994b52023a40ec47c0dd Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Fri, 16 Oct 2020 18:30:17 -0400 Subject: [PATCH 19/19] Add license headers --- rust/bridge/jni/src/lib.rs | 7 +++++++ rust/bridge/jni/src/util.rs | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/rust/bridge/jni/src/lib.rs b/rust/bridge/jni/src/lib.rs index 8e55b7ee97..3dbdbd6106 100644 --- a/rust/bridge/jni/src/lib.rs +++ b/rust/bridge/jni/src/lib.rs @@ -1,3 +1,10 @@ +// +// Copyright (C) 2020 Signal Messenger, LLC. +// All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-only +// + #![allow(clippy::missing_safety_doc)] #![deny(warnings)] diff --git a/rust/bridge/jni/src/util.rs b/rust/bridge/jni/src/util.rs index 2b90f0b92b..c6cdfb31af 100644 --- a/rust/bridge/jni/src/util.rs +++ b/rust/bridge/jni/src/util.rs @@ -1,3 +1,10 @@ +// +// Copyright (C) 2020 Signal Messenger, LLC. +// All rights reserved. +// +// SPDX-License-Identifier: GPL-3.0-only +// + use jni::objects::{JObject, JString, JThrowable, JValue}; use jni::sys::{_jobject, jboolean, jbyteArray, jint, jlong, jobject, jstring}; use jni::JNIEnv;