refactor: Olm Exceptions
This commit is contained in:
parent
33500012b2
commit
39b776716c
|
|
@ -155,7 +155,7 @@ class Encryption {
|
|||
var canRequestSession = false;
|
||||
try {
|
||||
if (event.content['algorithm'] != AlgorithmTypes.megolmV1AesSha2) {
|
||||
throw (DecryptError.UNKNOWN_ALGORITHM);
|
||||
throw DecryptException(DecryptException.unknownAlgorithm);
|
||||
}
|
||||
final String sessionId = event.content['session_id'];
|
||||
final String senderKey = event.content['sender_key'];
|
||||
|
|
@ -163,10 +163,11 @@ class Encryption {
|
|||
keyManager.getInboundGroupSession(roomId, sessionId, senderKey);
|
||||
if (inboundGroupSession == null) {
|
||||
canRequestSession = true;
|
||||
throw (DecryptError.UNKNOWN_SESSION);
|
||||
throw DecryptException(DecryptException.unknownSession);
|
||||
}
|
||||
// decrypt errors here may mean we have a bad session key - others might have a better one
|
||||
canRequestSession = true;
|
||||
|
||||
final decryptResult = inboundGroupSession.inboundGroupSession
|
||||
.decrypt(event.content['ciphertext']);
|
||||
canRequestSession = false;
|
||||
|
|
@ -179,7 +180,7 @@ class Encryption {
|
|||
if (haveIndex &&
|
||||
inboundGroupSession.indexes[messageIndexKey] != messageIndexValue) {
|
||||
Logs().e('[Decrypt] Could not decrypt due to a corrupted session.');
|
||||
throw (DecryptError.CHANNEL_CORRUPTED);
|
||||
throw DecryptException(DecryptException.channelCorrupted);
|
||||
}
|
||||
inboundGroupSession.indexes[messageIndexKey] = messageIndexValue;
|
||||
if (!haveIndex) {
|
||||
|
|
@ -197,7 +198,7 @@ class Encryption {
|
|||
} catch (exception) {
|
||||
// alright, if this was actually by our own outbound group session, we might as well clear it
|
||||
if (client.enableE2eeRecovery &&
|
||||
exception != DecryptError.UNKNOWN_SESSION &&
|
||||
exception.toString() != DecryptException.unknownSession &&
|
||||
(keyManager
|
||||
.getOutboundGroupSession(roomId)
|
||||
?.outboundGroupSession
|
||||
|
|
@ -383,11 +384,30 @@ class Encryption {
|
|||
}
|
||||
}
|
||||
|
||||
abstract class DecryptError {
|
||||
static const String NOT_ENABLED = 'Encryption is not enabled in your client.';
|
||||
static const String UNKNOWN_ALGORITHM = 'Unknown encryption algorithm.';
|
||||
static const String UNKNOWN_SESSION =
|
||||
class DecryptException implements Exception {
|
||||
String cause;
|
||||
String libolmMessage;
|
||||
DecryptException(this.cause, [this.libolmMessage]);
|
||||
|
||||
@override
|
||||
String toString() => cause;
|
||||
|
||||
static const String notEnabled = 'Encryption is not enabled in your client.';
|
||||
static const String unknownAlgorithm = 'Unknown encryption algorithm.';
|
||||
static const String unknownSession =
|
||||
'The sender has not sent us the session key.';
|
||||
static const String CHANNEL_CORRUPTED =
|
||||
static const String channelCorrupted =
|
||||
'The secure channel with the sender was corrupted.';
|
||||
static const String unableToDecryptWithAnyOlmSession =
|
||||
'Unable to decrypt with any existing OLM session';
|
||||
static const String senderDoesntMatch =
|
||||
"Message was decrypted but sender doesn't match";
|
||||
static const String recipientDoesntMatch =
|
||||
"Message was decrypted but recipient doesn't match";
|
||||
static const String ownFingerprintDoesntMatch =
|
||||
"Message was decrypted but own fingerprint Key doesn't match";
|
||||
static const String isntSentForThisDevice =
|
||||
"The message isn't sent for this device";
|
||||
static const String unknownMessageType = 'Unknown message type';
|
||||
static const String decryptionFailed = 'Decryption failed';
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,17 +248,17 @@ class OlmManager {
|
|||
return event;
|
||||
}
|
||||
if (event.content['algorithm'] != AlgorithmTypes.olmV1Curve25519AesSha2) {
|
||||
throw ('Unknown algorithm: ${event.content['algorithm']}');
|
||||
throw DecryptException(DecryptException.unknownAlgorithm);
|
||||
}
|
||||
if (!event.content['ciphertext'].containsKey(identityKey)) {
|
||||
throw ("The message isn't sent for this device");
|
||||
throw DecryptException(DecryptException.isntSentForThisDevice);
|
||||
}
|
||||
String plaintext;
|
||||
final String senderKey = event.content['sender_key'];
|
||||
final String body = event.content['ciphertext'][identityKey]['body'];
|
||||
final int type = event.content['ciphertext'][identityKey]['type'];
|
||||
if (type != 0 && type != 1) {
|
||||
throw ('Unknown message type');
|
||||
throw DecryptException(DecryptException.unknownMessageType);
|
||||
}
|
||||
final device = client.userDeviceKeys[event.sender]?.deviceKeys?.values
|
||||
?.firstWhere((d) => d.curve25519Key == senderKey, orElse: () => null);
|
||||
|
|
@ -280,7 +280,12 @@ class OlmManager {
|
|||
if (existingSessions != null) {
|
||||
for (var session in existingSessions) {
|
||||
if (type == 0 && session.session.matches_inbound(body) == true) {
|
||||
try {
|
||||
plaintext = session.session.decrypt(type, body);
|
||||
} catch (e) {
|
||||
throw DecryptException(
|
||||
DecryptException.decryptionFailed, e.toString());
|
||||
}
|
||||
updateSessionUsage(session);
|
||||
break;
|
||||
} else if (type == 1) {
|
||||
|
|
@ -295,7 +300,7 @@ class OlmManager {
|
|||
}
|
||||
}
|
||||
if (plaintext == null && type != 0) {
|
||||
throw ('Unable to decrypt with any existing OLM session');
|
||||
throw DecryptException(DecryptException.unableToDecryptWithAnyOlmSession);
|
||||
}
|
||||
|
||||
if (plaintext == null) {
|
||||
|
|
@ -313,24 +318,24 @@ class OlmManager {
|
|||
lastReceived: DateTime.now(),
|
||||
)));
|
||||
updateSessionUsage();
|
||||
} catch (_) {
|
||||
} catch (e) {
|
||||
newSession?.free();
|
||||
rethrow;
|
||||
throw DecryptException(DecryptException.decryptionFailed, e.toString());
|
||||
}
|
||||
}
|
||||
final Map<String, dynamic> plainContent = json.decode(plaintext);
|
||||
if (plainContent.containsKey('sender') &&
|
||||
plainContent['sender'] != event.sender) {
|
||||
throw ("Message was decrypted but sender doesn't match");
|
||||
throw DecryptException(DecryptException.senderDoesntMatch);
|
||||
}
|
||||
if (plainContent.containsKey('recipient') &&
|
||||
plainContent['recipient'] != client.userID) {
|
||||
throw ("Message was decrypted but recipient doesn't match");
|
||||
throw DecryptException(DecryptException.recipientDoesntMatch);
|
||||
}
|
||||
if (plainContent['recipient_keys'] is Map &&
|
||||
plainContent['recipient_keys']['ed25519'] is String &&
|
||||
plainContent['recipient_keys']['ed25519'] != fingerprintKey) {
|
||||
throw ("Message was decrypted but own fingerprint Key doesn't match");
|
||||
throw DecryptException(DecryptException.ownFingerprintDoesntMatch);
|
||||
}
|
||||
return ToDeviceEvent(
|
||||
content: plainContent['content'],
|
||||
|
|
|
|||
|
|
@ -43,16 +43,16 @@ abstract class EventLocalizations {
|
|||
case MessageTypes.BadEncrypted:
|
||||
String errorText;
|
||||
switch (event.body) {
|
||||
case DecryptError.CHANNEL_CORRUPTED:
|
||||
case DecryptException.channelCorrupted:
|
||||
errorText = i18n.channelCorruptedDecryptError + '.';
|
||||
break;
|
||||
case DecryptError.NOT_ENABLED:
|
||||
case DecryptException.notEnabled:
|
||||
errorText = i18n.encryptionNotEnabled + '.';
|
||||
break;
|
||||
case DecryptError.UNKNOWN_ALGORITHM:
|
||||
case DecryptException.unknownAlgorithm:
|
||||
errorText = i18n.unknownEncryptionAlgorithm + '.';
|
||||
break;
|
||||
case DecryptError.UNKNOWN_SESSION:
|
||||
case DecryptException.unknownSession:
|
||||
errorText = i18n.noPermission + '.';
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ void main() {
|
|||
'status': 2,
|
||||
'content': json.encode({
|
||||
'msgtype': 'm.bad.encrypted',
|
||||
'body': DecryptError.UNKNOWN_SESSION,
|
||||
'body': DecryptException.unknownSession,
|
||||
'can_request_session': true,
|
||||
'algorithm': AlgorithmTypes.megolmV1AesSha2,
|
||||
'ciphertext': 'AwgAEnACgAkLmt6qF84IK++J7UDH2Za1YVchHyprqTqsg...',
|
||||
|
|
|
|||
Loading…
Reference in New Issue