Skip to content

Commit

Permalink
Merge pull request #1735 from matrix-org/andy/legacy_store
Browse files Browse the repository at this point in the history
Fully deprecate MXCryptoStore
  • Loading branch information
Anderas authored Mar 14, 2023
2 parents 0d2d53e + 6ed38f6 commit efdf2f4
Show file tree
Hide file tree
Showing 25 changed files with 670 additions and 163 deletions.
2 changes: 1 addition & 1 deletion MatrixSDK.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Pod::Spec.new do |s|
ss.dependency 'OLMKit', '~> 3.2.5'
ss.dependency 'Realm', '10.27.0'
ss.dependency 'libbase58', '~> 0.1.4'
ss.dependency 'MatrixSDKCrypto', '0.2.1', :configurations => ["DEBUG", "RELEASE"], :inhibit_warnings => true
ss.dependency 'MatrixSDKCrypto', '0.3.0', :configurations => ["DEBUG", "RELEASE"], :inhibit_warnings => true
end

s.subspec 'JingleCallStack' do |ss|
Expand Down
62 changes: 44 additions & 18 deletions MatrixSDK.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

47 changes: 14 additions & 33 deletions MatrixSDK/Crypto/Algorithms/RoomEvent/MXRoomEventEncryption.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,24 +47,19 @@ struct MXRoomEventEncryption: MXRoomEventEncrypting {
private static let keyRotationPeriodSec: Int = 7 * 24 * 3600 // Rotate room keys each week

private let handler: MXCryptoRoomEventEncrypting
private let legacyStore: MXCryptoStore
private let getRoomAction: GetRoomAction
private let log = MXNamedLog(name: "MXRoomEventEncryption")

init(
handler: MXCryptoRoomEventEncrypting,
legacyStore: MXCryptoStore,
getRoomAction: @escaping GetRoomAction
) {
self.handler = handler
self.legacyStore = legacyStore
self.getRoomAction = getRoomAction
}

func isRoomEncrypted(roomId: String) -> Bool {
// State of room encryption is not yet implemented in `MatrixSDKCrypto`
// Will be moved to `MatrixSDKCrypto` eventually
return legacyStore.algorithm(forRoom: roomId) != nil
return handler.roomSettings(roomId: roomId)?.algorithm != nil
}

func ensureRoomKeysShared(roomId: String) async throws {
Expand Down Expand Up @@ -144,37 +139,23 @@ struct MXRoomEventEncryption: MXRoomEventEncrypting {

/// Make sure that we recognize (and store if necessary) the claimed room encryption algorithm
private func ensureRoomEncryption(roomId: String, algorithm: String?) throws {
let existingAlgorithm = legacyStore.algorithm(forRoom: roomId)
if existingAlgorithm != nil && existingAlgorithm == algorithm {
// Encryption in room is already set to the correct algorithm
return
}
log.debug("Attempting to set algorithm to \(algorithm ?? "empty")")

guard let algorithm = algorithm else {
if existingAlgorithm != nil {
log.error("Resetting encryption is not allowed")
return
do {
let algorithm = try EventEncryptionAlgorithm(string: algorithm)
try handler.setRoomAlgorithm(roomId: roomId, algorithm: algorithm)
} catch {
if let existing = handler.roomSettings(roomId: roomId)?.algorithm {
log.error("Failed to set algorithm, but another room algorithm already stored", context: [
"existing": existing,
"new": algorithm ?? "empty"
])
} else {
throw Error.invalidEncryptionAlgorithm
log.error("Failed to set algorithm", context: error)
throw error
}
}

let supportedAlgorithms = Set([kMXCryptoMegolmAlgorithm])
guard supportedAlgorithms.contains(algorithm) else {
log.error("Ignoring invalid room algorithm", context: [
"room_id": roomId,
"algorithm": algorithm
])
throw Error.invalidEncryptionAlgorithm
}

if let existing = existingAlgorithm, existing != algorithm {
log.warning("New m.room.encryption event in \(roomId) with an algorithm change from \(existing) to \(algorithm)")
} else {
log.debug("New m.room.encryption event with algorithm \(algorithm)")
}

legacyStore.storeAlgorithm(forRoom: roomId, algorithm: algorithm)
}

/// Get user ids for all room members that should be able to decrypt events, based on the history visibility setting
Expand Down Expand Up @@ -208,7 +189,7 @@ struct MXRoomEventEncryption: MXRoomEventEncrypting {
}

private func onlyTrustedDevices(in roomId: String) -> Bool {
return legacyStore.globalBlacklistUnverifiedDevices || legacyStore.blacklistUnverifiedDevices(inRoom: roomId)
return handler.onlyAllowTrustedDevices || handler.roomSettings(roomId: roomId)?.onlyAllowTrustedDevices == true
}

private func room(for roomId: String) throws -> MXRoom {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// 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
import MatrixSDKCrypto

extension EventEncryptionAlgorithm {
enum Error: Swift.Error {
case cannotResetEncryption
case invalidAlgorithm
}

init(string: String?) throws {
guard let string = string else {
throw Error.cannotResetEncryption
}

switch string {
case kMXCryptoOlmAlgorithm:
self = .olmV1Curve25519AesSha2
case kMXCryptoMegolmAlgorithm:
self = .megolmV1AesSha2
default:
throw Error.invalidAlgorithm
}
}
}
37 changes: 36 additions & 1 deletion MatrixSDK/Crypto/CryptoMachine/MXCryptoMachine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,24 @@ extension MXCryptoMachine: MXCryptoUserIdentitySource {
}

extension MXCryptoMachine: MXCryptoRoomEventEncrypting {
var onlyAllowTrustedDevices: Bool {
get {
do {
return try machine.getOnlyAllowTrustedDevices()
} catch {
log.error("Failed getting value", context: error)
return false
}
}
set {
do {
try machine.setOnlyAllowTrustedDevices(onlyAllowTrustedDevices: newValue)
} catch {
log.error("Failed setting value", context: error)
}
}
}

func isUserTracked(userId: String) -> Bool {
do {
return try machine.isUserTracked(userId: userId)
Expand All @@ -381,6 +399,23 @@ extension MXCryptoMachine: MXCryptoRoomEventEncrypting {
}
}

func roomSettings(roomId: String) -> RoomSettings? {
do {
return try machine.getRoomSettings(roomId: roomId)
} catch {
log.error("Failed getting room settings", context: error)
return nil
}
}

func setRoomAlgorithm(roomId: String, algorithm: EventEncryptionAlgorithm) throws {
try machine.setRoomAlgorithm(roomId: roomId, algorithm: algorithm)
}

func setOnlyAllowTrustedDevices(for roomId: String, onlyAllowTrustedDevices: Bool) throws {
try machine.setRoomOnlyAllowTrustedDevices(roomId: roomId, onlyAllowTrustedDevices: onlyAllowTrustedDevices)
}

func shareRoomKeysIfNecessary(
roomId: String,
users: [String],
Expand Down Expand Up @@ -478,7 +513,7 @@ extension MXCryptoMachine: MXCryptoRoomEventDecrypting {
roomId: roomId,
// Handling verification events automatically during event decryption is now a deprecated behavior,
// all verification events are handled manually via `receiveVerificationEvent`
handleVerificatonEvents: false
handleVerificationEvents: false
)
}

Expand Down
5 changes: 5 additions & 0 deletions MatrixSDK/Crypto/CryptoMachine/MXCryptoProtocols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,13 @@ protocol MXCryptoUserIdentitySource: MXCryptoIdentity {

/// Room event encryption
protocol MXCryptoRoomEventEncrypting: MXCryptoIdentity {
var onlyAllowTrustedDevices: Bool { get set }

func isUserTracked(userId: String) -> Bool
func updateTrackedUsers(_ users: [String])
func roomSettings(roomId: String) -> RoomSettings?
func setRoomAlgorithm(roomId: String, algorithm: EventEncryptionAlgorithm) throws
func setOnlyAllowTrustedDevices(for roomId: String, onlyAllowTrustedDevices: Bool) throws
func shareRoomKeysIfNecessary(roomId: String, users: [String], settings: EncryptionSettings) async throws
func encryptRoomEvent(content: [AnyHashable: Any], roomId: String, eventType: String) throws -> [String: Any]
func discardRoomKey(roomId: String)
Expand Down
46 changes: 46 additions & 0 deletions MatrixSDK/Crypto/Data/MXRoomSettings.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// 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

// Object containing stored room settings, such as algorithm used
// and additional crypto options
@objc public class MXRoomSettings: NSObject {
enum Error: Swift.Error {
case missingParameters
}

public let roomId: String
public let algorithm: String
public let blacklistUnverifiedDevices: Bool

@objc public init(
roomId: String!,
algorithm: String!,
blacklistUnverifiedDevices: Bool
) throws {
guard
let roomId = roomId,
let algorithm = algorithm
else {
throw Error.missingParameters
}

self.roomId = roomId
self.algorithm = algorithm
self.blacklistUnverifiedDevices = blacklistUnverifiedDevices
}
}
6 changes: 6 additions & 0 deletions MatrixSDK/Crypto/Data/Store/MXCryptoStore.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

@class OLMAccount;
@class OLMOutboundGroupSession;
@class MXRoomSettings;

/**
The `MXCryptoStore` protocol defines an interface that must be implemented in order to store
Expand Down Expand Up @@ -247,6 +248,11 @@
*/
- (NSString*)algorithmForRoom:(NSString*)roomId;

/**
Fetch all stored room settings, containing room algorithm and other crypto options
*/
- (NSArray <MXRoomSettings *> *)roomSettings;

/**
Store a session between this device and another device.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,23 @@ - (MXRealmRoomAlgorithm *)realmRoomAlgorithmForRoom:(NSString*)roomId inRealm:(R
return [MXRealmRoomAlgorithm objectInRealm:realm forPrimaryKey:roomId];
}

- (NSArray<MXRealmRoomAlgorithm *> *)roomSettings
{
NSMutableArray *objects = [NSMutableArray array];
for (MXRealmRoomAlgorithm *item in [MXRealmRoomAlgorithm allObjectsInRealm:self.realm]) {
NSError *error = nil;
MXRoomSettings *settings = [[MXRoomSettings alloc] initWithRoomId:item.roomId
algorithm:item.algorithm
blacklistUnverifiedDevices:item.blacklistUnverifiedDevices
error:&error];
if (settings) {
[objects addObject:settings];
} else {
MXLogErrorDetails(@"[MXRealmCryptoStore] roomSettings: Cannot create settings", error);
}
}
return objects.copy;
}

- (void)storeSession:(MXOlmSession*)session
{
Expand Down
18 changes: 9 additions & 9 deletions MatrixSDK/Crypto/MXCryptoV2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class MXCryptoV2: NSObject, MXCrypto {
// MARK: - Private properties

private weak var session: MXSession?
private let legacyStore: MXCryptoStore

private let machine: MXCryptoMachine
private let encryptor: MXRoomEventEncrypting
Expand Down Expand Up @@ -69,11 +68,9 @@ class MXCryptoV2: NSObject, MXCrypto {
userId: String,
deviceId: String,
session: MXSession,
restClient: MXRestClient,
legacyStore: MXCryptoStore
restClient: MXRestClient
) throws {
self.session = session
self.legacyStore = legacyStore

let getRoomAction: (String) -> MXRoom? = { [weak session] in
session?.room(withRoomId: $0)
Expand All @@ -88,7 +85,6 @@ class MXCryptoV2: NSObject, MXCrypto {

encryptor = MXRoomEventEncryption(
handler: machine,
legacyStore: legacyStore,
getRoomAction: getRoomAction
)
decryptor = MXRoomEventDecryption(handler: machine)
Expand Down Expand Up @@ -599,19 +595,23 @@ class MXCryptoV2: NSObject, MXCrypto {

public var globalBlacklistUnverifiedDevices: Bool {
get {
return legacyStore.globalBlacklistUnverifiedDevices
return machine.onlyAllowTrustedDevices
}
set {
legacyStore.globalBlacklistUnverifiedDevices = newValue
machine.onlyAllowTrustedDevices = newValue
}
}

public func isBlacklistUnverifiedDevices(inRoom roomId: String) -> Bool {
return legacyStore.blacklistUnverifiedDevices(inRoom: roomId)
return machine.roomSettings(roomId: roomId)?.onlyAllowTrustedDevices == true
}

public func setBlacklistUnverifiedDevicesInRoom(_ roomId: String, blacklist: Bool) {
legacyStore.storeBlacklistUnverifiedDevices(inRoom: roomId, blacklist: blacklist)
do {
try machine.setOnlyAllowTrustedDevices(for: roomId, onlyAllowTrustedDevices: blacklist)
} catch {
log.error("Failed blocking unverified devices", context: error)
}
}

// MARK: - Private
Expand Down
Loading

0 comments on commit efdf2f4

Please sign in to comment.