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 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/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" 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()); }) }