1 //
2 // Copyright 2021 Signal Messenger, LLC.
3 // SPDX-License-Identifier: AGPL-3.0-only
4 //
5 
6 use super::*;
7 use async_trait::async_trait;
8 use uuid::Uuid;
9 
10 pub type JavaIdentityKeyStore<'a> = JObject<'a>;
11 pub type JavaPreKeyStore<'a> = JObject<'a>;
12 pub type JavaSignedPreKeyStore<'a> = JObject<'a>;
13 pub type JavaSessionStore<'a> = JObject<'a>;
14 pub type JavaSenderKeyStore<'a> = JObject<'a>;
15 
16 pub struct JniIdentityKeyStore<'a> {
17     env: &'a JNIEnv<'a>,
18     store: JObject<'a>,
19 }
20 
21 impl<'a> JniIdentityKeyStore<'a> {
new(env: &'a JNIEnv, store: JObject<'a>) -> Result<Self, SignalJniError>22     pub fn new(env: &'a JNIEnv, store: JObject<'a>) -> Result<Self, SignalJniError> {
23         check_jobject_type(
24             env,
25             store,
26             "org/whispersystems/libsignal/state/IdentityKeyStore",
27         )?;
28         Ok(Self { env, store })
29     }
30 }
31 
32 impl<'a> JniIdentityKeyStore<'a> {
do_get_identity_key_pair(&self) -> Result<IdentityKeyPair, SignalJniError>33     fn do_get_identity_key_pair(&self) -> Result<IdentityKeyPair, SignalJniError> {
34         let callback_sig = jni_signature!(() -> org.whispersystems.libsignal.IdentityKeyPair);
35         let bits = get_object_with_serialization(
36             self.env,
37             self.store,
38             &[],
39             callback_sig,
40             "getIdentityKeyPair",
41         )?;
42 
43         match bits {
44             None => Err(SignalJniError::Signal(SignalProtocolError::InternalError(
45                 "getIdentityKeyPair returned null",
46             ))),
47             Some(k) => Ok(IdentityKeyPair::try_from(k.as_ref())?),
48         }
49     }
50 
do_get_local_registration_id(&self) -> Result<u32, SignalJniError>51     fn do_get_local_registration_id(&self) -> Result<u32, SignalJniError> {
52         let callback_sig = jni_signature!(() -> int);
53         let i: jint = call_method_checked(
54             self.env,
55             self.store,
56             "getLocalRegistrationId",
57             callback_sig,
58             &[],
59         )?;
60         jint_to_u32(i)
61     }
62 
do_save_identity( &mut self, address: &ProtocolAddress, identity: &IdentityKey, ) -> Result<bool, SignalJniError>63     fn do_save_identity(
64         &mut self,
65         address: &ProtocolAddress,
66         identity: &IdentityKey,
67     ) -> Result<bool, SignalJniError> {
68         let address_jobject = protocol_address_to_jobject(self.env, address)?;
69         let key_jobject = jobject_from_serialized(
70             self.env,
71             "org/whispersystems/libsignal/IdentityKey",
72             identity.serialize().as_ref(),
73         )?;
74         let callback_sig = jni_signature!((
75             org.whispersystems.libsignal.SignalProtocolAddress,
76             org.whispersystems.libsignal.IdentityKey
77         ) -> boolean);
78         let callback_args = [address_jobject.into(), key_jobject.into()];
79         let result: jboolean = call_method_checked(
80             self.env,
81             self.store,
82             "saveIdentity",
83             callback_sig,
84             &callback_args,
85         )?;
86         Ok(result != 0)
87     }
88 
do_is_trusted_identity( &self, address: &ProtocolAddress, identity: &IdentityKey, direction: Direction, ) -> Result<bool, SignalJniError>89     fn do_is_trusted_identity(
90         &self,
91         address: &ProtocolAddress,
92         identity: &IdentityKey,
93         direction: Direction,
94     ) -> Result<bool, SignalJniError> {
95         let address_jobject = protocol_address_to_jobject(self.env, address)?;
96         let key_jobject = jobject_from_serialized(
97             self.env,
98             "org/whispersystems/libsignal/IdentityKey",
99             identity.serialize().as_ref(),
100         )?;
101 
102         let direction_class = self
103             .env
104             .find_class("org/whispersystems/libsignal/state/IdentityKeyStore$Direction")?;
105         let field_name = match direction {
106             Direction::Sending => "SENDING",
107             Direction::Receiving => "RECEIVING",
108         };
109 
110         let field_value = self.env.get_static_field(
111             direction_class,
112             field_name,
113             "Lorg/whispersystems/libsignal/state/IdentityKeyStore$Direction;",
114         )?;
115 
116         let callback_sig = jni_signature!((
117             org.whispersystems.libsignal.SignalProtocolAddress,
118             org.whispersystems.libsignal.IdentityKey,
119             "Lorg/whispersystems/libsignal/state/IdentityKeyStore$Direction;",
120         ) -> boolean);
121         let callback_args = [address_jobject.into(), key_jobject.into(), field_value];
122         let result: jboolean = call_method_checked(
123             self.env,
124             self.store,
125             "isTrustedIdentity",
126             callback_sig,
127             &callback_args,
128         )?;
129 
130         Ok(result != 0)
131     }
132 
do_get_identity( &self, address: &ProtocolAddress, ) -> Result<Option<IdentityKey>, SignalJniError>133     fn do_get_identity(
134         &self,
135         address: &ProtocolAddress,
136     ) -> Result<Option<IdentityKey>, SignalJniError> {
137         with_local_frame_no_jobject_result(
138             self.env,
139             64,
140             || -> SignalJniResult<Option<IdentityKey>> {
141                 let address_jobject = protocol_address_to_jobject(self.env, address)?;
142                 let callback_sig = jni_signature!(
143                     (org.whispersystems.libsignal.SignalProtocolAddress)
144                     -> org.whispersystems.libsignal.IdentityKey);
145                 let callback_args = [address_jobject.into()];
146 
147                 let bits = get_object_with_serialization(
148                     self.env,
149                     self.store,
150                     &callback_args,
151                     callback_sig,
152                     "getIdentity",
153                 )?;
154 
155                 match bits {
156                     None => Ok(None),
157                     Some(k) => Ok(Some(IdentityKey::decode(&k)?)),
158                 }
159             },
160         )
161     }
162 }
163 
164 #[async_trait(?Send)]
165 impl<'a> IdentityKeyStore for JniIdentityKeyStore<'a> {
get_identity_key_pair( &self, _ctx: Context, ) -> Result<IdentityKeyPair, SignalProtocolError>166     async fn get_identity_key_pair(
167         &self,
168         _ctx: Context,
169     ) -> Result<IdentityKeyPair, SignalProtocolError> {
170         Ok(self.do_get_identity_key_pair()?)
171     }
172 
get_local_registration_id(&self, _ctx: Context) -> Result<u32, SignalProtocolError>173     async fn get_local_registration_id(&self, _ctx: Context) -> Result<u32, SignalProtocolError> {
174         Ok(self.do_get_local_registration_id()?)
175     }
176 
save_identity( &mut self, address: &ProtocolAddress, identity: &IdentityKey, _ctx: Context, ) -> Result<bool, SignalProtocolError>177     async fn save_identity(
178         &mut self,
179         address: &ProtocolAddress,
180         identity: &IdentityKey,
181         _ctx: Context,
182     ) -> Result<bool, SignalProtocolError> {
183         Ok(self.do_save_identity(address, identity)?)
184     }
185 
is_trusted_identity( &self, address: &ProtocolAddress, identity: &IdentityKey, direction: Direction, _ctx: Context, ) -> Result<bool, SignalProtocolError>186     async fn is_trusted_identity(
187         &self,
188         address: &ProtocolAddress,
189         identity: &IdentityKey,
190         direction: Direction,
191         _ctx: Context,
192     ) -> Result<bool, SignalProtocolError> {
193         Ok(self.do_is_trusted_identity(address, identity, direction)?)
194     }
195 
get_identity( &self, address: &ProtocolAddress, _ctx: Context, ) -> Result<Option<IdentityKey>, SignalProtocolError>196     async fn get_identity(
197         &self,
198         address: &ProtocolAddress,
199         _ctx: Context,
200     ) -> Result<Option<IdentityKey>, SignalProtocolError> {
201         Ok(self.do_get_identity(address)?)
202     }
203 }
204 
205 pub struct JniPreKeyStore<'a> {
206     env: &'a JNIEnv<'a>,
207     store: JObject<'a>,
208 }
209 
210 impl<'a> JniPreKeyStore<'a> {
new(env: &'a JNIEnv, store: JObject<'a>) -> Result<Self, SignalJniError>211     pub fn new(env: &'a JNIEnv, store: JObject<'a>) -> Result<Self, SignalJniError> {
212         check_jobject_type(env, store, "org/whispersystems/libsignal/state/PreKeyStore")?;
213         Ok(Self { env, store })
214     }
215 }
216 
217 impl<'a> JniPreKeyStore<'a> {
do_get_pre_key(&self, prekey_id: u32) -> Result<PreKeyRecord, SignalJniError>218     fn do_get_pre_key(&self, prekey_id: u32) -> Result<PreKeyRecord, SignalJniError> {
219         let callback_sig = jni_signature!((int) -> org.whispersystems.libsignal.state.PreKeyRecord);
220         let callback_args = [JValue::from(prekey_id.convert_into(self.env)?)];
221         let pk = get_object_with_native_handle::<PreKeyRecord>(
222             self.env,
223             self.store,
224             &callback_args,
225             callback_sig,
226             "loadPreKey",
227         )?;
228         match pk {
229             Some(pk) => Ok(pk),
230             None => Err(SignalJniError::Signal(SignalProtocolError::InvalidPreKeyId)),
231         }
232     }
233 
do_save_pre_key( &mut self, prekey_id: u32, record: &PreKeyRecord, ) -> Result<(), SignalJniError>234     fn do_save_pre_key(
235         &mut self,
236         prekey_id: u32,
237         record: &PreKeyRecord,
238     ) -> Result<(), SignalJniError> {
239         let jobject_record = jobject_from_serialized(
240             self.env,
241             "org/whispersystems/libsignal/state/PreKeyRecord",
242             &record.serialize()?,
243         )?;
244         let callback_sig = jni_signature!((
245             int,
246             org.whispersystems.libsignal.state.PreKeyRecord
247         ) -> void);
248         let callback_args = [
249             JValue::from(prekey_id.convert_into(self.env)?),
250             jobject_record.into(),
251         ];
252         let _: () = call_method_checked(
253             self.env,
254             self.store,
255             "storePreKey",
256             callback_sig,
257             &callback_args,
258         )?;
259         Ok(())
260     }
261 
do_remove_pre_key(&mut self, prekey_id: u32) -> Result<(), SignalJniError>262     fn do_remove_pre_key(&mut self, prekey_id: u32) -> Result<(), SignalJniError> {
263         let callback_sig = jni_signature!((int) -> void);
264         let callback_args = [JValue::from(prekey_id.convert_into(self.env)?)];
265         let _: () = call_method_checked(
266             self.env,
267             self.store,
268             "removePreKey",
269             callback_sig,
270             &callback_args,
271         )?;
272         Ok(())
273     }
274 }
275 
276 #[async_trait(?Send)]
277 impl<'a> PreKeyStore for JniPreKeyStore<'a> {
get_pre_key( &self, prekey_id: u32, _ctx: Context, ) -> Result<PreKeyRecord, SignalProtocolError>278     async fn get_pre_key(
279         &self,
280         prekey_id: u32,
281         _ctx: Context,
282     ) -> Result<PreKeyRecord, SignalProtocolError> {
283         Ok(self.do_get_pre_key(prekey_id)?)
284     }
285 
save_pre_key( &mut self, prekey_id: u32, record: &PreKeyRecord, _ctx: Context, ) -> Result<(), SignalProtocolError>286     async fn save_pre_key(
287         &mut self,
288         prekey_id: u32,
289         record: &PreKeyRecord,
290         _ctx: Context,
291     ) -> Result<(), SignalProtocolError> {
292         Ok(self.do_save_pre_key(prekey_id, record)?)
293     }
294 
remove_pre_key( &mut self, prekey_id: u32, _ctx: Context, ) -> Result<(), SignalProtocolError>295     async fn remove_pre_key(
296         &mut self,
297         prekey_id: u32,
298         _ctx: Context,
299     ) -> Result<(), SignalProtocolError> {
300         Ok(self.do_remove_pre_key(prekey_id)?)
301     }
302 }
303 
304 pub struct JniSignedPreKeyStore<'a> {
305     env: &'a JNIEnv<'a>,
306     store: JObject<'a>,
307 }
308 
309 impl<'a> JniSignedPreKeyStore<'a> {
new(env: &'a JNIEnv, store: JObject<'a>) -> Result<Self, SignalJniError>310     pub fn new(env: &'a JNIEnv, store: JObject<'a>) -> Result<Self, SignalJniError> {
311         check_jobject_type(
312             env,
313             store,
314             "org/whispersystems/libsignal/state/SignedPreKeyStore",
315         )?;
316         Ok(Self { env, store })
317     }
318 }
319 
320 impl<'a> JniSignedPreKeyStore<'a> {
do_get_signed_pre_key(&self, prekey_id: u32) -> Result<SignedPreKeyRecord, SignalJniError>321     fn do_get_signed_pre_key(&self, prekey_id: u32) -> Result<SignedPreKeyRecord, SignalJniError> {
322         let callback_sig = jni_signature!((
323             int
324         ) -> org.whispersystems.libsignal.state.SignedPreKeyRecord);
325         let callback_args = [JValue::from(prekey_id.convert_into(self.env)?)];
326         let spk = get_object_with_native_handle::<SignedPreKeyRecord>(
327             self.env,
328             self.store,
329             &callback_args,
330             callback_sig,
331             "loadSignedPreKey",
332         )?;
333         match spk {
334             Some(spk) => Ok(spk),
335             None => Err(SignalJniError::Signal(
336                 SignalProtocolError::InvalidSignedPreKeyId,
337             )),
338         }
339     }
340 
do_save_signed_pre_key( &mut self, prekey_id: u32, record: &SignedPreKeyRecord, ) -> Result<(), SignalJniError>341     fn do_save_signed_pre_key(
342         &mut self,
343         prekey_id: u32,
344         record: &SignedPreKeyRecord,
345     ) -> Result<(), SignalJniError> {
346         let jobject_record = jobject_from_serialized(
347             self.env,
348             "org/whispersystems/libsignal/state/SignedPreKeyRecord",
349             &record.serialize()?,
350         )?;
351         let callback_sig = jni_signature!((
352             int,
353             org.whispersystems.libsignal.state.SignedPreKeyRecord
354         ) -> void);
355         let callback_args = [
356             JValue::from(prekey_id.convert_into(self.env)?),
357             jobject_record.into(),
358         ];
359         let _: () = call_method_checked(
360             self.env,
361             self.store,
362             "storeSignedPreKey",
363             callback_sig,
364             &callback_args,
365         )?;
366         Ok(())
367     }
368 }
369 
370 #[async_trait(?Send)]
371 impl<'a> SignedPreKeyStore for JniSignedPreKeyStore<'a> {
get_signed_pre_key( &self, prekey_id: u32, _ctx: Context, ) -> Result<SignedPreKeyRecord, SignalProtocolError>372     async fn get_signed_pre_key(
373         &self,
374         prekey_id: u32,
375         _ctx: Context,
376     ) -> Result<SignedPreKeyRecord, SignalProtocolError> {
377         Ok(self.do_get_signed_pre_key(prekey_id)?)
378     }
379 
save_signed_pre_key( &mut self, prekey_id: u32, record: &SignedPreKeyRecord, _ctx: Context, ) -> Result<(), SignalProtocolError>380     async fn save_signed_pre_key(
381         &mut self,
382         prekey_id: u32,
383         record: &SignedPreKeyRecord,
384         _ctx: Context,
385     ) -> Result<(), SignalProtocolError> {
386         Ok(self.do_save_signed_pre_key(prekey_id, record)?)
387     }
388 }
389 
390 pub struct JniSessionStore<'a> {
391     env: &'a JNIEnv<'a>,
392     store: JObject<'a>,
393 }
394 
395 impl<'a> JniSessionStore<'a> {
new(env: &'a JNIEnv, store: JObject<'a>) -> Result<Self, SignalJniError>396     pub fn new(env: &'a JNIEnv, store: JObject<'a>) -> Result<Self, SignalJniError> {
397         check_jobject_type(
398             env,
399             store,
400             "org/whispersystems/libsignal/state/SessionStore",
401         )?;
402         Ok(Self { env, store })
403     }
404 }
405 
406 impl<'a> JniSessionStore<'a> {
do_load_session( &self, address: &ProtocolAddress, ) -> Result<Option<SessionRecord>, SignalJniError>407     fn do_load_session(
408         &self,
409         address: &ProtocolAddress,
410     ) -> Result<Option<SessionRecord>, SignalJniError> {
411         let address_jobject = protocol_address_to_jobject(self.env, address)?;
412 
413         let callback_sig = jni_signature!((
414             org.whispersystems.libsignal.SignalProtocolAddress
415         ) -> org.whispersystems.libsignal.state.SessionRecord);
416         let callback_args = [address_jobject.into()];
417         get_object_with_native_handle::<SessionRecord>(
418             self.env,
419             self.store,
420             &callback_args,
421             callback_sig,
422             "loadSession",
423         )
424     }
425 
do_store_session( &mut self, address: &ProtocolAddress, record: &SessionRecord, ) -> Result<(), SignalJniError>426     fn do_store_session(
427         &mut self,
428         address: &ProtocolAddress,
429         record: &SessionRecord,
430     ) -> Result<(), SignalJniError> {
431         let address_jobject = protocol_address_to_jobject(self.env, address)?;
432         let session_jobject = jobject_from_serialized(
433             self.env,
434             "org/whispersystems/libsignal/state/SessionRecord",
435             &record.serialize()?,
436         )?;
437 
438         let callback_sig = jni_signature!((
439             org.whispersystems.libsignal.SignalProtocolAddress,
440             org.whispersystems.libsignal.state.SessionRecord,
441         ) -> void);
442         let callback_args = [address_jobject.into(), session_jobject.into()];
443         let _: () = call_method_checked(
444             self.env,
445             self.store,
446             "storeSession",
447             callback_sig,
448             &callback_args,
449         )?;
450         Ok(())
451     }
452 }
453 
454 #[async_trait(?Send)]
455 impl<'a> SessionStore for JniSessionStore<'a> {
load_session( &self, address: &ProtocolAddress, _ctx: Context, ) -> Result<Option<SessionRecord>, SignalProtocolError>456     async fn load_session(
457         &self,
458         address: &ProtocolAddress,
459         _ctx: Context,
460     ) -> Result<Option<SessionRecord>, SignalProtocolError> {
461         Ok(self.do_load_session(address)?)
462     }
463 
store_session( &mut self, address: &ProtocolAddress, record: &SessionRecord, _ctx: Context, ) -> Result<(), SignalProtocolError>464     async fn store_session(
465         &mut self,
466         address: &ProtocolAddress,
467         record: &SessionRecord,
468         _ctx: Context,
469     ) -> Result<(), SignalProtocolError> {
470         Ok(self.do_store_session(address, record)?)
471     }
472 }
473 
474 pub struct JniSenderKeyStore<'a> {
475     env: &'a JNIEnv<'a>,
476     store: JObject<'a>,
477 }
478 
479 impl<'a> JniSenderKeyStore<'a> {
new(env: &'a JNIEnv, store: JObject<'a>) -> Result<Self, SignalJniError>480     pub fn new(env: &'a JNIEnv, store: JObject<'a>) -> Result<Self, SignalJniError> {
481         check_jobject_type(
482             env,
483             store,
484             "org/whispersystems/libsignal/groups/state/SenderKeyStore",
485         )?;
486         Ok(Self { env, store })
487     }
488 }
489 
490 impl<'a> JniSenderKeyStore<'a> {
do_store_sender_key( &mut self, sender: &ProtocolAddress, distribution_id: Uuid, record: &SenderKeyRecord, ) -> Result<(), SignalJniError>491     fn do_store_sender_key(
492         &mut self,
493         sender: &ProtocolAddress,
494         distribution_id: Uuid,
495         record: &SenderKeyRecord,
496     ) -> Result<(), SignalJniError> {
497         let sender_jobject = protocol_address_to_jobject(self.env, sender)?;
498         let distribution_id_jobject = distribution_id.convert_into(self.env)?;
499         let sender_key_record_jobject = jobject_from_native_handle(
500             self.env,
501             "org/whispersystems/libsignal/groups/state/SenderKeyRecord",
502             box_object::<SenderKeyRecord>(Ok(record.clone()))?,
503         )?;
504 
505         let callback_args = [
506             sender_jobject.into(),
507             distribution_id_jobject.into(),
508             sender_key_record_jobject.into(),
509         ];
510         let callback_sig = jni_signature!((
511             org.whispersystems.libsignal.SignalProtocolAddress,
512             java.util.UUID,
513             org.whispersystems.libsignal.groups.state.SenderKeyRecord,
514         ) -> void);
515         let _: () = call_method_checked(
516             self.env,
517             self.store,
518             "storeSenderKey",
519             callback_sig,
520             &callback_args[..],
521         )?;
522 
523         Ok(())
524     }
525 
do_load_sender_key( &mut self, sender: &ProtocolAddress, distribution_id: Uuid, ) -> Result<Option<SenderKeyRecord>, SignalJniError>526     fn do_load_sender_key(
527         &mut self,
528         sender: &ProtocolAddress,
529         distribution_id: Uuid,
530     ) -> Result<Option<SenderKeyRecord>, SignalJniError> {
531         let sender_jobject = protocol_address_to_jobject(self.env, sender)?;
532         let distribution_id_jobject = distribution_id.convert_into(self.env)?;
533         let callback_args = [sender_jobject.into(), distribution_id_jobject.into()];
534         let callback_sig = jni_signature!((
535             org.whispersystems.libsignal.SignalProtocolAddress,
536             java.util.UUID,
537         ) -> org.whispersystems.libsignal.groups.state.SenderKeyRecord);
538 
539         let skr = get_object_with_native_handle::<SenderKeyRecord>(
540             self.env,
541             self.store,
542             &callback_args,
543             callback_sig,
544             "loadSenderKey",
545         )?;
546 
547         Ok(skr)
548     }
549 }
550 
551 #[async_trait(?Send)]
552 impl<'a> SenderKeyStore for JniSenderKeyStore<'a> {
store_sender_key( &mut self, sender: &ProtocolAddress, distribution_id: Uuid, record: &SenderKeyRecord, _ctx: Context, ) -> Result<(), SignalProtocolError>553     async fn store_sender_key(
554         &mut self,
555         sender: &ProtocolAddress,
556         distribution_id: Uuid,
557         record: &SenderKeyRecord,
558         _ctx: Context,
559     ) -> Result<(), SignalProtocolError> {
560         Ok(self.do_store_sender_key(sender, distribution_id, record)?)
561     }
562 
load_sender_key( &mut self, sender: &ProtocolAddress, distribution_id: Uuid, _ctx: Context, ) -> Result<Option<SenderKeyRecord>, SignalProtocolError>563     async fn load_sender_key(
564         &mut self,
565         sender: &ProtocolAddress,
566         distribution_id: Uuid,
567         _ctx: Context,
568     ) -> Result<Option<SenderKeyRecord>, SignalProtocolError> {
569         Ok(self.do_load_sender_key(sender, distribution_id)?)
570     }
571 }
572