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