Skip to content

Commit

Permalink
Control CryptoSDK via feature flag
Browse files Browse the repository at this point in the history
  • Loading branch information
Anderas committed Feb 15, 2023
1 parent a58ad16 commit 87f739f
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 49 deletions.
6 changes: 6 additions & 0 deletions MatrixSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -2025,6 +2025,8 @@
EDC8C4092968A993003792C5 /* MXKeysQueryScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDC8C4072968A993003792C5 /* MXKeysQueryScheduler.swift */; };
EDC8C40D2968C37E003792C5 /* MXKeysQuerySchedulerUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDC8C40A2968A9F7003792C5 /* MXKeysQuerySchedulerUnitTests.swift */; };
EDC8C40E2968C37F003792C5 /* MXKeysQuerySchedulerUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDC8C40A2968A9F7003792C5 /* MXKeysQuerySchedulerUnitTests.swift */; };
EDCAD251299BF7F40088B4DA /* MXCryptoV2Feature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDCAD250299BF7F40088B4DA /* MXCryptoV2Feature.swift */; };
EDCAD252299BF7F40088B4DA /* MXCryptoV2Feature.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDCAD250299BF7F40088B4DA /* MXCryptoV2Feature.swift */; };
EDCB65E22912AB0C00F55D4D /* MXRoomEventDecryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDCB65E12912AB0C00F55D4D /* MXRoomEventDecryption.swift */; };
EDCB65E32912AB0C00F55D4D /* MXRoomEventDecryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDCB65E12912AB0C00F55D4D /* MXRoomEventDecryption.swift */; };
EDCF802D2941FF220059E774 /* MXCryptoMigrationV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDCF802C2941FF220059E774 /* MXCryptoMigrationV2.swift */; };
Expand Down Expand Up @@ -3171,6 +3173,7 @@
EDC2A0E528369E740039F3D6 /* CryptoTests.xctestplan */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = CryptoTests.xctestplan; sourceTree = "<group>"; };
EDC8C4072968A993003792C5 /* MXKeysQueryScheduler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXKeysQueryScheduler.swift; sourceTree = "<group>"; };
EDC8C40A2968A9F7003792C5 /* MXKeysQuerySchedulerUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXKeysQuerySchedulerUnitTests.swift; sourceTree = "<group>"; };
EDCAD250299BF7F40088B4DA /* MXCryptoV2Feature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXCryptoV2Feature.swift; sourceTree = "<group>"; };
EDCB65E12912AB0C00F55D4D /* MXRoomEventDecryption.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXRoomEventDecryption.swift; sourceTree = "<group>"; };
EDCF802C2941FF220059E774 /* MXCryptoMigrationV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXCryptoMigrationV2.swift; sourceTree = "<group>"; };
EDD4197D28DCAA5F007F3757 /* MXNativeKeyBackupEngine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MXNativeKeyBackupEngine.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3525,6 +3528,7 @@
322A51B41D9AB15900C8536D /* MXCrypto.h */,
322A51B51D9AB15900C8536D /* MXCrypto.m */,
ED47CB6C28523995004FD755 /* MXCryptoV2.swift */,
EDCAD250299BF7F40088B4DA /* MXCryptoV2Feature.swift */,
ED5EF151297AB33E00A5ADDA /* MXCryptoV2Factory.swift */,
325D1C251DFECE0D0070B8BF /* MXCrypto_Private.h */,
322A51C51D9BBD3C00C8536D /* MXOlmDevice.h */,
Expand Down Expand Up @@ -7142,6 +7146,7 @@
EC2EACFF266625170038B61F /* MXRoomLastMessage.m in Sources */,
EDF1B6902876CD2C00BBBCEE /* MXTaskQueue.swift in Sources */,
EC8A539525B1BC77004E0802 /* MXUserModel.m in Sources */,
EDCAD251299BF7F40088B4DA /* MXCryptoV2Feature.swift in Sources */,
ED5EF14F297AB29F00A5ADDA /* MXEventDecryptionResult+DecryptedEvent.swift in Sources */,
3252DCAF224BE5D40032264F /* MXKeyVerificationManager.m in Sources */,
323E0C5C1A306D7A00A31D73 /* MXEvent.m in Sources */,
Expand Down Expand Up @@ -7809,6 +7814,7 @@
EC8A53D925B1BCC6004E0802 /* MXThirdPartyProtocolInstance.m in Sources */,
EDF1B6912876CD2C00BBBCEE /* MXTaskQueue.swift in Sources */,
B14EF2422397E90400758AF0 /* MXDeviceInfo.m in Sources */,
EDCAD252299BF7F40088B4DA /* MXCryptoV2Feature.swift in Sources */,
ED5EF150297AB29F00A5ADDA /* MXEventDecryptionResult+DecryptedEvent.swift in Sources */,
B14EF2432397E90400758AF0 /* MXIncomingSASTransaction.m in Sources */,
B14EF2442397E90400758AF0 /* NSObject+sortedKeys.m in Sources */,
Expand Down
22 changes: 13 additions & 9 deletions MatrixSDK/Background/MXBackgroundSyncService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,12 @@ public enum MXBackgroundSyncServiceError: Error {

/// Initializer
/// - Parameter credentials: account credentials
public init(withCredentials credentials: MXCredentials, persistTokenDataHandler: MXRestClientPersistTokenDataHandler? = nil, unauthenticatedHandler: MXRestClientUnauthenticatedHandler? = nil) {
public init(
withCredentials credentials: MXCredentials,
isCryptoSDKEnabled: Bool = false,
persistTokenDataHandler: MXRestClientPersistTokenDataHandler? = nil,
unauthenticatedHandler: MXRestClientUnauthenticatedHandler? = nil
) {
processingQueue = DispatchQueue(label: "MXBackgroundSyncServiceQueue-" + MXTools.generateSecret())
self.credentials = credentials

Expand All @@ -88,14 +93,13 @@ public enum MXBackgroundSyncServiceError: Error {
// We can flush any crypto data if our sync response store is empty
let resetBackgroundCryptoStore = syncResponseStoreManager.syncToken() == nil

crypto = {
if MXSDKOptions.sharedInstance().isCryptoSDKAvailable && MXSDKOptions.sharedInstance().enableCryptoSDK {
return MXBackgroundCryptoV2(credentials: credentials, restClient: restClient)
}

MXLog.debug("[MXBackgroundSyncService] init: constructing legacy crypto \(MXSDKOptions.sharedInstance().isCryptoSDKAvailable) \(MXSDKOptions.sharedInstance().enableCryptoSDK)")
return MXLegacyBackgroundCrypto(credentials: credentials, resetBackgroundCryptoStore: resetBackgroundCryptoStore)
}()
if isCryptoSDKEnabled {
MXLog.debug("[MXBackgroundSyncService] init: constructing crypto v2")
crypto = MXBackgroundCryptoV2(credentials: credentials, restClient: restClient)
} else {
MXLog.debug("[MXBackgroundSyncService] init: constructing legacy crypto")
crypto = MXLegacyBackgroundCrypto(credentials: credentials, resetBackgroundCryptoStore: resetBackgroundCryptoStore)
}

pushRulesManager = MXBackgroundPushRulesManager(withCredentials: credentials)
MXLog.debug("[MXBackgroundSyncService] init complete")
Expand Down
36 changes: 14 additions & 22 deletions MatrixSDK/Crypto/MXCrypto.m
Original file line number Diff line number Diff line change
Expand Up @@ -150,25 +150,13 @@ @implementation MXLegacyCrypto
@synthesize keyVerificationManager = _keyVerificationManager;
@synthesize recoveryService = _recoveryService;

+ (MXCryptoV2Factory *)sharedCryptoV2Factory
{
static MXCryptoV2Factory *factory = nil;
static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{
factory = [[MXCryptoV2Factory alloc] init];
});

return factory;
}

+ (id<MXCrypto>)createCryptoWithMatrixSession:(MXSession *)mxSession
error:(NSError **)error
{
__block id<MXCrypto> crypto;

#ifdef MX_CRYPTO
if (MXSDKOptions.sharedInstance.isCryptoSDKAvailable && MXSDKOptions.sharedInstance.enableCryptoSDK)
if (MXSDKOptions.sharedInstance.enableCryptoSDK)
{
MXLogFailure(@"[MXCrypto] createCryptoWithMatrixSession: Crypto V2 should not be created directly, use initializeCryptoWithMatrixSession instead");
return nil;
Expand All @@ -192,15 +180,19 @@ + (void)initializeCryptoWithMatrixSession:(MXSession *)mxSession
complete:(void (^)(id<MXCrypto> crypto, NSError *error))complete
{
#ifdef MX_CRYPTO
if (MXSDKOptions.sharedInstance.isCryptoSDKAvailable && MXSDKOptions.sharedInstance.enableCryptoSDK)
{
MXCryptoV2Factory *factory = [MXLegacyCrypto sharedCryptoV2Factory];
[factory buildCryptoWithSession:mxSession migrationProgress:migrationProgress
success:^(id<MXCrypto> crypto) {
complete(crypto, nil);
} failure:^(NSError *error) {
complete(nil, error);
}];

// Each time we construct the crypto module (app launch, login etc) we have a chance to try to enable
// the newer SDK crypto module, if it is available for this particular user.
[MXSDKOptions.sharedInstance.cryptoSDKFeature enableIfAvailableForUserId:mxSession.myUserId];
if (MXSDKOptions.sharedInstance.enableCryptoSDK)
{
[MXCryptoV2Factory.shared buildCryptoWithSession:mxSession
migrationProgress:migrationProgress
success:^(id<MXCrypto> crypto) {
complete(crypto, nil); }
failure:^(NSError *error) {
complete(nil, error);
}];
return;
}

Expand Down
1 change: 1 addition & 0 deletions MatrixSDK/Crypto/MXCryptoV2Factory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Foundation
case storeNotAvailable
}

@objc public static let shared = MXCryptoV2Factory()
private let log = MXNamedLog(name: "MXCryptoV2Factory")

@objc public func buildCrypto(
Expand Down
45 changes: 45 additions & 0 deletions MatrixSDK/Crypto/MXCryptoV2Feature.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// Copyright 2023 The Matrix.org Foundation C.I.C
//
// 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 Foundation

/// Feature representing the availability of the external rust-based Crypto SDK
/// whilst it is not fully available to everyone and / or is an optional feature.
@objc public protocol MXCryptoV2Feature {

/// Is Crypto SDK currently enabled
///
/// By default this value is `false`. Once enabled, it can only be disabled by logging out,
/// as there is no way to migrate from from Crypto SDK back to legacy crypto.
var isEnabled: Bool { get }

/// Manually enable the feature
///
/// This is typically trigger by some user settings / Labs as an experimental feature. Once called
/// it should restart the session to re-initialize the crypto module.
func enable()

/// Try to enable the feature for a given user
///
/// This method should only be called when initializing a crypto module (e.g. during app launch or login),
/// as it is not possible to swap out crypto modules whilst a session is active.
///
/// The availability conditions are implementation details, typically consisting of
/// various feature flags.
///
/// If available, this method will set `isEnabled` permanently to `true`.
func enableIfAvailable(forUserId userId: String!)
}
21 changes: 8 additions & 13 deletions MatrixSDK/MXSDKOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ typedef NS_ENUM(NSUInteger, MXCallTransferType)

NS_ASSUME_NONNULL_BEGIN

@protocol MXBackgroundModeHandler;
@protocol MXBackgroundModeHandler, MXCryptoV2Feature;

/**
SDK options that can be set at the launch time.
Expand Down Expand Up @@ -204,23 +204,18 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic) BOOL enableRoomSharedHistoryOnInvite;

/**
The state of the rust-based `MatrixCryptoSDK` which replaces `MatrixSDK`'s internal crypto module,
and whether it is available to a user as an option.
An object which controls the availabilty of the rust-based `MatrixCryptoSDK`.
To control which crypto module is actually used, set `enableCryptoSDK`.
@remark NO by default.
@remark nil by default.
*/
@property (nonatomic) BOOL isCryptoSDKAvailable;
@property (nonatomic, nullable) id<MXCryptoV2Feature> cryptoSDKFeature;

/**
Use the rust-based `MatrixCryptoSDK` instead of `MatrixSDK`'s internal crypto module.
This option should only be enabled if `isCryptoSDKAvailable` is set to YES.
@remark NO by default.
@remark this property is a convenience getter for `cryptoSDKFeature.isEnabled`
*/
@property (nonatomic) BOOL enableCryptoSDK;
@property (nonatomic, readonly) BOOL enableCryptoSDK;

/**
Enable symmetric room key backups
Expand All @@ -240,9 +235,9 @@ NS_ASSUME_NONNULL_BEGIN
Enable the calculating of progress during session startup, incl counting the number
of attempts to sync with the server and percentage of response data processed.
@remark NO by default
@remark the value currently depends on `enableCryptoSDK` being `YES`
*/
@property (nonatomic) BOOL enableStartupProgress;
@property (nonatomic, readonly) BOOL enableStartupProgress;

@end

Expand Down
23 changes: 18 additions & 5 deletions MatrixSDK/MXSDKOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,31 @@ - (instancetype)init
_authEnableRefreshTokens = NO;
_enableThreads = NO;
_enableRoomSharedHistoryOnInvite = NO;

_isCryptoSDKAvailable = YES;
_enableCryptoSDK = NO;

_enableSymmetricBackup = NO;
_enableNewClientInformationFeature = NO;
_enableStartupProgress = NO;
}

return self;
}

- (BOOL)enableCryptoSDK
{
if (!self.cryptoSDKFeature)
{
MXLogError(@"[MXSDKOptions] enableCryptoSDK: Crypto SDK feature is not configured");
return NO;
}
return self.cryptoSDKFeature.isEnabled;
}

- (BOOL)enableStartupProgress
{
// The value of `enableStartupProgress` depends on `enableCryptoSDK` as the latter provides some new UX elements
// such as initial data migration. It is a good opportunity to enable startup progress as well, before it becomes
// default to all.
return self.enableCryptoSDK;
}

- (void)setRoomListDataManagerClass:(Class)roomListDataManagerClass
{
// Sanity check
Expand Down
1 change: 1 addition & 0 deletions changelog.d/pr-1719.change
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CryptoV2: Control CryptoSDK via feature flag

0 comments on commit 87f739f

Please sign in to comment.