diff --git a/java/java/src/main/java/org/signal/internal/Native.java b/java/java/src/main/java/org/signal/internal/Native.java index a301192d8..844629eb5 100644 --- a/java/java/src/main/java/org/signal/internal/Native.java +++ b/java/java/src/main/java/org/signal/internal/Native.java @@ -79,14 +79,14 @@ public final class Native { public static native void ECPrivateKey_Destroy(long handle); public static native long ECPrivateKey_Generate(); public static native long ECPrivateKey_GetPublicKey(long k); - public static native byte[] ECPrivateKey_Serialize(long handle); + public static native byte[] ECPrivateKey_Serialize(long obj); public static native byte[] ECPrivateKey_Sign(long key, byte[] message); public static native int ECPublicKey_Compare(long key1, long key2); public static native long ECPublicKey_Deserialize(byte[] data, int offset); public static native void ECPublicKey_Destroy(long handle); - public static native byte[] ECPublicKey_GetPublicKeyBytes(long handle); - public static native byte[] ECPublicKey_Serialize(long handle); + public static native byte[] ECPublicKey_GetPublicKeyBytes(long obj); + public static native byte[] ECPublicKey_Serialize(long obj); public static native boolean ECPublicKey_Verify(long key, byte[] message, byte[] signature); public static native byte[] GroupCipher_DecryptMessage(long senderKeyName, byte[] message, SenderKeyStore store); @@ -105,7 +105,7 @@ public final class Native { public static native void NumericFingerprintGenerator_Destroy(long handle); public static native String NumericFingerprintGenerator_GetDisplayString(long obj); - public static native byte[] NumericFingerprintGenerator_GetScannableEncoding(long handle); + public static native byte[] NumericFingerprintGenerator_GetScannableEncoding(long obj); public static native long NumericFingerprintGenerator_New(int iterations, int version, byte[] localIdentifier, byte[] localKey, byte[] remoteIdentifier, byte[] remoteKey); public static native void PreKeyBundle_Destroy(long handle); @@ -116,7 +116,7 @@ public final class Native { public static native int PreKeyBundle_GetRegistrationId(long obj); public static native int PreKeyBundle_GetSignedPreKeyId(long obj); public static native long PreKeyBundle_GetSignedPreKeyPublic(long obj); - public static native byte[] PreKeyBundle_GetSignedPreKeySignature(long handle); + public static native byte[] PreKeyBundle_GetSignedPreKeySignature(long obj); public static native long PreKeyBundle_New(int registrationId, int deviceId, int prekeyId, long prekey, int signedPrekeyId, long signedPrekey, byte[] signedPrekeySignature, long identityKey); public static native long PreKeyRecord_Deserialize(byte[] data); @@ -124,17 +124,17 @@ public final class Native { public static native int PreKeyRecord_GetId(long obj); public static native long PreKeyRecord_GetPrivateKey(long obj); public static native long PreKeyRecord_GetPublicKey(long obj); - public static native byte[] PreKeyRecord_GetSerialized(long handle); + public static native byte[] PreKeyRecord_GetSerialized(long obj); public static native long PreKeyRecord_New(int id, long pubKey, long privKey); public static native long PreKeySignalMessage_Deserialize(byte[] data); public static native void PreKeySignalMessage_Destroy(long handle); - public static native byte[] PreKeySignalMessage_GetBaseKey(long handle); - public static native byte[] PreKeySignalMessage_GetIdentityKey(long handle); + public static native byte[] PreKeySignalMessage_GetBaseKey(long m); + public static native byte[] PreKeySignalMessage_GetIdentityKey(long m); public static native int PreKeySignalMessage_GetPreKeyId(long obj); public static native int PreKeySignalMessage_GetRegistrationId(long obj); - public static native byte[] PreKeySignalMessage_GetSerialized(long handle); - public static native byte[] PreKeySignalMessage_GetSignalMessage(long handle); + public static native byte[] PreKeySignalMessage_GetSerialized(long obj); + public static native byte[] PreKeySignalMessage_GetSignalMessage(long m); public static native int PreKeySignalMessage_GetSignedPreKeyId(long obj); public static native int PreKeySignalMessage_GetVersion(long obj); public static native long PreKeySignalMessage_New(int messageVersion, int registrationId, int preKeyId, int signedPreKeyId, long baseKey, long identityKey, long signalMessage); @@ -151,33 +151,33 @@ public final class Native { public static native long SenderCertificate_Deserialize(byte[] data); public static native void SenderCertificate_Destroy(long handle); - public static native byte[] SenderCertificate_GetCertificate(long handle); + public static native byte[] SenderCertificate_GetCertificate(long obj); public static native int SenderCertificate_GetDeviceId(long obj); public static native long SenderCertificate_GetExpiration(long obj); public static native long SenderCertificate_GetKey(long obj); public static native String SenderCertificate_GetSenderE164(long obj); public static native String SenderCertificate_GetSenderUuid(long obj); - public static native byte[] SenderCertificate_GetSerialized(long handle); + public static native byte[] SenderCertificate_GetSerialized(long obj); public static native long SenderCertificate_GetServerCertificate(long cert); - public static native byte[] SenderCertificate_GetSignature(long handle); + public static native byte[] SenderCertificate_GetSignature(long obj); public static native long SenderCertificate_New(String senderUuid, String senderE164, int senderDeviceId, long senderKey, long expiration, long signerCert, long signerKey); public static native boolean SenderCertificate_Validate(long cert, long key, long time); public static native long SenderKeyDistributionMessage_Deserialize(byte[] data); public static native void SenderKeyDistributionMessage_Destroy(long handle); - public static native byte[] SenderKeyDistributionMessage_GetChainKey(long handle); + public static native byte[] SenderKeyDistributionMessage_GetChainKey(long obj); public static native int SenderKeyDistributionMessage_GetId(long obj); public static native int SenderKeyDistributionMessage_GetIteration(long obj); - public static native byte[] SenderKeyDistributionMessage_GetSerialized(long handle); - public static native byte[] SenderKeyDistributionMessage_GetSignatureKey(long handle); + public static native byte[] SenderKeyDistributionMessage_GetSerialized(long obj); + public static native byte[] SenderKeyDistributionMessage_GetSignatureKey(long m); public static native long SenderKeyDistributionMessage_New(int keyId, int iteration, byte[] chainkey, long pk); public static native long SenderKeyMessage_Deserialize(byte[] data); public static native void SenderKeyMessage_Destroy(long handle); - public static native byte[] SenderKeyMessage_GetCipherText(long handle); + public static native byte[] SenderKeyMessage_GetCipherText(long obj); public static native int SenderKeyMessage_GetIteration(long obj); public static native int SenderKeyMessage_GetKeyId(long obj); - public static native byte[] SenderKeyMessage_GetSerialized(long handle); + public static native byte[] SenderKeyMessage_GetSerialized(long obj); public static native long SenderKeyMessage_New(int keyId, int iteration, byte[] ciphertext, long pk); public static native boolean SenderKeyMessage_VerifySignature(long skm, long pubkey); @@ -189,16 +189,16 @@ public final class Native { public static native long SenderKeyRecord_Deserialize(byte[] data); public static native void SenderKeyRecord_Destroy(long handle); - public static native byte[] SenderKeyRecord_GetSerialized(long handle); + public static native byte[] SenderKeyRecord_GetSerialized(long obj); public static native long SenderKeyRecord_New(); public static native long ServerCertificate_Deserialize(byte[] data); public static native void ServerCertificate_Destroy(long handle); - public static native byte[] ServerCertificate_GetCertificate(long handle); + public static native byte[] ServerCertificate_GetCertificate(long obj); public static native long ServerCertificate_GetKey(long obj); public static native int ServerCertificate_GetKeyId(long obj); - public static native byte[] ServerCertificate_GetSerialized(long handle); - public static native byte[] ServerCertificate_GetSignature(long handle); + public static native byte[] ServerCertificate_GetSerialized(long obj); + public static native byte[] ServerCertificate_GetSignature(long obj); public static native long ServerCertificate_New(int keyId, long serverKey, long trustRoot); public static native void SessionBuilder_ProcessPreKeyBundle(long bundle, long protocolAddress, SessionStore sessionStore, IdentityKeyStore identityKeyStore); @@ -211,27 +211,27 @@ public final class Native { public static native long SessionRecord_Deserialize(byte[] data); public static native void SessionRecord_Destroy(long handle); public static native long SessionRecord_FromSingleSessionState(byte[] sessionState); - public static native byte[] SessionRecord_GetAliceBaseKey(long handle); - public static native byte[] SessionRecord_GetLocalIdentityKeyPublic(long handle); + public static native byte[] SessionRecord_GetAliceBaseKey(long obj); + public static native byte[] SessionRecord_GetLocalIdentityKeyPublic(long obj); public static native int SessionRecord_GetLocalRegistrationId(long obj); public static native byte[] SessionRecord_GetReceiverChainKeyValue(long sessionState, long key); - public static native byte[] SessionRecord_GetRemoteIdentityKeyPublic(long handle); + public static native byte[] SessionRecord_GetRemoteIdentityKeyPublic(long obj); public static native int SessionRecord_GetRemoteRegistrationId(long obj); - public static native byte[] SessionRecord_GetSenderChainKeyValue(long handle); + public static native byte[] SessionRecord_GetSenderChainKeyValue(long obj); public static native int SessionRecord_GetSessionVersion(long s); public static native boolean SessionRecord_HasSenderChain(long obj); public static native long SessionRecord_InitializeAliceSession(long identityKeyPrivate, long identityKeyPublic, long basePrivate, long basePublic, long theirIdentityKey, long theirSignedPrekey, long theirRatchetKey); public static native long SessionRecord_InitializeBobSession(long identityKeyPrivate, long identityKeyPublic, long signedPrekeyPrivate, long signedPrekeyPublic, long ephPrivate, long ephPublic, long theirIdentityKey, long theirBaseKey); public static native long SessionRecord_NewFresh(); - public static native byte[] SessionRecord_Serialize(long handle); + public static native byte[] SessionRecord_Serialize(long obj); public static native long SignalMessage_Deserialize(byte[] data); public static native void SignalMessage_Destroy(long handle); - public static native byte[] SignalMessage_GetBody(long handle); + public static native byte[] SignalMessage_GetBody(long obj); public static native int SignalMessage_GetCounter(long obj); public static native int SignalMessage_GetMessageVersion(long obj); - public static native byte[] SignalMessage_GetSenderRatchetKey(long handle); - public static native byte[] SignalMessage_GetSerialized(long handle); + public static native byte[] SignalMessage_GetSenderRatchetKey(long m); + public static native byte[] SignalMessage_GetSerialized(long obj); public static native long SignalMessage_New(int messageVersion, byte[] macKey, long senderRatchetKey, int counter, int previousCounter, byte[] ciphertext, long senderIdentityKey, long receiverIdentityKey); public static native boolean SignalMessage_VerifyMac(long msg, long senderIdentityKey, long receiverIdentityKey, byte[] macKey); @@ -240,24 +240,24 @@ public final class Native { public static native int SignedPreKeyRecord_GetId(long obj); public static native long SignedPreKeyRecord_GetPrivateKey(long obj); public static native long SignedPreKeyRecord_GetPublicKey(long obj); - public static native byte[] SignedPreKeyRecord_GetSerialized(long handle); - public static native byte[] SignedPreKeyRecord_GetSignature(long handle); + public static native byte[] SignedPreKeyRecord_GetSerialized(long obj); + public static native byte[] SignedPreKeyRecord_GetSignature(long obj); public static native long SignedPreKeyRecord_GetTimestamp(long obj); public static native long SignedPreKeyRecord_New(int id, long timestamp, long pubKey, long privKey, byte[] signature); public static native long UnidentifiedSenderMessageContent_Deserialize(byte[] data); public static native void UnidentifiedSenderMessageContent_Destroy(long handle); - public static native byte[] UnidentifiedSenderMessageContent_GetContents(long handle); + public static native byte[] UnidentifiedSenderMessageContent_GetContents(long obj); public static native int UnidentifiedSenderMessageContent_GetMsgType(long m); public static native long UnidentifiedSenderMessageContent_GetSenderCert(long m); - public static native byte[] UnidentifiedSenderMessageContent_GetSerialized(long handle); + public static native byte[] UnidentifiedSenderMessageContent_GetSerialized(long obj); public static native long UnidentifiedSenderMessageContent_New(int msgType, long sender, byte[] contents); public static native long UnidentifiedSenderMessage_Deserialize(byte[] data); public static native void UnidentifiedSenderMessage_Destroy(long handle); - public static native byte[] UnidentifiedSenderMessage_GetEncryptedMessage(long handle); - public static native byte[] UnidentifiedSenderMessage_GetEncryptedStatic(long handle); + public static native byte[] UnidentifiedSenderMessage_GetEncryptedMessage(long obj); + public static native byte[] UnidentifiedSenderMessage_GetEncryptedStatic(long obj); public static native long UnidentifiedSenderMessage_GetEphemeralPublic(long obj); - public static native byte[] UnidentifiedSenderMessage_GetSerialized(long handle); + public static native byte[] UnidentifiedSenderMessage_GetSerialized(long obj); public static native long UnidentifiedSenderMessage_New(long publicKey, byte[] encryptedStatic, byte[] encryptedMessage); } diff --git a/rust/bridge/shared/src/ffi/mod.rs b/rust/bridge/shared/src/ffi/mod.rs index ce9b63281..31bbb7076 100644 --- a/rust/bridge/shared/src/ffi/mod.rs +++ b/rust/bridge/shared/src/ffi/mod.rs @@ -148,36 +148,3 @@ macro_rules! ffi_bridge_deserialize { } }; } - -/// Implementation of [`bridge_get_bytearray`](crate::support::bridge_get_bytearray) for FFI. -macro_rules! ffi_bridge_get_bytearray { - ( $name:ident($typ:ty) as false => $body:expr ) => {}; - ( $name:ident($typ:ty) as $ffi_name:tt => $body:expr ) => { - paste! { - #[no_mangle] - pub unsafe extern "C" fn []( - out: *mut *const libc::c_uchar, - out_len: *mut libc::size_t, - obj: *const $typ, - ) -> *mut ffi::SignalFfiError { - expr_as_fn!(inner_get<'a>( - obj: &'a $typ - ) -> Result> + 'a> => $body); - ffi::run_ffi_safe(|| { - let obj = ffi::native_handle_cast::<$typ>(obj)?; - ffi::write_bytearray_to(out, out_len, inner_get(obj)?) - }) - } - } - }; - ( $name:ident($typ:ty) => $body:expr ) => { - paste! { - ffi_bridge_get_bytearray!($name($typ) as [<$typ:snake _ $name:snake>] => $body); - } - }; -} - -// Currently unneeded. -macro_rules! ffi_bridge_get_optional_bytearray { - ( $name:ident($typ:ty) as false => $body:expr ) => {}; -} diff --git a/rust/bridge/shared/src/jni/mod.rs b/rust/bridge/shared/src/jni/mod.rs index 1a6bc1901..0920695b6 100644 --- a/rust/bridge/shared/src/jni/mod.rs +++ b/rust/bridge/shared/src/jni/mod.rs @@ -491,62 +491,3 @@ macro_rules! jni_bridge_deserialize { jni_bridge_deserialize!($typ::$fn as $typ); }; } - -/// Implementation of [`bridge_get_bytearray`](crate::support::bridge_get_bytearray) for JNI. -macro_rules! jni_bridge_get_bytearray { - ( $name:ident($typ:ty) as false => $body:expr ) => {}; - ( $name:ident($typ:ty) as $jni_name:tt => $body:expr ) => { - paste! { - #[no_mangle] - pub unsafe extern "C" fn []( - env: jni::JNIEnv, - _class: jni::JClass, - handle: jni::ObjectHandle, - ) -> jni::jbyteArray { - expr_as_fn!(inner_get<'a>( - obj: &'a $typ - ) -> Result + 'a> => $body); - jni::run_ffi_safe(&env, || { - let obj = jni::native_handle_cast::<$typ>(handle)?; - jni::to_jbytearray(&env, inner_get(obj)) - }) - } - } - }; - ( $name:ident($typ:ty) => $body:expr ) => { - paste! { - jni_bridge_get_bytearray!($name($typ) as [<$typ _1 $name:camel>] => $body); - } - }; -} - -/// Implementation of [`bridge_get_optional_bytearray`](crate::support::bridge_get_optional_bytearray) for JNI. -macro_rules! jni_bridge_get_optional_bytearray { - ( $name:ident($typ:ty) as false => $body:expr ) => {}; - ( $name:ident($typ:ty) as $jni_name:tt => $body:expr ) => { - paste! { - #[no_mangle] - pub unsafe extern "C" fn []( - env: jni::JNIEnv, - _class: jni::JClass, - handle: jni::ObjectHandle, - ) -> jni::jbyteArray { - expr_as_fn!(inner_get<'a>( - obj: &'a $typ - ) -> Result + 'a>> => $body); - jni::run_ffi_safe(&env, || { - let obj = jni::native_handle_cast::<$typ>(handle)?; - match inner_get(obj)? { - Some(v) => jni::to_jbytearray(&env, Ok(v)), - None => Ok(std::ptr::null_mut()), - } - }) - } - } - }; - ( $name:ident($typ:ty) => $body:expr ) => { - paste! { - jni_bridge_get_optional_bytearray!($name($typ) as [<$typ _1 $name:camel>] => $body); - } - }; -} diff --git a/rust/bridge/shared/src/node/mod.rs b/rust/bridge/shared/src/node/mod.rs index a5c9e85ed..723b633da 100644 --- a/rust/bridge/shared/src/node/mod.rs +++ b/rust/bridge/shared/src/node/mod.rs @@ -145,63 +145,3 @@ macro_rules! node_bridge_deserialize { node_bridge_deserialize!($typ::$fn as $typ); }; } - -/// Implementation of [`bridge_get_bytearray`](crate::support::bridge_get_bytearray) for Node. -macro_rules! node_bridge_get_bytearray { - ( $name:ident($typ:ty) as false => $body:expr ) => {}; - ( $name:ident($typ:ty) as $node_name:tt => $body:expr ) => { - paste! { - #[allow(non_snake_case)] - #[doc = "ts: export function " $node_name "(obj: &" $typ "): Buffer"] - pub fn []( - mut cx: node::FunctionContext - ) -> node::JsResult { - expr_as_fn!(inner_get<'a>( - obj: &'a $typ - ) -> Result + 'a> => $body); - let obj_arg = cx.argument::<<&$typ as node::ArgTypeInfo>::ArgType>(0)?; - let mut obj_borrow = <&$typ as node::ArgTypeInfo>::borrow(&mut cx, obj_arg)?; - let obj = <&$typ as node::ArgTypeInfo>::load_from(&mut obj_borrow); - let bytes = inner_get(obj); - node::return_binary_data(&mut cx, bytes.map(Some)) - } - - node_register!($node_name); - } - }; - ( $name:ident($typ:ty) => $body:expr ) => { - paste! { - node_bridge_get_bytearray!($name($typ) as [<$typ _ $name:camel>] => $body); - } - }; -} - -/// Implementation of [`bridge_get_optional_bytearray`](crate::support::bridge_get_optional_bytearray) for Node. -macro_rules! node_bridge_get_optional_bytearray { - ( $name:ident($typ:ty) as false => $body:expr ) => {}; - ( $name:ident($typ:ty) as $node_name:tt => $body:expr ) => { - paste! { - #[allow(non_snake_case)] - #[doc = "ts: export function " $node_name "(obj: &" $typ "): Buffer | null"] - pub fn []( - mut cx: node::FunctionContext - ) -> node::JsResult { - expr_as_fn!(inner_get<'a>( - obj: &'a $typ - ) -> Result + 'a>> => $body); - let obj_arg = cx.argument::<<&$typ as node::ArgTypeInfo>::ArgType>(0)?; - let mut obj_borrow = <&$typ as node::ArgTypeInfo>::borrow(&mut cx, obj_arg)?; - let obj = <&$typ as node::ArgTypeInfo>::load_from(&mut obj_borrow); - let bytes = inner_get(obj); - node::return_binary_data(&mut cx, bytes) - } - - node_register!($node_name); - } - }; - ( $name:ident($typ:ty) => $body:expr ) => { - paste! { - node_bridge_get_optional_bytearray!($name($typ) as [<$typ _ $name:camel>] => $body); - } - }; -} diff --git a/rust/bridge/shared/src/protocol.rs b/rust/bridge/shared/src/protocol.rs index 47af23596..32f6303f5 100644 --- a/rust/bridge/shared/src/protocol.rs +++ b/rust/bridge/shared/src/protocol.rs @@ -82,13 +82,15 @@ fn ECPublicKey_Deserialize(data: &[u8], offset: u32) -> Result { PublicKey::deserialize(&data[offset..]) } -bridge_get_bytearray!(Serialize(PublicKey), ffi = "publickey_serialize", jni = "ECPublicKey_1Serialize" => - |k| Ok(k.serialize())); bridge_get_bytearray!( - GetPublicKeyBytes(PublicKey), + PublicKey::serialize as Serialize, + ffi = "publickey_serialize", + jni = "ECPublicKey_1Serialize" +); +bridge_get_bytearray!( + PublicKey::public_key_bytes, ffi = "publickey_get_public_key_bytes", - jni = "ECPublicKey_1GetPublicKeyBytes" => - PublicKey::public_key_bytes + jni = "ECPublicKey_1GetPublicKeyBytes" ); bridge_get!(ProtocolAddress::device_id as DeviceId -> u32, ffi = "address_get_device_id"); bridge_get!(ProtocolAddress::name as Name -> &str, ffi = "address_get_name"); @@ -113,10 +115,9 @@ bridge_deserialize!( jni = ECPrivateKey ); bridge_get_bytearray!( - Serialize(PrivateKey), + PrivateKey::serialize as Serialize, ffi = "privatekey_serialize", - jni = "ECPrivateKey_1Serialize" => - |k| Ok(k.serialize()) + jni = "ECPrivateKey_1Serialize" ); #[bridge_fn(ffi = "privatekey_generate", node = "PrivateKey_Generate")] @@ -200,11 +201,11 @@ fn NumericFingerprintGenerator_New( ) } -bridge_get_bytearray!( - ScannableEncoding(Fingerprint), - jni = "NumericFingerprintGenerator_1GetScannableEncoding" => - |f| f.scannable.serialize() -); +#[bridge_fn_buffer(jni = "NumericFingerprintGenerator_1GetScannableEncoding")] +fn Fingerprint_ScannableEncoding(env: E, obj: &Fingerprint) -> Result { + Ok(env.buffer(obj.scannable.serialize()?)) +} + bridge_get!( Fingerprint::display_string as DisplayString -> String, jni = "NumericFingerprintGenerator_1GetDisplayString" @@ -216,15 +217,14 @@ fn ScannableFingerprint_Compare(fprint1: &[u8], fprint2: &[u8]) -> Result } bridge_deserialize!(SignalMessage::try_from, ffi = message); -bridge_get_bytearray!(GetSenderRatchetKey(SignalMessage), ffi = false, node = false => - |m| Ok(m.sender_ratchet_key().serialize()) -); -bridge_get_bytearray!(GetBody(SignalMessage), ffi = "message_get_body" => - |m| Ok(m.body()) -); -bridge_get_bytearray!(GetSerialized(SignalMessage), ffi = "message_get_serialized" => - |m| Ok(m.serialized()) -); + +#[bridge_fn_buffer(ffi = false, node = false)] +fn SignalMessage_GetSenderRatchetKey(env: E, m: &SignalMessage) -> E::Buffer { + env.buffer(m.sender_ratchet_key().serialize().into_vec()) +} + +bridge_get_bytearray!(SignalMessage::body, ffi = "message_get_body"); +bridge_get_bytearray!(SignalMessage::serialized, ffi = "message_get_serialized"); bridge_get!(SignalMessage::counter -> u32, ffi = "message_get_counter"); bridge_get!(SignalMessage::message_version -> u32, ffi = "message_get_message_version"); @@ -266,7 +266,7 @@ fn SignalMessage_VerifyMac( } #[bridge_fn(ffi = "message_get_sender_ratchet_key", jni = false, node = false)] -fn SignalMessage_GetSenderRatchetKey(m: &SignalMessage) -> PublicKey { +fn Message_GetSenderRatchetKey(m: &SignalMessage) -> PublicKey { *m.sender_ratchet_key() } @@ -307,26 +307,47 @@ fn PreKeySignalMessage_GetSignalMessage(m: &PreKeySignalMessage) -> SignalMessag } bridge_deserialize!(PreKeySignalMessage::try_from); -bridge_get_bytearray!(Serialize(PreKeySignalMessage), jni = "PreKeySignalMessage_1GetSerialized" => - |m| Ok(m.serialized()) -); -bridge_get_bytearray!(GetBaseKey(PreKeySignalMessage), ffi = false, node = false => - |m| Ok(m.base_key().serialize()) -); -bridge_get_bytearray!(GetIdentityKey(PreKeySignalMessage), ffi = false, node = false => - |m| Ok(m.identity_key().serialize()) -); -bridge_get_bytearray!(GetSignalMessage(PreKeySignalMessage), ffi = false, node = false => - |m| Ok(m.message().serialized()) +bridge_get_bytearray!( + PreKeySignalMessage::serialized as Serialize, + jni = "PreKeySignalMessage_1GetSerialized" ); + +#[bridge_fn_buffer(ffi = false, jni = "PreKeySignalMessage_1GetBaseKey", node = false)] +fn PreKeySignalMessage_GetBaseKeySerialized(env: E, m: &PreKeySignalMessage) -> E::Buffer { + env.buffer(m.base_key().serialize().into_vec()) +} + +#[bridge_fn_buffer(ffi = false, jni = "PreKeySignalMessage_1GetIdentityKey", node = false)] +fn PreKeySignalMessage_GetIdentityKeySerialized( + env: E, + m: &PreKeySignalMessage, +) -> E::Buffer { + env.buffer(m.identity_key().serialize().into_vec()) +} + +#[bridge_fn_buffer( + ffi = false, + jni = "PreKeySignalMessage_1GetSignalMessage", + node = false +)] +fn PreKeySignalMessage_GetSignalMessageSerialized( + env: E, + m: &PreKeySignalMessage, +) -> E::Buffer { + env.buffer(m.message().serialized()) +} + bridge_get!(PreKeySignalMessage::registration_id -> u32); bridge_get!(PreKeySignalMessage::signed_pre_key_id -> u32); bridge_get!(PreKeySignalMessage::pre_key_id -> Option); bridge_get!(PreKeySignalMessage::message_version as GetVersion -> u32); bridge_deserialize!(SenderKeyMessage::try_from); -bridge_get_bytearray!(GetCipherText(SenderKeyMessage) => |m| Ok(m.ciphertext())); -bridge_get_bytearray!(Serialize(SenderKeyMessage), jni = "SenderKeyMessage_1GetSerialized" => |m| Ok(m.serialized())); +bridge_get_bytearray!(SenderKeyMessage::ciphertext as GetCipherText); +bridge_get_bytearray!( + SenderKeyMessage::serialized as Serialize, + jni = "SenderKeyMessage_1GetSerialized" +); bridge_get!(SenderKeyMessage::key_id -> u32); bridge_get!(SenderKeyMessage::iteration -> u32); @@ -347,12 +368,23 @@ fn SenderKeyMessage_VerifySignature(skm: &SenderKeyMessage, pubkey: &PublicKey) } bridge_deserialize!(SenderKeyDistributionMessage::try_from); -bridge_get_bytearray!(GetChainKey(SenderKeyDistributionMessage) => SenderKeyDistributionMessage::chain_key); -bridge_get_bytearray!(GetSignatureKey(SenderKeyDistributionMessage), ffi = false, node = false => - |m| Ok(m.signing_key()?.serialize()) -); -bridge_get_bytearray!(Serialize(SenderKeyDistributionMessage), jni = "SenderKeyDistributionMessage_1GetSerialized" => - |m| Ok(m.serialized()) +bridge_get_bytearray!(SenderKeyDistributionMessage::chain_key); + +#[bridge_fn_buffer( + ffi = false, + jni = "SenderKeyDistributionMessage_1GetSignatureKey", + node = false +)] +fn SenderKeyDistributionMessage_GetSignatureKeySerialized( + env: E, + m: &SenderKeyDistributionMessage, +) -> Result { + Ok(env.buffer(m.signing_key()?.serialize().into_vec())) +} + +bridge_get_bytearray!( + SenderKeyDistributionMessage::serialized as Serialize, + jni = "SenderKeyDistributionMessage_1GetSerialized" ); bridge_get!(SenderKeyDistributionMessage::id -> u32); bridge_get!(SenderKeyDistributionMessage::iteration -> u32); @@ -413,7 +445,7 @@ fn PreKeyBundle_GetIdentityKey(p: &PreKeyBundle) -> Result { Ok(*p.identity_key()?.public_key()) } -bridge_get_bytearray!(GetSignedPreKeySignature(PreKeyBundle) => PreKeyBundle::signed_pre_key_signature); +bridge_get_bytearray!(PreKeyBundle::signed_pre_key_signature); bridge_get!(PreKeyBundle::registration_id -> u32); bridge_get!(PreKeyBundle::device_id -> u32); bridge_get!(PreKeyBundle::signed_pre_key_id -> u32); @@ -422,9 +454,10 @@ bridge_get!(PreKeyBundle::pre_key_public -> Option); bridge_get!(PreKeyBundle::signed_pre_key_public -> PublicKey); bridge_deserialize!(SignedPreKeyRecord::deserialize); -bridge_get_bytearray!(GetSignature(SignedPreKeyRecord) => SignedPreKeyRecord::signature); -bridge_get_bytearray!(Serialize(SignedPreKeyRecord), jni = "SignedPreKeyRecord_1GetSerialized" => - SignedPreKeyRecord::serialize +bridge_get_bytearray!(SignedPreKeyRecord::signature); +bridge_get_bytearray!( + SignedPreKeyRecord::serialize as Serialize, + jni = "SignedPreKeyRecord_1GetSerialized" ); bridge_get!(SignedPreKeyRecord::id -> u32); bridge_get!(SignedPreKeyRecord::timestamp -> u64); @@ -444,8 +477,9 @@ fn SignedPreKeyRecord_New( } bridge_deserialize!(PreKeyRecord::deserialize); -bridge_get_bytearray!(Serialize(PreKeyRecord), jni = "PreKeyRecord_1GetSerialized" => - PreKeyRecord::serialize +bridge_get_bytearray!( + PreKeyRecord::serialize as Serialize, + jni = "PreKeyRecord_1GetSerialized" ); bridge_get!(PreKeyRecord::id -> u32); bridge_get!(PreKeyRecord::public_key -> PublicKey); @@ -482,8 +516,9 @@ fn SenderKeyName_GetSenderDeviceId(skn: &SenderKeyName) -> Result { } bridge_deserialize!(SenderKeyRecord::deserialize); -bridge_get_bytearray!(Serialize(SenderKeyRecord), jni = "SenderKeyRecord_1GetSerialized" => - SenderKeyRecord::serialize +bridge_get_bytearray!( + SenderKeyRecord::serialize as Serialize, + jni = "SenderKeyRecord_1GetSerialized" ); #[bridge_fn(ffi = "sender_key_record_new_fresh")] @@ -492,9 +527,9 @@ fn SenderKeyRecord_New() -> SenderKeyRecord { } bridge_deserialize!(ServerCertificate::deserialize); -bridge_get_bytearray!(GetSerialized(ServerCertificate) => ServerCertificate::serialized); -bridge_get_bytearray!(GetCertificate(ServerCertificate) => ServerCertificate::certificate); -bridge_get_bytearray!(GetSignature(ServerCertificate) => ServerCertificate::signature); +bridge_get_bytearray!(ServerCertificate::serialized); +bridge_get_bytearray!(ServerCertificate::certificate); +bridge_get_bytearray!(ServerCertificate::signature); bridge_get!(ServerCertificate::key_id -> u32); bridge_get!(ServerCertificate::public_key as GetKey -> PublicKey); @@ -509,9 +544,9 @@ fn ServerCertificate_New( } bridge_deserialize!(SenderCertificate::deserialize); -bridge_get_bytearray!(GetSerialized(SenderCertificate) => SenderCertificate::serialized); -bridge_get_bytearray!(GetCertificate(SenderCertificate) => SenderCertificate::certificate); -bridge_get_bytearray!(GetSignature(SenderCertificate) => SenderCertificate::signature); +bridge_get_bytearray!(SenderCertificate::serialized); +bridge_get_bytearray!(SenderCertificate::certificate); +bridge_get_bytearray!(SenderCertificate::signature); bridge_get!(SenderCertificate::sender_uuid -> &str); bridge_get!(SenderCertificate::sender_e164 -> Option<&str>); bridge_get!(SenderCertificate::expiration -> u64); @@ -558,13 +593,10 @@ fn SenderCertificate_New( bridge_deserialize!(UnidentifiedSenderMessageContent::deserialize); bridge_get_bytearray!( - Serialize(UnidentifiedSenderMessageContent), - jni = "UnidentifiedSenderMessageContent_1GetSerialized" => - UnidentifiedSenderMessageContent::serialized -); -bridge_get_bytearray!(GetContents(UnidentifiedSenderMessageContent) => - UnidentifiedSenderMessageContent::contents + UnidentifiedSenderMessageContent::serialized as Serialize, + jni = "UnidentifiedSenderMessageContent_1GetSerialized" ); +bridge_get_bytearray!(UnidentifiedSenderMessageContent::contents); #[bridge_fn] fn UnidentifiedSenderMessageContent_GetSenderCert( @@ -603,14 +635,20 @@ bridge_deserialize!( ffi = false, node = false ); -bridge_get_bytearray!(GetSerialized(UnidentifiedSenderMessage), ffi = false, node = false => - UnidentifiedSenderMessage::serialized +bridge_get_bytearray!( + UnidentifiedSenderMessage::serialized, + ffi = false, + node = false ); -bridge_get_bytearray!(GetEncryptedMessage(UnidentifiedSenderMessage), ffi = false, node = false => - UnidentifiedSenderMessage::encrypted_message +bridge_get_bytearray!( + UnidentifiedSenderMessage::encrypted_message, + ffi = false, + node = false ); -bridge_get_bytearray!(GetEncryptedStatic(UnidentifiedSenderMessage), ffi = false, node = false => - UnidentifiedSenderMessage::encrypted_static +bridge_get_bytearray!( + UnidentifiedSenderMessage::encrypted_static, + ffi = false, + node = false ); bridge_get!(UnidentifiedSenderMessage::ephemeral_public -> PublicKey, ffi = false, node = false); @@ -659,7 +697,7 @@ fn CiphertextMessage_Type(msg: &CiphertextMessage) -> u8 { msg.message_type() as u8 } -bridge_get_bytearray!(serialize(CiphertextMessage), jni = false => |m| Ok(m.serialize())); +bridge_get_bytearray!(CiphertextMessage::serialize as Serialize, jni = false); #[bridge_fn(ffi = false, node = false)] fn SessionRecord_NewFresh() -> SessionRecord { @@ -689,15 +727,17 @@ fn SessionRecord_ArchiveCurrentState(session_record: &mut SessionRecord) -> Resu bridge_get!(SessionRecord::has_current_session_state as HasCurrentState -> bool, jni = false, node = false); bridge_deserialize!(SessionRecord::deserialize); -bridge_get_bytearray!(Serialize(SessionRecord) => SessionRecord::serialize); -bridge_get_bytearray!(GetAliceBaseKey(SessionRecord), ffi = false, node = false => - |s| Ok(s.alice_base_key()?.to_vec()) +bridge_get_bytearray!(SessionRecord::serialize as Serialize); +bridge_get_bytearray!(SessionRecord::alice_base_key, ffi = false, node = false); +bridge_get_bytearray!( + SessionRecord::local_identity_key_bytes as GetLocalIdentityKeyPublic, + ffi = false, + node = false ); -bridge_get_bytearray!(GetLocalIdentityKeyPublic(SessionRecord), ffi = false, node = false => - SessionRecord::local_identity_key_bytes -); -bridge_get_optional_bytearray!(GetRemoteIdentityKeyPublic(SessionRecord), ffi = false, node = false => - SessionRecord::remote_identity_key_bytes +bridge_get_optional_bytearray!( + SessionRecord::remote_identity_key_bytes as GetRemoteIdentityKeyPublic, + ffi = false, + node = false ); bridge_get!(SessionRecord::local_registration_id -> u32); bridge_get!(SessionRecord::remote_registration_id -> u32); @@ -706,14 +746,18 @@ bridge_get!(SessionRecord::has_sender_chain as HasSenderChain -> bool, ffi = fal bridge_get!(SealedSenderDecryptionResult::sender_uuid -> String, ffi = false, jni = false); bridge_get!(SealedSenderDecryptionResult::sender_e164 -> Option, ffi = false, jni = false); bridge_get!(SealedSenderDecryptionResult::device_id -> u32, ffi = false, jni = false); -bridge_get_bytearray!(Message(SealedSenderDecryptionResult), ffi = false, jni = false => - SealedSenderDecryptionResult::message +bridge_get_bytearray!( + SealedSenderDecryptionResult::message as Message, + ffi = false, + jni = false ); // The following SessionRecord APIs are just exposed to make it possible to retain some of the Java tests: -bridge_get_bytearray!(GetSenderChainKeyValue(SessionRecord), ffi = false, node = false => - SessionRecord::get_sender_chain_key_bytes +bridge_get_bytearray!( + SessionRecord::get_sender_chain_key_bytes as GetSenderChainKeyValue, + ffi = false, + node = false ); #[bridge_fn_buffer(ffi = false, node = false)] fn SessionRecord_GetReceiverChainKeyValue( diff --git a/rust/bridge/shared/src/support/mod.rs b/rust/bridge/shared/src/support/mod.rs index 65eb9cf9d..f8bafa074 100644 --- a/rust/bridge/shared/src/support/mod.rs +++ b/rust/bridge/shared/src/support/mod.rs @@ -33,20 +33,6 @@ pub(crate) trait Env { fn buffer<'a, T: Into>>(self, input: T) -> Self::Buffer; } -/// Wraps an expression in a function with a given name and type... -/// except that if the expression is a closure with a single typeless argument, -/// it's flattened into the function. -/// -/// This allows the expression to return a value with a lifetime depending on the input. -macro_rules! expr_as_fn { - ($name:ident $(<$l:lifetime>)? ($_:ident: $arg_ty:ty) -> $result:ty => |$arg:ident| $e:expr) => { - fn $name $(<$l>)? ($arg: $arg_ty) -> $result { $e } - }; - ($name:ident $(<$l:lifetime>)? ($arg:ident: $arg_ty:ty) -> $result:ty => $e:expr) => { - fn $name $(<$l>)? ($arg: $arg_ty) -> $result { $e($arg) } - }; -} - /// Exposes a Rust type to each of the bridges as a boxed value. /// /// Full form: @@ -157,25 +143,29 @@ macro_rules! bridge_deserialize { /// # } /// # } /// -/// bridge_get_bytearray!(Serialize(Foo) => Foo::payload); // generates Foo_Serialize +/// bridge_get_bytearray!(Foo::payload); // generates Foo_GetPayload /// ``` /// -/// The underlying implementation is expected to return a [`Result`] of a type that adopts -/// `AsRef<[u8]>`. Note that the most common "body" is a method name, but it can also be a closure. +/// The underlying implementation is expected to return `Result`, where `T` is a type that +/// adopts `Into>`. As a special case, `T` can also be `Box<[u8]>`. /// /// Like `bridge_fn`, the `ffi`, `jni`, and `node` parameters allow customizing the name of the /// resulting entry points; they can also be `false` to disable a particular entry point. -/// -/// _Note: This is not currently based on `bridge_fn_buffer`, but it probably should be._ macro_rules! bridge_get_bytearray { - ($name:ident($typ:ty) $(, ffi = $ffi_name:tt)? $(, jni = $jni_name:tt)? $(, node = $node_name:tt)? => $body:expr ) => { - #[cfg(feature = "ffi")] - ffi_bridge_get_bytearray!($name($typ) $(as $ffi_name)? => $body); - #[cfg(feature = "jni")] - jni_bridge_get_bytearray!($name($typ) $(as $jni_name)? => $body); - #[cfg(feature = "node")] - node_bridge_get_bytearray!($name($typ) $(as $node_name)? => $body); - } + ($typ:ident :: $method:ident as $name:ident $(, $param:ident = $val:tt)*) => { + paste! { + #[bridge_fn_buffer($($param = $val),*)] + fn [<$typ _ $name>](env: E, obj: &$typ) -> Result { + let result = TransformHelper($typ::$method(obj)); + Ok(env.buffer(result.ok_if_needed()?.into_vec_if_needed().0)) + } + } + }; + ($typ:ident :: $method:ident $(, $param:ident = $val:tt)*) => { + paste! { + bridge_get_bytearray!($typ::$method as [] $(, $param = $val)*); + } + }; } /// Exposes an optional-buffer-returning getter to the bridges. @@ -191,26 +181,34 @@ macro_rules! bridge_get_bytearray { /// # } /// # } /// -/// bridge_get_optional_bytearray!(Payload(Foo) => Foo::payload); // generates Foo_Payload +/// bridge_get_optional_bytearray!(Foo::payload); // generates Foo_GetPayload /// ``` /// /// The underlying implementation is expected to return `Result, _>`, where `T` is a type -/// that adopts `AsRef<[u8]>`. Note that the most common "body" is a method name, but it can also -/// be a closure. +/// that adopts `Into>`. As a special case, `T` can also be `Box<[u8]>`. /// /// Like `bridge_fn`, the `ffi`, `jni`, and `node` parameters allow customizing the name of the /// resulting entry points; they can also be `false` to disable a particular entry point. -/// -/// _Note: This is not currently based on `bridge_fn_buffer`, but it probably should be._ macro_rules! bridge_get_optional_bytearray { - ($name:ident($typ:ty) $(, ffi = $ffi_name:tt)? $(, jni = $jni_name:tt)? $(, node = $node_name:tt)? => $body:expr ) => { - #[cfg(feature = "ffi")] - ffi_bridge_get_optional_bytearray!($name($typ) $(as $ffi_name)? => $body); - #[cfg(feature = "jni")] - jni_bridge_get_optional_bytearray!($name($typ) $(as $jni_name)? => $body); - #[cfg(feature = "node")] - node_bridge_get_optional_bytearray!($name($typ) $(as $node_name)? => $body); - } + ($typ:ident :: $method:ident as $name:ident $(, $param:ident = $val:tt)*) => { + paste! { + #[bridge_fn_buffer($($param = $val),*)] + fn [<$typ _ $name>](env: E, obj: &$typ) -> Result> { + let result = $typ::$method(obj); + let result_without_errors = TransformHelper(result).ok_if_needed()?.0; + let result_buffer = result_without_errors.map(|b| { + env.buffer(TransformHelper(b).into_vec_if_needed().0) + }); + Ok(result_buffer) + } + } + }; + ($typ:ident :: $method:ident $(, $param:ident = $val:tt)*) => { + paste! { + bridge_get_optional_bytearray!( + $typ::$method as [] $(, $param = $val)*); + } + }; } /// Exposes a getter method as a `bridge_fn`. diff --git a/rust/bridge/shared/src/support/transform_helper.rs b/rust/bridge/shared/src/support/transform_helper.rs index 474ee1a43..da8555ff1 100644 --- a/rust/bridge/shared/src/support/transform_helper.rs +++ b/rust/bridge/shared/src/support/transform_helper.rs @@ -34,6 +34,7 @@ impl TransformHelper> { self.0.map(TransformHelper) } } + impl TransformHelper> { /// Transforms `TransformHelper>` into a `TransformHelper>` /// and leaves other TransformHelper values unchanged. @@ -45,6 +46,14 @@ impl TransformHelper> { } } +impl TransformHelper> { + /// Transforms `TransformHelper>` into a `TransformHelper>` + /// and leaves other TransformHelper values unchanged. + pub(crate) fn into_vec_if_needed(self) -> TransformHelper> { + TransformHelper(self.0.into_vec()) + } +} + pub(crate) trait TransformHelperImpl: Sized { fn ok_if_needed(self) -> Result { Ok(self) @@ -52,6 +61,9 @@ pub(crate) trait TransformHelperImpl: Sized { fn option_map_into(self) -> Self { self } + fn into_vec_if_needed(self) -> Self { + self + } } impl TransformHelperImpl for TransformHelper {}