crypto: Forward some more errors from the rust side to the kotlin side

This commit is contained in:
Damir Jelić 2021-04-12 15:03:28 +02:00
parent 0d708bc35a
commit 543a638e87
4 changed files with 90 additions and 56 deletions

View File

@ -22,6 +22,7 @@ import java.io.File
import java.util.concurrent.ConcurrentHashMap
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.coroutines.runBlocking
import org.matrix.android.sdk.api.listeners.ProgressListener
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
import org.matrix.android.sdk.api.session.events.model.Content
@ -179,6 +180,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device
*
* @param responseBody The body of the response that was received.
*/
@Throws(CryptoStoreErrorException::class)
suspend fun markRequestAsSent(
requestId: String,
requestType: RequestType,
@ -206,11 +208,12 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device
*
* @param keyCounts The map of uploaded one-time key types and counts.
*/
@Throws(CryptoStoreErrorException::class)
suspend fun receiveSyncChanges(
toDevice: ToDeviceSyncResponse?,
deviceChanges: DeviceListResponse?,
keyCounts: DeviceOneTimeKeysCountSyncResponse?
) = withContext(Dispatchers.IO) {
): ToDeviceSyncResponse = withContext(Dispatchers.IO) {
var counts: MutableMap<String, Int> = mutableMapOf()
if (keyCounts?.signedCurve25519 != null) {
@ -221,7 +224,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device
val adapter = MoshiProvider.providesMoshi().adapter<ToDeviceSyncResponse>(ToDeviceSyncResponse::class.java)
val events = adapter.toJson(toDevice ?: ToDeviceSyncResponse())!!
inner.receiveSyncChanges(events, devices, counts)
adapter.fromJson(inner.receiveSyncChanges(events, devices, counts))!!
}
/**
@ -254,6 +257,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device
*
* @return A keys claim request that needs to be sent out to the server.
*/
@Throws(CryptoStoreErrorException::class)
suspend fun getMissingSessions(users: List<String>): Request? = withContext(Dispatchers.IO) {
inner.getMissingSessions(users)
}
@ -277,6 +281,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device
*
* @return The list of requests that need to be sent out.
*/
@Throws(CryptoStoreErrorException::class)
suspend fun shareGroupSession(roomId: String, users: List<String>): List<Request> = withContext(Dispatchers.IO) {
inner.shareGroupSession(roomId, users)
}
@ -315,6 +320,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device
*
* @return The encrypted version of the content
*/
@Throws(CryptoStoreErrorException::class)
suspend fun encrypt(roomId: String, eventType: String, content: Content): Content = withContext(Dispatchers.IO) {
val adapter = MoshiProvider.providesMoshi().adapter<Content>(Map::class.java)
val contentString = adapter.toJson(content)
@ -400,6 +406,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device
*
* @return The Device if it found one.
*/
@Throws(CryptoStoreErrorException::class)
suspend fun getDevice(userId: String, deviceId: String): CryptoDeviceInfo? = withContext(Dispatchers.IO) {
when (val device: Device? = inner.getDevice(userId, deviceId)) {
null -> null
@ -414,6 +421,7 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device
*
* @return The list of Devices or an empty list if there aren't any.
*/
@Throws(CryptoStoreErrorException::class)
suspend fun getUserDevices(userId: String): List<CryptoDeviceInfo> {
return inner.getUserDevices(userId).map { toCryptoDeviceInfo(it) }
}
@ -481,7 +489,10 @@ internal class OlmMachine(user_id: String, device_id: String, path: File, device
/**
* Discard the currently active room key for the given room if there is one.
*/
@Throws(CryptoStoreErrorException::class)
fun discardRoomKey(roomId: String) {
this.inner.discardRoomKey(roomId)
runBlocking {
inner.discardRoomKey(roomId)
}
}
}

View File

@ -27,6 +27,8 @@ pub enum CryptoStoreError {
OlmError(#[from] OlmError),
#[error(transparent)]
Serialization(#[from] serde_json::Error),
#[error(transparent)]
Identifier(#[from] RumaIdentifierError),
}
#[derive(Debug, thiserror::Error)]

View File

@ -87,13 +87,17 @@ impl OlmMachine {
/// * `user_id` - The id of the device owner.
///
/// * `device_id` - The id of the device itself.
pub fn get_device(&self, user_id: &str, device_id: &str) -> Option<Device> {
let user_id = UserId::try_from(user_id).unwrap();
pub fn get_device(
&self,
user_id: &str,
device_id: &str,
) -> Result<Option<Device>, CryptoStoreError> {
let user_id = UserId::try_from(user_id)?;
self.runtime
.block_on(self.inner.get_device(&user_id, device_id.into()))
.unwrap()
.map(|d| d.into())
Ok(self
.runtime
.block_on(self.inner.get_device(&user_id, device_id.into()))?
.map(|d| d.into()))
}
/// Get all devices of an user.
@ -101,14 +105,15 @@ impl OlmMachine {
/// # Arguments
///
/// * `user_id` - The id of the device owner.
pub fn get_user_devices(&self, user_id: &str) -> Vec<Device> {
let user_id = UserId::try_from(user_id).unwrap();
self.runtime
.block_on(self.inner.get_user_devices(&user_id))
.unwrap()
pub fn get_user_devices(&self, user_id: &str) -> Result<Vec<Device>, CryptoStoreError> {
let user_id = UserId::try_from(user_id)?;
Ok(self
.runtime
.block_on(self.inner.get_user_devices(&user_id))?
.devices()
.map(|d| d.into())
.collect()
.collect())
}
/// Get our own identity keys.
@ -190,8 +195,8 @@ impl OlmMachine {
events: &str,
device_changes: DeviceLists,
key_counts: HashMap<String, i32>,
) {
let events: ToDevice = serde_json::from_str(events).unwrap();
) -> Result<String, CryptoStoreError> {
let events: ToDevice = serde_json::from_str(events)?;
let device_changes: RumaDeviceLists = device_changes.into();
let key_counts: BTreeMap<DeviceKeyAlgorithm, UInt> = key_counts
.into_iter()
@ -205,12 +210,15 @@ impl OlmMachine {
})
.collect();
self.runtime
let events = self
.runtime
.block_on(
self.inner
.receive_sync_changes(&events, &device_changes, &key_counts),
)
.unwrap();
Ok(serde_json::to_string(&events)?)
}
/// Add the given list of users to be tracked, triggering a key query request
@ -293,23 +301,24 @@ impl OlmMachine {
///
/// * `users` - The list of users which are considered to be members of the
/// room and should receive the room key.
pub fn share_group_session(&self, room_id: &str, users: Vec<String>) -> Vec<Request> {
pub fn share_group_session(
&self,
room_id: &str,
users: Vec<String>,
) -> Result<Vec<Request>, CryptoStoreError> {
let users: Vec<UserId> = users
.into_iter()
.filter_map(|u| UserId::try_from(u).ok())
.collect();
let room_id = RoomId::try_from(room_id).unwrap();
let requests = self
.runtime
.block_on(self.inner.share_group_session(
&room_id,
users.iter(),
EncryptionSettings::default(),
))
.unwrap();
let room_id = RoomId::try_from(room_id)?;
let requests = self.runtime.block_on(self.inner.share_group_session(
&room_id,
users.iter(),
EncryptionSettings::default(),
))?;
requests.into_iter().map(|r| (&*r).into()).collect()
Ok(requests.into_iter().map(|r| (&*r).into()).collect())
}
/// Encrypt the given event with the given type and content for the given
@ -345,17 +354,22 @@ impl OlmMachine {
/// * `even_type` - The type of the event.
///
/// * `content` - The serialized content of the event.
pub fn encrypt(&self, room_id: &str, event_type: &str, content: &str) -> String {
let room_id = RoomId::try_from(room_id).unwrap();
let content: Box<RawValue> = serde_json::from_str(content).unwrap();
pub fn encrypt(
&self,
room_id: &str,
event_type: &str,
content: &str,
) -> Result<String, CryptoStoreError> {
let room_id = RoomId::try_from(room_id)?;
let content: Box<RawValue> = serde_json::from_str(content)?;
let content = AnyMessageEventContent::from_parts(event_type, content).unwrap();
let content = AnyMessageEventContent::from_parts(event_type, content)?;
let encrypted_content = self
.runtime
.block_on(self.inner.encrypt(&room_id, content))
.unwrap();
serde_json::to_string(&encrypted_content).unwrap()
Ok(serde_json::to_string(&encrypted_content)?)
}
/// Decrypt the given event that was sent in the given room.
@ -452,14 +466,17 @@ impl OlmMachine {
/// Discard the currently active room key for the given room if there is
/// one.
pub fn discard_room_key(&self, room_id: &str) {
let room_id = RoomId::try_from(room_id).unwrap();
pub fn discard_room_key(&self, room_id: &str) -> Result<(), CryptoStoreError> {
let room_id = RoomId::try_from(room_id)?;
self.inner.invalidate_group_session(&room_id);
self.runtime
.block_on(self.inner.invalidate_group_session(&room_id))?;
Ok(())
}
pub fn start_verification(&self, device: &Device) -> Result<Sas, CryptoStoreError> {
let user_id = UserId::try_from(device.user_id.clone()).unwrap();
let user_id = UserId::try_from(device.user_id.clone())?;
let device_id = device.device_id.as_str().into();
let device = self
.runtime

View File

@ -27,6 +27,7 @@ enum CryptoStoreError {
"CryptoStore",
"OlmError",
"Serialization",
"Identifier",
};
[Error]
@ -89,29 +90,15 @@ interface OlmMachine {
[Throws=MachineCreationError]
constructor([ByRef] string user_id, [ByRef] string device_id, [ByRef] string path);
void receive_sync_changes([ByRef] string events,
DeviceLists device_changes,
record<DOMString, i32> key_counts);
[Throws=DecryptionError]
DecryptedEvent decrypt_room_event([ByRef] string event, [ByRef] string room_id);
string encrypt([ByRef] string room_id, [ByRef] string event_type, [ByRef] string content);
record<DOMString, string> identity_keys();
string user_id();
string device_id();
Device? get_device([ByRef] string user_id, [ByRef] string device_id);
sequence<Device> get_user_devices([ByRef] string user_id);
sequence<Request> outgoing_requests();
void update_tracked_users(sequence<string> users);
[Throws=CryptoStoreError]
Request? get_missing_sessions(sequence<string> users);
sequence<Request> share_group_session([ByRef] string room_id, sequence<string> users);
string receive_sync_changes([ByRef] string events,
DeviceLists device_changes,
record<DOMString, i32> key_counts);
sequence<Request> outgoing_requests();
[Throws=CryptoStoreError]
void mark_request_as_sent(
[ByRef] string request_id,
@ -119,6 +106,22 @@ interface OlmMachine {
[ByRef] string response
);
[Throws=DecryptionError]
DecryptedEvent decrypt_room_event([ByRef] string event, [ByRef] string room_id);
[Throws=CryptoStoreError]
string encrypt([ByRef] string room_id, [ByRef] string event_type, [ByRef] string content);
[Throws=CryptoStoreError]
Device? get_device([ByRef] string user_id, [ByRef] string device_id);
[Throws=CryptoStoreError]
sequence<Device> get_user_devices([ByRef] string user_id);
void update_tracked_users(sequence<string> users);
[Throws=CryptoStoreError]
Request? get_missing_sessions(sequence<string> users);
[Throws=CryptoStoreError]
sequence<Request> share_group_session([ByRef] string room_id, sequence<string> users);
[Throws=CryptoStoreError]
Sas start_verification([ByRef] Device device);
@ -130,5 +133,6 @@ interface OlmMachine {
[ByRef] string passphrase,
ProgressListener progress_listener
);
[Throws=CryptoStoreError]
void discard_room_key([ByRef] string room_id);
};