diff --git a/CHANGES.md b/CHANGES.md index 91be1e113a..67e45d61d6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,9 @@ +## Changes in 0.20.14 (2021-12-09) + +🐛 Bugfixes + +- Sending blank m.room.encryption on iOS will disable encryption ([Security advisory](https://github.com/matrix-org/matrix-ios-sdk/security/advisories/GHSA-fxvm-7vhj-wj98)) + ## Changes in 0.20.13 (2021-12-06) Others diff --git a/MatrixSDK.podspec b/MatrixSDK.podspec index 3795ee19ba..a5779732ae 100644 --- a/MatrixSDK.podspec +++ b/MatrixSDK.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "MatrixSDK" - s.version = "0.20.13" + s.version = "0.20.14" s.summary = "The iOS SDK to build apps compatible with Matrix (https://www.matrix.org)" s.description = <<-DESC diff --git a/MatrixSDK/Crypto/MXCrypto.m b/MatrixSDK/Crypto/MXCrypto.m index 9b70a251b1..6191ec9065 100644 --- a/MatrixSDK/Crypto/MXCrypto.m +++ b/MatrixSDK/Crypto/MXCrypto.m @@ -2039,19 +2039,21 @@ - (MXDeviceInfo *)eventSenderDeviceOfEvent:(MXEvent *)event - (BOOL)setEncryptionInRoom:(NSString*)roomId withMembers:(NSArray*)members algorithm:(NSString*)algorithm inhibitDeviceQuery:(BOOL)inhibitDeviceQuery { - // If we already have encryption in this room, we should ignore this event - // (for now at least. Maybe we should alert the user somehow?) NSString *existingAlgorithm = [_store algorithmForRoom:roomId]; if (existingAlgorithm && ![existingAlgorithm isEqualToString:algorithm]) { - MXLogDebug(@"[MXCrypto] setEncryptionInRoom: Ignoring m.room.encryption event which requests a change of config in %@", roomId); - return NO; + MXLogWarning(@"[MXCrypto] setEncryptionInRoom: New m.room.encryption event in %@ with an algorithm change from %@ to %@", roomId, existingAlgorithm, algorithm); + + // Reset the current encryption in this room. + // If the new algo is supported, it will be used + // Else, encryption and sending will be no more possible in this room + [roomEncryptors removeObjectForKey:roomId]; } Class encryptionClass = [[MXCryptoAlgorithms sharedAlgorithms] encryptorClassForAlgorithm:algorithm]; if (!encryptionClass) { - MXLogDebug(@"[MXCrypto] setEncryptionInRoom: Unable to encrypt with %@", algorithm); + MXLogError(@"[MXCrypto] setEncryptionInRoom: Unable to encrypt with %@", algorithm); return NO; } diff --git a/MatrixSDK/Data/MXRoomState.m b/MatrixSDK/Data/MXRoomState.m index 26cb38e01c..b42525c231 100644 --- a/MatrixSDK/Data/MXRoomState.m +++ b/MatrixSDK/Data/MXRoomState.m @@ -358,7 +358,7 @@ - (MXRoomGuestAccess)guestAccess - (BOOL)isEncrypted { - return (0 != self.encryptionAlgorithm.length); + return stateEvents[kMXEventTypeStringRoomEncryption] != nil; } - (NSArray *)pinnedEvents diff --git a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m index 2d36c4a4ca..beffb09178 100644 --- a/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m +++ b/MatrixSDK/Data/Store/MXFileStore/MXFileStore.m @@ -28,7 +28,7 @@ #import "MXTools.h" #import "MatrixSDKSwiftHeader.h" -static NSUInteger const kMXFileVersion = 76; +static NSUInteger const kMXFileVersion = 77; static NSString *const kMXFileStoreFolder = @"MXFileStore"; static NSString *const kMXFileStoreMedaDataFile = @"MXFileStore"; diff --git a/MatrixSDK/MatrixSDKVersion.m b/MatrixSDK/MatrixSDKVersion.m index 343e512f6e..c1b38a41f5 100644 --- a/MatrixSDK/MatrixSDKVersion.m +++ b/MatrixSDK/MatrixSDKVersion.m @@ -16,4 +16,4 @@ #import -NSString *const MatrixSDKVersion = @"0.20.13"; +NSString *const MatrixSDKVersion = @"0.20.14"; diff --git a/MatrixSDKTests/MXCryptoTests.m b/MatrixSDKTests/MXCryptoTests.m index 2e2c5c83f6..ad162aacbb 100644 --- a/MatrixSDKTests/MXCryptoTests.m +++ b/MatrixSDKTests/MXCryptoTests.m @@ -3056,6 +3056,79 @@ - (void)testFallbackKeySignatures }]; } +// Test encryption algorithm change with a blank m.room.encryption event +// - Alice and bob in a megolm encrypted room +// - Send a blank m.room.encryption event +// -> The room should be still marked as encrypted +// -> It must be impossible to send a messages (because the algorithm is not supported) +// - Fix e2e algorithm in the room +// -> The room should be still marked as encrypted with the right algorithm +// -> It must be possible to send message again +// -> The message must be e2e encrypted +- (void)testEncryptionAlgorithmChange +{ + // - Alice and bob in a megolm encrypted room + [matrixSDKTestsE2EData doE2ETestWithAliceAndBobInARoom:self cryptedBob:YES warnOnUnknowDevices:NO readyToTest:^(MXSession *aliceSession, MXSession *bobSession, NSString *roomId, XCTestExpectation *expectation) { + + MXRoom *roomFromAlicePOV= [aliceSession roomWithRoomId:roomId]; + + // - Send a blank m.room.encryption event + [roomFromAlicePOV sendStateEventOfType:kMXEventTypeStringRoomEncryption + content:@{ } + stateKey:nil + success:nil + failure:^(NSError *error) { + XCTFail(@"Cannot set up intial test conditions - error: %@", error); + [expectation fulfill]; + }]; + + __block id listener = [roomFromAlicePOV listenToEventsOfTypes:@[kMXEventTypeStringRoomEncryption] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { + + [roomFromAlicePOV removeListener:listener]; + + [roomFromAlicePOV liveTimeline:^(MXEventTimeline *liveTimeline) { + + // -> The room should be still marked as encrypted + XCTAssertTrue(liveTimeline.state.isEncrypted); + XCTAssertEqual(liveTimeline.state.encryptionAlgorithm.length, 0); // with a nil algorithm + XCTAssertTrue(roomFromAlicePOV.summary.isEncrypted); + + // -> It must be impossible to send a messages (because the algorithm is not supported) + [roomFromAlicePOV sendTextMessage:@"An encrypted message" success:^(NSString *eventId) { + XCTFail(@"It should not possible to send encrypted message anymore"); + } failure:^(NSError *error) { + + // - Fix e2e algorithm in the room + [roomFromAlicePOV enableEncryptionWithAlgorithm:kMXCryptoMegolmAlgorithm success:^{ + + // -> The room should be still marked as encrypted with the right algorithm + XCTAssertTrue(liveTimeline.state.isEncrypted); + XCTAssertEqualObjects(liveTimeline.state.encryptionAlgorithm, kMXCryptoMegolmAlgorithm); + XCTAssertTrue(roomFromAlicePOV.summary.isEncrypted); + + // -> It must be possible to send message again + [roomFromAlicePOV sendTextMessage:@"An encrypted message" success:nil failure:^(NSError *error) { + XCTFail(@"The request should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + + [roomFromAlicePOV listenToEventsOfTypes:@[kMXEventTypeStringRoomMessage] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) { + // -> The message must be e2e encrypted + XCTAssertTrue(event.isEncrypted); + XCTAssertEqualObjects(event.wireContent[@"algorithm"], kMXCryptoMegolmAlgorithm); + [expectation fulfill]; + }]; + + } failure:^(NSError *error) { + XCTFail(@"The request should not fail - NSError: %@", error); + [expectation fulfill]; + }]; + }]; + }]; + }]; + }]; +} + @end #pragma clang diagnostic pop