From c8a85758f083c533cfdc77a337de8e377b7da414 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 18 Dec 2018 17:27:44 +0100 Subject: [PATCH 1/5] MXCryptoStore: Rework methods to query OLMSessions --- MatrixSDK/Crypto/Data/Store/MXCryptoStore.h | 16 +++++++++++++--- .../MXRealmCryptoStore/MXRealmCryptoStore.m | 16 ++++++++++++---- MatrixSDK/Crypto/MXOlmDevice.m | 12 +++++++++--- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h b/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h index 387214bec1..c94ea25120 100644 --- a/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h +++ b/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h @@ -191,13 +191,23 @@ - (void)storeSession:(OLMSession*)session forDevice:(NSString*)deviceKey; /** - Retrieve the end-to-end sessions between the logged-in user and another + Retrieve an end-to-end session between the logged-in user and another device. @param deviceKey the public key of the other device. - @return {object} A map from sessionId to Base64 end-to-end session. + @return a array of end-to-end sessions sorted by the last updated first. */ -- (NSDictionary*)sessionsWithDevice:(NSString*)deviceKey; +- (OLMSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*)sessionId; + +/** + Retrieve all end-to-end sessions between the logged-in user and another + device. + + @param deviceKey the public key of the other device. + @return a array of end-to-end sessions. + */ +- (NSArray*)sessionsWithDevice:(NSString*)deviceKey; + /** Store an inbound group session. diff --git a/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m b/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m index 1593ca99a4..8bba460815 100644 --- a/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m +++ b/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m @@ -628,19 +628,27 @@ - (void)storeSession:(OLMSession*)session forDevice:(NSString*)deviceKey NSLog(@"[MXRealmCryptoStore] storeSession (%@) in %.0fms", (isNew?@"NEW":@"UPDATE"), [[NSDate date] timeIntervalSinceDate:startDate] * 1000); } -- (NSDictionary*)sessionsWithDevice:(NSString*)deviceKey +- (OLMSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*)sessionId { - NSMutableDictionary *sessionsWithDevice; + MXRealmOlmSession *realmOlmSession = [MXRealmOlmSession objectsInRealm:self.realm + where:@"sessionId = %@ AND deviceKey = %@", sessionId, deviceKey].firstObject; + + return [NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]; +} + +- (NSArray*)sessionsWithDevice:(NSString*)deviceKey; +{ + NSMutableArray *sessionsWithDevice; RLMResults *realmOlmSessions = [MXRealmOlmSession objectsInRealm:self.realm where:@"deviceKey = %@", deviceKey]; for (MXRealmOlmSession *realmOlmSession in realmOlmSessions) { if (!sessionsWithDevice) { - sessionsWithDevice = [NSMutableDictionary dictionary]; + sessionsWithDevice = [NSMutableArray array]; } - sessionsWithDevice[realmOlmSession.sessionId] = [NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]; + [sessionsWithDevice addObject:[NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]]; } return sessionsWithDevice; diff --git a/MatrixSDK/Crypto/MXOlmDevice.m b/MatrixSDK/Crypto/MXOlmDevice.m index d956182dc1..022fc3e1a6 100644 --- a/MatrixSDK/Crypto/MXOlmDevice.m +++ b/MatrixSDK/Crypto/MXOlmDevice.m @@ -198,9 +198,15 @@ - (NSString*)createInboundSession:(NSString*)theirDeviceIdentityKey messageType: - (NSArray *)sessionIdsForDevice:(NSString *)theirDeviceIdentityKey { - NSDictionary *sessions = [store sessionsWithDevice:theirDeviceIdentityKey]; + NSArray *sessions = [store sessionsWithDevice:theirDeviceIdentityKey]; - return sessions.allKeys; + NSMutableArray *sessionIds = [NSMutableArray arrayWithCapacity:sessions.count]; + for (OLMSession *session in sessions) + { + [sessionIds addObject:session.sessionIdentifier]; + } + + return sessionIds; } - (NSString *)sessionIdForDevice:(NSString *)theirDeviceIdentityKey @@ -561,7 +567,7 @@ - (NSString *)sha256:(NSString *)message #pragma mark - Private methods - (OLMSession*)sessionForDevice:(NSString *)theirDeviceIdentityKey andSessionId:(NSString*)sessionId { - return [store sessionsWithDevice:theirDeviceIdentityKey][sessionId]; + return [store sessionWithDevice:theirDeviceIdentityKey andSessionId:sessionId]; } /** From c7d9e6ef578cb53b65050eeab264afa16caf44f0 Mon Sep 17 00:00:00 2001 From: manuroe Date: Tue, 18 Dec 2018 18:07:55 +0100 Subject: [PATCH 2/5] MXCrypto: Create MXOlmSession to add additional information to OLMSession objects from OLMKit --- MatrixSDK.xcodeproj/project.pbxproj | 8 ++++ MatrixSDK/Crypto/Data/MXOlmSession.h | 44 +++++++++++++++++++ MatrixSDK/Crypto/Data/MXOlmSession.m | 31 +++++++++++++ MatrixSDK/Crypto/Data/Store/MXCryptoStore.h | 7 +-- .../MXRealmCryptoStore/MXRealmCryptoStore.m | 28 +++++++----- MatrixSDK/Crypto/MXOlmDevice.m | 34 +++++++------- 6 files changed, 122 insertions(+), 30 deletions(-) create mode 100644 MatrixSDK/Crypto/Data/MXOlmSession.h create mode 100644 MatrixSDK/Crypto/Data/MXOlmSession.m diff --git a/MatrixSDK.xcodeproj/project.pbxproj b/MatrixSDK.xcodeproj/project.pbxproj index 38502bf6eb..a725636f3b 100644 --- a/MatrixSDK.xcodeproj/project.pbxproj +++ b/MatrixSDK.xcodeproj/project.pbxproj @@ -240,6 +240,8 @@ 32E226A61D06AC9F00E6CA54 /* MXPeekingRoom.h in Headers */ = {isa = PBXBuildFile; fileRef = 32E226A41D06AC9F00E6CA54 /* MXPeekingRoom.h */; settings = {ATTRIBUTES = (Public, ); }; }; 32E226A71D06AC9F00E6CA54 /* MXPeekingRoom.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E226A51D06AC9F00E6CA54 /* MXPeekingRoom.m */; }; 32E226A91D081CE200E6CA54 /* MXPeekingRoomTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E226A81D081CE200E6CA54 /* MXPeekingRoomTests.m */; }; + 32E402B921C957D2004E87A6 /* MXOlmSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 32E402B721C957D2004E87A6 /* MXOlmSession.h */; }; + 32E402BA21C957D2004E87A6 /* MXOlmSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 32E402B821C957D2004E87A6 /* MXOlmSession.m */; }; 32F634AB1FC5E3480054EF49 /* MXEventDecryptionResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 32F634A91FC5E3470054EF49 /* MXEventDecryptionResult.h */; settings = {ATTRIBUTES = (Public, ); }; }; 32F634AC1FC5E3480054EF49 /* MXEventDecryptionResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 32F634AA1FC5E3470054EF49 /* MXEventDecryptionResult.m */; }; 32F945F51FAB83D900622468 /* MXIncomingRoomKeyRequestCancellation.m in Sources */ = {isa = PBXBuildFile; fileRef = 32F945F11FAB83D800622468 /* MXIncomingRoomKeyRequestCancellation.m */; }; @@ -614,6 +616,8 @@ 32E226A41D06AC9F00E6CA54 /* MXPeekingRoom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MXPeekingRoom.h; sourceTree = ""; }; 32E226A51D06AC9F00E6CA54 /* MXPeekingRoom.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXPeekingRoom.m; sourceTree = ""; }; 32E226A81D081CE200E6CA54 /* MXPeekingRoomTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MXPeekingRoomTests.m; sourceTree = ""; }; + 32E402B721C957D2004E87A6 /* MXOlmSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXOlmSession.h; sourceTree = ""; }; + 32E402B821C957D2004E87A6 /* MXOlmSession.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MXOlmSession.m; sourceTree = ""; }; 32F1FE9AF82A426C2EAED587 /* Pods-MatrixSDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatrixSDK.release.xcconfig"; path = "Pods/Target Support Files/Pods-MatrixSDK/Pods-MatrixSDK.release.xcconfig"; sourceTree = ""; }; 32F634A91FC5E3470054EF49 /* MXEventDecryptionResult.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXEventDecryptionResult.h; sourceTree = ""; }; 32F634AA1FC5E3470054EF49 /* MXEventDecryptionResult.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MXEventDecryptionResult.m; sourceTree = ""; }; @@ -1131,6 +1135,8 @@ 32A151451DAF7C0C00400192 /* MXUsersDevicesMap.m */, 324BE46A1E422766008D99D4 /* MXMegolmSessionData.h */, 324BE46B1E422766008D99D4 /* MXMegolmSessionData.m */, + 32E402B721C957D2004E87A6 /* MXOlmSession.h */, + 32E402B821C957D2004E87A6 /* MXOlmSession.m */, ); path = Data; sourceTree = ""; @@ -1593,6 +1599,7 @@ 323F3F9420D3F0C700D26D6A /* MXRoomEventFilter.h in Headers */, 32A9E8251EF4026E0081358A /* MXUIKitBackgroundModeHandler.h in Headers */, 325D1C261DFECE0D0070B8BF /* MXCrypto_Private.h in Headers */, + 32E402B921C957D2004E87A6 /* MXOlmSession.h in Headers */, B146D4D621A5A44E00D8C2C6 /* MXScanRealmInMemoryProvider.h in Headers */, B17285792100C8EA0052C51E /* MXSendReplyEventStringsLocalizable.h in Headers */, 32A151521DAF8A7200400192 /* MXQueuedEncryption.h in Headers */, @@ -1866,6 +1873,7 @@ 32D776821A27877300FC4AA2 /* MXMemoryRoomStore.m in Sources */, 3293C701214BBA4F009B3DDB /* MXPeekingRoomSummary.m in Sources */, C602B58C1F2268F700B67D87 /* MXRoom.swift in Sources */, + 32E402BA21C957D2004E87A6 /* MXOlmSession.m in Sources */, 32A151271DABB0CB00400192 /* MXMegolmDecryption.m in Sources */, C6D5D60E1E4FBD2900706C0F /* MXSession.swift in Sources */, 320DFDE319DD99B60068622A /* MXError.m in Sources */, diff --git a/MatrixSDK/Crypto/Data/MXOlmSession.h b/MatrixSDK/Crypto/Data/MXOlmSession.h new file mode 100644 index 0000000000..af6cf21558 --- /dev/null +++ b/MatrixSDK/Crypto/Data/MXOlmSession.h @@ -0,0 +1,44 @@ +/* + Copyright 2018 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import + +#import "MXSDKOptions.h" + +#ifdef MX_CRYPTO + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + The 'MXOlmSession' class adds additional information to an OLMSession object from OLMKit. + */ +@interface MXOlmSession : NSObject + + +- (instancetype)initWithOlmSession:(OLMSession*)session; + +/** + The associated olm session. + */ +@property (nonatomic, readonly) OLMSession *session; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/MatrixSDK/Crypto/Data/MXOlmSession.m b/MatrixSDK/Crypto/Data/MXOlmSession.m new file mode 100644 index 0000000000..00e1b785ad --- /dev/null +++ b/MatrixSDK/Crypto/Data/MXOlmSession.m @@ -0,0 +1,31 @@ +/* + Copyright 2018 New Vector Ltd + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#import "MXOlmSession.h" + +@implementation MXOlmSession + +- (instancetype)initWithOlmSession:(OLMSession *)session +{ + self = [super init]; + if (self) + { + _session = session; + } + return self; +} + +@end diff --git a/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h b/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h index c94ea25120..384cc8daad 100644 --- a/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h +++ b/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h @@ -24,6 +24,7 @@ #import "MXJSONModels.h" #import +#import "MXOlmSession.h" #import "MXOlmInboundGroupSession.h" #import "MXDeviceInfo.h" #import "MXOutgoingRoomKeyRequest.h" @@ -188,7 +189,7 @@ @param deviceKey the public key of the other device. @param session the end-to-end session. */ -- (void)storeSession:(OLMSession*)session forDevice:(NSString*)deviceKey; +- (void)storeSession:(MXOlmSession*)session forDevice:(NSString*)deviceKey; /** Retrieve an end-to-end session between the logged-in user and another @@ -197,7 +198,7 @@ @param deviceKey the public key of the other device. @return a array of end-to-end sessions sorted by the last updated first. */ -- (OLMSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*)sessionId; +- (MXOlmSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*)sessionId; /** Retrieve all end-to-end sessions between the logged-in user and another @@ -206,7 +207,7 @@ @param deviceKey the public key of the other device. @return a array of end-to-end sessions. */ -- (NSArray*)sessionsWithDevice:(NSString*)deviceKey; +- (NSArray*)sessionsWithDevice:(NSString*)deviceKey; /** diff --git a/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m b/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m index 8bba460815..923895abaf 100644 --- a/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m +++ b/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m @@ -599,7 +599,7 @@ - (MXRealmRoomAlgorithm *)realmRoomAlgorithmForRoom:(NSString*)roomId inRealm:(R } -- (void)storeSession:(OLMSession*)session forDevice:(NSString*)deviceKey +- (void)storeSession:(MXOlmSession*)session forDevice:(NSString*)deviceKey { BOOL isNew = NO; NSDate *startDate = [NSDate date]; @@ -607,19 +607,19 @@ - (void)storeSession:(OLMSession*)session forDevice:(NSString*)deviceKey RLMRealm *realm = self.realm; [realm transactionWithBlock:^{ - MXRealmOlmSession *realmOlmSession = [MXRealmOlmSession objectsInRealm:realm where:@"sessionId = %@ AND deviceKey = %@", session.sessionIdentifier, deviceKey].firstObject; + MXRealmOlmSession *realmOlmSession = [MXRealmOlmSession objectsInRealm:realm where:@"sessionId = %@ AND deviceKey = %@", session.session.sessionIdentifier, deviceKey].firstObject; if (realmOlmSession) { // Update the existing one - realmOlmSession.olmSessionData = [NSKeyedArchiver archivedDataWithRootObject:session]; + realmOlmSession.olmSessionData = [NSKeyedArchiver archivedDataWithRootObject:session.session]; } else { // Create it realmOlmSession = [[MXRealmOlmSession alloc] initWithValue:@{ - @"sessionId": session.sessionIdentifier, + @"sessionId": session.session.sessionIdentifier, @"deviceKey": deviceKey, - @"olmSessionData": [NSKeyedArchiver archivedDataWithRootObject:session] + @"olmSessionData": [NSKeyedArchiver archivedDataWithRootObject:session.session] }]; [realm addObject:realmOlmSession]; } @@ -628,17 +628,20 @@ - (void)storeSession:(OLMSession*)session forDevice:(NSString*)deviceKey NSLog(@"[MXRealmCryptoStore] storeSession (%@) in %.0fms", (isNew?@"NEW":@"UPDATE"), [[NSDate date] timeIntervalSinceDate:startDate] * 1000); } -- (OLMSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*)sessionId +- (MXOlmSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*)sessionId { MXRealmOlmSession *realmOlmSession = [MXRealmOlmSession objectsInRealm:self.realm where:@"sessionId = %@ AND deviceKey = %@", sessionId, deviceKey].firstObject; - - return [NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]; + + OLMSession *olmSession = [NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]; + MXOlmSession *mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; + + return mxOlmSession; } -- (NSArray*)sessionsWithDevice:(NSString*)deviceKey; +- (NSArray*)sessionsWithDevice:(NSString*)deviceKey; { - NSMutableArray *sessionsWithDevice; + NSMutableArray *sessionsWithDevice; RLMResults *realmOlmSessions = [MXRealmOlmSession objectsInRealm:self.realm where:@"deviceKey = %@", deviceKey]; for (MXRealmOlmSession *realmOlmSession in realmOlmSessions) @@ -648,7 +651,10 @@ - (OLMSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*)se sessionsWithDevice = [NSMutableArray array]; } - [sessionsWithDevice addObject:[NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]]; + OLMSession *olmSession = [NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]; + MXOlmSession *mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; + + [sessionsWithDevice addObject:mxOlmSession]; } return sessionsWithDevice; diff --git a/MatrixSDK/Crypto/MXOlmDevice.m b/MatrixSDK/Crypto/MXOlmDevice.m index 022fc3e1a6..1310f9a596 100644 --- a/MatrixSDK/Crypto/MXOlmDevice.m +++ b/MatrixSDK/Crypto/MXOlmDevice.m @@ -148,7 +148,8 @@ - (NSString *)createOutboundSession:(NSString *)theirIdentityKey theirOneTimeKey if (olmSession) { - [store storeSession:olmSession forDevice:theirIdentityKey]; + MXOlmSession *mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; + [store storeSession:mxOlmSession forDevice:theirIdentityKey]; return olmSession.sessionIdentifier; } else if (error) @@ -184,7 +185,8 @@ - (NSString*)createInboundSession:(NSString*)theirDeviceIdentityKey messageType: NSLog(@"[MXOlmDevice] createInboundSession. decryptMessage error: %@", error); } - [store storeSession:olmSession forDevice:theirDeviceIdentityKey]; + MXOlmSession *mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; + [store storeSession:mxOlmSession forDevice:theirDeviceIdentityKey]; return olmSession.sessionIdentifier; } @@ -198,12 +200,12 @@ - (NSString*)createInboundSession:(NSString*)theirDeviceIdentityKey messageType: - (NSArray *)sessionIdsForDevice:(NSString *)theirDeviceIdentityKey { - NSArray *sessions = [store sessionsWithDevice:theirDeviceIdentityKey]; + NSArray *sessions = [store sessionsWithDevice:theirDeviceIdentityKey]; NSMutableArray *sessionIds = [NSMutableArray arrayWithCapacity:sessions.count]; - for (OLMSession *session in sessions) + for (MXOlmSession *session in sessions) { - [sessionIds addObject:session.sessionIdentifier]; + [sessionIds addObject:session.session.sessionIdentifier]; } return sessionIds; @@ -229,21 +231,21 @@ - (NSDictionary *)encryptMessage:(NSString *)theirDeviceIdentityKey sessionId:(N NSError *error; OLMMessage *olmMessage; - OLMSession *olmSession = [self sessionForDevice:theirDeviceIdentityKey andSessionId:sessionId]; + MXOlmSession *mxOlmSession = [self sessionForDevice:theirDeviceIdentityKey andSessionId:sessionId]; // NSLog(@">>>> encryptMessage: olmSession.sessionIdentifier: %@", olmSession.sessionIdentifier); // NSLog(@">>>> payloadString: %@", payloadString); - if (olmSession) + if (mxOlmSession.session) { - olmMessage = [olmSession encryptMessage:payloadString error:&error]; + olmMessage = [mxOlmSession.session encryptMessage:payloadString error:&error]; if (error) { NSLog(@"[MXOlmDevice] encryptMessage failed: %@", error); } - [store storeSession:olmSession forDevice:theirDeviceIdentityKey]; + [store storeSession:mxOlmSession forDevice:theirDeviceIdentityKey]; } //NSLog(@">>>> ciphertext: %@", olmMessage.ciphertext); @@ -260,17 +262,17 @@ - (NSString*)decryptMessage:(NSString*)ciphertext withType:(NSUInteger)messageTy NSError *error; NSString *payloadString; - OLMSession *olmSession = [self sessionForDevice:theirDeviceIdentityKey andSessionId:sessionId]; - if (olmSession) + MXOlmSession *mxOlmSession = [self sessionForDevice:theirDeviceIdentityKey andSessionId:sessionId]; + if (mxOlmSession) { - payloadString = [olmSession decryptMessage:[[OLMMessage alloc] initWithCiphertext:ciphertext type:messageType] error:&error]; + payloadString = [mxOlmSession.session decryptMessage:[[OLMMessage alloc] initWithCiphertext:ciphertext type:messageType] error:&error]; if (error) { NSLog(@"[MXOlmDevice] decryptMessage failed: %@", error); } - [store storeSession:olmSession forDevice:theirDeviceIdentityKey]; + [store storeSession:mxOlmSession forDevice:theirDeviceIdentityKey]; } return payloadString; @@ -283,8 +285,8 @@ - (BOOL)matchesSession:(NSString *)theirDeviceIdentityKey sessionId:(NSString *) return NO; } - OLMSession *olmSession = [self sessionForDevice:theirDeviceIdentityKey andSessionId:sessionId]; - return [olmSession matchesInboundSession:ciphertext]; + MXOlmSession *mxOlmSession = [self sessionForDevice:theirDeviceIdentityKey andSessionId:sessionId]; + return [mxOlmSession.session matchesInboundSession:ciphertext]; } @@ -565,7 +567,7 @@ - (NSString *)sha256:(NSString *)message #pragma mark - Private methods -- (OLMSession*)sessionForDevice:(NSString *)theirDeviceIdentityKey andSessionId:(NSString*)sessionId +- (MXOlmSession*)sessionForDevice:(NSString *)theirDeviceIdentityKey andSessionId:(NSString*)sessionId { return [store sessionWithDevice:theirDeviceIdentityKey andSessionId:sessionId]; } From ea1fe678635aa53f7cf3b9e4695da531a8d7716f Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 20 Dec 2018 14:36:55 +0100 Subject: [PATCH 3/5] MXCrypto: Use the last olm session that got a message With the add MXOlmSession.lastReceivedMessageTs https://github.com/vector-im/riot-ios/issues/2128 --- CHANGES.rst | 9 +++--- MatrixSDK/Crypto/Data/MXOlmSession.h | 12 ++++++++ MatrixSDK/Crypto/Data/MXOlmSession.m | 6 ++++ MatrixSDK/Crypto/Data/Store/MXCryptoStore.h | 2 +- .../MXRealmCryptoStore/MXRealmCryptoStore.m | 30 +++++++++++++++++-- MatrixSDK/Crypto/MXOlmDevice.m | 26 +++++++++------- 6 files changed, 67 insertions(+), 18 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 813387b49c..3a7af474ec 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,13 +1,14 @@ Changes in Matrix iOS SDK in 0.12.1 (2012-12-xx) =============================================== +Improvements: +* MXCrypto: Use the last olm session that got a message (vector-im/riot-ios/issues/2128). +* MXScanManager: Support the encrypted body (the request body is now encrypted by default using the server public key). +* MXMediaManager: Support the encrypted body. + Bug Fix: * MXCryptoStore: Stop duplicating devices in the store (vector-im/riot-ios/issues/2132). -Improvements: - * MXScanManager: Support the encrypted body (the request body is now encrypted by default using the server public key). - * MXMediaManager: Support the encrypted body. - Changes in Matrix iOS SDK in 0.12.0 (2018-12-06) =============================================== diff --git a/MatrixSDK/Crypto/Data/MXOlmSession.h b/MatrixSDK/Crypto/Data/MXOlmSession.h index af6cf21558..80ba7b1535 100644 --- a/MatrixSDK/Crypto/Data/MXOlmSession.h +++ b/MatrixSDK/Crypto/Data/MXOlmSession.h @@ -37,6 +37,18 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nonatomic, readonly) OLMSession *session; +/** + Timestamp at which the session last received a message. + */ +@property (nonatomic) NSTimeInterval lastReceivedMessageTs; + + +/** + Notify this model that a message has been received on this olm session + so that it updates `lastReceivedMessageTs` + */ +- (void)didReceiveMessage; + @end NS_ASSUME_NONNULL_END diff --git a/MatrixSDK/Crypto/Data/MXOlmSession.m b/MatrixSDK/Crypto/Data/MXOlmSession.m index 00e1b785ad..5dea2c50bb 100644 --- a/MatrixSDK/Crypto/Data/MXOlmSession.m +++ b/MatrixSDK/Crypto/Data/MXOlmSession.m @@ -24,8 +24,14 @@ - (instancetype)initWithOlmSession:(OLMSession *)session if (self) { _session = session; + _lastReceivedMessageTs = 0; } return self; } +- (void)didReceiveMessage +{ + _lastReceivedMessageTs = [[NSDate date] timeIntervalSince1970]; +} + @end diff --git a/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h b/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h index 384cc8daad..f17360451a 100644 --- a/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h +++ b/MatrixSDK/Crypto/Data/Store/MXCryptoStore.h @@ -202,7 +202,7 @@ /** Retrieve all end-to-end sessions between the logged-in user and another - device. + device sorted by `lastReceivedMessageTs`, the most recent(higest value) first. @param deviceKey the public key of the other device. @return a array of end-to-end sessions. diff --git a/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m b/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m index 923895abaf..9194b72336 100644 --- a/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m +++ b/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m @@ -23,7 +23,7 @@ #import "MXSession.h" #import "MXTools.h" -NSUInteger const kMXRealmCryptoStoreVersion = 8; +NSUInteger const kMXRealmCryptoStoreVersion = 9; static NSString *const kMXRealmCryptoStoreFolder = @"MXRealmCryptoStore"; @@ -84,6 +84,7 @@ + (NSString *)primaryKey @interface MXRealmOlmSession : RLMObject @property NSString *sessionId; @property NSString *deviceKey; +@property NSTimeInterval lastReceivedMessageTs; @property NSData *olmSessionData; @end @@ -621,6 +622,8 @@ - (void)storeSession:(MXOlmSession*)session forDevice:(NSString*)deviceKey @"deviceKey": deviceKey, @"olmSessionData": [NSKeyedArchiver archivedDataWithRootObject:session.session] }]; + realmOlmSession.lastReceivedMessageTs = session.lastReceivedMessageTs; + [realm addObject:realmOlmSession]; } }]; @@ -634,7 +637,9 @@ - (MXOlmSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*) where:@"sessionId = %@ AND deviceKey = %@", sessionId, deviceKey].firstObject; OLMSession *olmSession = [NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]; + MXOlmSession *mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; + mxOlmSession.lastReceivedMessageTs = realmOlmSession.lastReceivedMessageTs; return mxOlmSession; } @@ -643,7 +648,9 @@ - (MXOlmSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*) { NSMutableArray *sessionsWithDevice; - RLMResults *realmOlmSessions = [MXRealmOlmSession objectsInRealm:self.realm where:@"deviceKey = %@", deviceKey]; + RLMResults *realmOlmSessions = [[MXRealmOlmSession objectsInRealm:self.realm + where:@"deviceKey = %@", deviceKey] + sortedResultsUsingKeyPath:@"lastReceivedMessageTs" ascending:NO]; for (MXRealmOlmSession *realmOlmSession in realmOlmSessions) { if (!sessionsWithDevice) @@ -652,7 +659,9 @@ - (MXOlmSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*) } OLMSession *olmSession = [NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]; + MXOlmSession *mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; + mxOlmSession.lastReceivedMessageTs = realmOlmSession.lastReceivedMessageTs; [sessionsWithDevice addObject:mxOlmSession]; } @@ -1203,6 +1212,23 @@ + (RLMRealm*)realmForUser:(NSString*)userId // make queries. So, the cleaning will be done afterwards. cleanDuplicatedDevices = YES; } + + case 8: + { + // MXRealmOlmSession.lastReceivedMessageTs has been added to implement: + // Use the last olm session that got a message + // https://github.com/vector-im/riot-ios/issues/2128 + + NSLog(@"[MXRealmCryptoStore] Migration from schema #8 -> #9"); + + NSLog(@" Add lastReceivedMessageTs = 0 to all MXRealmOlmSession objects"); + [migration enumerateObjects:MXRealmOlmSession.className block:^(RLMObject *oldObject, RLMObject *newObject) { + + newObject[@"lastReceivedMessageTs"] = 0; + }]; + + NSLog(@"[MXRealmCryptoStore] Migration from schema #6 -> #7 completed"); + } } } }; diff --git a/MatrixSDK/Crypto/MXOlmDevice.m b/MatrixSDK/Crypto/MXOlmDevice.m index 1310f9a596..82cb66007f 100644 --- a/MatrixSDK/Crypto/MXOlmDevice.m +++ b/MatrixSDK/Crypto/MXOlmDevice.m @@ -149,6 +149,12 @@ - (NSString *)createOutboundSession:(NSString *)theirIdentityKey theirOneTimeKey if (olmSession) { MXOlmSession *mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; + + // Pretend we've received a message at this point, otherwise + // if we try to send a message to the device, it won't use + // this session + [mxOlmSession didReceiveMessage]; + [store storeSession:mxOlmSession forDevice:theirIdentityKey]; return olmSession.sessionIdentifier; } @@ -186,6 +192,11 @@ - (NSString*)createInboundSession:(NSString*)theirDeviceIdentityKey messageType: } MXOlmSession *mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; + + // This counts as a received message: set last received message time + // to now + [mxOlmSession didReceiveMessage]; + [store storeSession:mxOlmSession forDevice:theirDeviceIdentityKey]; return olmSession.sessionIdentifier; @@ -213,17 +224,9 @@ - (NSString*)createInboundSession:(NSString*)theirDeviceIdentityKey messageType: - (NSString *)sessionIdForDevice:(NSString *)theirDeviceIdentityKey { - NSString *sessionId; - - NSArray *sessionIds = [self sessionIdsForDevice:theirDeviceIdentityKey]; - if (sessionIds.count) - { - // Use the session with the lowest ID. - NSArray *sortedSessionIds = [sessionIds sortedArrayUsingSelector:@selector(compare:)]; - sessionId = sortedSessionIds[0]; - } - - return sessionId; + // Use the session that has most recently received a message + // This is the first item in the sorted array returned by the store + return [store sessionsWithDevice:theirDeviceIdentityKey].firstObject.session.sessionIdentifier; } - (NSDictionary *)encryptMessage:(NSString *)theirDeviceIdentityKey sessionId:(NSString *)sessionId payloadString:(NSString *)payloadString @@ -272,6 +275,7 @@ - (NSString*)decryptMessage:(NSString*)ciphertext withType:(NSUInteger)messageTy NSLog(@"[MXOlmDevice] decryptMessage failed: %@", error); } + [mxOlmSession didReceiveMessage]; [store storeSession:mxOlmSession forDevice:theirDeviceIdentityKey]; } From c930a86ca581a95d28c34f5085c8df3c6eb36f77 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 20 Dec 2018 14:42:18 +0100 Subject: [PATCH 4/5] MXCrypto: Use the last olm session that got a message typo --- .../Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m b/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m index 9194b72336..ef1b812ad5 100644 --- a/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m +++ b/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m @@ -1227,7 +1227,7 @@ + (RLMRealm*)realmForUser:(NSString*)userId newObject[@"lastReceivedMessageTs"] = 0; }]; - NSLog(@"[MXRealmCryptoStore] Migration from schema #6 -> #7 completed"); + NSLog(@"[MXRealmCryptoStore] Migration from schema #8 -> #9 completed"); } } } From f2c0f2ac4009db9558f88b6fcc5e2851aa15aa71 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 20 Dec 2018 16:02:47 +0100 Subject: [PATCH 5/5] MXCrypto: Use the last olm session that got a message Fix Steve's comment --- .../MXRealmCryptoStore/MXRealmCryptoStore.m | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m b/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m index ef1b812ad5..4573ff5c95 100644 --- a/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m +++ b/MatrixSDK/Crypto/Data/Store/MXRealmCryptoStore/MXRealmCryptoStore.m @@ -636,10 +636,14 @@ - (MXOlmSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*) MXRealmOlmSession *realmOlmSession = [MXRealmOlmSession objectsInRealm:self.realm where:@"sessionId = %@ AND deviceKey = %@", sessionId, deviceKey].firstObject; - OLMSession *olmSession = [NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]; + MXOlmSession *mxOlmSession; + if (realmOlmSession.olmSessionData) + { + OLMSession *olmSession = [NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]; - MXOlmSession *mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; - mxOlmSession.lastReceivedMessageTs = realmOlmSession.lastReceivedMessageTs; + mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; + mxOlmSession.lastReceivedMessageTs = realmOlmSession.lastReceivedMessageTs; + } return mxOlmSession; } @@ -658,12 +662,15 @@ - (MXOlmSession*)sessionWithDevice:(NSString*)deviceKey andSessionId:(NSString*) sessionsWithDevice = [NSMutableArray array]; } - OLMSession *olmSession = [NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]; + if (realmOlmSession.olmSessionData) + { + OLMSession *olmSession = [NSKeyedUnarchiver unarchiveObjectWithData:realmOlmSession.olmSessionData]; - MXOlmSession *mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; - mxOlmSession.lastReceivedMessageTs = realmOlmSession.lastReceivedMessageTs; + MXOlmSession *mxOlmSession = [[MXOlmSession alloc] initWithOlmSession:olmSession]; + mxOlmSession.lastReceivedMessageTs = realmOlmSession.lastReceivedMessageTs; - [sessionsWithDevice addObject:mxOlmSession]; + [sessionsWithDevice addObject:mxOlmSession]; + } } return sessionsWithDevice;