Skip to content

Commit 421333b

Browse files
committed
v3.0 (793)
1 parent 137ed1e commit 421333b

File tree

266 files changed

+10092
-2484
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

266 files changed

+10092
-2484
lines changed

CHANGELOG.en.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Changelog
22

3+
## [3.0 (793)] - 2024-06-28
4+
5+
- Reliability Boost: Significant improvements in multi-device settings, ensuring a smoother experience across all devices.
6+
- Instant Connections: When adding a new contact, you can now start chatting immediately, with no waiting time whatsoever.
7+
- URL Preview Refinement: When a preview is available, URLs at the end of messages are now hidden.
8+
- Read Message Sync: Fixed an issue where messages marked as read on one device would incorrectly remain unread on other devices.
9+
- Secure Call Stability: Resolved a rare issue with secure calls in multi-device settings, where calls could occasionally hang up after 30 seconds.
10+
- Enhanced Notification Reliability: Improved notifications for messages received in recently joined groups, ensuring consistent delivery across all devices.
11+
- Draft Fix: Resolved an issue where drafts with attachments but no text couldn't be sent using the keyboard shortcut.
12+
- Multi-Device Discussion Deletion: Fixed various issues related to deleting discussions across multiple devices.
13+
- Admin Preserved in Group Cloning: Cloning a group now retains the admin's chosen settings.
14+
- Duration Display and Modification Fix: Fixed a bug preventing the display and modification of existence or visibility durations outside of enum values.
15+
- Database Migration Recovery: Improved strategies to recover from certain database migration errors.
16+
- Miscellaneous Improvements and Bug Fixes: Various minor enhancements and bug fixes to further enhance the overall user experience.
17+
18+
## [2.5 (782)] - 2024-06-06
19+
20+
- Resolved an intermittent issue with profile transfers from other devices.
21+
- Enhanced the cryptographic library.
22+
- Various minor improvements and bug fixes.
23+
324
## [2.4 (778)] - 2024-06-03
425

526
### macOS

CHANGELOG.fr.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Changelog
22

3+
## [3.0 (793)] - 2024-06-28
4+
5+
- Amélioration de la fiabilité: Des améliorations significatives dans les paramètres multi-appareils, garantissant une expérience plus fluide sur tous les appareils.
6+
- Connexions instantanées: Lors de l'ajout d'un nouveau contact, vous pouvez maintenant démarrer une conversation immédiatement, sans délai aucun.
7+
- Raffinement de l'aperçu URL: Lorsqu'un prévisualisation est disponible, les URLs en fin des messages sont maintenant cachées.
8+
- Synchronisation des messages lus: Correction d'un problème où les messages marqués comme lus sur un appareil restaient incorrectement non lus sur d'autres appareils.
9+
- Stabilité des appels sécurisés: Résolution d'un problème rare avec les appels sécurisés dans les paramètres multi-appareils, où les appels pouvaient occasionnellement être coupés après 30 secondes.
10+
- Fiabilité améliorée des notifications: Amélioration des notifications pour les messages reçus dans les groupes récemment joints, garantissant une livraison cohérente sur tous les appareils.
11+
- Correction de brouillon: Résolution d'un problème où les brouillons avec des pièces jointes mais sans texte ne pouvaient pas être envoyés à l'aide du raccourci clavier.
12+
- Suppression de discussion multi-appareil: Correction de divers problèmes liés à la suppression de discussions sur plusieurs appareils.
13+
- Administrateur préservé lors du clonage de groupe: Le clonage d'un groupe conserve maintenant les paramètres choisis par l'administrateur.
14+
- Correction de l'affichage et de la modification des durées: Correction d'un bug empêchant l'affichage et la modification des durées d'existence ou de visibilité en dehors des valeurs énumérées.
15+
- Récupération après erreur de migration de base de données: Amélioration des stratégies pour récupérer d'éventuelles erreurs de migration de base de données.
16+
- Autres améliorations et corrections de bugs mineures: Diverses améliorations et corrections de bugs mineures pour améliorer l'expérience utilisateur globale.
17+
18+
## [2.5 (782)] - 2024-06-06
19+
20+
- Résolution d'un problème intermittent lors du transfert d'un profil depuis un autre appareil.
21+
- Amélioration de la bibliothèque cryptographique.
22+
- Diverses améliorations mineures et corrections de bugs.
23+
324
## [2.4 (778)] - 2024-05-31
425

526
### macOS

Engine/BigInt/BigInt/BigInt/BigInt.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,10 @@ final public class BigInt: Comparable, Hashable, CustomDebugStringConvertible, D
395395
public func isNonNegative() -> Bool {
396396
return self.readVal._mp_size >= 0
397397
}
398+
399+
public func isPositive() -> Bool {
400+
return self.readVal._mp_size > 0
401+
}
398402

399403
public class func cmp(op1: BigInt, op2: BigInt) -> Int {
400404
return Int(__gmpz_cmp(&op1.readVal, &op2.readVal))

Engine/ObvBackupManager/ObvBackupManager/ObvBackupManagerImplementation.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,10 @@ extension ObvBackupManagerImplementation {
609609

610610
os_log("Encrypting the full backup for backupRequestIdentifier %{public}@", log: log, type: .info, backupRequestIdentifier.description)
611611

612-
let encryptedBackup = PublicKeyEncryption.encrypt(fullBackupData, using: derivedKeysForBackup.publicKeyForEncryption, and: prng)
612+
guard let encryptedBackup = PublicKeyEncryption.encrypt(fullBackupData, using: derivedKeysForBackup.publicKeyForEncryption, and: prng) else {
613+
assertionFailure()
614+
throw Self.makeError(message: "Failed to encrypt full backup data")
615+
}
613616
let macOfEncryptedBackup = try MAC.compute(forData: encryptedBackup, withKey: derivedKeysForBackup.macKey)
614617
let authenticatedEncryptedBackup = EncryptedData(data: encryptedBackup.raw + macOfEncryptedBackup)
615618

Engine/ObvChannelManager/ObvChannelManager/ChannelTypes/ObvAsymmetricChannel.swift

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ final class ObvAsymmetricChannel: ObvNetworkChannel {
4747
// MARK: Init
4848

4949
init(to identity: ObvCryptoIdentity, deviceUid: UID, delegateManager: ObvChannelDelegateManager) throws {
50-
guard let delegate = delegateManager.keyWrapperForIdentityDelegate else {
51-
throw ObvAsymmetricChannel.makeError(message: "The key wrapper delegate is not set")
50+
guard let delegate = delegateManager.keyWrapperForIdentityDelegate else {
51+
assertionFailure()
52+
throw ObvError.keyWrapperForIdentityDelegateIsNil
5253
}
5354
self.keyWrapperForIdentityDelegate = delegate
5455
self.identity = identity
@@ -59,26 +60,38 @@ final class ObvAsymmetricChannel: ObvNetworkChannel {
5960

6061
// MARK: Encryption/Wrapping method and helpers
6162

62-
func wrapMessageKey(_ messageKey: AuthenticatedEncryptionKey, randomizedWith prng: PRNGService) -> ObvNetworkMessageToSend.Header {
63-
let wrappedMessageKey = keyWrapperForIdentityDelegate.wrap(messageKey, for: identity, randomizedWith: prng)
63+
func wrapMessageKey(_ messageKey: AuthenticatedEncryptionKey, randomizedWith prng: PRNGService) -> ObvNetworkMessageToSend.Header? {
64+
guard let wrappedMessageKey = keyWrapperForIdentityDelegate.wrap(messageKey, for: identity, randomizedWith: prng) else {
65+
assertionFailure()
66+
return nil
67+
}
6468
let header = ObvNetworkMessageToSend.Header(toIdentity: identity, deviceUid: deviceUid, wrappedMessageKey: wrappedMessageKey)
6569
return header
6670
}
6771

6872
// MARK: Decryption/Unwrapping method and helpers
6973

70-
static func unwrapMessageKey(wrappedKey: EncryptedData, toOwnedIdentity: ObvCryptoIdentity, delegateManager: ObvChannelDelegateManager, within obvContext: ObvContext) -> (AuthenticatedEncryptionKey, ObvProtocolReceptionChannelInfo)? {
74+
static func unwrapMessageKey(wrappedKey: EncryptedData, toOwnedIdentity: ObvCryptoIdentity, delegateManager: ObvChannelDelegateManager, within obvContext: ObvContext) throws -> UnwrapMessageKeyResult {
7175

7276
let log = OSLog(subsystem: delegateManager.logSubsystem, category: ObvAsymmetricChannel.logCategory)
7377

7478
guard let keyWrapperForIdentityDelegate = delegateManager.keyWrapperForIdentityDelegate else {
7579
os_log("The key wrapper for identity delegate is not set", log: log, type: .fault)
76-
return nil
80+
assertionFailure()
81+
throw ObvError.keyWrapperForIdentityDelegateIsNil
7782
}
7883

79-
guard let messageKey = keyWrapperForIdentityDelegate.unwrap(wrappedKey, for: toOwnedIdentity, within: obvContext) else { return nil }
80-
return (messageKey, ObvProtocolReceptionChannelInfo.AsymmetricChannel)
84+
guard let messageKey = keyWrapperForIdentityDelegate.unwrap(wrappedKey, for: toOwnedIdentity, within: obvContext) else { return .couldNotUnwrap }
85+
return .unwrapSucceeded(messageKey: messageKey,
86+
receptionChannelInfo: .asymmetricChannel,
87+
updateOrCheckGKMV2SupportOnMessageContentAvailable: nil)
8188
}
89+
90+
91+
enum ObvError: Error {
92+
case keyWrapperForIdentityDelegateIsNil
93+
}
94+
8295
}
8396

8497
extension ObvAsymmetricChannel {
@@ -91,7 +104,7 @@ extension ObvAsymmetricChannel {
91104

92105
switch message.channelType {
93106

94-
case .AsymmetricChannel(to: let toIdentity, remoteDeviceUids: let remoteDeviceUids, fromOwnedIdentity: _):
107+
case .asymmetricChannel(to: let toIdentity, remoteDeviceUids: let remoteDeviceUids, fromOwnedIdentity: _):
95108
// Only protocol messages may be sent through AsymmetricChannel channels
96109
guard message.messageType == .ProtocolMessage else {
97110
throw ObvAsymmetricChannel.makeError(message: "Only protocol messages may be sent through AsymmetricChannel channels")
@@ -101,7 +114,7 @@ extension ObvAsymmetricChannel {
101114
try ObvAsymmetricChannel(to: toIdentity, deviceUid: $0, delegateManager: delegateManager)
102115
}
103116

104-
case .AsymmetricChannelBroadcast(to: let toIdentity, fromOwnedIdentity: _):
117+
case .asymmetricChannelBroadcast(to: let toIdentity, fromOwnedIdentity: _):
105118
// Only protocol messages may be sent through AsymmetricChannel channels
106119
guard message.messageType == .ProtocolMessage else {
107120
throw ObvAsymmetricChannel.makeError(message: "Only protocol messages may be sent through AsymmetricChannel channels")

Engine/ObvChannelManager/ObvChannelManager/ChannelTypes/ObvChannel.swift

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Olvid for iOS
3-
* Copyright © 2019-2022 Olvid SAS
3+
* Copyright © 2019-2024 Olvid SAS
44
*
55
* This file is part of Olvid for iOS.
66
*
@@ -36,14 +36,26 @@ protocol ObvChannel {
3636

3737
}
3838

39+
/// Only relevant for an `ObvObliviousChannel`.
40+
typealias UpdateGKMV2SupportOnMessageContentAvailable = (Data) throws -> Void
41+
3942
protocol ObvNetworkChannel: ObvChannel {
4043

41-
func wrapMessageKey(_ messageKey: AuthenticatedEncryptionKey, randomizedWith prng: PRNGService) -> ObvNetworkMessageToSend.Header
44+
func wrapMessageKey(_ messageKey: AuthenticatedEncryptionKey, randomizedWith prng: PRNGService) -> ObvNetworkMessageToSend.Header?
4245

43-
static func unwrapMessageKey(wrappedKey: EncryptedData, toOwnedIdentity: ObvCryptoIdentity, delegateManager: ObvChannelDelegateManager, within obvContext: ObvContext) throws -> (AuthenticatedEncryptionKey, ObvProtocolReceptionChannelInfo)?
46+
static func unwrapMessageKey(wrappedKey: EncryptedData, toOwnedIdentity: ObvCryptoIdentity, delegateManager: ObvChannelDelegateManager, within obvContext: ObvContext) throws -> UnwrapMessageKeyResult
4447

4548
}
4649

50+
51+
enum UnwrapMessageKeyResult {
52+
case unwrapSucceeded(messageKey: AuthenticatedEncryptionKey, receptionChannelInfo: ObvProtocolReceptionChannelInfo, updateOrCheckGKMV2SupportOnMessageContentAvailable: UpdateGKMV2SupportOnMessageContentAvailable?)
53+
case unwrapSucceededButRemoteCryptoIdIsUnknown(remoteCryptoIdentity: ObvCryptoIdentity) // Only used by PreKey channel
54+
case couldNotUnwrap
55+
case contactIsRevokedAsCompromised
56+
}
57+
58+
4759
extension ObvNetworkChannel {
4860

4961
private static var errorDomain: String { "ObvNetworkChannel" }
@@ -53,25 +65,15 @@ extension ObvNetworkChannel {
5365
return NSError(domain: errorDomain, code: 0, userInfo: userInfo)
5466
}
5567

56-
private static func generateMessageKeyAndHeaders(using acceptableChannels: [ObvNetworkChannel], randomizedWith prng: PRNGService) -> (AuthenticatedEncryptionKey, [ObvNetworkMessageToSend.Header])? {
57-
let cryptoSuiteVersion = acceptableChannels.reduce(ObvCryptoSuite.sharedInstance.latestVersion) { min($0, $1.cryptoSuiteVersion) }
58-
guard let authEnc = ObvCryptoSuite.sharedInstance.authenticatedEncryption(forSuiteVersion: cryptoSuiteVersion) else {
59-
return nil
60-
}
61-
let messageKey = authEnc.generateKey(with: prng)
62-
let headers = acceptableChannels.map { $0.wrapMessageKey(messageKey, randomizedWith: prng) }
63-
return (messageKey, headers)
64-
}
65-
6668
/// Generates one or more `ObvNetworkMessageToSend` for the given `ObvChannelMessageToSend`. The reasons why multiple messages can be returned is that we generate one message for server URL found in the destination identities.
67-
private static func generateObvNetworkMessagesToSend(from message: ObvChannelMessageToSend, messageKey: AuthenticatedEncryptionKey, headers: [ObvNetworkMessageToSend.Header], randomizedWith prng: PRNGService) throws -> [ObvNetworkMessageToSend] {
69+
private static func generateObvNetworkMessagesToSend(from message: ObvChannelMessageToSend, acceptableChannels: [ObvNetworkChannel], randomizedWith prng: PRNGService, log: OSLog) throws -> [ObvNetworkMessageToSend] {
6870

6971
let wrapperMessage: ObvChannelMessageToSendWrapper?
7072
switch message.messageType {
7173
case .ProtocolMessage:
72-
wrapperMessage = ObvChannelProtocolMessageToSendWrapper(message: message, messageKey: messageKey, headers: headers, randomizedWith: prng)
74+
wrapperMessage = ObvChannelProtocolMessageToSendWrapper(message: message, acceptableChannels: acceptableChannels, randomizedWith: prng, log: log)
7375
case .ApplicationMessage:
74-
wrapperMessage = ObvChannelApplicationMessageToSendWrapper(message: message, messageKey: messageKey, headers: headers, randomizedWith: prng)
76+
wrapperMessage = ObvChannelApplicationMessageToSendWrapper(message: message, acceptableChannels: acceptableChannels, randomizedWith: prng, log: log)
7577
case .DialogMessage,
7678
.DialogResponseMessage,
7779
.ServerQuery,
@@ -102,11 +104,7 @@ extension ObvNetworkChannel {
102104
return [:]
103105
}
104106

105-
guard let (messageKey, headers) = generateMessageKeyAndHeaders(using: acceptableChannels, randomizedWith: prng) else {
106-
throw Self.makeError(message: "Could not generate message key and headers")
107-
}
108-
109-
let networkMessages = try generateObvNetworkMessagesToSend(from: message, messageKey: messageKey, headers: headers, randomizedWith: prng)
107+
let networkMessages = try generateObvNetworkMessagesToSend(from: message, acceptableChannels: acceptableChannels, randomizedWith: prng, log: log)
110108
guard !networkMessages.isEmpty else {
111109
throw Self.makeError(message: "Could not generate obv network message to send")
112110
}

Engine/ObvChannelManager/ObvChannelManager/ChannelTypes/ObvLocalChannel.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ final class ObvLocalChannel: ObvChannel {
7979

8080
let receivedMessage = ObvProtocolReceivedMessage(messageId: messageId,
8181
timestamp: message.timestamp,
82-
receptionChannelInfo: .Local,
82+
receptionChannelInfo: .local,
8383
encodedElements: message.encodedElements)
8484

8585
os_log("Processing a posted protocol message with a (just created) messageId %{public}@", log: log, type: .info, messageId.debugDescription)
@@ -109,7 +109,7 @@ final class ObvLocalChannel: ObvChannel {
109109

110110
let receivedMessage = ObvProtocolReceivedDialogResponse(toOwnedIdentity: ownedIdentity,
111111
timestamp: message.timestamp,
112-
receptionChannelInfo: .Local,
112+
receptionChannelInfo: .local,
113113
encodedElements: message.encodedElements,
114114
encodedUserDialogResponse: message.encodedUserDialogResponse,
115115
dialogUuid: message.uuid)
@@ -131,7 +131,7 @@ final class ObvLocalChannel: ObvChannel {
131131

132132
let receivedMessage = ObvProtocolReceivedServerResponse(toOwnedIdentity: ownedIdentity,
133133
serverTimestamp: message.serverTimestamp,
134-
receptionChannelInfo: .Local,
134+
receptionChannelInfo: .local,
135135
encodedElements: message.encodedElements,
136136
serverResponseType: message.responseType)
137137

@@ -162,7 +162,7 @@ extension ObvLocalChannel {
162162
let acceptableChannels: [ObvChannel]
163163

164164
switch message.channelType {
165-
case .Local(ownedIdentity: let ownedIdentity):
165+
case .local(ownedIdentity: let ownedIdentity):
166166

167167
guard message.messageType == .ProtocolMessage || message.messageType == .DialogResponseMessage || message.messageType == .ServerResponse else {
168168
throw ObvLocalChannel.makeError(message: "Wrong message type")

Engine/ObvChannelManager/ObvChannelManager/ChannelTypes/ObvServerChannel.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ extension ObvServerChannel {
111111
serverQueryType = .transferWait(protocolInstanceUID: protocolInstanceUID, connectionIdentifier: connectionIdentifier)
112112
case .closeWebsocketConnection(protocolInstanceUID: let protocolInstanceUID):
113113
serverQueryType = .closeWebsocketConnection(protocolInstanceUID: protocolInstanceUID)
114+
case .uploadPreKeyForCurrentDevice(deviceBlobOnServerToUpload: let deviceBlobOnServerToUpload):
115+
serverQueryType = .uploadPreKeyForCurrentDevice(deviceBlobOnServerToUpload: deviceBlobOnServerToUpload)
114116
}
115117

116118
let serverQuery = ServerQuery(ownedIdentity: ownedIdentity, queryType: serverQueryType, encodedElements: message.encodedElements)
@@ -142,7 +144,7 @@ extension ObvServerChannel {
142144

143145
switch message.channelType {
144146

145-
case .ServerQuery(ownedIdentity: let ownedIdentity):
147+
case .serverQuery(ownedIdentity: let ownedIdentity):
146148
// Only server query messages may be sent through the server channel
147149
guard message.messageType == .ServerQuery else {
148150
throw ObvServerChannel.makeError(message: "Wrong message type")

Engine/ObvChannelManager/ObvChannelManager/ChannelTypes/ObvUserInterfaceChannel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ extension ObvUserInterfaceChannel {
9494
let acceptableChannels: [ObvChannel]
9595

9696
switch message.channelType {
97-
case .UserInterface(uuid: _, ownedIdentity: let ownedIdentity, dialogType: _):
97+
case .userInterface(uuid: _, ownedIdentity: let ownedIdentity, dialogType: _):
9898

9999
// Only dialog messages can be sent to the user interface
100100
guard message.messageType == .DialogMessage else {

0 commit comments

Comments
 (0)