Skip to content

Commit

Permalink
Merge branch 'release/0.23.19/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
Anderas committed Sep 28, 2022
2 parents bacba64 + 95458f1 commit 4442142
Show file tree
Hide file tree
Showing 46 changed files with 2,398 additions and 201 deletions.
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## Changes in 0.23.19 (2022-09-28)

🐛 Bugfixes

- CVE-2022-39255: Olm/Megolm protocol confusion ([Security advisory](https://github.com/matrix-org/matrix-ios-sdk/security/advisories/GHSA-hw6g-j8v6-9hcm))
- CVE-2022-39257: Impersonation via forwarded Megolm sessions ([Security advisory](https://github.com/matrix-org/matrix-ios-sdk/security/advisories/GHSA-qxr3-5jmq-xcf4))

## Changes in 0.23.18 (2022-09-07)

✨ Features
Expand Down
2 changes: 1 addition & 1 deletion MatrixSDK.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "MatrixSDK"
s.version = "0.23.18"
s.version = "0.23.19"
s.summary = "The iOS SDK to build apps compatible with Matrix (https://www.matrix.org)"

s.description = <<-DESC
Expand Down
122 changes: 122 additions & 0 deletions MatrixSDK.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

76 changes: 28 additions & 48 deletions MatrixSDK/Background/MXBackgroundSyncService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,12 @@ public enum MXBackgroundSyncServiceError: Error {
}

private func handleToDeviceEvent(_ event: MXEvent) {
// only handle supported events
guard MXTools.isSupportedToDeviceEvent(event) else {
MXLog.debug("[MXBackgroundSyncService] handleToDeviceEvent: ignore unsupported event")
return
}

if event.isEncrypted {
do {
try decryptEvent(event)
Expand All @@ -573,61 +579,35 @@ public enum MXBackgroundSyncServiceError: Error {
}
}

guard let content = event.content else {
MXLog.debug("[MXBackgroundSyncService] handleToDeviceEvent: ERROR: incomplete event content: \(String(describing: event.jsonDictionary()))")
guard let userId = credentials.userId else {
MXLog.error("[MXBackgroundSyncService] handleToDeviceEvent: Cannot get userId")
return
}

guard let roomId = content["room_id"] as? String,
let sessionId = content["session_id"] as? String,
let sessionKey = content["session_key"] as? String,
var senderKey = event.senderKey else {
MXLog.debug("[MXBackgroundSyncService] handleToDeviceEvent: ERROR: incomplete event: \(String(describing: event.jsonDictionary()))")
let factory = MXRoomKeyInfoFactory(myUserId: userId, store: cryptoStore)
guard let key = factory.roomKey(for: event) else {
MXLog.error("[MXBackgroundSyncService] handleToDeviceEvent: Cannot create megolm key from event")
return
}

var forwardingKeyChain: [String] = []
var exportFormat: Bool = false
var keysClaimed: [String: String] = [:]

switch event.eventType {
case .roomKey:
keysClaimed = event.keysClaimed as! [String: String]
case .roomForwardedKey:
exportFormat = true

if let array = content["forwarding_curve25519_key_chain"] as? [String] {
forwardingKeyChain = array
}
forwardingKeyChain.append(senderKey)

if let senderKeyInContent = content["sender_key"] as? String {
senderKey = senderKeyInContent
} else {
return
}

guard let ed25519Key = event.content["sender_claimed_ed25519_key"] as? String else {
return
}

keysClaimed = [
"ed25519": ed25519Key
]
default:
MXLog.debug("[MXBackgroundSyncService] handleToDeviceEvent: ERROR: Not supported type: \(event.eventType)")
return
switch key.type {
case .safe:
olmDevice.addInboundGroupSession(
key.info.sessionId,
sessionKey: key.info.sessionKey,
roomId: key.info.roomId,
senderKey: key.info.senderKey,
forwardingCurve25519KeyChain: key.info.forwardingKeyChain,
keysClaimed: key.info.keysClaimed,
exportFormat: key.info.exportFormat,
sharedHistory: key.info.sharedHistory,
untrusted: key.type != .safe
)
case .unsafe:
MXLog.warning("[MXBackgroundSyncService] handleToDeviceEvent: Ignoring unsafe keys")
case .unrequested:
MXLog.warning("[MXBackgroundSyncService] handleToDeviceEvent: Ignoring unrequested keys")
}

let sharedHistory = (content[kMXSharedHistoryKeyName] as? Bool) ?? false
olmDevice.addInboundGroupSession(sessionId,
sessionKey: sessionKey,
roomId: roomId,
senderKey: senderKey,
forwardingCurve25519KeyChain: forwardingKeyChain,
keysClaimed: keysClaimed,
exportFormat: exportFormat,
sharedHistory: sharedHistory)
}

private func updateBackgroundServiceStoresIfNeeded() {
Expand Down
8 changes: 7 additions & 1 deletion MatrixSDK/Contrib/Swift/JSONModels/MXEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ public enum MXEventType: Equatable, Hashable {
case keyVerificationMac
case keyVerificationCancel
case keyVerificationDone
case secretRequest
case secretSend
case secretStorageDefaultKey
case taggedEvents
case spaceChild
case spaceOrder
Expand Down Expand Up @@ -132,6 +135,9 @@ public enum MXEventType: Equatable, Hashable {
case .keyVerificationMac: return kMXEventTypeStringKeyVerificationMac
case .keyVerificationCancel: return kMXEventTypeStringKeyVerificationCancel
case .keyVerificationDone: return kMXEventTypeStringKeyVerificationDone
case .secretRequest: return kMXEventTypeStringSecretRequest
case .secretSend: return kMXEventTypeStringSecretSend
case .secretStorageDefaultKey: return kMXEventTypeStringSecretStorageDefaultKey
case .taggedEvents: return kMXEventTypeStringTaggedEvents
case .spaceChild: return kMXEventTypeStringSpaceChild
case .spaceOrder: return kMXEventTypeStringSpaceOrderMSC3230
Expand All @@ -151,7 +157,7 @@ public enum MXEventType: Equatable, Hashable {
}

public init(identifier: String) {
let events: [MXEventType] = [.roomName, .roomTopic, .roomAvatar, .roomMember, .roomCreate, .roomJoinRules, .roomPowerLevels, .roomAliases, .roomCanonicalAlias, .roomEncrypted, .roomEncryption, .roomGuestAccess, .roomHistoryVisibility, .roomKey, .roomForwardedKey, .roomKeyRequest, .roomMessage, .roomMessageFeedback, .roomRedaction, .roomThirdPartyInvite, .roomTag, .presence, .typing, .callInvite, .callCandidates, .callAnswer, .callSelectAnswer, .callHangup, .callReject, .callNegotiate, .callReplaces, .callRejectReplacement, .callAssertedIdentity, .callAssertedIdentityUnstable, .reaction, .receipt, .roomTombStone, .keyVerificationStart, .keyVerificationAccept, .keyVerificationKey, .keyVerificationMac, .keyVerificationCancel, .keyVerificationDone, .taggedEvents, .spaceChild, .spaceOrder, .pollStart, .pollResponse, .pollEnd, .beaconInfo, .beacon]
let events: [MXEventType] = [.roomName, .roomTopic, .roomAvatar, .roomMember, .roomCreate, .roomJoinRules, .roomPowerLevels, .roomAliases, .roomCanonicalAlias, .roomEncrypted, .roomEncryption, .roomGuestAccess, .roomHistoryVisibility, .roomKey, .roomForwardedKey, .roomKeyRequest, .roomMessage, .roomMessageFeedback, .roomRedaction, .roomThirdPartyInvite, .roomTag, .presence, .typing, .callInvite, .callCandidates, .callAnswer, .callSelectAnswer, .callHangup, .callReject, .callNegotiate, .callReplaces, .callRejectReplacement, .callAssertedIdentity, .callAssertedIdentityUnstable, .reaction, .receipt, .roomTombStone, .keyVerificationStart, .keyVerificationAccept, .keyVerificationKey, .keyVerificationMac, .keyVerificationCancel, .keyVerificationDone, .secretRequest, .secretSend, .secretStorageDefaultKey, .taggedEvents, .spaceChild, .spaceOrder, .pollStart, .pollResponse, .pollEnd, .beaconInfo, .beacon]

if let type = events.first(where: { $0.identifier == identifier }) {
self = type
Expand Down
15 changes: 11 additions & 4 deletions MatrixSDK/Crypto/Algorithms/MXDecrypting.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#import "MXEventDecryptionResult.h"
#import "MXIncomingRoomKeyRequest.h"

@class MXCrypto, MXOlmInboundGroupSession;
@class MXCrypto, MXOlmInboundGroupSession, MXRoomKeyResult;


@protocol MXDecrypting <NSObject>
Expand Down Expand Up @@ -56,12 +56,19 @@
- (MXEventDecryptionResult *)decryptEvent:(MXEvent*)event inTimeline:(NSString*)timeline;

/**
* Handle a key event.
*
* @param event the key event.
Handle a key event.
@param event the key event.
*/
- (void)onRoomKeyEvent:(MXEvent*)event;

/**
Handle new room key
@param key the domain object with key details and safety
*/
- (void)onRoomKey:(MXRoomKeyResult*)key;

/**
Notification that a room key has been imported.
Expand Down
121 changes: 44 additions & 77 deletions MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmDecryption.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#import "MXTools.h"
#import "MatrixSDKSwiftHeader.h"
#import "MXSharedHistoryKeyService.h"
#import "MXForwardedRoomKeyEventContent.h"

@interface MXMegolmDecryption ()
{
Expand All @@ -41,6 +42,10 @@ @interface MXMegolmDecryption ()
NSMutableDictionary<NSString* /* timelineId */,
NSMutableDictionary<NSString* /* eventId */, MXEvent*>*>*> *pendingEvents;
}

// Factory to create room key info
@property (nonatomic, strong) MXRoomKeyInfoFactory *roomKeyInfoFactory;

@end

@implementation MXMegolmDecryption
Expand All @@ -59,6 +64,7 @@ - (instancetype)initWithCrypto:(MXCrypto *)theCrypto
{
crypto = theCrypto;
olmDevice = theCrypto.olmDevice;
_roomKeyInfoFactory = [[MXRoomKeyInfoFactory alloc] initWithMyUserId:crypto.mxSession.credentials.userId store:crypto.store];
pendingEvents = [NSMutableDictionary dictionary];
}
return self;
Expand Down Expand Up @@ -191,98 +197,59 @@ - (void)addEventToPendingList:(MXEvent*)event inTimeline:(NSString*)timelineId

- (void)onRoomKeyEvent:(MXEvent *)event
{
NSDictionary *content = event.content;
NSString *roomId, *sessionId, *sessionKey;

MXJSONModelSetString(roomId, content[@"room_id"]);
MXJSONModelSetString(sessionId, content[@"session_id"]);
MXJSONModelSetString(sessionKey, content[@"session_key"]);

if (!roomId || !sessionId || !sessionKey)
MXRoomKeyResult *key = [self.roomKeyInfoFactory roomKeyFor:event];
if (!key)
{
MXLogDebug(@"[MXMegolmDecryption] onRoomKeyEvent: ERROR: Key event is missing fields");
MXLogError(@"[MXMegolmDecryption] onRoomKeyEvent: Cannot create megolm key from event");
return;
}

NSString *senderKey = event.senderKey;
if (!senderKey)
{
MXLogDebug(@"[MXMegolmDecryption] onRoomKeyEvent: ERROR: Key event has no sender key (not encrypted?)");
return;
}

NSArray<NSString*> *forwardingKeyChain;
BOOL exportFormat = NO;
NSDictionary *keysClaimed;
BOOL sharedHistory = NO;
if (content[kMXSharedHistoryKeyName] != nil)
{
MXJSONModelSetBoolean(sharedHistory, content[kMXSharedHistoryKeyName]);
}

if (event.eventType == MXEventTypeRoomForwardedKey)
{
exportFormat = YES;
MXJSONModelSetArray(forwardingKeyChain, content[@"forwarding_curve25519_key_chain"]);
if (!forwardingKeyChain)
{
forwardingKeyChain = @[];
}

// copy content before we modify it
NSMutableArray *forwardingKeyChain2 = [NSMutableArray arrayWithArray:forwardingKeyChain];
[forwardingKeyChain2 addObject:senderKey];
forwardingKeyChain = forwardingKeyChain2;

MXJSONModelSetString(senderKey, content[@"sender_key"]);
if (!senderKey)
{
MXLogDebug(@"[MXMegolmDecryption] onRoomKeyEvent: ERROR: forwarded_room_key event is missing sender_key field");
return;
}

NSString *ed25519Key;
MXJSONModelSetString(ed25519Key, content[@"sender_claimed_ed25519_key"]);
if (!ed25519Key)
{
MXLogDebug(@"[MXMegolmDecryption] onRoomKeyEvent: ERROR: forwarded_room_key_event is missing sender_claimed_ed25519_key field");
return;
}

keysClaimed = @{
@"ed25519": ed25519Key
};
}
else
{
keysClaimed = event.keysClaimed;

switch (key.type) {
case MXRoomKeyTypeSafe:
MXLogDebug(@"[MXMegolmDecryption] onRoomKeyEvent: Adding key for megolm session %@|%@ from %@ event", key.info.senderKey, key.info.sessionId, event.type);
[self onRoomKey:key];
break;
case MXRoomKeyTypeUnsafe:
MXLogWarning(@"[MXMegolmDecryption] onRoomKeyEvent: Ignoring unsafe key");
break;
case MXRoomKeyTypeUnrequested:
[crypto handleUnrequestedRoomKeyInfo:key.info senderId:event.sender senderKey:event.senderKey];
break;
default:
MXLogFailureDetails(@"[MXMegolmDecryption] onRoomKeyEvent: Unknown key type", @{
@"key_type": @(key.type)
});
break;
}
}

MXLogDebug(@"[MXMegolmDecryption] onRoomKeyEvent: Adding key for megolm session %@|%@ from %@ event", senderKey, sessionId, event.type);

[olmDevice addInboundGroupSession:sessionId
sessionKey:sessionKey
roomId:roomId
senderKey:senderKey
forwardingCurve25519KeyChain:forwardingKeyChain
keysClaimed:keysClaimed
exportFormat:exportFormat
sharedHistory:sharedHistory];
- (void)onRoomKey:(MXRoomKeyResult *)key
{
MXRoomKeyInfo *keyInfo = key.info;
[olmDevice addInboundGroupSession:keyInfo.sessionId
sessionKey:keyInfo.sessionKey
roomId:keyInfo.roomId
senderKey:keyInfo.senderKey
forwardingCurve25519KeyChain:keyInfo.forwardingKeyChain
keysClaimed:keyInfo.keysClaimed
exportFormat:keyInfo.exportFormat
sharedHistory:keyInfo.sharedHistory
untrusted:key.type != MXRoomKeyTypeSafe];

[crypto.backup maybeSendKeyBackup];

MXWeakify(self);
[self retryDecryption:senderKey sessionId:content[@"session_id"] complete:^(BOOL allDecrypted) {
[self retryDecryption:keyInfo.senderKey sessionId:keyInfo.sessionId complete:^(BOOL allDecrypted) {
MXStrongifyAndReturnIfNil(self);

if (allDecrypted)
{
// cancel any outstanding room key requests for this session
[self->crypto cancelRoomKeyRequest:@{
@"algorithm": content[@"algorithm"],
@"room_id": content[@"room_id"],
@"session_id": content[@"session_id"],
@"sender_key": senderKey
@"algorithm": keyInfo.algorithm,
@"room_id": keyInfo.roomId,
@"session_id": keyInfo.sessionId,
@"sender_key": keyInfo.senderKey
}];
}
}];
Expand Down
1 change: 1 addition & 0 deletions MatrixSDK/Crypto/Algorithms/Megolm/MXMegolmEncryption.m
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ - (MXOutboundSessionInfo*)prepareNewSession
}
exportFormat:NO
sharedHistory:sharedHistory
untrusted:NO
];

[crypto.backup maybeSendKeyBackup];
Expand Down
5 changes: 5 additions & 0 deletions MatrixSDK/Crypto/Algorithms/Olm/MXOlmDecryption.m
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,11 @@ - (void)onRoomKeyEvent:(MXEvent *)event
// No impact for olm
}

- (void)onRoomKeyInfo:(MXRoomKeyInfo *)keyInfo
{
// No impact for olm
}

- (void)didImportRoomKey:(MXOlmInboundGroupSession *)session
{
// No impact for olm
Expand Down
5 changes: 0 additions & 5 deletions MatrixSDK/Crypto/KeyBackup/Data/MXKeyBackupVersionTrust.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ NS_ASSUME_NONNULL_BEGIN
*/
@property (nonatomic) NSArray<MXKeyBackupVersionTrustSignature*> *signatures;

/**
Flag indicating the backup trusted locally.
*/
@property (nonatomic, getter=isTrustedLocally) BOOL trustedLocally;

@end


Expand Down
1 change: 0 additions & 1 deletion MatrixSDK/Crypto/KeyBackup/Data/MXKeyBackupVersionTrust.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ - (instancetype)init
{
_usable = NO;
_signatures = [NSArray new];
_trustedLocally = NO;
}
return self;
}
Expand Down
Loading

0 comments on commit 4442142

Please sign in to comment.