crypto: Add configuration flag to enable invisible crypto (#3247)

This commit is contained in:
Valere
2024-09-18 17:30:45 +02:00
committed by GitHub
parent 5acfb5dd87
commit f7d878bac6
10 changed files with 44 additions and 27 deletions
+14 -1
View File
@@ -8,6 +8,12 @@
import Foundation
import SwiftUI
// Common settings between app and NSE
protocol CommonSettingsProtocol {
var logLevel: TracingConfiguration.LogLevel { get }
var invisibleCryptoEnabled: Bool { get }
}
/// Store Element specific app settings.
final class AppSettings {
private enum UserDefaultsKeys: String {
@@ -37,6 +43,7 @@ final class AppSettings {
case publicSearchEnabled
case fuzzyRoomListSearchEnabled
case pinningEnabled
case invisibleCryptoEnabled
}
private static var suiteName: String = InfoPlistReader.main.appGroupIdentifier
@@ -270,11 +277,17 @@ final class AppSettings {
enum SlidingSyncDiscovery: Codable { case proxy, native, forceNative }
@UserPreference(key: UserDefaultsKeys.slidingSyncDiscovery, defaultValue: .native, storageType: .userDefaults(store))
var slidingSyncDiscovery: SlidingSyncDiscovery
#endif
// MARK: - Shared
@UserPreference(key: UserDefaultsKeys.logLevel, defaultValue: TracingConfiguration.LogLevel.info, storageType: .userDefaults(store))
var logLevel
/// Configuration to enable invisible crypto. In this mode only devices signed by their owner will be considered in e2ee rooms.
@UserPreference(key: UserDefaultsKeys.invisibleCryptoEnabled, defaultValue: false, storageType: .userDefaults(store))
var invisibleCryptoEnabled
}
extension AppSettings: CommonSettingsProtocol { }
@@ -14,12 +14,12 @@ extension ClientBuilder {
httpProxy: String? = nil,
slidingSync: ClientBuilderSlidingSync,
sessionDelegate: ClientSessionDelegate,
appHooks: AppHooks) -> ClientBuilder {
appHooks: AppHooks,
invisibleCryptoEnabled: Bool) -> ClientBuilder {
var builder = ClientBuilder()
.enableCrossProcessRefreshLock(processId: InfoPlistReader.main.bundleIdentifier, sessionDelegate: sessionDelegate)
.userAgent(userAgent: UserAgentBuilder.makeASCIIUserAgent())
.requestConfig(config: .init(retryLimit: 0, timeout: 30000, maxConcurrentRequests: nil, retryTimeout: nil))
.roomKeyRecipientStrategy(strategy: .deviceBasedStrategy(onlyAllowTrustedDevices: false, errorOnVerifiedUserProblem: true))
builder = switch slidingSync {
case .restored: builder
@@ -33,6 +33,12 @@ extension ClientBuilder {
.autoEnableCrossSigning(autoEnableCrossSigning: true)
.backupDownloadStrategy(backupDownloadStrategy: .afterDecryptionFailure)
.autoEnableBackups(autoEnableBackups: true)
if invisibleCryptoEnabled {
builder = builder.roomKeyRecipientStrategy(strategy: CollectStrategy.identityBasedStrategy)
} else {
builder = builder.roomKeyRecipientStrategy(strategy: .deviceBasedStrategy(onlyAllowTrustedDevices: false, errorOnVerifiedUserProblem: true))
}
}
if let httpProxy {
@@ -47,6 +47,7 @@ protocol DeveloperOptionsProtocol: AnyObject {
var elementCallBaseURLOverride: URL? { get set }
var fuzzyRoomListSearchEnabled: Bool { get set }
var pinningEnabled: Bool { get set }
var invisibleCryptoEnabled: Bool { get set }
}
extension AppSettings: DeveloperOptionsProtocol { }
@@ -52,6 +52,17 @@ struct DeveloperOptionsScreen: View {
}
}
Section {
Toggle(isOn: $context.invisibleCryptoEnabled) {
Text("Enabled Invisible Crypto")
Text("Requires app reboot")
}
} header: {
Text("Trust and Decoration")
} footer: {
Text("This setting controls how end-to-end encryption (E2EE) keys are shared. Enabling it will prevent the inclusion of devices that have not been explicitly verified by their owners.")
}
Section {
TextField(context.viewState.elementCallBaseURL.absoluteString, text: $elementCallURLOverrideString)
.autocorrectionDisabled(true)
@@ -69,7 +69,8 @@ struct AuthenticationClientBuilder {
.baseBuilder(httpProxy: appSettings.websiteURL.globalProxy,
slidingSync: slidingSync,
sessionDelegate: clientSessionDelegate,
appHooks: appHooks)
appHooks: appHooks,
invisibleCryptoEnabled: appSettings.invisibleCryptoEnabled)
.sessionPaths(dataPath: sessionDirectories.dataPath,
cachePath: sessionDirectories.cachePath)
.passphrase(passphrase: passphrase)
@@ -124,7 +124,8 @@ class UserSessionStore: UserSessionStoreProtocol {
.baseBuilder(httpProxy: URL(string: homeserverURL)?.globalProxy,
slidingSync: .restored,
sessionDelegate: keychainController,
appHooks: appHooks)
appHooks: appHooks,
invisibleCryptoEnabled: appSettings.enableNotifications)
.sessionPaths(dataPath: credentials.restorationToken.sessionDirectories.dataPath,
cachePath: credentials.restorationToken.sessionDirectories.cachePath)
.username(username: credentials.userID)