diff --git a/Cartfile b/Cartfile index 886a8fe4990..22d9f9c9b9f 100644 --- a/Cartfile +++ b/Cartfile @@ -1,3 +1,2 @@ -github "wireapp/cryptobox-ios" "v1.1.0_xcframework_arm64simulator" github "wireapp/libPhoneNumber-iOS" "1.1" github "wireapp/ocmock" "v3.4.3_Xcode14.3.1" diff --git a/README.md b/README.md index 77984a3fbf1..cb3c24648bf 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ No license is granted to the Wire trademark and its associated logos, all of whi The Wire mobile app has an architectural layer that we call *sync engine*. It is the client-side layer that processes all the data that is displayed in the mobile app. It handles network communication and authentication with the backend, push notifications, local caching of data, client-side business logic, signaling with the audio-video libraries, encryption and decryption (using encryption libraries from a lower level) and other bits and pieces. The user interface layer of the mobile app is built on top of the *sync engine*, which provides the data to display to the UI. -The sync engine itself is built on top of a few third-party frameworks, and uses Wire components that are shared between platforms for cryptography (Proteus/Cryptobox) and audio-video signaling (AVS). +The sync engine itself is built on top of a few third-party frameworks, and uses Wire components that are shared between platforms for cryptography (Proteus/MLS) and audio-video signaling (AVS). ![Mobile app architecture](https://github.com/wireapp/wire/blob/master/assets/mobile-architecture.png?raw=true) diff --git a/WireDomain/Sources/WireDomain/Repositories/Message/MessageLocalStore.swift b/WireDomain/Sources/WireDomain/Repositories/Message/MessageLocalStore.swift index f94f9fb6a82..b9f98c0be89 100644 --- a/WireDomain/Sources/WireDomain/Repositories/Message/MessageLocalStore.swift +++ b/WireDomain/Sources/WireDomain/Repositories/Message/MessageLocalStore.swift @@ -18,7 +18,6 @@ import CoreData import GenericMessageProtocol -import WireCryptobox import WireDataModel import WireLogging diff --git a/wire-ios-cryptobox/WireCryptobox/ChaCha20Poly1305/AEADEncryption.swift b/WireFoundation/Sources/WireCrypto/AEADEncryption.swift similarity index 95% rename from wire-ios-cryptobox/WireCryptobox/ChaCha20Poly1305/AEADEncryption.swift rename to WireFoundation/Sources/WireCrypto/AEADEncryption.swift index a6967a34100..abaf3918cf9 100644 --- a/wire-ios-cryptobox/WireCryptobox/ChaCha20Poly1305/AEADEncryption.swift +++ b/WireFoundation/Sources/WireCrypto/AEADEncryption.swift @@ -17,9 +17,7 @@ // import Clibsodium -import Foundation -import WireCrypto -import WireUtilities +public import Foundation public extension ChaCha20Poly1305 { @@ -152,11 +150,11 @@ public extension ChaCha20Poly1305 { // MARK: - Verification - private static func verifyKey(bytes: [Byte]) throws { + private static func verifyKey(bytes: [UInt8]) throws { guard bytes.count == keyLength else { throw EncryptionError.malformedKey } } - private static func verifyNonce(bytes: [Byte]) throws { + private static func verifyNonce(bytes: [UInt8]) throws { guard bytes.count == nonceLength else { throw EncryptionError.malformedNonce } } @@ -182,14 +180,14 @@ public extension ChaCha20Poly1305 { // MARK: - Buffer creation - static func generateRandomNonceBytes() -> [Byte] { + static func generateRandomNonceBytes() -> [UInt8] { var nonce = createByteArray(length: nonceLength) randombytes_buf(&nonce, nonce.count) return nonce } - private static func createByteArray(length: Int) -> [Byte] { - [Byte](repeating: 0, count: length) + private static func createByteArray(length: Int) -> [UInt8] { + [UInt8](repeating: 0, count: length) } } diff --git a/fastlane/framework.rb b/fastlane/framework.rb index 20f4c3ef347..7f5b4f4368f 100644 --- a/fastlane/framework.rb +++ b/fastlane/framework.rb @@ -70,7 +70,6 @@ def self.all frameworks["wire-ios-mocktransport"].add_dependency(frameworks["wire-ios-testing"]) - frameworks["wire-ios-transport"].add_dependency(frameworks["wire-ios-utilities"]) frameworks["wire-ios-transport"].add_dependency(frameworks["wire-ios-testing"]) # included in WireTransportTests frameworks["wire-ios-transport"].add_dependency(frameworks["WireLogging"]) diff --git a/wire-ios-cryptobox/Resources/Configurations/WireCryptobox.xcconfig b/wire-ios-cryptobox/Resources/Configurations/WireCryptobox.xcconfig deleted file mode 100644 index f7770bbfec3..00000000000 --- a/wire-ios-cryptobox/Resources/Configurations/WireCryptobox.xcconfig +++ /dev/null @@ -1,22 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -APPLICATION_EXTENSION_API_ONLY = YES -PRODUCT_NAME = WireCryptobox -SWIFT_INCLUDE_PATHS = $(inherited) $(SRCROOT)/WireCryptobox -CRYPTOBOX_VERSION = 1.1.0 diff --git a/wire-ios-cryptobox/Resources/Configurations/version.xcconfig b/wire-ios-cryptobox/Resources/Configurations/version.xcconfig deleted file mode 100644 index 9d103b53b56..00000000000 --- a/wire-ios-cryptobox/Resources/Configurations/version.xcconfig +++ /dev/null @@ -1,20 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -MAJOR_VERSION = 34 -CURRENT_PROJECT_VERSION = 34.0.1 diff --git a/wire-ios-cryptobox/Resources/Configurations/zmc-config/ios-test-host.xcconfig b/wire-ios-cryptobox/Resources/Configurations/zmc-config/ios-test-host.xcconfig deleted file mode 100644 index 89c90917712..00000000000 --- a/wire-ios-cryptobox/Resources/Configurations/zmc-config/ios-test-host.xcconfig +++ /dev/null @@ -1,17 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// diff --git a/wire-ios-cryptobox/Resources/Configurations/zmc-config/ios-test-target.xcconfig b/wire-ios-cryptobox/Resources/Configurations/zmc-config/ios-test-target.xcconfig deleted file mode 100644 index 7aa6aecfd77..00000000000 --- a/wire-ios-cryptobox/Resources/Configurations/zmc-config/ios-test-target.xcconfig +++ /dev/null @@ -1,21 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -#include "tests.xcconfig" - -SWIFT_INCLUDE_PATHS = $(inherited) $(SRCROOT)/WireCryptobox diff --git a/wire-ios-cryptobox/Resources/Configurations/zmc-config/project-common.xcconfig b/wire-ios-cryptobox/Resources/Configurations/zmc-config/project-common.xcconfig deleted file mode 100644 index 928434aea8c..00000000000 --- a/wire-ios-cryptobox/Resources/Configurations/zmc-config/project-common.xcconfig +++ /dev/null @@ -1,25 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -#include "warnings.xcconfig" -#include "../version.xcconfig" -#include "../../../../xcconfigs/ios-arm64Simulator.xcconfig" - - -// info.plist -INFOPLIST_PREPROCESS = YES diff --git a/wire-ios-cryptobox/Resources/Configurations/zmc-config/project-debug.xcconfig b/wire-ios-cryptobox/Resources/Configurations/zmc-config/project-debug.xcconfig deleted file mode 100644 index 152c0fc9c70..00000000000 --- a/wire-ios-cryptobox/Resources/Configurations/zmc-config/project-debug.xcconfig +++ /dev/null @@ -1,42 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -#include "warnings.xcconfig" -#include "project-common.xcconfig" - -// Deployment -// -COPY_PHASE_STRIP = NO - - -// LLVM - Code Generation -// -GCC_OPTIMIZATION_LEVEL = 0 - - -// Swift Compiler - Code Generation -// -SWIFT_OPTIMIZATION_LEVEL = -Onone -OTHER_SWIFT_FLAGS = -D DEBUG -ENABLE_TESTABILITY = YES - - - -// LLVM - Preprocessing -// -GCC_PREPROCESSOR_DEFINITIONS = DEBUG=1 ZM_MAJOR_VERSION=$(MAJOR_VERSION) $(inherited) $(GCC_PREPROCESSOR_DEFINITIONS_shared) diff --git a/wire-ios-cryptobox/Resources/Configurations/zmc-config/project.xcconfig b/wire-ios-cryptobox/Resources/Configurations/zmc-config/project.xcconfig deleted file mode 100644 index adced5a0e1f..00000000000 --- a/wire-ios-cryptobox/Resources/Configurations/zmc-config/project.xcconfig +++ /dev/null @@ -1,35 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -#include "warnings.xcconfig" -#include "project-common.xcconfig" - -// Build Options -// -DEBUG_INFORMATION_FORMAT = dwarf-with-dsym -VALIDATE_PRODUCT = YES - -// Deployment -// -COPY_PHASE_STRIP = YES - - -// LLVM - Preprocessing -// -GCC_PREPROCESSOR_DEFINITIONS = DEBUG=0 ZM_MAJOR_VERSION=$(MAJOR_VERSION) $(inherited) $(GCC_PREPROCESSOR_DEFINITIONS_shared) - diff --git a/wire-ios-cryptobox/Resources/Configurations/zmc-config/tests.xcconfig b/wire-ios-cryptobox/Resources/Configurations/zmc-config/tests.xcconfig deleted file mode 100644 index 4b94eb69c14..00000000000 --- a/wire-ios-cryptobox/Resources/Configurations/zmc-config/tests.xcconfig +++ /dev/null @@ -1,21 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -// Preprocessing -// -GCC_PREPROCESSOR_DEFINITIONS_shared = TEST_TARGET=1 diff --git a/wire-ios-cryptobox/Resources/Configurations/zmc-config/warnings.xcconfig b/wire-ios-cryptobox/Resources/Configurations/zmc-config/warnings.xcconfig deleted file mode 100644 index b899f81ef4e..00000000000 --- a/wire-ios-cryptobox/Resources/Configurations/zmc-config/warnings.xcconfig +++ /dev/null @@ -1,71 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -// Warnings - All languages -// -CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR -CLANG_WARN_EMPTY_BODY = YES -CLANG_WARN_BOOL_CONVERSION = YES -CLANG_WARN_CONSTANT_CONVERSION = YES -GCC_WARN_64_TO_32_BIT_CONVERSION = YES -CLANG_WARN_ENUM_CONVERSION = YES -CLANG_WARN_INT_CONVERSION = YES -GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR -GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE -GCC_WARN_UNUSED_FUNCTION = YES -GCC_WARN_UNUSED_VARIABLE = YES -GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES -GCC_WARN_SHADOW = YES -GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES -GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES -GCC_WARN_ABOUT_MISSING_NEWLINE = NO -GCC_WARN_SIGN_COMPARE = YES -CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES -GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES -GCC_WARN_UNKNOWN_PRAGMAS = YES -GCC_WARN_UNUSED_LABEL = YES -GCC_WARN_UNUSED_PARAMETER = YES -CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES -GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES -CLANG_WARN_UNREACHABLE_CODE = YES - -// Warnings - Objective C -// -CLANG_WARN__DUPLICATE_METHOD_MATCH = YES -CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES -CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES -CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES -GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = YES -CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES -GCC_WARN_STRICT_SELECTOR_MATCH = YES -GCC_WARN_UNDECLARED_SELECTOR = YES -CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR - -// Static Analyzer - Issues - Security -// -CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES -CLANG_ANALYZER_SECURITY_INSECUREAPI_RAND = YES -CLANG_ANALYZER_SECURITY_INSECUREAPI_STRCPY = YES - -CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; -CLANG_WARN_COMMA = YES; -CLANG_WARN_INFINITE_RECURSION = YES; -CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; -CLANG_WARN_STRICT_PROTOTYPES = YES; -CLANG_WARN_SUSPICIOUS_MOVE = YES; -GCC_NO_COMMON_BLOCKS = YES; diff --git a/wire-ios-cryptobox/Scripts/config.txt b/wire-ios-cryptobox/Scripts/config.txt deleted file mode 100644 index 31dbf54b2ef..00000000000 --- a/wire-ios-cryptobox/Scripts/config.txt +++ /dev/null @@ -1,6 +0,0 @@ -framework=WireCryptobox -organization=wireapp -repository=wire-ios-cryptobox -release-name-format=You should never {VERB} in {CITY} -platforms=ios,osx -dont_test_platforms=osx \ No newline at end of file diff --git a/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.pbxproj b/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.pbxproj deleted file mode 100644 index d12b67d0307..00000000000 --- a/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.pbxproj +++ /dev/null @@ -1,520 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 71; - objects = { - -/* Begin PBXBuildFile section */ - 591B6E5E2C8B09E8009F8A7B /* WireCryptobox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0928E2341BA0777A0057232E /* WireCryptobox.framework */; }; - 591B6E612C8B09ED009F8A7B /* WireCryptobox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0928E2341BA0777A0057232E /* WireCryptobox.framework */; }; - CBD35F2E2D09EBC10080DA37 /* Clibsodium in Frameworks */ = {isa = PBXBuildFile; productRef = CBD35F2D2D09EBC10080DA37 /* Clibsodium */; }; - CBD35F302D09EBD00080DA37 /* WireCrypto in Frameworks */ = {isa = PBXBuildFile; productRef = CBD35F2F2D09EBD00080DA37 /* WireCrypto */; }; - EE97411D295493B9000C9340 /* WireUtilities.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE97411C295493B9000C9340 /* WireUtilities.framework */; }; - EEE25B2229719A240008B894 /* cryptobox.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE67F6B9296F05BF001D7C88 /* cryptobox.xcframework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 5471A66C1D24216D0092A9A9 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BA7EF9561B7109B600204A8E /* Project object */; - proxyType = 1; - remoteGlobalIDString = 5471A6541D24215B0092A9A9; - remoteInfo = "test-host"; - }; - 5471A6701D24221A0092A9A9 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BA7EF9561B7109B600204A8E /* Project object */; - proxyType = 1; - remoteGlobalIDString = 0928E2331BA0777A0057232E; - remoteInfo = "Cryptobox-ios"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 0928E2341BA0777A0057232E /* WireCryptobox.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WireCryptobox.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5471A6551D24215B0092A9A9 /* WireCryptoboxTestHost.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireCryptoboxTestHost.app; sourceTree = BUILT_PRODUCTS_DIR; }; - BA7EF9691B7109B600204A8E /* WireCryptoboxTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WireCryptoboxTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - EE67F6B8296F05BF001D7C88 /* Clibsodium.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Clibsodium.xcframework; path = ../Carthage/Build/Clibsodium.xcframework; sourceTree = ""; }; - EE67F6B9296F05BF001D7C88 /* cryptobox.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = cryptobox.xcframework; path = ../Carthage/Build/cryptobox.xcframework; sourceTree = ""; }; - EE97411C295493B9000C9340 /* WireUtilities.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = WireUtilities.framework; sourceTree = BUILT_PRODUCTS_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ - 594E14852D660CC200864BC1 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - Info.plist, - ); - target = 5471A6541D24215B0092A9A9 /* WireCryptoboxTestHost */; - }; - 594E14992D660CCF00864BC1 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - Info.plist, - TestPlans/AllTests.xctestplan, - ); - target = BA7EF9681B7109B600204A8E /* WireCryptoboxTests */; - }; - 594E14C42D660D1C00864BC1 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { - isa = PBXFileSystemSynchronizedBuildFileExceptionSet; - membershipExceptions = ( - Info.plist, - ); - publicHeaders = ( - cbox.h, - WireCryptobox.h, - ); - target = 0928E2331BA0777A0057232E /* WireCryptobox */; - }; -/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ - -/* Begin PBXFileSystemSynchronizedRootGroup section */ - 594E147E2D660CC200864BC1 /* test-host */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (594E14852D660CC200864BC1 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = "test-host"; sourceTree = ""; }; - 594E14902D660CCF00864BC1 /* WireCryptoboxTests */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (594E14992D660CCF00864BC1 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = WireCryptoboxTests; sourceTree = ""; }; - 594E14A52D660CD200864BC1 /* Resources */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Resources; sourceTree = ""; }; - 594E14B72D660D1C00864BC1 /* WireCryptobox */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (594E14C42D660D1C00864BC1 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = WireCryptobox; sourceTree = ""; }; -/* End PBXFileSystemSynchronizedRootGroup section */ - -/* Begin PBXFrameworksBuildPhase section */ - 0928E2301BA0777A0057232E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - EE97411D295493B9000C9340 /* WireUtilities.framework in Frameworks */, - CBD35F2E2D09EBC10080DA37 /* Clibsodium in Frameworks */, - CBD35F302D09EBD00080DA37 /* WireCrypto in Frameworks */, - EEE25B2229719A240008B894 /* cryptobox.xcframework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5471A6521D24215B0092A9A9 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 591B6E612C8B09ED009F8A7B /* WireCryptobox.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BA7EF9661B7109B600204A8E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 591B6E5E2C8B09E8009F8A7B /* WireCryptobox.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - BA7EF9551B7109B600204A8E = { - isa = PBXGroup; - children = ( - 594E14B72D660D1C00864BC1 /* WireCryptobox */, - 594E14A52D660CD200864BC1 /* Resources */, - 594E14902D660CCF00864BC1 /* WireCryptoboxTests */, - 594E147E2D660CC200864BC1 /* test-host */, - F10C8E221E9296BA00020408 /* Frameworks */, - BA7EF95F1B7109B600204A8E /* Products */, - ); - indentWidth = 4; - sourceTree = ""; - tabWidth = 4; - usesTabs = 0; - wrapsLines = 1; - }; - BA7EF95F1B7109B600204A8E /* Products */ = { - isa = PBXGroup; - children = ( - BA7EF9691B7109B600204A8E /* WireCryptoboxTests.xctest */, - 0928E2341BA0777A0057232E /* WireCryptobox.framework */, - 5471A6551D24215B0092A9A9 /* WireCryptoboxTestHost.app */, - ); - name = Products; - sourceTree = ""; - }; - F10C8E221E9296BA00020408 /* Frameworks */ = { - isa = PBXGroup; - children = ( - EE97411C295493B9000C9340 /* WireUtilities.framework */, - EE67F6B8296F05BF001D7C88 /* Clibsodium.xcframework */, - EE67F6B9296F05BF001D7C88 /* cryptobox.xcframework */, - ); - name = Frameworks; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 0928E2311BA0777A0057232E /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 0928E2331BA0777A0057232E /* WireCryptobox */ = { - isa = PBXNativeTarget; - buildConfigurationList = 0928E24B1BA0777A0057232E /* Build configuration list for PBXNativeTarget "WireCryptobox" */; - buildPhases = ( - 5459C4B81C0FB0F600F4963F /* Placeholder Carthage folder */, - 0928E22F1BA0777A0057232E /* Sources */, - 0928E2301BA0777A0057232E /* Frameworks */, - 0928E2311BA0777A0057232E /* Headers */, - 0928E2321BA0777A0057232E /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - fileSystemSynchronizedGroups = ( - 594E14B72D660D1C00864BC1 /* WireCryptobox */, - ); - name = WireCryptobox; - productName = "Cryptobox-ios"; - productReference = 0928E2341BA0777A0057232E /* WireCryptobox.framework */; - productType = "com.apple.product-type.framework"; - }; - 5471A6541D24215B0092A9A9 /* WireCryptoboxTestHost */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5471A6691D24215B0092A9A9 /* Build configuration list for PBXNativeTarget "WireCryptoboxTestHost" */; - buildPhases = ( - 5471A6511D24215B0092A9A9 /* Sources */, - 5471A6521D24215B0092A9A9 /* Frameworks */, - 5471A6531D24215B0092A9A9 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 5471A6711D24221A0092A9A9 /* PBXTargetDependency */, - ); - fileSystemSynchronizedGroups = ( - 594E147E2D660CC200864BC1 /* test-host */, - ); - name = WireCryptoboxTestHost; - productName = "test-host"; - productReference = 5471A6551D24215B0092A9A9 /* WireCryptoboxTestHost.app */; - productType = "com.apple.product-type.application"; - }; - BA7EF9681B7109B600204A8E /* WireCryptoboxTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = BA7EF9751B7109B600204A8E /* Build configuration list for PBXNativeTarget "WireCryptoboxTests" */; - buildPhases = ( - BA7EF9651B7109B600204A8E /* Sources */, - BA7EF9661B7109B600204A8E /* Frameworks */, - BA7EF9671B7109B600204A8E /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 5471A66D1D24216D0092A9A9 /* PBXTargetDependency */, - ); - fileSystemSynchronizedGroups = ( - 594E14902D660CCF00864BC1 /* WireCryptoboxTests */, - ); - name = WireCryptoboxTests; - productName = CryptoboxTests; - productReference = BA7EF9691B7109B600204A8E /* WireCryptoboxTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - BA7EF9561B7109B600204A8E /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 1310; - ORGANIZATIONNAME = Cryptobox; - TargetAttributes = { - 0928E2331BA0777A0057232E = { - CreatedOnToolsVersion = 6.4; - LastSwiftMigration = 1000; - }; - 5471A6541D24215B0092A9A9 = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 0800; - ProvisioningStyle = Manual; - }; - BA7EF9681B7109B600204A8E = { - CreatedOnToolsVersion = 6.4; - LastSwiftMigration = 1000; - TestTargetID = 5471A6541D24215B0092A9A9; - }; - }; - }; - buildConfigurationList = BA7EF9591B7109B600204A8E /* Build configuration list for PBXProject "WireCryptobox" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = BA7EF9551B7109B600204A8E; - productRefGroup = BA7EF95F1B7109B600204A8E /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 0928E2331BA0777A0057232E /* WireCryptobox */, - BA7EF9681B7109B600204A8E /* WireCryptoboxTests */, - 5471A6541D24215B0092A9A9 /* WireCryptoboxTestHost */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 0928E2321BA0777A0057232E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5471A6531D24215B0092A9A9 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BA7EF9671B7109B600204A8E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 5459C4B81C0FB0F600F4963F /* Placeholder Carthage folder */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Placeholder Carthage folder"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "mkdir -p Carthage/Build\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 0928E22F1BA0777A0057232E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5471A6511D24215B0092A9A9 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - BA7EF9651B7109B600204A8E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 5471A66D1D24216D0092A9A9 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 5471A6541D24215B0092A9A9 /* WireCryptoboxTestHost */; - targetProxy = 5471A66C1D24216D0092A9A9 /* PBXContainerItemProxy */; - }; - 5471A6711D24221A0092A9A9 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 0928E2331BA0777A0057232E /* WireCryptobox */; - targetProxy = 5471A6701D24221A0092A9A9 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 0928E2471BA0777A0057232E /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 594E14A52D660CD200864BC1 /* Resources */; - baseConfigurationReferenceRelativePath = Configurations/WireCryptobox.xcconfig; - buildSettings = { - CODE_SIGN_STYLE = Manual; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = WireCryptobox/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.wire.cryptobox; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; - SKIP_INSTALL = YES; - }; - name = Debug; - }; - 0928E2481BA0777A0057232E /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 594E14A52D660CD200864BC1 /* Resources */; - baseConfigurationReferenceRelativePath = Configurations/WireCryptobox.xcconfig; - buildSettings = { - CODE_SIGN_STYLE = Manual; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = WireCryptobox/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.wire.cryptobox; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; - SKIP_INSTALL = YES; - }; - name = Release; - }; - 5471A66A1D24215B0092A9A9 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 594E14A52D660CD200864BC1 /* Resources */; - baseConfigurationReferenceRelativePath = "Configurations/zmc-config/ios-test-host.xcconfig"; - buildSettings = { - INFOPLIST_FILE = "test-host/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.marco83.test-host"; - PRODUCT_NAME = "$(TARGET_NAME)"; - VALIDATE_WORKSPACE = YES; - }; - name = Debug; - }; - 5471A66B1D24215B0092A9A9 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 594E14A52D660CD200864BC1 /* Resources */; - baseConfigurationReferenceRelativePath = "Configurations/zmc-config/ios-test-host.xcconfig"; - buildSettings = { - INFOPLIST_FILE = "test-host/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.marco83.test-host"; - PRODUCT_NAME = "$(TARGET_NAME)"; - VALIDATE_WORKSPACE = YES; - }; - name = Release; - }; - BA7EF9701B7109B600204A8E /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 594E14A52D660CD200864BC1 /* Resources */; - baseConfigurationReferenceRelativePath = "Configurations/zmc-config/project-debug.xcconfig"; - buildSettings = { - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - BA7EF9711B7109B600204A8E /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 594E14A52D660CD200864BC1 /* Resources */; - baseConfigurationReferenceRelativePath = "Configurations/zmc-config/project.xcconfig"; - buildSettings = { - SDKROOT = iphoneos; - }; - name = Release; - }; - BA7EF9761B7109B600204A8E /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 594E14A52D660CD200864BC1 /* Resources */; - baseConfigurationReferenceRelativePath = "Configurations/zmc-config/ios-test-target.xcconfig"; - buildSettings = { - CODE_SIGN_STYLE = Manual; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = "$(PRODUCT_NAME)/Info.plist"; - PRODUCT_BUNDLE_IDENTIFIER = "com.wire.cryptobox.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; - SWIFT_OBJC_BRIDGING_HEADER = "$(PRODUCT_NAME)/CryptoboxTests-Bridging-Header.h"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WireCryptoboxTestHost.app/WireCryptoboxTestHost"; - VALIDATE_WORKSPACE = YES; - }; - name = Debug; - }; - BA7EF9771B7109B600204A8E /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReferenceAnchor = 594E14A52D660CD200864BC1 /* Resources */; - baseConfigurationReferenceRelativePath = "Configurations/zmc-config/ios-test-target.xcconfig"; - buildSettings = { - CODE_SIGN_STYLE = Manual; - DEVELOPMENT_TEAM = ""; - INFOPLIST_FILE = "$(PRODUCT_NAME)/Info.plist"; - PRODUCT_BUNDLE_IDENTIFIER = "com.wire.cryptobox.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - "PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*]" = ""; - SWIFT_OBJC_BRIDGING_HEADER = "$(PRODUCT_NAME)/CryptoboxTests-Bridging-Header.h"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WireCryptoboxTestHost.app/WireCryptoboxTestHost"; - VALIDATE_WORKSPACE = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 0928E24B1BA0777A0057232E /* Build configuration list for PBXNativeTarget "WireCryptobox" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 0928E2471BA0777A0057232E /* Debug */, - 0928E2481BA0777A0057232E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5471A6691D24215B0092A9A9 /* Build configuration list for PBXNativeTarget "WireCryptoboxTestHost" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5471A66A1D24215B0092A9A9 /* Debug */, - 5471A66B1D24215B0092A9A9 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - BA7EF9591B7109B600204A8E /* Build configuration list for PBXProject "WireCryptobox" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - BA7EF9701B7109B600204A8E /* Debug */, - BA7EF9711B7109B600204A8E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - BA7EF9751B7109B600204A8E /* Build configuration list for PBXNativeTarget "WireCryptoboxTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - BA7EF9761B7109B600204A8E /* Debug */, - BA7EF9771B7109B600204A8E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - -/* Begin XCSwiftPackageProductDependency section */ - CBD35F2D2D09EBC10080DA37 /* Clibsodium */ = { - isa = XCSwiftPackageProductDependency; - productName = Clibsodium; - }; - CBD35F2F2D09EBD00080DA37 /* WireCrypto */ = { - isa = XCSwiftPackageProductDependency; - productName = WireCrypto; - }; -/* End XCSwiftPackageProductDependency section */ - }; - rootObject = BA7EF9561B7109B600204A8E /* Project object */; -} diff --git a/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index cf961d2e914..00000000000 --- a/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/xcshareddata/IDETemplateMacros.plist b/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/xcshareddata/IDETemplateMacros.plist deleted file mode 120000 index 0aa12047039..00000000000 --- a/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/xcshareddata/IDETemplateMacros.plist +++ /dev/null @@ -1 +0,0 @@ -../../../../wire-ios-mono.xcworkspace/xcshareddata/IDETemplateMacros.plist \ No newline at end of file diff --git a/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d6..00000000000 --- a/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index dc8d12300fe..00000000000 --- a/wire-ios-cryptobox/WireCryptobox.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,10 +0,0 @@ - - - - - BuildSystemType - Latest - IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded - - - diff --git a/wire-ios-cryptobox/WireCryptobox.xcodeproj/xcshareddata/xcschemes/WireCryptobox.xcscheme b/wire-ios-cryptobox/WireCryptobox.xcodeproj/xcshareddata/xcschemes/WireCryptobox.xcscheme deleted file mode 100644 index 583513c3e0c..00000000000 --- a/wire-ios-cryptobox/WireCryptobox.xcodeproj/xcshareddata/xcschemes/WireCryptobox.xcscheme +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/wire-ios-cryptobox/WireCryptobox/CryptoBoxError.swift b/wire-ios-cryptobox/WireCryptobox/CryptoBoxError.swift deleted file mode 100644 index 735afe4fa9f..00000000000 --- a/wire-ios-cryptobox/WireCryptobox/CryptoBoxError.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import Clibsodium -import Foundation -import WireSystem - -extension CBoxResult: Error { - - /// Throw if self represents an error - func throwIfError() throws { - guard self == CBOX_SUCCESS else { - failIfCritical() - throw self - } - } - - func failIfCritical() { - if self == CBOX_PANIC || self == CBOX_INIT_ERROR { - fatalError("Cryptobox panic") - } - } -} - -extension CBoxResult: SafeForLoggingStringConvertible { - public var safeForLoggingDescription: String { - String(describing: self) - } -} diff --git a/wire-ios-cryptobox/WireCryptobox/Data+SafeForLogging.swift b/wire-ios-cryptobox/WireCryptobox/Data+SafeForLogging.swift deleted file mode 100644 index 6716f346ae7..00000000000 --- a/wire-ios-cryptobox/WireCryptobox/Data+SafeForLogging.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import WireUtilities - -extension Data: SafeForLoggingStringConvertible { - public var safeForLoggingDescription: String { - "<\(readableHash)>" - } -} - -// This allows for dump of data in safe logs. It's called "unsafe" because the data is -// dumped as-is, no hashing is applied. Be aware of what you are dumping here. -struct HexDumpUnsafeLoggingData: SafeForLoggingStringConvertible { - - let data: Data - - public var safeForLoggingDescription: String { - data.zmHexEncodedString() - } -} diff --git a/wire-ios-cryptobox/WireCryptobox/EncryptionContext.swift b/wire-ios-cryptobox/WireCryptobox/EncryptionContext.swift deleted file mode 100644 index e276be4166f..00000000000 --- a/wire-ios-cryptobox/WireCryptobox/EncryptionContext.swift +++ /dev/null @@ -1,200 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import Clibsodium -import Foundation -import WireSystem - -class _CBox: PointerWrapper {} - -/// A cryptobox context that manages access to sessions, allowing the -/// same sessions to be accessed by multuple processes in a safe way. -/// Inside a process, only a single session context should be used. -/// -/// - note: -/// In order to be used by multiple processes (see iOS extensions), cryptobox needs to lock the -/// directory with the key material as it works on it, so that no other process will touch it. -/// -/// This class introduces the concept of *encryption context*, similar to the concept of context in Core Data. -/// A context must be used only from a single thread. Multiple contexts can refer to the same -/// directory on disk, locking the directory when needed so that they don't interfere with -/// each other. -/// -/// Conflicts and race conditions are avoided by loading from disk and saving to disk -/// every time a context it used, and locking around these operations. -/// This is slow, but extensions are not supposed to need to access -/// cryptobox very frequently. -/// -/// The intended use of this class is: -/// -/// 1. Create context once, reuse the same context to avoid having to create/load identity -/// (which never changes once created, so no race condition other than during creation) -/// 2. use `perform:` with a block to create sessions, prekeys, encrypt and decrypt. -/// During the execution of the block, the directory is locked. -/// When decrypting, the decrypted data should be saved synchronously inside this block -/// (e.g. in case of Core Data, should be inserted and immediately saved) to enforce it -/// being saved before the session state is persisted later. -/// If the decrypted data is not persisted, and there is a crash before the data is -/// persisted, the data is lost forever as it can not be decrypted again once the session -/// is saved. -/// 3. When the block passed to `perform:` is completed, the sessions are persisted to disk. -/// The lock is relased. -public final class EncryptionContext: NSObject { - - /// What to do with modified sessions - public enum ModifiedSessionsBehaviour { - case save - case discard - } - - /// Set of session identifier that require full debugging logs - private var extensiveLoggingSessions = Set() - - /// Underlying C-style implementation - let implementation = _CBox() - - /// File directory with the implementation files - let path: URL - - /// The latest created and still open session directory - /// will be set to `nil` after calling `doneUsingSessions` - fileprivate(set) var currentSessionsDirectory: EncryptionSessionsDirectory? - - /// Folder file descriptor - fileprivate var fileDescriptor: CInt! - - /// Keeps track of how many times we enter a `perform` block, - /// to allow re-entry - fileprivate var performCount: UInt = 0 - - // The maximum size of the end-to-end encrypted payload is defined by ZMClientMessageByteSizeExternalThreshold - // It's currently 128KB of data. NOTE that this cache is shared between all sessions in an encryption context. - fileprivate let cache = Cache(maxCost: 10_000_000, maxElementsCount: 100_000) - - /// Opens cryptobox from a given folder - /// - throws: CryptoBox error in case of lower-level error - public init(path: URL) { - let result = cbox_file_open((path.path as NSString).utf8String, &implementation.ptr) - self.path = path - super.init() - if result != CBOX_SUCCESS { - fatal("Failed to open cryptobox: ERROR \(result.rawValue)") - } - self.fileDescriptor = open(self.path.path, 0) - if fileDescriptor <= 0 { - fatal("Can't obtain FD for folder \(self.path)") - } - zmLog.debug("Opened cryptobox at path: \(path)") - } - - deinit { - // unlock - self.releaseDirectoryLock() - // close - close(self.fileDescriptor) - // close cbox - cbox_close(implementation.ptr) - zmLog.debug("Closed cryptobox at path: \(path)") - - } - -} - -// MARK: - Start and stop using sessions - -extension EncryptionContext { - - /// Access sessions and other data in this context. While the block is executed, - /// no other process can use sessions from this context. If another process or thread is already - /// using sessions from a context with the same path, this call will block until the other process - /// stops using sessions. Nested calls to this method on the same objects on the same - /// thread are allowed. - /// - warning: this method is not thread safe - public func perform(_ block: (_ sessionsDirectory: EncryptionSessionsDirectory) -> Void) { - acquireDirectoryLock() - if currentSessionsDirectory == nil { - currentSessionsDirectory = - EncryptionSessionsDirectory( - generatingContext: self, - encryptionPayloadCache: cache, - extensiveLoggingSessions: extensiveLoggingSessions - ) - } - performCount += 1 - block(currentSessionsDirectory!) - performCount -= 1 - if performCount == 0 { - currentSessionsDirectory = nil - } - releaseDirectoryLock() - } - - // swiftlint:disable:next todo_requires_jira_link - // TODO: can this be removed? - public func performAsync(_ block: (_ sessionsDirectory: EncryptionSessionsDirectory) async -> Void) async { - acquireDirectoryLock() - if currentSessionsDirectory == nil { - currentSessionsDirectory = - EncryptionSessionsDirectory( - generatingContext: self, - encryptionPayloadCache: cache, - extensiveLoggingSessions: extensiveLoggingSessions - ) - } - performCount += 1 - await block(currentSessionsDirectory!) - performCount -= 1 - if performCount == 0 { - currentSessionsDirectory = nil - } - releaseDirectoryLock() - } - - private func acquireDirectoryLock() { - if flock(fileDescriptor, LOCK_EX) != 0 { - fatal("Failed to lock \(path)") - } - } - - private func releaseDirectoryLock() { - if flock(fileDescriptor, LOCK_UN) != 0 { - fatal("Failed to unlock \(path)") - } - } -} - -public extension EncryptionContext { - - /// Enables or disables extended logging for any message encrypted from or to - /// a specific session. - /// note: if the session is already cached in memory, this will apply from the - /// next time the session is reloaded - func setExtendedLogging(identifier: EncryptionSessionIdentifier, enabled: Bool) { - if enabled { - extensiveLoggingSessions.insert(identifier) - } else { - extensiveLoggingSessions.remove(identifier) - } - } - - /// Disable extensive logging on all sessions - func disableExtendedLoggingOnAllSessions() { - extensiveLoggingSessions.removeAll() - } - -} diff --git a/wire-ios-cryptobox/WireCryptobox/EncryptionSessionsDirectory.swift b/wire-ios-cryptobox/WireCryptobox/EncryptionSessionsDirectory.swift deleted file mode 100644 index c44027a11c3..00000000000 --- a/wire-ios-cryptobox/WireCryptobox/EncryptionSessionsDirectory.swift +++ /dev/null @@ -1,788 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import Foundation -import WireSystem -import WireUtilities - -@objc -enum EncryptionSessionError: Int { - - case unknown - case encryptionFailed - case decryptionFailed - - var userInfo: [String: AnyObject] { - let info = switch self { - case .unknown: - "Unknown EncryptionSessionError" - case .encryptionFailed: - "Encryption Failed" - case .decryptionFailed: - "Decryption Failed" - } - - return [kCFErrorLocalizedDescriptionKey as String: info as AnyObject] - } - - var error: NSError { - NSError(domain: "EncryptionSessionsDirectoryDomain", code: rawValue, userInfo: userInfo) - } - -} - -class _CBoxSession: PointerWrapper {} - -/// An encryption state that is usable to encrypt/decrypt messages -/// It maintains an in-memory cache of encryption sessions with other clients -/// that is persisted to disk as soon as it is deallocated. -public final class EncryptionSessionsDirectory: NSObject { - - /// Used for testing only. If set to true, - /// will not try to validate with the generating context - var debug_disableContextValidityCheck = false - - /// Set of session identifier that require full debugging logs - let extensiveLoggingSessions: Set - - /// Context that created this status - fileprivate weak var generatingContext: EncryptionContext! - - /// Local fingerprint - public var localFingerprint: Data - - fileprivate let encryptionPayloadCache: Cache - - /// Cache of transient sessions, indexed by client ID. - /// Transient sessions are session that are (potentially) modified in memory - /// and not yet committed to disk. When trying to load a session, - /// and that session is already in the list of transient sessions, - /// the transient session will be returned without any loading - /// occurring. As soon as a session is saved, it is removed from the cache. - /// - /// - note: This is an optimization: instead of loading, decrypting, - /// saving, unloading every time, if the same session is reused within - /// the same execution block, we don't need to spend time reading - /// and writing to disk every time we use the session, we can just - /// load once and save once at the end. - fileprivate var pendingSessionsCache: [EncryptionSessionIdentifier: EncryptionSession] = [:] - - init( - generatingContext: EncryptionContext, - encryptionPayloadCache: Cache, - extensiveLoggingSessions: Set - ) { - self.generatingContext = generatingContext - self.localFingerprint = generatingContext.implementation.localFingerprint - self.encryptionPayloadCache = encryptionPayloadCache - self.extensiveLoggingSessions = extensiveLoggingSessions - super.init() - zmLog.safePublic("Loaded encryption status - local fingerprint \(localFingerprint)") - } - - /// The underlying implementation of the box - var box: _CBox { - generatingContext!.implementation - } - - /// Checks whether self is in a valid state, i.e. the generating context is still open and - /// this is the current status. If not, it means that we are using this status after - /// the context was done using this status. - /// Will assert if this is the case. - fileprivate func validateContext() -> EncryptionContext { - guard debug_disableContextValidityCheck || generatingContext.currentSessionsDirectory === self else { - // If you hit this line, check if the status was stored in a variable for later use, - // or if it was used from different threads - it should never be. - fatalError("Using encryption status outside of a context") - } - return generatingContext! - } - - deinit { - self.commitCache() - } - - private func hash(for data: Data, recipient: EncryptionSessionIdentifier) -> GenericHash { - let builder = GenericHashBuilder() - builder.append(data) - builder.append(recipient.rawValue.data(using: .utf8)!) - return builder.build() - } - - /// Encrypts data for a client. Caches the encrypted payload based on `hash(data + recepient)` as the cache key. - /// It invokes @c encrypt() in case of the cache miss. - /// - throws: EncryptionSessionError in case no session with given recipient - public func encryptCaching(_ plainText: Data, for recipientIdentifier: EncryptionSessionIdentifier) throws -> Data { - let key = hash(for: plainText, recipient: recipientIdentifier) - - if let cachedObject = encryptionPayloadCache.value(for: key) { - zmLog.safePublic("Encrypting, cache hit") - return cachedObject - } else { - zmLog.debug("Encrypting, cache miss") - let data = try encrypt(plainText, for: recipientIdentifier) - let didPurgeData = encryptionPayloadCache.set(value: data, for: key, cost: data.count) - - if didPurgeData { - zmLog.safePublic("Encrypting, cache limit reached") - } - - return data - } - } - - /// Purges the cache of encrypted payloads created as the result of @c encryptCaching() call - public func purgeEncryptedPayloadCache() { - zmLog.safePublic("Encryption cache purged") - encryptionPayloadCache.purge() - } -} - -// MARK: - Encryption sessions - -public protocol EncryptionSessionManager { - /// Migrate session to a new identifier, if a session with the old identifier exists - /// and a session with the new identifier does not exist - func migrateSession(from previousIdentifier: String, to newIdentifier: EncryptionSessionIdentifier) - - /// Creates a session to a client using a prekey of that client - /// The session is not saved to disk until the cache is committed - /// - throws: CryptoBox error in case of lower-level error - func createClientSession(_ identifier: EncryptionSessionIdentifier, base64PreKeyString: String) throws - - /// Creates a session to a client using a prekey message from that client - /// The session is not saved to disk until the cache is committed - /// - returns: the plaintext - /// - throws: CryptoBox error in case of lower-level error - func createClientSessionAndReturnPlaintext(for identifier: EncryptionSessionIdentifier, prekeyMessage: Data) throws - -> Data - - /// Deletes a session with a client - func delete(_ identifier: EncryptionSessionIdentifier) - - /// Returns true if there is an existing session for this client ID - func hasSession(for identifier: EncryptionSessionIdentifier) -> Bool - - /// Closes all transient sessions without saving them - func discardCache() - - /// Returns the remote fingerprint of a encryption session - func fingerprint(for identifier: EncryptionSessionIdentifier) -> Data? -} - -extension EncryptionSessionsDirectory: EncryptionSessionManager { - - public func migrateSession(from previousIdentifier: String, to newIdentifier: EncryptionSessionIdentifier) { - - let previousSessionIdentifier = EncryptionSessionIdentifier(fromLegacyV1Identifier: previousIdentifier) - // this scopes guarantee that `old` is released - repeat { - guard let old = clientSession(for: previousSessionIdentifier) else { - return - } - - // save and close old one - old.save(box) - discardFromCache(previousSessionIdentifier) - } while false - - guard clientSession(for: newIdentifier) == nil else { - // There is an old and a new, delete the old - delete(previousSessionIdentifier) - return - } - - // copy to new one - let oldPath = filePath(for: previousSessionIdentifier) - let newPath = filePath(for: newIdentifier) - - guard FileManager.default.fileExists(atPath: oldPath.path) else { - fatal("Can't migrate session \(previousSessionIdentifier) because file \(oldPath) does not exist") - } - - guard (try? FileManager.default.moveItem(at: oldPath, to: newPath)) != nil else { - fatal("Can't migrate session \(newIdentifier) because the move failed") - } - - } - - public func createClientSession(_ identifier: EncryptionSessionIdentifier, base64PreKeyString: String) throws { - - // validate - guard let prekeyData = Data(base64Encoded: base64PreKeyString, options: []) else { - fatal("String is not base64 encoded from client: \(identifier)") - } - let context = validateContext() - - // check if pre-existing - if let session = clientSession(for: identifier) { - zmLog - .safePublic( - "Tried to create session for client \(identifier) with prekey but session already existed - fingerprint \(session.remoteFingerprint)" - ) - return - } - - // init - let cbsession = _CBoxSession() - let result = prekeyData.withUnsafeBytes { (prekeyDataPointer: UnsafeRawBufferPointer) -> CBoxResult in - cbox_session_init_from_prekey( - context.implementation.ptr, - identifier.rawValue, - prekeyDataPointer.bindMemory(to: UInt8.self).baseAddress!, - prekeyData.count, - &cbsession.ptr - ) - } - - try result.throwIfError() - - let session = EncryptionSession( - id: identifier, - session: cbsession, - requiresSave: true, - cryptoboxPath: generatingContext!.path, - extensiveLogging: extensiveLoggingSessions.contains(identifier) - ) - pendingSessionsCache[identifier] = session - - zmLog.safePublic("Created session for client \(identifier) - fingerprint \(session.remoteFingerprint)") - } - - public func createClientSessionAndReturnPlaintext( - for identifier: EncryptionSessionIdentifier, - prekeyMessage: Data - ) throws -> Data { - let context = validateContext() - let cbsession = _CBoxSession() - var plainTextBacking: OpaquePointer? - - let result = prekeyMessage.withUnsafeBytes { (prekeyMessagePointer: UnsafeRawBufferPointer) -> CBoxResult in - cbox_session_init_from_message( - context.implementation.ptr, - identifier.rawValue, - prekeyMessagePointer.baseAddress!.assumingMemoryBound(to: UInt8.self), - prekeyMessage.count, - &cbsession.ptr, - &plainTextBacking - ) - } - - let extensiveLogging = extensiveLoggingSessions.contains(identifier) - if extensiveLogging { - EncryptionSession.logSessionAndCyphertext( - sessionId: identifier, - reason: "decrypting prekey cyphertext", - data: prekeyMessage, - sessionURL: filePath(for: identifier) - ) - } - try result.throwIfError() - - let plainText = Data.moveFromCBoxVector(plainTextBacking)! - let session = EncryptionSession( - id: identifier, - session: cbsession, - requiresSave: true, - cryptoboxPath: generatingContext!.path, - extensiveLogging: extensiveLogging - ) - pendingSessionsCache[identifier] = session - - zmLog - .safePublic( - "Created session for client \(identifier) from prekey message - fingerprint \(session.remoteFingerprint)" - ) - - return plainText - } - - public func delete(_ identifier: EncryptionSessionIdentifier) { - let context = validateContext() - discardFromCache(identifier) - let result = cbox_session_delete(context.implementation.ptr, identifier.rawValue) - zmLog.safePublic("Delete session for client \(identifier)") - - guard result == CBOX_SUCCESS else { - fatal("Error in deletion in cbox: \(result)") - } - } - - /// Returns an existing session for a client - /// - returns: a session if it exists, or nil if not there - fileprivate func clientSession(for identifier: EncryptionSessionIdentifier) -> EncryptionSession? { - let context = validateContext() - - // check cache - if let transientSession = pendingSessionsCache[identifier] { - zmLog - .safePublic( - "Tried to load session for client \(identifier), session was already loaded - fingerprint \(transientSession.remoteFingerprint)" - ) - return transientSession - } - - let cbsession = _CBoxSession() - let result = cbox_session_load(context.implementation.ptr, identifier.rawValue, &cbsession.ptr) - switch result { - case CBOX_SESSION_NOT_FOUND: - zmLog.safePublic("Tried to load session for client \(identifier), no session found") - return nil - case CBOX_SUCCESS: - let session = EncryptionSession( - id: identifier, - session: cbsession, - requiresSave: false, - cryptoboxPath: generatingContext!.path, - extensiveLogging: extensiveLoggingSessions.contains(identifier) - ) - pendingSessionsCache[identifier] = session - zmLog.safePublic("Loaded session for client \(identifier) - fingerprint \(session.remoteFingerprint)") - return session - default: - fatalError("Error in loading from cbox: \(result)") - } - } - - public func hasSession(for identifier: EncryptionSessionIdentifier) -> Bool { - clientSession(for: identifier) != nil - } - - public func discardCache() { - zmLog.safePublic("Discarded all sessions from cache") - pendingSessionsCache = [:] - } - - /// Save and unload all transient sessions - fileprivate func commitCache() { - for (_, session) in pendingSessionsCache { - session.save(box) - } - discardCache() - } - - /// Closes a transient session. Any unsaved change will be lost - fileprivate func discardFromCache(_ identifier: EncryptionSessionIdentifier) { - zmLog.safePublic("Discarded session \(identifier) from cache") - pendingSessionsCache.removeValue(forKey: identifier) - } - - /// Saves the cached session for a client and removes it from the cache - fileprivate func saveSession(_ identifier: EncryptionSessionIdentifier) { - guard let session = pendingSessionsCache[identifier] else { - return - } - session.save(box) - discardFromCache(identifier) - } - - public func fingerprint(for identifier: EncryptionSessionIdentifier) -> Data? { - guard let session = clientSession(for: identifier) else { - return nil - } - return session.remoteFingerprint - } -} - -public protocol PrekeyGeneratorType { - func generatePrekey(_ id: UInt16) throws -> String - func generateLastPrekey() throws -> String - func generatePrekeys(_ range: CountableRange) throws -> [(id: UInt16, prekey: String)] - func generatePrekeys(_ nsRange: NSRange) throws -> [[String: AnyObject]] -} - -// MARK: - Prekeys - -extension EncryptionSessionsDirectory: PrekeyGeneratorType { - - /// Generates one prekey of the given ID. If the prekey exists already, - /// it will replace that prekey - /// - returns: base 64 encoded string - public func generatePrekey(_ id: UInt16) throws -> String { - guard id <= CBOX_LAST_PREKEY_ID else { - // this should never happen, as CBOX_LAST_PREKEY_ID is UInt16.max - fatal("Prekey out of bound \(id)") - } - var vectorBacking: OpaquePointer? - let context = validateContext() - let result = cbox_new_prekey(context.implementation.ptr, id, &vectorBacking) - let prekey = Data.moveFromCBoxVector(vectorBacking) - zmLog.debug("Generate prekey \(id)") - - try result.throwIfError() - - return prekey!.base64EncodedString(options: []) - } - - /// Generates the last prekey. If the prekey exists already, - /// it will replace that prekey - public func generateLastPrekey() throws -> String { - try generatePrekey(CBOX_LAST_PREKEY_ID) - } - - /// Generates prekeys from a range of IDs. If prekeys with those IDs exist already, - /// they will be replaced - public func generatePrekeys(_ range: CountableRange) throws -> [(id: UInt16, prekey: String)] { - try range.map { - let prekey = try self.generatePrekey($0) - return (id: $0, prekey: prekey) - } - } - - /// Generates prekeys from a range of IDs. If prekeys with those IDs exist already, - /// they will be replaced - /// This method wraps the Swift only method generatePrekeys(range: Range) for objC interoparability - @objc - public func generatePrekeys(_ nsRange: NSRange) throws -> [[String: AnyObject]] { - let prekeys = try generatePrekeys(UInt16(nsRange.location) ..< UInt16(nsRange.length)) - return prekeys.map { ["id": NSNumber(value: $0.id as UInt16), "prekey": $0.prekey as AnyObject] } - } - - /// Extracts the fingerprint from a prekey - /// - /// - returns: HEX encoded fingerprint - @objc(fingerprintFromPrekey:) - public static func fingerprint(fromPrekey prekey: Data) -> Data? { - prekey.withUnsafeBytes { - let bytes = $0.baseAddress?.assumingMemoryBound(to: UInt8.self) - var vectorBacking: OpaquePointer? - let result = cbox_fingerprint_prekey(bytes, $0.count, &vectorBacking) - - guard result == CBOX_SUCCESS else { - return nil - } - - return Data.moveFromCBoxVector(vectorBacking)! - } - } -} - -// MARK: - Fingerprint - -private extension _CBox { - - /// Local fingerprint - var localFingerprint: Data { - var vectorBacking: OpaquePointer? - let result = cbox_fingerprint_local(ptr, &vectorBacking) - guard result == CBOX_SUCCESS else { - fatal("Can't get local fingerprint") // this is so rare, that we don't even throw - } - return Data.moveFromCBoxVector(vectorBacking)! - } -} - -/// A cryptographic session used to encrypt/decrypt data send to and received from -/// another client -/// - note: This class is private because we want to make sure that no one can use -/// sessions outside of a status, that only dirty sessions are kept in memory, and -/// that sessions are unloaded as soon as possible, and that sessions are closed as soon -/// as they are unloaded. -/// We let the status manages closing sessions as there is no -/// other easy way to enforce (other than asserting) that we don't use a session to encrypt/decrypt -/// after it has been closed, and there is no easy way to ensure that sessions are always closed. -/// By hiding the implementation inside this file, only code in this file has the chance to screw up! -class EncryptionSession { - - /// Whether this session has changes that require saving - var hasChanges: Bool - - /// client ID - let id: EncryptionSessionIdentifier - - /// Underlying C-style implementation - let implementation: _CBoxSession - - /// The fingerpint of the client - let remoteFingerprint: Data - - /// Path of the containing cryptobox (used for debugging) - let cryptoboxPath: URL - - /// Whether to log additional information - let isExtensiveLoggingEnabled: Bool - - /// Creates a session from a C-level session pointer - /// - parameter id: id of the client - /// - parameter requiresSave: if true, mark this session as having pending changes to save - init( - id: EncryptionSessionIdentifier, - session: _CBoxSession, - requiresSave: Bool, - cryptoboxPath: URL, - extensiveLogging: Bool - ) { - self.id = id - self.implementation = session - self.remoteFingerprint = session.remoteFingerprint - self.hasChanges = requiresSave - self.cryptoboxPath = cryptoboxPath - self.isExtensiveLoggingEnabled = extensiveLogging - } - - /// Closes the session in CBox - private func closeInCryptobox() { - zmLog.safePublic("Closing cryptobox session \(id)") - cbox_session_close(implementation.ptr) - } - - /// Save the session to disk - fileprivate func save(_ cryptobox: _CBox) { - if hasChanges { - zmLog.safePublic("Saving cryptobox session \(id)") - let result = cbox_session_save(cryptobox.ptr, implementation.ptr) - switch result { - case CBOX_SUCCESS: - return - default: - fatal("Can't save session: error \(result)") - } - } - } - - deinit { - closeInCryptobox() - } -} - -// MARK: - Logging - -extension EncryptionSession { - - func logSessionAndCyphertext( - reason: SanitizedString, - data: Data - ) { - EncryptionSession.logSessionAndCyphertext( - sessionId: id, - reason: reason, - data: data, - sessionURL: path - ) - } - - static func logSessionAndCyphertext( - sessionId: EncryptionSessionIdentifier, - reason: SanitizedString, - data: Data, - sessionURL: URL - ) { - let encodedData = HexDumpUnsafeLoggingData(data: data) - let sessionContent = (try? Data(contentsOf: sessionURL)) - .map { HexDumpUnsafeLoggingData(data: $0) } - zmLog.safePublic( - SanitizedString("Extensive logging (session \(sessionId)): ") + - SanitizedString("\(reason): cyphertext: \(encodedData); ") + - SanitizedString("session content: \(sessionContent)"), - level: .public - ) - } -} - -// MARK: - Encryption - -public protocol Encryptor: AnyObject { - /// Encrypts data for a client - /// It immediately saves the session - /// - throws: EncryptionSessionError in case no session with given recipient - func encrypt(_ plainText: Data, for recipientIdentifier: EncryptionSessionIdentifier) throws -> Data -} - -// MARK: - Decryption - -public protocol Decryptor: AnyObject { - /// Decrypts data from a client - /// The session is not saved to disk until the cache is committed - /// - throws: EncryptionSessionError in case no session with given recipient - func decrypt(_ cypherText: Data, from senderIdentifier: EncryptionSessionIdentifier) throws -> Data -} - -extension EncryptionSessionsDirectory: Encryptor, Decryptor { - - public func encrypt(_ plainText: Data, for recipientIdentifier: EncryptionSessionIdentifier) throws -> Data { - _ = validateContext() - guard let session = clientSession(for: recipientIdentifier) else { - zmLog.safePublic("Can't find session to encrypt for client \(recipientIdentifier)") - throw EncryptionSessionError.encryptionFailed.error - } - let cypherText = try session.encrypt(plainText) - saveSession(recipientIdentifier) - return cypherText - } - - public func decrypt(_ cypherText: Data, from senderIdentifier: EncryptionSessionIdentifier) throws -> Data { - _ = validateContext() - guard let session = clientSession(for: senderIdentifier) else { - zmLog.safePublic("Can't find session to decrypt for client \(senderIdentifier)") - throw EncryptionSessionError.decryptionFailed.error - } - return try session.decrypt(cypherText) - } -} - -private extension EncryptionSession { - - /// Decrypts data using the session. This function modifies the session - /// and it should be saved later - func decrypt(_ cypher: Data) throws -> Data { - var vectorBacking: OpaquePointer? - - zmLog.safePublic("Decrypting with session \(id)") - - let result = cypher.withUnsafeBytes { (cypherPointer: UnsafeRawBufferPointer) -> CBoxResult in - cbox_decrypt( - self.implementation.ptr, - cypherPointer.baseAddress!.assumingMemoryBound(to: UInt8.self), - cypher.count, - &vectorBacking - ) - } - - let resultRequiresLogging = result != CBOX_DUPLICATE_MESSAGE && result != CBOX_SUCCESS - if resultRequiresLogging || isExtensiveLoggingEnabled { - if isExtensiveLoggingEnabled { - logSessionAndCyphertext( - reason: "decrypting cyphertext: result \(result)", - data: cypher - ) - } else { - let encodedData = HexDumpUnsafeLoggingData(data: cypher) - zmLog.safePublic("Failed to decrypt cyphertext: session \(id): \(encodedData)", level: .public) - } - } - - try result.throwIfError() - - hasChanges = true - return Data.moveFromCBoxVector(vectorBacking)! - } - - /// Encrypts data using the session. This function modifies the session - /// and it should be saved later - func encrypt(_ plainText: Data) throws -> Data { - var vectorBacking: OpaquePointer? - - zmLog.safePublic("Encrypting with session \(id)") - let result = plainText.withUnsafeBytes { (plainTextPointer: UnsafeRawBufferPointer) -> CBoxResult in - cbox_encrypt( - self.implementation.ptr, - plainTextPointer.baseAddress!.assumingMemoryBound(to: UInt8.self), - plainText.count, - &vectorBacking - ) - } - - try result.throwIfError() - - hasChanges = true - let data = Data.moveFromCBoxVector(vectorBacking)! - - if isExtensiveLoggingEnabled { - logSessionAndCyphertext( - reason: "encrypted to cyphertext", - data: data - ) - } - return data - } -} - -// MARK: - Fingerprint - -private extension _CBoxSession { - - /// Returns the remote fingerprint associated with a session - var remoteFingerprint: Data { - var backingVector: OpaquePointer? - let result = cbox_fingerprint_remote(ptr, &backingVector) - guard result == CBOX_SUCCESS else { - fatal("Can't access remote fingerprint of session \(result)") - } - return Data.moveFromCBoxVector(backingVector)! - } -} - -// MARK: - Backing files - -extension EncryptionSession { - - /// Returns the expected path of the session file, given the root folder - fileprivate static func expectedPath(root: URL, for identifier: EncryptionSessionIdentifier) -> URL { - root.appendingPathComponent("sessions").appendingPathComponent(identifier.rawValue) - } - - /// Returns the expected path of this session - var path: URL { - EncryptionSession.expectedPath(root: cryptoboxPath, for: id) - } -} - -private extension EncryptionSessionsDirectory { - - /// Returns the file path where the session with the given identifier would be saved - func filePath(for identifier: EncryptionSessionIdentifier) -> URL { - EncryptionSession.expectedPath(root: generatingContext.path, for: identifier) - } -} - -// MARK: - Session identifier - -public struct EncryptionSessionIdentifier: Hashable, Equatable { - - public let userId: String - public let clientId: String - public let domain: String - - public var rawValue: String { - guard !userId.isEmpty else { - return clientId - } - guard !domain.isEmpty else { - return "\(userId)_\(clientId)" - } - - return "\(domain)_\(userId)_\(clientId)" - } - - public init(domain: String? = nil, userId: String, clientId: String) { - self.userId = userId - self.clientId = clientId - self.domain = domain ?? "" - } - - /// Use when migrating from old session identifier to new session identifier - init(fromLegacyV1Identifier clientId: String) { - self.userId = String() - self.clientId = clientId - self.domain = String() - } - - public func hash(into hasher: inout Hasher) { - hasher.combine(rawValue) - } -} - -public func == (lhs: EncryptionSessionIdentifier, rhs: EncryptionSessionIdentifier) -> Bool { - lhs.rawValue == rhs.rawValue -} - -extension EncryptionSessionIdentifier: SafeForLoggingStringConvertible { - public var safeForLoggingDescription: String { - "<\(domain.readableHash)>_<\(userId.readableHash)>_<\(clientId.readableHash)>" - } -} diff --git a/wire-ios-cryptobox/WireCryptobox/GenericHash.swift b/wire-ios-cryptobox/WireCryptobox/GenericHash.swift deleted file mode 100644 index b1e3019b5f1..00000000000 --- a/wire-ios-cryptobox/WireCryptobox/GenericHash.swift +++ /dev/null @@ -1,92 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import Clibsodium -import Foundation - -/// Encapsulates the hash value. - -public struct GenericHash: Hashable { - private let value: Int - - init(value: Int) { - self.value = value - } -} - -extension GenericHash: CustomStringConvertible { - public var description: String { - "GenericHash \(hashValue)" - } -} - -/// This class is designed to generate the hash value for the given input data. -/// Sample usage: -/// -/// let builder = GenericHashBuilder() -/// builder.append(data1) -/// builder.append(data2) -/// let hash = builder.build() -public final class GenericHashBuilder { - private enum State { - case initial - case readyToBuild - case done - } - - private var cryptoState: UnsafeMutableRawBufferPointer - private var opaqueCryptoState: OpaquePointer - - private var state: State = .initial - private static let size = MemoryLayout.size - - init() { - self.cryptoState = UnsafeMutableRawBufferPointer.allocate( - byteCount: crypto_generichash_statebytes(), - alignment: 64 - ) - self.opaqueCryptoState = OpaquePointer(cryptoState.baseAddress!) - - crypto_generichash_init(opaqueCryptoState, nil, 0, GenericHashBuilder.size) - } - - public func append(_ data: Data) { - assert(state != .done, "This builder cannot be used any more: hash is already calculated") - state = data.withUnsafeBytes { (bytes: UnsafeRawBufferPointer) -> State in - crypto_generichash_update( - opaqueCryptoState, - bytes.baseAddress!.assumingMemoryBound(to: UInt8.self), - UInt64(data.count) - ) - return .readyToBuild - } - } - - public func build() -> GenericHash { - assert(state != .done, "This builder cannot be used any more: hash is already calculated") - var hashBytes: [UInt8] = Array(repeating: 0, count: GenericHashBuilder.size) - crypto_generichash_final(opaqueCryptoState, &hashBytes, GenericHashBuilder.size) - state = .done - let bigEndianUInt = hashBytes.withUnsafeBytes { $0.load(as: Int.self) } - let value = CFByteOrderGetCurrent() == CFByteOrder(CFByteOrderLittleEndian.rawValue) - ? Int(bigEndian: bigEndianUInt) - : bigEndianUInt - - return GenericHash(value: value) - } -} diff --git a/wire-ios-cryptobox/WireCryptobox/Info.plist b/wire-ios-cryptobox/WireCryptobox/Info.plist deleted file mode 100644 index 0e600e67e7d..00000000000 --- a/wire-ios-cryptobox/WireCryptobox/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - $(CURRENT_PROJECT_VERSION) - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSPrincipalClass - - - diff --git a/wire-ios-cryptobox/WireCryptobox/Logs.swift b/wire-ios-cryptobox/WireCryptobox/Logs.swift deleted file mode 100644 index 4f82bacaae8..00000000000 --- a/wire-ios-cryptobox/WireCryptobox/Logs.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import Foundation -import WireSystem - -let zmLog = ZMSLog(tag: "cryptobox") diff --git a/wire-ios-cryptobox/WireCryptobox/NSData+CBox.swift b/wire-ios-cryptobox/WireCryptobox/NSData+CBox.swift deleted file mode 100644 index 09d0a3ed477..00000000000 --- a/wire-ios-cryptobox/WireCryptobox/NSData+CBox.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import Clibsodium -import Foundation - -extension Data { - - /// Moves from a CBoxVector to this data - /// During this call, the CBoxVector is freed - static func moveFromCBoxVector(_ vector: OpaquePointer?) -> Data? { - guard let vector else { return nil } - - let data = cbox_vec_data(vector) - let length = cbox_vec_len(vector) - let finalData = Data(bytes: UnsafePointer(data!), count: length) // this ctor copies - cbox_vec_free(vector) - return finalData - } -} diff --git a/wire-ios-cryptobox/WireCryptobox/PointerWrapper.swift b/wire-ios-cryptobox/WireCryptobox/PointerWrapper.swift deleted file mode 100644 index fc8330d5936..00000000000 --- a/wire-ios-cryptobox/WireCryptobox/PointerWrapper.swift +++ /dev/null @@ -1,35 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import Foundation - -/// This class is used to add type safety to C opaque pointers. -/// Just subclass this class and add the subclass to all signatures -/// -/// E.g. -/// ``` -/// class CStruct : PointerWrapper {} -/// -/// func foo(struct: CStruct) -> Int { -/// return some_c_function(struct.ptr) -/// } -/// -/// ``` -class PointerWrapper { - var ptr: OpaquePointer? -} diff --git a/wire-ios-cryptobox/WireCryptobox/WireCryptobox.h b/wire-ios-cryptobox/WireCryptobox/WireCryptobox.h deleted file mode 100644 index a6b2e605cc4..00000000000 --- a/wire-ios-cryptobox/WireCryptobox/WireCryptobox.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -#import - -//! Project version number for WireCryptobox. -FOUNDATION_EXPORT double WireCryptobox_VersionNumber; - -//! Project version string for WireCryptobox. -FOUNDATION_EXPORT const unsigned char WireCryptobox_VersionString[]; - -#import diff --git a/wire-ios-cryptobox/WireCryptobox/cbox.h b/wire-ios-cryptobox/WireCryptobox/cbox.h deleted file mode 120000 index 5f3e4c2b3f9..00000000000 --- a/wire-ios-cryptobox/WireCryptobox/cbox.h +++ /dev/null @@ -1 +0,0 @@ -../../Carthage/Build/cryptobox.xcframework/ios-arm64/Headers/cbox.h \ No newline at end of file diff --git a/wire-ios-cryptobox/WireCryptoboxTests/ChaCha20AEADEncryptionTests.swift b/wire-ios-cryptobox/WireCryptoboxTests/ChaCha20AEADEncryptionTests.swift deleted file mode 100644 index a0c1848201e..00000000000 --- a/wire-ios-cryptobox/WireCryptoboxTests/ChaCha20AEADEncryptionTests.swift +++ /dev/null @@ -1,167 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import Clibsodium -import WireCrypto -import XCTest - -@testable import WireCryptobox - -class ChaCha20AEADEncryptionTests: XCTestCase { - - private let context = Data.secureRandomData(length: 8) - - // MARK: - Helpers - - private typealias Sut = ChaCha20Poly1305.AEADEncryption - - private func generateRandomCiphertext(length: UInt) -> Data { - // Large enough to include authentication bytes in the ciphertext. - Data.secureRandomData(length: length + UInt(crypto_aead_aes256gcm_ABYTES)) - } - - // MARK: - Positive Tests - - func testThatItEncryptsAndDecryptsMessage() throws { - // Given - let message = Data("Hello, world".utf8) - let key = Data.zmRandomSHA256Key() - - // When - let (ciphertext, nonce) = try Sut.encrypt(message: message, context: context, key: key) - - // Then - XCTAssertNotEqual(ciphertext, message) - XCTAssertFalse(nonce.isEmpty) - - // When - let decryptedMessage = try Sut.decrypt(ciphertext: ciphertext, nonce: nonce, context: context, key: key) - - // Then - XCTAssertEqual(decryptedMessage, message) - } - - // MARK: - Negative Tests - - func testThatItFailsToEncryptIfKeyIsMalformed() throws { - // Given - let keyOfWrongLength = Data.zmRandomSHA256Key().dropLast() - - do { - // When - _ = try Sut.encrypt(message: Data(), context: context, key: keyOfWrongLength) - } catch let error as Sut.EncryptionError { - // Then - XCTAssertEqual(error, .malformedKey) - } catch { - XCTFail("Unexpected error: \(error.localizedDescription)") - } - } - - func testThatItFailsToDecryptIfKeyIsMalformed() throws { - // Given - let ciphertext = generateRandomCiphertext(length: 8) - let nonce = Data(Sut.generateRandomNonceBytes()) - let keyOfWrongLength = Data.zmRandomSHA256Key().dropLast() - - do { - // When - _ = try Sut.decrypt(ciphertext: ciphertext, nonce: nonce, context: context, key: keyOfWrongLength) - } catch let error as Sut.EncryptionError { - // Then - XCTAssertEqual(error, .malformedKey) - } catch { - XCTFail("Unexpected error: \(error.localizedDescription)") - } - } - - func testThatItFailsToDecryptIfNonceIsMalformed() throws { - // Given - let ciphertext = generateRandomCiphertext(length: 8) - let nonceOfWrongLength = Data(Sut.generateRandomNonceBytes()).dropLast() - let key = Data.zmRandomSHA256Key() - - do { - // When - _ = try Sut.decrypt(ciphertext: ciphertext, nonce: nonceOfWrongLength, context: context, key: key) - } catch let error as Sut.EncryptionError { - // Then - XCTAssertEqual(error, .malformedNonce) - } catch { - XCTFail("Unexpected error: \(error.localizedDescription)") - } - } - - func testThatItFailsToDecryptWithDifferentKey() throws { - // Given - let message = Data("Hello, world".utf8) - let key1 = Data.zmRandomSHA256Key() - let key2 = Data.zmRandomSHA256Key() - - let (ciphertext, nonce) = try Sut.encrypt(message: message, context: context, key: key1) - - do { - // When - _ = try Sut.decrypt(ciphertext: ciphertext, nonce: nonce, context: context, key: key2) - } catch let error as Sut.EncryptionError { - // Then - XCTAssertEqual(error, .failedToDecrypt) - } catch { - XCTFail("Unexpected error: \(error.localizedDescription)") - } - } - - func testThatItFailsToDecryptWithDifferentNonce() throws { - // Given - let message = Data("Hello, world".utf8) - let key = Data.zmRandomSHA256Key() - let randomNonce = Data(Sut.generateRandomNonceBytes()) - - let (ciphertext, _) = try Sut.encrypt(message: message, context: context, key: key) - - do { - // When - _ = try Sut.decrypt(ciphertext: ciphertext, nonce: randomNonce, context: context, key: key) - } catch let error as Sut.EncryptionError { - // Then - XCTAssertEqual(error, .failedToDecrypt) - } catch { - XCTFail("Unexpected error: \(error.localizedDescription)") - } - } - - func testThatItFailsToDecryptWithDifferentContext() throws { - // Given - let message = Data("Hello, world".utf8) - let key = Data.zmRandomSHA256Key() - let randomNonce = Data(Sut.generateRandomNonceBytes()) - - let (ciphertext, _) = try Sut.encrypt(message: message, context: context, key: key) - - do { - // When - _ = try Sut.decrypt(ciphertext: ciphertext, nonce: randomNonce, context: context.dropFirst(), key: key) - } catch let error as Sut.EncryptionError { - // Then - XCTAssertEqual(error, .failedToDecrypt) - } catch { - XCTFail("Unexpected error: \(error.localizedDescription)") - } - } - -} diff --git a/wire-ios-cryptobox/WireCryptoboxTests/CryptoboxTests-Bridging-Header.h b/wire-ios-cryptobox/WireCryptoboxTests/CryptoboxTests-Bridging-Header.h deleted file mode 100644 index 89c90917712..00000000000 --- a/wire-ios-cryptobox/WireCryptoboxTests/CryptoboxTests-Bridging-Header.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// diff --git a/wire-ios-cryptobox/WireCryptoboxTests/EncryptionContextCachingTests.swift b/wire-ios-cryptobox/WireCryptoboxTests/EncryptionContextCachingTests.swift deleted file mode 100644 index 5d65a2346f6..00000000000 --- a/wire-ios-cryptobox/WireCryptoboxTests/EncryptionContextCachingTests.swift +++ /dev/null @@ -1,152 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import XCTest -@testable import WireCryptobox - -let someTextToEncrypt = "ENCRYPT THIS!" - -class DebugEncryptor: Encryptor { - var index: Int = 0 - func encrypt(_ plainText: Data, for recipientIdentifier: EncryptionSessionIdentifier) throws -> Data { - var result = plainText - result.append(recipientIdentifier.rawValue.data(using: .utf8)!) - result.append(Data("\(index)".utf8)) - index += 1 - return result - } -} - -class EncryptionContextCachingTests: XCTestCase { - func testThatItDoesNotCachePerDefault() { - // GIVEN - let tempDir = createTempFolder() - let mainContext = EncryptionContext(path: tempDir) - - let expectation = expectation(description: "Encryption succeeded") - - // WHEN - mainContext.perform { sessionContext in - try! sessionContext.createClientSession(hardcodedClientId, base64PreKeyString: hardcodedPrekey) - - let encryptedDataNonCachedFirst = try! sessionContext.encrypt( - someTextToEncrypt.data(using: .utf8)!, - for: hardcodedClientId - ) - let encryptedDataNonCachedSecond = try! sessionContext.encrypt( - someTextToEncrypt.data(using: .utf8)!, - for: hardcodedClientId - ) - - XCTAssertNotEqual(encryptedDataNonCachedFirst, encryptedDataNonCachedSecond) - - expectation.fulfill() - } - - // THEN - waitForExpectations(timeout: 0) { _ in } - } - - func testThatItCachesWhenRequested() { - // GIVEN - let tempDir = createTempFolder() - let mainContext = EncryptionContext(path: tempDir) - - let expectation = expectation(description: "Encryption succeeded") - - // WHEN - mainContext.perform { sessionContext in - try! sessionContext.createClientSession(hardcodedClientId, base64PreKeyString: hardcodedPrekey) - - let encryptedDataFirst = try! sessionContext.encryptCaching( - someTextToEncrypt.data(using: .utf8)!, - for: hardcodedClientId - ) - let encryptedDataSecond = try! sessionContext.encryptCaching( - someTextToEncrypt.data(using: .utf8)!, - for: hardcodedClientId - ) - - XCTAssertEqual(encryptedDataFirst, encryptedDataSecond) - - expectation.fulfill() - } - - // THEN - waitForExpectations(timeout: 0) { _ in } - } - - func testThatCacheKeyDependsOnData() { - // GIVEN - let tempDir = createTempFolder() - let mainContext = EncryptionContext(path: tempDir) - - let expectation = expectation(description: "Encryption succeeded") - - // WHEN - mainContext.perform { sessionContext in - try! sessionContext.createClientSession(hardcodedClientId, base64PreKeyString: hardcodedPrekey) - - let encryptedDataFirst = try! sessionContext.encryptCaching( - someTextToEncrypt.data(using: .utf8)!, - for: hardcodedClientId - ) - let encryptedDataSecond = try! sessionContext.encryptCaching( - someTextToEncrypt.appending(someTextToEncrypt).data(using: .utf8)!, - for: hardcodedClientId - ) - - XCTAssertNotEqual(encryptedDataFirst, encryptedDataSecond) - - expectation.fulfill() - } - - // THEN - waitForExpectations(timeout: 0) { _ in } - } - - func testThatItFlushesTheCache() { - // GIVEN - let tempDir = createTempFolder() - let mainContext = EncryptionContext(path: tempDir) - - let expectation = expectation(description: "Encryption succeeded") - - // WHEN - mainContext.perform { sessionContext in - try! sessionContext.createClientSession(hardcodedClientId, base64PreKeyString: hardcodedPrekey) - - let encryptedDataFirst = try! sessionContext.encryptCaching( - someTextToEncrypt.data(using: .utf8)!, - for: hardcodedClientId - ) - sessionContext.purgeEncryptedPayloadCache() - let encryptedDataSecond = try! sessionContext.encryptCaching( - someTextToEncrypt.data(using: .utf8)!, - for: hardcodedClientId - ) - - XCTAssertNotEqual(encryptedDataFirst, encryptedDataSecond) - - expectation.fulfill() - } - - // THEN - waitForExpectations(timeout: 0) { _ in } - } -} diff --git a/wire-ios-cryptobox/WireCryptoboxTests/EncryptionContextTests.swift b/wire-ios-cryptobox/WireCryptoboxTests/EncryptionContextTests.swift deleted file mode 100644 index 04d9953eb42..00000000000 --- a/wire-ios-cryptobox/WireCryptoboxTests/EncryptionContextTests.swift +++ /dev/null @@ -1,272 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import XCTest -@testable import WireCryptobox - -class EncryptionContextTests: XCTestCase { - - /// This test verifies that the critical section (in usingSessions) - /// can not be entered at the same time on two different EncryptionContext - func testThatItBlockWhileUsingSessionsOnTwoDifferentObjects() { - - // GIVEN - let tempDir = createTempFolder() - - // have to do work on other queues because the main thread can't be blocked - let queue1 = DispatchQueue(label: name) - let queue2 = DispatchQueue(label: name) - - // coordinate between the two threads to make sure that they are executed in the right order - let context2CanEnterSemaphore = DispatchSemaphore(value: 0) - let context1CanCompleteSemaphore = DispatchSemaphore(value: 0) - let queue2IsDoneSemaphore = DispatchSemaphore(value: 0) - - // whether the queues entered the critical section - var queue1EnteredCriticalSection = false - var queue1LeftCriticalSection = false - var queue2EnteredCriticalSection = false - var queue2LeftCriticalSection = false - - // WHEN - - // queue 1 will enter critical section and wait there until told to complete - queue1.async { - - // entering the critical section - EncryptionContext(path: tempDir).perform { _ in - queue1EnteredCriticalSection = true - // signal queue2 other thread that it should attempt to enter critical section - context2CanEnterSemaphore.signal() - // wait until it's told to leave critical section - context1CanCompleteSemaphore.wait() - } - queue1LeftCriticalSection = true - } - - // queue 2 will try to enter critical section, but should block (because of queue 1) - queue2.async { - - // make sure queue 1 is in the right place (critical section) before attempting to enter critical section - context2CanEnterSemaphore.wait() - EncryptionContext(path: tempDir).perform { _ in - // will not get here until queue1 has quit critical section - queue2EnteredCriticalSection = true - } - queue2LeftCriticalSection = true - queue2IsDoneSemaphore.signal() - } - - // wait a few ms so that all threads are ready - Thread.sleep(forTimeInterval: 0.3) - - // THEN - XCTAssertTrue(queue1EnteredCriticalSection) - XCTAssertFalse(queue1LeftCriticalSection) - XCTAssertFalse(queue2EnteredCriticalSection) - XCTAssertFalse(queue2LeftCriticalSection) - - // WHEN - context1CanCompleteSemaphore.signal() - - // THEN - queue2IsDoneSemaphore.wait() - XCTAssertTrue(queue1EnteredCriticalSection) - XCTAssertTrue(queue1LeftCriticalSection) - XCTAssertTrue(queue2EnteredCriticalSection) - XCTAssertTrue(queue2LeftCriticalSection) - } - - func testThatItDoesNotBlockWhileUsingSessionsMultipleTimesOnTheSameObject() { - - // GIVEN - let tempDir = createTempFolder() - - let mainContext = EncryptionContext(path: tempDir) - let invocation1 = expectation(description: "first begin using session") - let invocation2 = expectation(description: "second begin using session") - - // WHEN - // enter critical section - mainContext.perform { _ in - invocation1.fulfill() - - // enter again - mainContext.perform { _ in - invocation2.fulfill() - } - } - - // THEN - waitForExpectations(timeout: 0) { _ in } - - } - - func testThatItReceivesTheSameSessionStatusWithNestedPerform() { - - // GIVEN - let tempDir = createTempFolder() - - let mainContext = EncryptionContext(path: tempDir) - var lastStatus: EncryptionSessionsDirectory? - - let invocation1 = expectation(description: "first begin using session") - let invocation2 = expectation(description: "second begin using session") - - // WHEN - - // enter critical section - mainContext.perform { context1 in - lastStatus = context1 - invocation1.fulfill() - - mainContext.perform { context2 in - XCTAssertTrue(lastStatus === context2) - invocation2.fulfill() - } - } - - // THEN - waitForExpectations(timeout: 0) { _ in } - } - - func testThatItSafelyEncryptDecryptDuringNestedPerform() { - - // GIVEN - let tempDir = createTempFolder() - - let mainContext = EncryptionContext(path: tempDir) - - let someTextToEncrypt = "ENCRYPT THIS!" - - // WHEN - - // enter critical section - mainContext.perform { (context1: EncryptionSessionsDirectory) in - - try! context1.createClientSession(hardcodedClientId, base64PreKeyString: hardcodedPrekey) - - mainContext.perform { (context2: EncryptionSessionsDirectory) in - _ = try! context2.encrypt(someTextToEncrypt.data(using: .utf8)!, for: hardcodedClientId) - - } - - _ = try! context1.encrypt(someTextToEncrypt.data(using: .utf8)!, for: hardcodedClientId) - } - - // THEN - // it didn't crash - } - - func testThatItDoesNotReceivesTheSameSessionStatusIfDonePerforming() { - - // GIVEN - let tempDir = createTempFolder() - - let mainContext = EncryptionContext(path: tempDir) - var lastStatus: EncryptionSessionsDirectory? - - let invocation1 = expectation(description: "first begin using session") - let invocation2 = expectation(description: "second begin using session") - - // WHEN - - // enter critical section - mainContext.perform { context in - lastStatus = context - invocation1.fulfill() - } - - // THEN - // enter again - mainContext.perform { context in - invocation2.fulfill() - XCTAssertFalse(lastStatus === context) - } - - waitForExpectations(timeout: 0) { _ in } - } - -} - -// MARK: - Logging - -extension EncryptionContextTests { - - func testThatItSetsExtendedLoggingOnSessions() { - - // GIVEN - let identifier = EncryptionSessionIdentifier(domain: "example.com", userId: "user", clientId: "foo") - let tempDir = createTempFolder() - let mainContext = EncryptionContext(path: tempDir) - - // WHEN - mainContext.setExtendedLogging(identifier: identifier, enabled: true) - - // THEN - mainContext.perform { - XCTAssertEqual($0.extensiveLoggingSessions, Set([identifier])) - } - } - - func testThatItDoesSetExtendedLoggingOnSessions() { - - // GIVEN - let tempDir = createTempFolder() - let mainContext = EncryptionContext(path: tempDir) - - // THEN - mainContext.perform { - XCTAssert($0.extensiveLoggingSessions.isEmpty) - } - } - - func testThatItDoesNotLogEncryptionWhenRemovingExtendedLogging() { - - // GIVEN - let identifier = EncryptionSessionIdentifier(domain: "example.com", userId: "user", clientId: "foo") - let tempDir = createTempFolder() - let mainContext = EncryptionContext(path: tempDir) - - // WHEN - mainContext.setExtendedLogging(identifier: identifier, enabled: true) - mainContext.setExtendedLogging(identifier: identifier, enabled: false) - - // THEN - mainContext.perform { - XCTAssert($0.extensiveLoggingSessions.isEmpty) - } - } - - func testThatItDoesNotLogEncryptionWhenRemovingAllExtendedLogging() { - - // GIVEN - let identifier = EncryptionSessionIdentifier(domain: "example.com", userId: "user", clientId: "foo") - let tempDir = createTempFolder() - let mainContext = EncryptionContext(path: tempDir) - - // WHEN - mainContext.setExtendedLogging(identifier: identifier, enabled: true) - mainContext.disableExtendedLoggingOnAllSessions() - - // THEN - mainContext.perform { - XCTAssert($0.extensiveLoggingSessions.isEmpty) - } - } -} diff --git a/wire-ios-cryptobox/WireCryptoboxTests/EncryptionSessionsDirectoryTests.swift b/wire-ios-cryptobox/WireCryptoboxTests/EncryptionSessionsDirectoryTests.swift deleted file mode 100644 index f1d17bfe8b8..00000000000 --- a/wire-ios-cryptobox/WireCryptoboxTests/EncryptionSessionsDirectoryTests.swift +++ /dev/null @@ -1,850 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import Foundation -import WireSystem -import XCTest -@testable import WireCryptobox - -class EncryptionSessionsDirectoryTests: XCTestCase { - - var contextAlice: EncryptionContext! - var contextBob: EncryptionContext! - var statusAlice: EncryptionSessionsDirectory! - var statusBob: EncryptionSessionsDirectory! - - override func setUp() { - contextAlice = createEncryptionContext() - contextBob = createEncryptionContext() - recreateStatuses() - } - - override func tearDown() { - statusAlice = nil - statusBob = nil - contextAlice = nil - contextBob = nil - } - -} - -// MARK: - Session creation and encoding/decoding - -extension EncryptionSessionsDirectoryTests { - - func testThatItCanDecodeAfterInitializingWithAValidKey() throws { - - // GIVEN - let plainText = Data("foo".utf8) - - // WHEN - try statusAlice.createClientSession(Person.Bob.identifier, base64PreKeyString: statusBob.generatePrekey(2)) - - // THEN - let prekeyMessage = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - let decoded = try! statusBob.createClientSessionAndReturnPlaintext( - for: Person.Alice.identifier, - prekeyMessage: prekeyMessage - ) - XCTAssertEqual(decoded, plainText) - } - - func testThatItCanCallCreateSessionWithTheSameKeyMultipleTimes() throws { - - // GIVEN - let plainText = Data("foo".utf8) - let prekey = try! statusBob.generatePrekey(34) - try statusAlice.createClientSession(Person.Bob.identifier, base64PreKeyString: prekey) - - // WHEN - try statusAlice.createClientSession(Person.Bob.identifier, base64PreKeyString: prekey) - - // THEN - let prekeyMessage = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - let decoded = try! statusBob.createClientSessionAndReturnPlaintext( - for: Person.Alice.identifier, - prekeyMessage: prekeyMessage - ) - XCTAssertEqual(decoded, plainText) - } - - func testThatItCanNotCreateANewSessionWithAnInvalidKey() { - - // GIVEN - - // WHEN - do { - _ = try statusAlice.createClientSession(Person.Bob.identifier, base64PreKeyString: "aabb") - XCTFail("should have failed to use prekey") - } catch let err as CBoxResult { - XCTAssertEqual(err, CBOX_DECODE_ERROR) - } catch { - XCTFail("should have thrown a CBoxResult") - } - } - - func testThatItCanNotDecodePrekeyMessagesWithTheWrongKey() throws { - - // WHEN - _ = try statusAlice.createClientSession(Person.Bob.identifier, base64PreKeyString: hardcodedPrekey) - - // THEN - XCTAssertFalse(checkThatAMessageCanBeSent(.Alice)) - } -} - -// MARK: - Prekeys - -extension EncryptionSessionsDirectoryTests { - - func testThatFingerprintExtractedFromPrekeyMatchesLocalFingerprint() throws { - let prekeyId: UInt16 = 12 - let prekeyData = try statusAlice.generatePrekey(prekeyId) - let fingerprint = EncryptionSessionsDirectory.fingerprint(fromPrekey: Data(base64Encoded: prekeyData)!) - - XCTAssertEqual(fingerprint, statusAlice.localFingerprint) - } - - func testThatItGeneratesAPrekey() { - - // GIVEN - let prekeyId: UInt16 = 12 - - // WHEN - let prekey = try! statusAlice.generatePrekey(prekeyId) - - // THEN - var prekeyRetrievedId: UInt16 = 0 - let prekeyData = Data(base64Encoded: prekey, options: [])! - let result = prekeyData - .withUnsafeBytes { (prekeyDataPointer: UnsafeRawBufferPointer) -> CBoxResult in cbox_is_prekey( - prekeyDataPointer.baseAddress!.assumingMemoryBound(to: UInt8.self), - prekeyData.count, - &prekeyRetrievedId - ) } - XCTAssertEqual(result, CBOX_SUCCESS) - XCTAssertEqual(prekeyRetrievedId, prekeyId) - - } - - func testThatItGeneratesLastPrekey() { - - // GIVEN - let prekeyId: UInt16 = CBOX_LAST_PREKEY_ID - - // WHEN - let prekey = try! statusAlice.generateLastPrekey() - - // THEN - var prekeyRetrievedId: UInt16 = 0 - let prekeyData = Data(base64Encoded: prekey, options: [])! - let result = prekeyData - .withUnsafeBytes { (prekeyDataPointer: UnsafeRawBufferPointer) -> CBoxResult in cbox_is_prekey( - prekeyDataPointer.baseAddress!.assumingMemoryBound(to: UInt8.self), - prekeyData.count, - &prekeyRetrievedId - ) } - XCTAssertEqual(result, CBOX_SUCCESS) - XCTAssertEqual(prekeyRetrievedId, prekeyId) - - } - - func testThatItGeneratesARangeOfPrekeys() { - - // GIVEN - let rangeStart = 3 - let rangeLength = 10 - let prekeyIds: CountableRange = UInt16(rangeStart) ..< UInt16(rangeStart + rangeLength) - - // WHEN - var prekeys: [(id: UInt16, prekey: String)] = [] - prekeys = try! statusAlice.generatePrekeys(prekeyIds) - - // THEN - XCTAssertEqual(prekeyIds.count, rangeLength) - for i in 0 ..< rangeLength { - let (id, prekey) = prekeys[i] - let prekeyData = Data(base64Encoded: prekey, options: [])! - var prekeyRetrievedId: UInt16 = 0 - let result = prekeyData - .withUnsafeBytes { (prekeyDataPointer: UnsafeRawBufferPointer) -> CBoxResult in cbox_is_prekey( - prekeyDataPointer.baseAddress!.assumingMemoryBound(to: UInt8.self), - prekeyData.count, - &prekeyRetrievedId - ) } - XCTAssertEqual(result, CBOX_SUCCESS) - XCTAssertEqual(Int(prekeyRetrievedId), i + rangeStart) - XCTAssertEqual(prekeyRetrievedId, id) - } - } -} - -// MARK: - Local fingerprint - -extension EncryptionSessionsDirectoryTests { - - func testThatItReturnsTheLocalFingerprint() { - - // GIVEN - - // WHEN - let fingerprint = statusAlice.localFingerprint - - // THEN - // check it's consistent - XCTAssertEqual(statusAlice.localFingerprint, fingerprint) - } - - func testThatASessionHasAMatchingRemoteFingerprint() { - - // GIVEN - - // WHEN - establishSessionBetweenAliceAndBob() - - // THEN - let aliceLocalFingerprint = statusAlice.localFingerprint - let bobLocalFingerprint = statusBob.localFingerprint - let aliceRemoteFingerprint = statusBob.fingerprint(for: Person.Alice.identifier) - let bobRemoteFingerprint = statusAlice.fingerprint(for: Person.Bob.identifier) - XCTAssertEqual(aliceLocalFingerprint, aliceRemoteFingerprint) - XCTAssertEqual(bobLocalFingerprint, bobRemoteFingerprint) - XCTAssertNotNil(aliceLocalFingerprint) - XCTAssertNotNil(bobLocalFingerprint) - } - - func testThatAClientWithoutSessionHasNoRemoteFingerprint() { - - // GIVEN - // WHEN - // THEN - XCTAssertNil(statusAlice.fingerprint(for: EncryptionSessionIdentifier( - domain: "example.com", - userId: "aa22", - clientId: "8899" - ))) - } -} - -// MARK: - Deletion - -extension EncryptionSessionsDirectoryTests { - - func testThatItDeletesASession() { - - // GIVEN - establishSessionBetweenAliceAndBob() - - // WHEN - statusAlice.delete(Person.Bob.identifier) - - // THEN - let cypherText = try? statusAlice.encrypt(Data("foo".utf8), for: Person.Bob.identifier) - XCTAssertNil(cypherText) - } - - func testThatItCanDeleteASessionThatDoesNotExist() { - - // GIVEN - - // WHEN - statusAlice.delete(hardcodedClientId) - - // THEN - // no crash - } -} - -// MARK: - Session cache management - -extension EncryptionSessionsDirectoryTests { - - func testThatCreatedSessionsAreNotSavedImmediately() { - - // GIVEN - - // WHEN - try! statusAlice.createClientSession(Person.Bob.identifier, base64PreKeyString: statusBob.generatePrekey(1)) - - // THEN - let statusAliceCopy = EncryptionSessionsDirectory( - generatingContext: contextAlice, - encryptionPayloadCache: Cache(maxCost: 1000, maxElementsCount: 100), - extensiveLoggingSessions: Set() - ) - statusAliceCopy.debug_disableContextValidityCheck = true - let cypher = try? statusAliceCopy.encrypt(Data("foo".utf8), for: Person.Bob.identifier) - XCTAssertNil(cypher) - } - - func testThatNewlyCreatedSessionsAreSavedWhenReleasingTheStatus() { - - // GIVEN - let plainText = Data("foo".utf8) - establishSessionFromAliceToBob() - - // WHEN - statusAlice = nil - - // THEN - let statusAliceCopy = EncryptionSessionsDirectory( - generatingContext: contextAlice, - encryptionPayloadCache: Cache(maxCost: 1000, maxElementsCount: 100), - extensiveLoggingSessions: Set() - ) - statusAliceCopy.debug_disableContextValidityCheck = true - let prekeyMessage = try! statusAliceCopy.encrypt(plainText, for: Person.Bob.identifier) - let decoded = try! statusBob.createClientSessionAndReturnPlaintext( - for: Person.Alice.identifier, - prekeyMessage: prekeyMessage - ) - XCTAssertEqual(plainText, decoded) - } - - func testThatNewlyCreatedSessionsAreNotSavedWhenDiscarding() { - - // GIVEN - establishSessionFromAliceToBob() - - // WHEN - statusAlice.discardCache() - statusAlice = nil - - // THEN - let statusAliceCopy = EncryptionSessionsDirectory( - generatingContext: contextAlice, - encryptionPayloadCache: Cache(maxCost: 1000, maxElementsCount: 100), - extensiveLoggingSessions: Set() - ) - statusAliceCopy.debug_disableContextValidityCheck = true - let cypher = try? statusAliceCopy.encrypt(Data("foo".utf8), for: Person.Bob.identifier) - XCTAssertNil(cypher) - } - - func testThatModifiedSessionsAreNotSavedWhenDiscarding() { - - // GIVEN - let plainText = Data("foo".utf8) - establishSessionFromAliceToBob() - let prekeyMessage = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - _ = try! statusBob.createClientSessionAndReturnPlaintext( - for: Person.Alice.identifier, - prekeyMessage: prekeyMessage - ) - recreateStatuses() // force save - - // WHEN - let cypherText = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - _ = try! statusBob.decrypt(cypherText, from: Person.Alice.identifier) - statusBob.discardCache() - statusBob = nil - - // THEN - let statusBobCopy = EncryptionSessionsDirectory( - generatingContext: contextBob, - encryptionPayloadCache: Cache(maxCost: 1000, maxElementsCount: 100), - extensiveLoggingSessions: Set() - ) - statusBobCopy.debug_disableContextValidityCheck = true - let decoded = try! statusBobCopy.decrypt(cypherText, from: Person.Alice.identifier) - XCTAssertEqual(decoded, plainText) - } - - func testThatItCanNotDecodeAfterDiscardingCache() { - - // GIVEN - establishSessionFromAliceToBob() - - // WHEN - statusAlice.discardCache() - - // THEN - XCTAssertFalse(checkThatAMessageCanBeSent(.Alice)) - } - - func testThatItDecodeFutureMessageAfterDiscardingCacheOnTheReceivingSide() { - - // GIVEN - establishSessionBetweenAliceAndBob() - checkThatAMessageCanBeSent(.Alice, saveReceiverCache: false) - - // WHEN - statusBob.discardCache() - - // THEN - XCTAssertNotNil(checkThatAMessageCanBeSent(.Alice)) - } - - func testThatItCanNotDecodeDuplicatedMessageIfTheCacheIsNotDiscarded() { - - // GIVEN - establishSessionBetweenAliceAndBob() - let plainText = Data("foo".utf8) - let cypherText = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - _ = try! statusBob.decrypt(cypherText, from: Person.Alice.identifier) - - // WHEN - do { - _ = try statusBob.decrypt(cypherText, from: Person.Alice.identifier) - XCTFail("Should have failed") - return - } catch let err as CBoxResult where err == CBOX_DUPLICATE_MESSAGE { - // pass - } catch { - XCTFail("Wrong error") - } - } - - func testThatItCanNotDecodeDuplicatedMessageIfTheCacheIsNotDiscardedAndReportsTheCorrectErrorInObjC() { - - // GIVEN - establishSessionBetweenAliceAndBob() - let plainText = Data("foo".utf8) - let cypherText = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - _ = try! statusBob.decrypt(cypherText, from: Person.Alice.identifier) - - // WHEN - do { - _ = try statusBob.decrypt(cypherText, from: Person.Alice.identifier) - XCTFail("Should have failed") - return - } catch let error as CBoxResult { - XCTAssertEqual(error, CBOX_DUPLICATE_MESSAGE) - } catch { - XCTFail() - } - } - - func testThatItCanDecodeDuplicatedMessageIfTheCacheIsDiscarded() { - - // GIVEN - establishSessionBetweenAliceAndBob() - let plainText = Data("foo".utf8) - let cypherText = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - _ = try! statusBob.decrypt(cypherText, from: Person.Alice.identifier) - - // WHEN - statusBob.discardCache() - - // THEN - do { - _ = try statusBob.decrypt(cypherText, from: Person.Alice.identifier) - } catch { - XCTFail("Should decrypt") - } - } - - func testThatItCanNotDecodeDuplicatedMessageIfTheCacheIsCommitted() { - - // GIVEN - establishSessionBetweenAliceAndBob() - let plainText = Data("foo".utf8) - let cypherText = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - _ = try! statusBob.decrypt(cypherText, from: Person.Alice.identifier) - - // WHEN - recreateStatuses() // force save - - // THEN - do { - _ = try statusBob.decrypt(cypherText, from: Person.Alice.identifier) - XCTFail("Should have failed") - return - } catch let err as CBoxResult where err == CBOX_DUPLICATE_MESSAGE { - // pass - } catch { - XCTFail("Wrong error") - } - } - - func testThatItCanDecodeAfterSavingCache() { - - // GIVEN - let plainText = Data("foo".utf8) - establishSessionFromAliceToBob() - - // WHEN - recreateStatuses() // force save - - // THEN - let prekeyMessage = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - let decoded = try! statusBob.createClientSessionAndReturnPlaintext( - for: Person.Alice.identifier, - prekeyMessage: prekeyMessage - ) - XCTAssertEqual(decoded, plainText) - } - - func testThatItCanDecodeMultipleMessagesWithoutSaving() { - - // GIVEN - establishSessionBetweenAliceAndBob() - - // WHEN - checkThatAMessageCanBeSent(.Alice, saveReceiverCache: false) - - // THEN - XCTAssertTrue(checkThatAMessageCanBeSent(.Alice)) - XCTAssertTrue(checkThatAMessageCanBeSent(.Alice)) - XCTAssertTrue(checkThatAMessageCanBeSent(.Alice)) - } -} - -// MARK: - Session migration tests - -extension EncryptionSessionsDirectoryTests { - - func testThatItCanMigrateASessionAndReceive() { - - // GIVEN - let oldIdentifier = "aabbccdd" - bobIdentifierOverride = oldIdentifier - - establishSessionBetweenAliceAndBob() - checkThatAMessageCanBeSent(.Alice) - checkThatAMessageCanBeSent(.Bob) - - // WHEN - bobIdentifierOverride = nil - statusAlice.migrateSession(from: oldIdentifier, to: Person.Bob.identifier) - - // THEN - XCTAssertTrue(checkThatAMessageCanBeSent(.Bob)) - } - - func testThatItCanMigrateASessionAndSend() { - - // GIVEN - let oldIdentifier = "aabbccdd" - bobIdentifierOverride = oldIdentifier - - establishSessionBetweenAliceAndBob() - checkThatAMessageCanBeSent(.Alice) - checkThatAMessageCanBeSent(.Bob) - - // WHEN - bobIdentifierOverride = nil - statusAlice.migrateSession(from: oldIdentifier, to: Person.Bob.identifier) - - // THEN - XCTAssertTrue(checkThatAMessageCanBeSent(.Alice)) - } - - func testThatItWontMigrateIfNewSessionAlreadyExists() { - - // GIVEN - let oldIdentifier = "aabbccdd" - - establishSessionBetweenAliceAndBob() - checkThatAMessageCanBeSent(.Alice) - checkThatAMessageCanBeSent(.Bob) - - bobIdentifierOverride = oldIdentifier - establishSessionFromAliceToBob() - - // WHEN - bobIdentifierOverride = nil - statusAlice.migrateSession(from: oldIdentifier, to: Person.Bob.identifier) - - // THEN - XCTAssertTrue(checkThatAMessageCanBeSent(.Bob)) - } - - func testThatItWontMigrateIfOldSessionDoesNotExists() { - - // GIVEN - let oldIdentifier = "aabbccdd" - - establishSessionBetweenAliceAndBob() - checkThatAMessageCanBeSent(.Alice) - checkThatAMessageCanBeSent(.Bob) - - // WHEN - statusAlice.migrateSession(from: oldIdentifier, to: Person.Bob.identifier) - - // THEN - XCTAssertTrue(checkThatAMessageCanBeSent(.Bob)) - } -} - -// MARK: - Extended logging - -extension EncryptionSessionsDirectoryTests { - - func testThatItLogsEncryptionWhenExtendedLoggingIsSet() { - - // GIVEN - recreateAliceStatus(extendedLoggingSession: Set([Person.Bob.identifier])) - let plainText = Data("foo".utf8) - establishSessionFromAliceToBob() - let logExpectation = expectation(description: "Encrypting") - - // EXPECT - let token = ZMSLog.addEntryHook { level, tag, entry, _ in - if level == .public, - tag == "cryptobox", - entry.text.contains("encrypted to cyphertext: cyphertext") { - logExpectation.fulfill() - } - } - - // WHEN - _ = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - - // THEN - waitForExpectations(timeout: 1) - - // AFTER - ZMSLog.removeLogHook(token: token) - } - - func testThatItDoesNotLogEncryptionWhenExtendedLoggingIsNotSet() { - - // GIVEN - // set logging for a different identifier - let wrongIdentifier = EncryptionSessionIdentifier(domain: "example.com", userId: "foo", clientId: "bar") - recreateAliceStatus(extendedLoggingSession: Set([wrongIdentifier])) - - let plainText = Data("foo".utf8) - establishSessionFromAliceToBob() - - // EXPECT - let token = ZMSLog.addEntryHook { _, _, _, _ in - XCTFail("Should not have logged") - } - - // WHEN - _ = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - - // AFTER - ZMSLog.removeLogHook(token: token) - } - - func testThatItLogsDecryptionWhenExtendedLoggingIsSet_prekeyMessage() { - - // GIVEN - recreateBobStatus(extendedLoggingSession: Set([Person.Alice.identifier])) - let plainText = Data("foo".utf8) - establishSessionFromAliceToBob() - let logExpectation = expectation(description: "Encrypting") - let prekeyMessage = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - - // EXPECT - let token = ZMSLog.addEntryHook { level, tag, entry, _ in - if level == .public, - tag == "cryptobox", - entry.text.contains("decrypting prekey cyphertext:") { - logExpectation.fulfill() - } - } - - // WHEN - _ = try! statusBob.createClientSessionAndReturnPlaintext( - for: Person.Alice.identifier, - prekeyMessage: prekeyMessage - ) - - // THEN - waitForExpectations(timeout: 1) - - // AFTER - ZMSLog.removeLogHook(token: token) - } - - func testThatItLogsDecryptionWhenExtendedLoggingIsSet_nonPrekeyMessage() { - - // GIVEN - - let plainText = Data("foo".utf8) - establishSessionBetweenAliceAndBob() - recreateBobStatus(extendedLoggingSession: Set([Person.Alice.identifier])) - let logExpectation = expectation(description: "Encrypting") - let message = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - - // EXPECT - let token = ZMSLog.addEntryHook { level, tag, entry, _ in - if level == .public, - tag == "cryptobox", - entry.text.contains("decrypting cyphertext:") { - logExpectation.fulfill() - } - } - - // WHEN - _ = try! statusBob.decrypt(message, from: Person.Alice.identifier) - - // THEN - waitForExpectations(timeout: 1) - - // AFTER - ZMSLog.removeLogHook(token: token) - } - - func testThatItDoesNotLogDecryptionWhenExtendedLoggingIsNotSet() { - - // GIVEN - // set logging for a different identifier - let wrongIdentifier = EncryptionSessionIdentifier(domain: "example.com", userId: "foo", clientId: "bar") - recreateBobStatus(extendedLoggingSession: Set([wrongIdentifier])) - - let plainText = Data("foo".utf8) - establishSessionFromAliceToBob() - - let prekeyMessage = try! statusAlice.encrypt(plainText, for: Person.Bob.identifier) - - // EXPECT - let token = ZMSLog.addEntryHook { _, _, _, _ in - XCTFail("Should not have logged") - } - - // WHEN - _ = try! statusBob.createClientSessionAndReturnPlaintext( - for: Person.Alice.identifier, - prekeyMessage: prekeyMessage - ) - - // AFTER - ZMSLog.removeLogHook(token: token) - } -} - -// MARK: - Helpers - -/// Custom session identifier for Bob -private var bobIdentifierOverride: String? - -extension EncryptionSessionsDirectoryTests { - - /// Recreate the statuses, reloading from disk. This also forces a save of the previous - /// statuses, if any. - func recreateStatuses( - only: Person? = nil - ) { - if only == nil || only == .Alice { - recreateAliceStatus() - } - if only == nil || only == .Bob { - recreateBobStatus() - } - } - - func recreateAliceStatus( - extendedLoggingSession: Set = Set() - ) { - statusAlice = EncryptionSessionsDirectory( - generatingContext: contextAlice, - encryptionPayloadCache: Cache(maxCost: 1000, maxElementsCount: 100), - extensiveLoggingSessions: extendedLoggingSession - ) - statusAlice.debug_disableContextValidityCheck = true - } - - func recreateBobStatus( - extendedLoggingSession: Set = Set() - ) { - statusBob = EncryptionSessionsDirectory( - generatingContext: contextBob, - encryptionPayloadCache: Cache(maxCost: 1000, maxElementsCount: 100), - extensiveLoggingSessions: extendedLoggingSession - ) - statusBob.debug_disableContextValidityCheck = true - } - - /// Sends a prekey message from Alice to Bob, decrypts it on Bob's side, and save both - func establishSessionBetweenAliceAndBob() { - establishSessionFromAliceToBob() - let prekeyMessage = try! statusAlice.encrypt(Data("foo".utf8), for: Person.Bob.identifier) - _ = try! statusBob.createClientSessionAndReturnPlaintext( - for: Person.Alice.identifier, - prekeyMessage: prekeyMessage - ) - - /// This will force commit - recreateStatuses() - } - - /// Creates a client session from Alice to Bob - func establishSessionFromAliceToBob() { - let prekey = try! statusBob.generatePrekey(2) - try! statusAlice.createClientSession(Person.Bob.identifier, base64PreKeyString: prekey) - } - - enum Person { - case Alice - case Bob - - var identifier: EncryptionSessionIdentifier { - switch self { - case .Alice: - EncryptionSessionIdentifier(domain: "example.com", userId: "234ab2e4", clientId: "c45-a11c30") - case .Bob: - EncryptionSessionIdentifier(fromLegacyV1Identifier: bobIdentifierOverride ?? "a34affe3366-b0b0b0b") - } - } - - var other: Person { - switch self { - case .Alice: - .Bob - case .Bob: - .Alice - } - } - } - - /// Checks if a person already decrypted a message - /// Reverts the session after performing the check - /// Will only work after after calling `establishSessionBetweenAliceAndBob` - func checkIfPersonAlreadyDecryptedMessage(_ person: Person, message: Data) -> Bool { - let clientId = person.identifier - let status = person == .Alice ? statusAlice : statusBob - guard (try? status?.decrypt(message, from: clientId)) != nil else { - return true - } - status?.discardCache() - return false - } - - /// Checks if a message can be encrypted and successfully decrypted - /// by the other person - /// - note: it does commit the session cache - @discardableResult - func checkThatAMessageCanBeSent(_ from: Person, saveReceiverCache: Bool = true) -> Bool { - let senderId = from.identifier - let receiverId = from.other.identifier - - let status1 = from == .Alice ? statusAlice : statusBob - let status2 = from == .Alice ? statusBob : statusAlice - - defer { - self.recreateStatuses(only: from) - if saveReceiverCache { - self.recreateStatuses(only: from.other) - } - } - - let plainText = Data("निर्वाण".utf8) - do { - let cypherText = try status1?.encrypt(plainText, for: receiverId) - let decoded = try status2?.decrypt(cypherText!, from: senderId) - return decoded == plainText - } catch { - return false - } - } -} diff --git a/wire-ios-cryptobox/WireCryptoboxTests/GenericHashBuilderTests.swift b/wire-ios-cryptobox/WireCryptoboxTests/GenericHashBuilderTests.swift deleted file mode 100644 index 4cce4537a1b..00000000000 --- a/wire-ios-cryptobox/WireCryptoboxTests/GenericHashBuilderTests.swift +++ /dev/null @@ -1,85 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import XCTest -@testable import WireCryptobox - -final class GenericHashBuilderTests: XCTestCase { - func testThatItHashesTheData() { - // GIVEN - let data = Data("some data".utf8) - // WHEN - let builder = GenericHashBuilder() - builder.append(data) - let hash = builder.build() - // THEN - let genericHash = GenericHash(value: 108_806_884_620_190_685) - XCTAssertEqual(hash, genericHash) - XCTAssertEqual(hash.hashValue, genericHash.hashValue) - } - - func testThatDifferentDataHasDifferentHash() { - // GIVEN - let data = Data("some data".utf8) - let otherData = Data("some other data".utf8) - // WHEN - let builder = GenericHashBuilder() - builder.append(data) - let hash = builder.build() - - let otherBuilder = GenericHashBuilder() - otherBuilder.append(otherData) - let otherHash = otherBuilder.build() - // THEN - XCTAssertNotEqual(hash.hashValue, otherHash.hashValue) - } - - func testThatSameDataHasSameHash() { - // GIVEN - let data = Data("some data".utf8) - let otherData = Data("some data".utf8) - // WHEN - let builder = GenericHashBuilder() - builder.append(data) - let hash = builder.build() - - let otherBuilder = GenericHashBuilder() - otherBuilder.append(otherData) - let otherHash = otherBuilder.build() - // THEN - XCTAssertEqual(hash.hashValue, otherHash.hashValue) - } - - func testThatDataCanBeAppended() { - // GIVEN - let data = Data("some data".utf8) - let otherData1 = Data("some ".utf8) - let otherData2 = Data("data".utf8) - // WHEN - let builder = GenericHashBuilder() - builder.append(data) - let hash = builder.build() - - let otherBuilder = GenericHashBuilder() - otherBuilder.append(otherData1) - otherBuilder.append(otherData2) - let otherHash = otherBuilder.build() - // THEN - XCTAssertEqual(hash.hashValue, otherHash.hashValue) - } -} diff --git a/wire-ios-cryptobox/WireCryptoboxTests/Info.plist b/wire-ios-cryptobox/WireCryptoboxTests/Info.plist deleted file mode 100644 index ba72822e872..00000000000 --- a/wire-ios-cryptobox/WireCryptoboxTests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/wire-ios-cryptobox/WireCryptoboxTests/TestHelper.swift b/wire-ios-cryptobox/WireCryptoboxTests/TestHelper.swift deleted file mode 100644 index 295dcaca596..00000000000 --- a/wire-ios-cryptobox/WireCryptoboxTests/TestHelper.swift +++ /dev/null @@ -1,39 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -import Foundation -import WireCryptobox - -/// sample client ID -let hardcodedClientId = EncryptionSessionIdentifier(domain: "example.com", userId: "1e9b4e18", clientId: "7a9eb715") - -/// sample prekey -let hardcodedPrekey = - "pQABAQUCoQBYIEIir0myj5MJTvs19t585RfVi1dtmL2nJsImTaNXszRwA6EAoQBYIGpa1sQFpCugwFJRfD18d9+TNJN2ZL3H0Mfj/0qZw0ruBPY=" - -/// Creates a temporary folder and returns its URL -func createTempFolder() -> URL { - let url = URL(fileURLWithPath: [NSTemporaryDirectory(), UUID().uuidString].joined(separator: "/")) - try! FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: [:]) - return url -} - -func createEncryptionContext() -> EncryptionContext { - let folder = createTempFolder() - return EncryptionContext(path: folder) -} diff --git a/wire-ios-cryptobox/WireCryptoboxTests/TestPlans/AllTests.xctestplan b/wire-ios-cryptobox/WireCryptoboxTests/TestPlans/AllTests.xctestplan deleted file mode 100644 index c4a0defe0c1..00000000000 --- a/wire-ios-cryptobox/WireCryptoboxTests/TestPlans/AllTests.xctestplan +++ /dev/null @@ -1,37 +0,0 @@ -{ - "configurations" : [ - { - "id" : "72E20F8C-AC1C-449E-A381-FF60B98DC3B7", - "name" : "Configuration 1", - "options" : { - - } - } - ], - "defaultOptions" : { - "environmentVariableEntries" : [ - { - "key" : "CI", - "value" : "${CI}" - } - ], - "language" : "en", - "region" : "DE", - "targetForVariableExpansion" : { - "containerPath" : "container:WireCryptobox.xcodeproj", - "identifier" : "BA7EF9681B7109B600204A8E", - "name" : "WireCryptoboxTests" - }, - "testExecutionOrdering" : "random" - }, - "testTargets" : [ - { - "target" : { - "containerPath" : "container:WireCryptobox.xcodeproj", - "identifier" : "BA7EF9681B7109B600204A8E", - "name" : "WireCryptoboxTests" - } - } - ], - "version" : 1 -} diff --git a/wire-ios-cryptobox/test-host/AppDelegate.h b/wire-ios-cryptobox/test-host/AppDelegate.h deleted file mode 100644 index 8880062a31d..00000000000 --- a/wire-ios-cryptobox/test-host/AppDelegate.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -#import - -@interface AppDelegate : UIResponder - -@property (strong, nonatomic) UIWindow *window; - - -@end - diff --git a/wire-ios-cryptobox/test-host/AppDelegate.m b/wire-ios-cryptobox/test-host/AppDelegate.m deleted file mode 100644 index 24341339c41..00000000000 --- a/wire-ios-cryptobox/test-host/AppDelegate.m +++ /dev/null @@ -1,55 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -#import "AppDelegate.h" - -@interface AppDelegate () - -@end - -@implementation AppDelegate - - -- (BOOL)application:(UIApplication * __unused)application didFinishLaunchingWithOptions:(NSDictionary * __unused)launchOptions { - // Override point for customization after application launch. - return YES; -} - -- (void)applicationWillResignActive:(UIApplication * __unused)application { - // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. - // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. -} - -- (void)applicationDidEnterBackground:(UIApplication * __unused)application { - // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. - // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. -} - -- (void)applicationWillEnterForeground:(UIApplication * __unused)application { - // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. -} - -- (void)applicationDidBecomeActive:(UIApplication * __unused)application { - // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. -} - -- (void)applicationWillTerminate:(UIApplication * __unused)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. -} - -@end diff --git a/wire-ios-cryptobox/test-host/Assets.xcassets/AppIcon.appiconset/Contents.json b/wire-ios-cryptobox/test-host/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 1d060ed2882..00000000000 --- a/wire-ios-cryptobox/test-host/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "83.5x83.5", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/wire-ios-cryptobox/test-host/Base.lproj/Main.storyboard b/wire-ios-cryptobox/test-host/Base.lproj/Main.storyboard deleted file mode 100644 index f56d2f3bb56..00000000000 --- a/wire-ios-cryptobox/test-host/Base.lproj/Main.storyboard +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/wire-ios-cryptobox/test-host/Info.plist b/wire-ios-cryptobox/test-host/Info.plist deleted file mode 100644 index fa00b2c967b..00000000000 --- a/wire-ios-cryptobox/test-host/Info.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/wire-ios-cryptobox/test-host/ViewController.h b/wire-ios-cryptobox/test-host/ViewController.h deleted file mode 100644 index 7a8a843211c..00000000000 --- a/wire-ios-cryptobox/test-host/ViewController.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -#import - -@interface ViewController : UIViewController - - -@end - diff --git a/wire-ios-cryptobox/test-host/ViewController.m b/wire-ios-cryptobox/test-host/ViewController.m deleted file mode 100644 index f2c0532ab70..00000000000 --- a/wire-ios-cryptobox/test-host/ViewController.m +++ /dev/null @@ -1,37 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -#import "ViewController.h" - -@interface ViewController () - -@end - -@implementation ViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - // Do any additional setup after loading the view, typically from a nib. -} - -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - -@end diff --git a/wire-ios-cryptobox/test-host/main.m b/wire-ios-cryptobox/test-host/main.m deleted file mode 100644 index 49fbe4b791a..00000000000 --- a/wire-ios-cryptobox/test-host/main.m +++ /dev/null @@ -1,26 +0,0 @@ -// -// Wire -// Copyright (C) 2025 Wire Swiss GmbH -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see http://www.gnu.org/licenses/. -// - -#import -#import "AppDelegate.h" - -int main(int argc, char * argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/wire-ios-data-model/Source/ManagedObjectContext/NSManagedObjectContext+EncryptionAtRest.swift b/wire-ios-data-model/Source/ManagedObjectContext/NSManagedObjectContext+EncryptionAtRest.swift index 8c6bb9959e3..65c4aa73029 100644 --- a/wire-ios-data-model/Source/ManagedObjectContext/NSManagedObjectContext+EncryptionAtRest.swift +++ b/wire-ios-data-model/Source/ManagedObjectContext/NSManagedObjectContext+EncryptionAtRest.swift @@ -18,7 +18,6 @@ import Foundation import WireCrypto -import WireCryptobox import WireLogging extension Sequence where Element: NSManagedObject { @@ -203,7 +202,7 @@ extension NSManagedObjectContext { case missingDatabaseKey case missingContextData - case cryptobox(error: ChaCha20Poly1305.AEADEncryption.EncryptionError) + case crypto(error: ChaCha20Poly1305.AEADEncryption.EncryptionError) var errorDescription: String? { switch self { @@ -213,7 +212,7 @@ extension NSManagedObjectContext { case .missingContextData: "Couldn't obtain context data." - case let .cryptobox(error): + case let .crypto(error): error.errorDescription } } @@ -247,7 +246,7 @@ extension NSManagedObjectContext { ) return (ciphertext, nonce) } catch let error as ChaCha20Poly1305.AEADEncryption.EncryptionError { - throw EncryptionError.cryptobox(error: error) + throw EncryptionError.crypto(error: error) } } @@ -283,7 +282,7 @@ extension NSManagedObjectContext { key: key._storage ) } catch let error as ChaCha20Poly1305.AEADEncryption.EncryptionError { - throw EncryptionError.cryptobox(error: error) + throw EncryptionError.crypto(error: error) } } diff --git a/wire-ios-data-model/Source/ManagedObjectContext/NSManagedObjectContext+zmessaging.m b/wire-ios-data-model/Source/ManagedObjectContext/NSManagedObjectContext+zmessaging.m index 055fb4964fe..b4c975e00c8 100644 --- a/wire-ios-data-model/Source/ManagedObjectContext/NSManagedObjectContext+zmessaging.m +++ b/wire-ios-data-model/Source/ManagedObjectContext/NSManagedObjectContext+zmessaging.m @@ -17,7 +17,6 @@ // @import UIKit; -@import WireCryptobox; @import WireUtilities; #import "NSManagedObjectContext+zmessaging-Internal.h" diff --git a/wire-ios-data-model/Source/Model/Conversation/ZMConversation+SecurityLevel.swift b/wire-ios-data-model/Source/Model/Conversation/ZMConversation+SecurityLevel.swift index 6a38f0c0bab..c3db51fc2e5 100644 --- a/wire-ios-data-model/Source/Model/Conversation/ZMConversation+SecurityLevel.swift +++ b/wire-ios-data-model/Source/Model/Conversation/ZMConversation+SecurityLevel.swift @@ -19,7 +19,6 @@ import Foundation import GenericMessageProtocol import WireCoreCrypto -import WireCryptobox import WireLogging @objc diff --git a/wire-ios-data-model/Source/Model/Conversation/ZMConversation.m b/wire-ios-data-model/Source/Model/Conversation/ZMConversation.m index 79a73353c3d..f7d0a3d51a8 100644 --- a/wire-ios-data-model/Source/Model/Conversation/ZMConversation.m +++ b/wire-ios-data-model/Source/Model/Conversation/ZMConversation.m @@ -20,7 +20,6 @@ @import WireImages; @import WireUtilities; @import WireTransport; -@import WireCryptobox; @import MobileCoreServices; @import WireImages; diff --git a/wire-ios-data-model/Source/Model/Message/ConversationMessage+Deletion.swift b/wire-ios-data-model/Source/Model/Message/ConversationMessage+Deletion.swift index 6ee9189ca8a..4a6d2a26125 100644 --- a/wire-ios-data-model/Source/Model/Message/ConversationMessage+Deletion.swift +++ b/wire-ios-data-model/Source/Model/Message/ConversationMessage+Deletion.swift @@ -18,7 +18,6 @@ import Foundation import GenericMessageProtocol -import WireCryptobox extension ZMConversation { static func appendHideMessageToSelfConversation(_ message: ZMMessage) throws { diff --git a/wire-ios-data-model/Source/Model/Message/ZMClientMessage+Encryption.swift b/wire-ios-data-model/Source/Model/Message/ZMClientMessage+Encryption.swift index 110248b4788..2bf67f245be 100644 --- a/wire-ios-data-model/Source/Model/Message/ZMClientMessage+Encryption.swift +++ b/wire-ios-data-model/Source/Model/Message/ZMClientMessage+Encryption.swift @@ -18,7 +18,6 @@ import Foundation import GenericMessageProtocol -import WireCryptobox import WireLogging private var zmLog = ZMSLog(tag: "message encryption") diff --git a/wire-ios-data-model/Source/Model/Message/ZMGenericMessageData.swift b/wire-ios-data-model/Source/Model/Message/ZMGenericMessageData.swift index 58f66d43a74..af0d3414e09 100644 --- a/wire-ios-data-model/Source/Model/Message/ZMGenericMessageData.swift +++ b/wire-ios-data-model/Source/Model/Message/ZMGenericMessageData.swift @@ -18,7 +18,6 @@ import Foundation import GenericMessageProtocol -import WireCryptobox import WireLogging @objc(ZMGenericMessageData) diff --git a/wire-ios-data-model/Source/Model/Message/ZMMessage.m b/wire-ios-data-model/Source/Model/Message/ZMMessage.m index 4695735f100..2c4535183c4 100644 --- a/wire-ios-data-model/Source/Model/Message/ZMMessage.m +++ b/wire-ios-data-model/Source/Model/Message/ZMMessage.m @@ -31,8 +31,6 @@ #import "ZMUpdateEvent+WireDataModel.h" #import -#import - static NSString *ZMLogTag ZM_UNUSED = @"ephemeral"; @@ -770,22 +768,6 @@ - (void)updateNeedsUpdatingUsersIfNeeded } } -- (BOOL)isDecryptionErrorRecoverable { - if (self.decryptionErrorCode == nil) { - return NO; - } - - NSInteger errorCode = self.decryptionErrorCode.integerValue; - - if (errorCode == CBOX_TOO_DISTANT_FUTURE || - errorCode == CBOX_DEGENERATED_KEY || - errorCode == CBOX_PREKEY_NOT_FOUND) { - return YES; - } - - return NO; -} - + (ZMSystemMessageType)systemMessageTypeFromUpdateEvent:(ZMUpdateEvent *)updateEvent; { switch (updateEvent.type) { diff --git a/wire-ios-data-model/Source/Model/User/ZMUser.m b/wire-ios-data-model/Source/Model/User/ZMUser.m index 162099df1cd..1ddeb0ef3b6 100644 --- a/wire-ios-data-model/Source/Model/User/ZMUser.m +++ b/wire-ios-data-model/Source/Model/User/ZMUser.m @@ -18,7 +18,6 @@ @import WireImages; @import WireUtilities; -@import WireCryptobox; @import WireTransport; @import Foundation; diff --git a/wire-ios-data-model/Source/Model/UserClient/UserClient.swift b/wire-ios-data-model/Source/Model/UserClient/UserClient.swift index cef1abba94f..5524c07711d 100644 --- a/wire-ios-data-model/Source/Model/UserClient/UserClient.swift +++ b/wire-ios-data-model/Source/Model/UserClient/UserClient.swift @@ -18,7 +18,6 @@ import CoreLocation import Foundation -import WireCryptobox import WireLogging import WireUtilities diff --git a/wire-ios-data-model/Source/Public/DraftMessage.swift b/wire-ios-data-model/Source/Public/DraftMessage.swift index 768d37d6a28..a595749516c 100644 --- a/wire-ios-data-model/Source/Public/DraftMessage.swift +++ b/wire-ios-data-model/Source/Public/DraftMessage.swift @@ -17,7 +17,6 @@ // import Foundation -import WireCryptobox /// This object holds information about a message draft that has not yet been sent /// by the user but was put into the input field. diff --git a/wire-ios-data-model/Tests/Source/Model/Conversation/ZMConversationTests+SecurityLevel.swift b/wire-ios-data-model/Tests/Source/Model/Conversation/ZMConversationTests+SecurityLevel.swift index 19e41b9695e..13c6001474b 100644 --- a/wire-ios-data-model/Tests/Source/Model/Conversation/ZMConversationTests+SecurityLevel.swift +++ b/wire-ios-data-model/Tests/Source/Model/Conversation/ZMConversationTests+SecurityLevel.swift @@ -490,30 +490,6 @@ final class ZMConversationTests_SecurityLevel: ZMConversationTestsBase { XCTAssertEqual(lastMessage.systemMessageType, ZMSystemMessageType.decryptionFailed_RemoteIdentityChanged) } - func testThatItAppendsASystemMessageOfGeneralTypeForCBErrorCodeInvalidMessage() { - // given - let conversation = ZMConversation.insertNewObject(in: uiMOC) - conversation.conversationType = .group - let user = ZMUser.insertNewObject(in: uiMOC) - user.name = "Fancy One" - let decryptionError = CBOX_INVALID_MESSAGE - - // when - conversation.appendDecryptionFailedSystemMessage( - at: Date(), - sender: user, - client: nil, - error: .Other(UInt16(decryptionError.rawValue)) - ) - - // then - guard let lastMessage = conversation.lastMessage as? ZMSystemMessage else { - return XCTFail() - } - XCTAssertEqual(lastMessage.systemMessageType, ZMSystemMessageType.decryptionFailed) - XCTAssertEqual(lastMessage.decryptionErrorCode?.intValue, Int(decryptionError.rawValue)) - } - func testThatAConversationIsNotTrustedIfItHasNoOtherParticipants() { // GIVEN let conversation = ZMConversation.insertNewObject(in: uiMOC) diff --git a/wire-ios-data-model/Tests/Source/Model/Messages/ZMClientMessageTests+Ephemeral.swift b/wire-ios-data-model/Tests/Source/Model/Messages/ZMClientMessageTests+Ephemeral.swift index ba3483a5a4c..1be6874fad0 100644 --- a/wire-ios-data-model/Tests/Source/Model/Messages/ZMClientMessageTests+Ephemeral.swift +++ b/wire-ios-data-model/Tests/Source/Model/Messages/ZMClientMessageTests+Ephemeral.swift @@ -18,7 +18,6 @@ import Foundation import GenericMessageProtocol -import WireCryptobox import WireLinkPreview @testable import WireDataModel diff --git a/wire-ios-data-model/Tests/Source/Model/Messages/ZMMessageTests+SystemMessages.swift b/wire-ios-data-model/Tests/Source/Model/Messages/ZMMessageTests+SystemMessages.swift index be3400daf6f..867d6b73974 100644 --- a/wire-ios-data-model/Tests/Source/Model/Messages/ZMMessageTests+SystemMessages.swift +++ b/wire-ios-data-model/Tests/Source/Model/Messages/ZMMessageTests+SystemMessages.swift @@ -21,60 +21,6 @@ import XCTest class ZMMessageTests_SystemMessages: BaseZMMessageTests { - func testThatOnlyRecoverableDecryptionErrorsAreReportedAsRecoverable() throws { - let allEncryptionErrors = [ - CBOX_STORAGE_ERROR, - CBOX_SESSION_NOT_FOUND, - CBOX_DECODE_ERROR, - CBOX_REMOTE_IDENTITY_CHANGED, - CBOX_INVALID_SIGNATURE, - CBOX_INVALID_MESSAGE, - CBOX_DUPLICATE_MESSAGE, - CBOX_TOO_DISTANT_FUTURE, - CBOX_OUTDATED_MESSAGE, - CBOX_UTF8_ERROR, - CBOX_NUL_ERROR, - CBOX_ENCODE_ERROR, - CBOX_IDENTITY_ERROR, - CBOX_PREKEY_NOT_FOUND, - CBOX_PANIC, - CBOX_INIT_ERROR, - CBOX_DEGENERATED_KEY - ] - - let recoverableEncryptionErrors = [ - CBOX_TOO_DISTANT_FUTURE, - CBOX_DEGENERATED_KEY, - CBOX_PREKEY_NOT_FOUND - ] - - for encryptionError in allEncryptionErrors { - assertDecryptionErrorIsReportedAsRecoverable( - encryptionError, - recoverable: recoverableEncryptionErrors.contains(encryptionError) - ) - } - } - - private func assertDecryptionErrorIsReportedAsRecoverable( - _ decryptionError: CBoxResult, - recoverable: Bool, - file: StaticString = #filePath, - line: UInt = #line - ) { - // given - let systemMessage = ZMSystemMessage(nonce: UUID(), managedObjectContext: uiMOC) - systemMessage.systemMessageType = .decryptionFailed - systemMessage.decryptionErrorCode = NSNumber(value: decryptionError.rawValue) - - // then - XCTAssertEqual(systemMessage.isDecryptionErrorRecoverable, recoverable, file: file, line: line) - } - -} - -extension ZMMessageTests_SystemMessages { - func testThatItGeneratesTheCorrectSystemMessageTypesFromUpdateEvents() { // expect a message checkThatUpdateEventTypeGeneratesSystemMessage( diff --git a/wire-ios-data-model/Tests/Source/Model/ZMBaseManagedObjectTest.h b/wire-ios-data-model/Tests/Source/Model/ZMBaseManagedObjectTest.h index 976ff13e93a..f6eccbcadb1 100644 --- a/wire-ios-data-model/Tests/Source/Model/ZMBaseManagedObjectTest.h +++ b/wire-ios-data-model/Tests/Source/Model/ZMBaseManagedObjectTest.h @@ -31,7 +31,6 @@ @protocol ZMObjectStrategyDirectory; @class ZMAssetClientMessage; -@import WireCryptobox; @import WireImages; @class UserClient; diff --git a/wire-ios-data-model/WireDataModel.xcodeproj/project.pbxproj b/wire-ios-data-model/WireDataModel.xcodeproj/project.pbxproj index 2550896f25c..660f5cf119e 100644 --- a/wire-ios-data-model/WireDataModel.xcodeproj/project.pbxproj +++ b/wire-ios-data-model/WireDataModel.xcodeproj/project.pbxproj @@ -535,7 +535,6 @@ EE7A90F02B21E29E00B58E84 /* OneOnOneMigratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE7A90EF2B21E29E00B58E84 /* OneOnOneMigratorTests.swift */; }; EE84227028EC353900B80FE5 /* MLSActionExecutorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE84226F28EC353900B80FE5 /* MLSActionExecutorTests.swift */; }; EE85C8B22B557C3D00D3182D /* DatabaseMigrationTests+OneOnOneConversation.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE85C8B12B557C3D00D3182D /* DatabaseMigrationTests+OneOnOneConversation.swift */; }; - EE8DA9672954A02B00F58B79 /* WireCryptobox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE8DA9662954A02B00F58B79 /* WireCryptobox.framework */; }; EE8DA96A2954A03100F58B79 /* WireTransport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE8DA9692954A03100F58B79 /* WireTransport.framework */; }; EE8DA96D2954A03800F58B79 /* WireLinkPreview.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE8DA96C2954A03800F58B79 /* WireLinkPreview.framework */; }; EE8DA9702954A03E00F58B79 /* WireImages.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE8DA96F2954A03E00F58B79 /* WireImages.framework */; }; @@ -1572,7 +1571,6 @@ buildActionMask = 2147483647; files = ( 34DC44B52E01C210004D5DD5 /* WireNetwork in Frameworks */, - EE8DA9672954A02B00F58B79 /* WireCryptobox.framework in Frameworks */, CBD35F2C2D09EBB20080DA37 /* WireCrypto in Frameworks */, 1657FA9A2D9C2EB800A7B337 /* WireCoreCryptoUniffi in Frameworks */, 591B6E4C2C8B09C6009F8A7B /* CoreData.framework in Frameworks */, diff --git a/wire-ios-mocktransport/Source/Clients and OTR/MockPendingLegalHoldClient.swift b/wire-ios-mocktransport/Source/Clients and OTR/MockPendingLegalHoldClient.swift index 490855c42a3..c76506480d5 100644 --- a/wire-ios-mocktransport/Source/Clients and OTR/MockPendingLegalHoldClient.swift +++ b/wire-ios-mocktransport/Source/Clients and OTR/MockPendingLegalHoldClient.swift @@ -58,33 +58,21 @@ public extension MockUser { let identifier = String.randomClientIdentifier() pendingClient.identifier = identifier - // Generate the prekeys - let encryptionContext = MockUserClient.encryptionContext(for: self, clientId: identifier) + // Generate mock prekey strings + let prekeysStrings = (0 ..< 5).map { _ in UUID().uuidString } - var generatedPrekeys: [[String: Any]]? - var generatedLastPrekey: String? - - encryptionContext.perform { session in - generatedPrekeys = try? session.generatePrekeys(NSRange(location: 0, length: 5)) - generatedLastPrekey = try? session.generateLastPrekey() - } - - guard let prekeys = generatedPrekeys, !prekeys.isEmpty, let lastPrekey = generatedLastPrekey else { - return false - } - - let mockPrekey = MockPreKey.insertNewKeys( - withPayload: prekeys.map { $0["prekey"] as! String }, + let prekeys = MockPreKey.insertNewKeys( + withPayload: prekeysStrings, context: managedObjectContext ) - pendingClient.prekeys = Set(mockPrekey) + pendingClient.prekeys = Set(prekeys) let mockLastPrekey = NSEntityDescription.insertNewObject( forEntityName: "PreKey", into: managedObjectContext ) as! MockPreKey - mockLastPrekey.identifier = Int(CBOX_LAST_PREKEY_ID) - mockLastPrekey.value = lastPrekey + mockLastPrekey.identifier = Int(UInt16.max) + mockLastPrekey.value = UUID().uuidString pendingClient.lastPrekey = mockLastPrekey return true diff --git a/wire-ios-mocktransport/Source/Clients and OTR/MockPreKey.h b/wire-ios-mocktransport/Source/Clients and OTR/MockPreKey.h index 12fe57bb7ed..db5d68639af 100644 --- a/wire-ios-mocktransport/Source/Clients and OTR/MockPreKey.h +++ b/wire-ios-mocktransport/Source/Clients and OTR/MockPreKey.h @@ -17,7 +17,6 @@ // @import CoreData; -@import WireCryptobox; @class MockUserClient; diff --git a/wire-ios-mocktransport/Source/Clients and OTR/MockTransportSession+OTR.swift b/wire-ios-mocktransport/Source/Clients and OTR/MockTransportSession+OTR.swift index 827c34c1ebf..03edb65b8b5 100644 --- a/wire-ios-mocktransport/Source/Clients and OTR/MockTransportSession+OTR.swift +++ b/wire-ios-mocktransport/Source/Clients and OTR/MockTransportSession+OTR.swift @@ -185,7 +185,7 @@ extension MockTransportSession { toConversation conversation: MockConversation, recipients: [Proteus_UserEntry], senderClient: MockUserClient, - createEventBlock: (MockUserClient, Data, Data) -> MockEvent + createEventBlock: (MockUserClient, Data) -> MockEvent ) { let activeUsers = conversation.activeUsers.array as? [MockUser] @@ -210,8 +210,7 @@ extension MockTransportSession { return } - let decryptedData = MockUserClient.decryptMessage(data: entry.text, from: senderClient, to: client) - _ = createEventBlock(client, entry.text, decryptedData) + _ = createEventBlock(client, entry.text) } } } diff --git a/wire-ios-mocktransport/Source/Clients and OTR/MockUserClient+Protos.swift b/wire-ios-mocktransport/Source/Clients and OTR/MockUserClient+Protos.swift index 20bd7a1fb21..32c5eed540d 100644 --- a/wire-ios-mocktransport/Source/Clients and OTR/MockUserClient+Protos.swift +++ b/wire-ios-mocktransport/Source/Clients and OTR/MockUserClient+Protos.swift @@ -72,7 +72,7 @@ extension MockUserClient { } return Proteus_ClientEntry.with { $0.client = clientId - $0.text = MockUserClient.encrypted(data: plainText, from: self, to: client) + $0.text = plainText } } diff --git a/wire-ios-mocktransport/Source/Clients and OTR/MockUserClient.swift b/wire-ios-mocktransport/Source/Clients and OTR/MockUserClient.swift index cd79781d94f..c339163fb5f 100644 --- a/wire-ios-mocktransport/Source/Clients and OTR/MockUserClient.swift +++ b/wire-ios-mocktransport/Source/Clients and OTR/MockUserClient.swift @@ -68,14 +68,6 @@ public class MockUserClient: NSManagedObject { public extension MockUserClient { - /// Identifier for the session in Cryptobox - var sessionIdentifier: EncryptionSessionIdentifier? { - guard let identifier, let userIdentifier = user?.identifier else { - return nil - } - return EncryptionSessionIdentifier(userId: userIdentifier, clientId: identifier) - } - /// Returns a fetch request to fetch MockUserClients with the given predicate @objc static func fetchRequest(predicate: NSPredicate) -> NSFetchRequest { @@ -169,28 +161,20 @@ public extension MockUserClient { newClient.deviceClass = deviceClass newClient.time = Date() - var generatedPrekeys: [[String: Any]]? - var generatedLastPrekey: String? - newClient.encryptionContext.perform { session in - generatedPrekeys = try? session.generatePrekeys(NSRange(location: 0, length: 5)) - generatedLastPrekey = try? session.generateLastPrekey() - } - - guard let prekeys = generatedPrekeys, !prekeys.isEmpty, - let lastPrekey = generatedLastPrekey - else { - return nil - } + // Generate mock prekey strings (no encryption needed for mock transport) + let mockPrekeys = (0 ..< 5).map { _ in UUID().uuidString } + let mockLastPrekey = UUID().uuidString - let mockPrekey = MockPreKey.insertNewKeys( - withPayload: prekeys.map { $0["prekey"] as! String }, + let prekeys = MockPreKey.insertNewKeys( + withPayload: mockPrekeys, context: context ) - newClient.prekeys = Set(mockPrekey) + newClient.prekeys = Set(prekeys) + + let lastPrekey = MockPreKey.insertNewKey(withPrekey: mockLastPrekey, for: newClient, in: context) + lastPrekey.identifier = Int(UInt16.max) + newClient.lastPrekey = lastPrekey - let mockLastPrekey = MockPreKey.insertNewKey(withPrekey: lastPrekey, for: newClient, in: context) - mockLastPrekey.identifier = Int(CBOX_LAST_PREKEY_ID) - newClient.lastPrekey = mockLastPrekey return newClient } @@ -221,81 +205,5 @@ public extension MockUserClient { } } -// MARK: - Encryption and sessions - -@objc -public extension MockUserClient { - - static var mockEncryptionSessionDirectory: URL { - FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask).first! - .appendingPathComponent("mocktransport-encryptionDirectory") - } - - internal static func encryptionContext(for user: MockUser?, clientId: String?) -> EncryptionContext { - let directory = MockUserClient.mockEncryptionSessionDirectory - .appendingPathComponent("mockclient_\(user?.identifier ?? "USER")_\(clientId ?? "IDENTIFIER")") - try! FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true, attributes: [:]) - return EncryptionContext(path: directory) - } - - private var encryptionContext: EncryptionContext { - MockUserClient.encryptionContext(for: user, clientId: identifier) - } - - /// Make sure that there is a session established between this client and the given client - /// If needed, it will use the last prekey to create a session - /// - returns: false if it was not possible to establish a session - func establishSession(client: MockUserClient) -> Bool { - guard let identifier = client.sessionIdentifier else { return false } - var hasSession = false - encryptionContext.perform { session in - if !session.hasSession(for: identifier) { - try? session.createClientSession(identifier, base64PreKeyString: client.lastPrekey.value) - hasSession = session.hasSession(for: identifier) - } else { - hasSession = true - } - } - return hasSession - } - - /// Encrypt data from a client to a client. If there is no session between the two clients, it will create - /// one using the last prekey - static func encrypted(data: Data, from: MockUserClient, to: MockUserClient) -> Data { - var encryptedData: Data? - guard from.establishSession(client: to) else { fatalError() } - from.encryptionContext.perform { session in - encryptedData = try? session.encrypt(data, for: to.sessionIdentifier!) - } - return encryptedData! - } - - /// Decrypt a message (possibly establishing a session, if there is no session) from a client to a client - static func decryptMessage(data: Data, from: MockUserClient, to: MockUserClient) -> Data { - var decryptedData: Data? - to.encryptionContext.perform { session in - if !session.hasSession(for: from.sessionIdentifier!) { - decryptedData = try? session.createClientSessionAndReturnPlaintext( - for: from.sessionIdentifier!, - prekeyMessage: data - ) - } else { - decryptedData = try? session.decrypt(data, from: from.sessionIdentifier!) - } - } - return decryptedData ?? Data() - } - - /// Returns whether there is a encryption session between self and the give client - func hasSession(with client: MockUserClient) -> Bool { - guard let identifier = client.sessionIdentifier else { return false } - var hasSession = false - encryptionContext.perform { session in - hasSession = session.hasSession(for: identifier) - } - return hasSession - } -} - /// Allowed client types private let validClientTypes = Set(["temporary", "permanent", "legalhold"]) diff --git a/wire-ios-mocktransport/Source/Conversations/MockConversation.h b/wire-ios-mocktransport/Source/Conversations/MockConversation.h index 18f2b2fe645..dc432e20052 100644 --- a/wire-ios-mocktransport/Source/Conversations/MockConversation.h +++ b/wire-ios-mocktransport/Source/Conversations/MockConversation.h @@ -81,11 +81,6 @@ typedef NS_ENUM(int16_t, ZMTConversationType) { - (nonnull MockEvent *)insertClientMessageFromUser:(nonnull MockUser *)fromUser data:(nonnull NSData *)data; -/// Encrypts and inserts a OTR message using the gerneric message data sent from the given client to the given client -- (nonnull MockEvent *)encryptAndInsertDataFromClient:(nonnull MockUserClient *)fromClient - toClient:(nonnull MockUserClient *)toClient - data:(nonnull NSData *)data; - - (nonnull MockEvent *)insertOTRMessageFromClient:(nonnull MockUserClient *)fromClient toClient:(nonnull MockUserClient *)toClient data:(nonnull NSData *)data; diff --git a/wire-ios-mocktransport/Source/Conversations/MockConversation.m b/wire-ios-mocktransport/Source/Conversations/MockConversation.m index 4799ad0d496..801dd45e1b1 100644 --- a/wire-ios-mocktransport/Source/Conversations/MockConversation.m +++ b/wire-ios-mocktransport/Source/Conversations/MockConversation.m @@ -18,7 +18,6 @@ @import WireTransport; @import WireUtilities; -@import WireCryptobox; #import "MockConversation.h" #import "MockEvent.h" @@ -264,17 +263,6 @@ - (MockEvent *)insertOTRMessageFromClient:(MockUserClient *)fromClient return [self eventIfNeededByUser:fromClient.user type:ZMUpdateEventTypeConversationOtrMessageAdd data:eventData]; } -- (MockEvent *)encryptAndInsertDataFromClient:(MockUserClient *)fromClient - toClient:(MockUserClient *)toClient - data:(NSData *)data; -{ - Require(fromClient.identifier != nil); - Require(toClient.identifier != nil); - Require(data != nil); - NSData *encrypted = [MockUserClient encryptedWithData:data from:fromClient to:toClient]; - return [self insertOTRMessageFromClient:fromClient toClient:toClient data:encrypted]; -} - - (MockEvent *)insertOTRAssetFromClient:(MockUserClient *)fromClient toClient:(MockUserClient *)toClient metaData:(NSData *)metaData diff --git a/wire-ios-mocktransport/Source/Conversations/MockTransportSession+conversations.swift b/wire-ios-mocktransport/Source/Conversations/MockTransportSession+conversations.swift index 16980e27ff7..6370674ff9f 100644 --- a/wire-ios-mocktransport/Source/Conversations/MockTransportSession+conversations.swift +++ b/wire-ios-mocktransport/Source/Conversations/MockTransportSession+conversations.swift @@ -525,9 +525,9 @@ public extension MockTransportSession { toConversation: conversation, recipients: otrMetaData.recipients, senderClient: senderClient, - createEventBlock: { recipient, messageData, decryptedData in + createEventBlock: { recipient, messageData in let event = conversation.insertOTRMessage(from: senderClient, to: recipient, data: messageData) - event.decryptedOTRData = decryptedData + event.decryptedOTRData = messageData return event } ) diff --git a/wire-ios-mocktransport/Tests/Source/Clients and OTR/MockTransportSessionClientsTests.m b/wire-ios-mocktransport/Tests/Source/Clients and OTR/MockTransportSessionClientsTests.m index 178b7392b05..0be4140b2aa 100644 --- a/wire-ios-mocktransport/Tests/Source/Clients and OTR/MockTransportSessionClientsTests.m +++ b/wire-ios-mocktransport/Tests/Source/Clients and OTR/MockTransportSessionClientsTests.m @@ -711,23 +711,4 @@ - (void)testThatItDoesNotSendsANoficationWhenRemovingAClientOfAnotherUser { XCTAssertEqual(self.sut.generatedPushEvents.count, 0u); } -- (void)testThatEncryptEncryptDataBetweenTwoClients; -{ - __block MockUserClient *selfClient; - __block MockUserClient *destClient; - [self.sut performRemoteChanges:^(id session) { - - MockUser *selfUser = [session insertSelfUserWithName:@"Brigite Sorço"]; - selfClient = [session registerClientForUser:selfUser label:@"moi" type:@"permanent" deviceClass:@"phone"]; - destClient = [session registerClientForUser:selfUser label:@"autre" type:@"permanent" deviceClass:@"phone"]; - }]; - WaitForAllGroupsToBeEmpty(0.5); - - NSData *clearData = [@"Please, encrypt me!" dataUsingEncoding:NSUTF8StringEncoding]; - NSData *encryptedData = [MockUserClient encryptedWithData:clearData from:destClient to:selfClient]; - - XCTAssertNotNil(encryptedData); - XCTAssertNotEqualObjects(clearData, encryptedData); -} - @end diff --git a/wire-ios-mocktransport/Tests/Source/Conversations/MockTransportSessionConversationsTests.m b/wire-ios-mocktransport/Tests/Source/Conversations/MockTransportSessionConversationsTests.m index 40c8bdfc717..a304655f815 100644 --- a/wire-ios-mocktransport/Tests/Source/Conversations/MockTransportSessionConversationsTests.m +++ b/wire-ios-mocktransport/Tests/Source/Conversations/MockTransportSessionConversationsTests.m @@ -699,21 +699,21 @@ - (void)testThatItCreatesPushEventsWhenReceivingEncryptedOTRMessageWithCorrectDa NSData *messageData = [@"Fofooof" dataUsingEncoding:NSUTF8StringEncoding]; NSString *base64Content = [messageData base64EncodedStringWithOptions:0]; - + // WHEN [self.sut performRemoteChanges:^(__unused id session) { - NSData *encryptedData = [MockUserClient encryptedWithData:messageData from:otherUserClient to:selfClient]; - [conversation insertOTRMessageFromClient:otherUserClient toClient:selfClient data:encryptedData]; + // Mock transport doesn't encrypt - just passes data through + [conversation insertOTRMessageFromClient:otherUserClient toClient:selfClient data:messageData]; }]; WaitForAllGroupsToBeEmpty(0.5); - + // THEN MockPushEvent *lastEvent = self.sut.generatedPushEvents.lastObject; NSDictionary *lastEventPayload = [lastEvent.payload asDictionary]; XCTAssertEqualObjects(lastEventPayload[@"type"], @"conversation.otr-message-add"); XCTAssertEqualObjects(lastEventPayload[@"data"][@"recipient"], selfClient.identifier); XCTAssertEqualObjects(lastEventPayload[@"data"][@"sender"], otherUserClient.identifier); - XCTAssertNotEqualObjects(lastEventPayload[@"data"][@"text"], base64Content); + XCTAssertEqualObjects(lastEventPayload[@"data"][@"text"], base64Content); } - (void)testThatItCreatesPushEventsWhenReceivingEncryptedOTRAssetWithCorrectData; @@ -746,8 +746,8 @@ - (void)testThatItCreatesPushEventsWhenReceivingEncryptedOTRAssetWithCorrectData NSString *base64Content = [messageData base64EncodedStringWithOptions:0]; // WHEN [self.sut performRemoteChanges:^(__unused id session) { - NSData *encryptedData = [MockUserClient encryptedWithData:messageData from:otherUserClient to:selfClient]; - [conversation insertOTRAssetFromClient:otherUserClient toClient:selfClient metaData:encryptedData imageData:imageData assetId:assetID isInline:YES]; + // Mock transport doesn't encrypt - just passes data through + [conversation insertOTRAssetFromClient:otherUserClient toClient:selfClient metaData:messageData imageData:imageData assetId:assetID isInline:YES]; }]; WaitForAllGroupsToBeEmpty(0.5); @@ -758,7 +758,7 @@ - (void)testThatItCreatesPushEventsWhenReceivingEncryptedOTRAssetWithCorrectData XCTAssertEqualObjects(lastEventPayload[@"data"][@"recipient"], selfClient.identifier); XCTAssertEqualObjects(lastEventPayload[@"data"][@"sender"], otherUserClient.identifier); XCTAssertEqualObjects(lastEventPayload[@"data"][@"data"], [imageData base64String]); - XCTAssertNotEqualObjects(lastEventPayload[@"data"][@"key"], base64Content); + XCTAssertNotNil(lastEventPayload[@"data"][@"key"]); } - (void)testThatInsertingArbitraryEventWithBlock:(MockEvent *(^)(id session, MockConversation *conversation))eventBlock expectedPayloadData:(id)expectedPayloadData diff --git a/wire-ios-mocktransport/Tests/Source/Conversations/MockTransportSessionConversationsTests.swift b/wire-ios-mocktransport/Tests/Source/Conversations/MockTransportSessionConversationsTests.swift index 8fc6731f4eb..59b76520a15 100644 --- a/wire-ios-mocktransport/Tests/Source/Conversations/MockTransportSessionConversationsTests.swift +++ b/wire-ios-mocktransport/Tests/Source/Conversations/MockTransportSessionConversationsTests.swift @@ -341,8 +341,12 @@ class MockTransportSessionConversationsTests_Swift: MockTransportSessionTests { let lastEvent = conversation!.events.lastObject as! MockEvent XCTAssertNotNil(lastEvent) XCTAssertEqual(lastEvent.eventType, ZMUpdateEventType.conversationOtrMessageAdd) - XCTAssertNotNil(lastEvent.decryptedOTRData) - let decryptedMessage = try! GenericMessage(serializedData: lastEvent.decryptedOTRData!) + + // Extract message data from event (mock transport doesn't decrypt) + let eventData = lastEvent.data as! NSDictionary + let messageDataBase64 = eventData["text"] as! String + let messageBytes = Data(base64Encoded: messageDataBase64)! + let decryptedMessage = try! GenericMessage(serializedData: messageBytes) XCTAssertEqual(decryptedMessage.text.content, messageText) } diff --git a/wire-ios-mocktransport/Tests/Source/MockTransportSessionTests.m b/wire-ios-mocktransport/Tests/Source/MockTransportSessionTests.m index bc126d46e6a..f62afa31ffc 100644 --- a/wire-ios-mocktransport/Tests/Source/MockTransportSessionTests.m +++ b/wire-ios-mocktransport/Tests/Source/MockTransportSessionTests.m @@ -138,7 +138,6 @@ - (void)tearDown self.cookieStorage = nil; self.pushChannelDidOpenCount = 0; self.pushChannelDidCloseCount = 0; - [NSFileManager.defaultManager removeItemAtURL:[MockUserClient mockEncryptionSessionDirectory] error:nil]; [super tearDown]; } diff --git a/wire-ios-mocktransport/WireMockTransport.xcodeproj/project.pbxproj b/wire-ios-mocktransport/WireMockTransport.xcodeproj/project.pbxproj index 3a0faa2b1dc..ae92f4b522a 100644 --- a/wire-ios-mocktransport/WireMockTransport.xcodeproj/project.pbxproj +++ b/wire-ios-mocktransport/WireMockTransport.xcodeproj/project.pbxproj @@ -13,7 +13,6 @@ 59EC73FB2C20B82F00E5C036 /* WireSystem.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 59EC73FA2C20B82F00E5C036 /* WireSystem.framework */; }; CB79AC682C6D0009003CF5F4 /* WireTransportSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CB79AC672C6D0009003CF5F4 /* WireTransportSupport.framework */; }; EE67F700296F09D8001D7C88 /* WireTesting.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE67F6FF296F09D8001D7C88 /* WireTesting.framework */; }; - EE974125295498DA000C9340 /* WireCryptobox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE974124295498DA000C9340 /* WireCryptobox.framework */; }; EE974128295498E2000C9340 /* WireTransport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE974127295498E2000C9340 /* WireTransport.framework */; }; EE9AEC922BD1596000F7853F /* WireMockTransport.docc in Sources */ = {isa = PBXBuildFile; fileRef = EE9AEC912BD1596000F7853F /* WireMockTransport.docc */; }; /* End PBXBuildFile section */ @@ -90,7 +89,6 @@ buildActionMask = 2147483647; files = ( 5950B03A2E2EA5990051B07A /* GenericMessageProtocol in Frameworks */, - EE974125295498DA000C9340 /* WireCryptobox.framework in Frameworks */, 59EC73FB2C20B82F00E5C036 /* WireSystem.framework in Frameworks */, EE67F700296F09D8001D7C88 /* WireTesting.framework in Frameworks */, CB79AC682C6D0009003CF5F4 /* WireTransportSupport.framework in Frameworks */, diff --git a/wire-ios-mono.xcworkspace/contents.xcworkspacedata b/wire-ios-mono.xcworkspace/contents.xcworkspacedata index c45ff0caf66..c007158cd3f 100644 --- a/wire-ios-mono.xcworkspace/contents.xcworkspacedata +++ b/wire-ios-mono.xcworkspace/contents.xcworkspacedata @@ -176,9 +176,6 @@ - - diff --git a/wire-ios-request-strategy/Sources/Helpers/EventDecoderDecryptionTests.swift b/wire-ios-request-strategy/Sources/Helpers/EventDecoderDecryptionTests.swift index c9547f14d30..7ca2011649a 100644 --- a/wire-ios-request-strategy/Sources/Helpers/EventDecoderDecryptionTests.swift +++ b/wire-ios-request-strategy/Sources/Helpers/EventDecoderDecryptionTests.swift @@ -19,7 +19,6 @@ import Foundation import GenericMessageProtocol import WireCoreCrypto -import WireCryptobox import WireDataModel import XCTest diff --git a/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategy.swift b/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategy.swift index 86883445d47..b40e6c226f3 100644 --- a/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategy.swift +++ b/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategy.swift @@ -17,7 +17,6 @@ // import Foundation -import WireCryptobox import WireDataModel import WireSystem import WireTransport diff --git a/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategyTests.swift b/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategyTests.swift index 7a2e0623763..0730f5af9ee 100644 --- a/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategyTests.swift +++ b/wire-ios-request-strategy/Sources/Request Strategies/User Clients/FetchingClientRequestStrategyTests.swift @@ -17,7 +17,6 @@ // import Foundation -import WireCryptobox import WireDataModel import WireTesting import WireTransport diff --git a/wire-ios-request-strategy/Sources/Synchronization/Decoding/EventDecoder+Proteus.swift b/wire-ios-request-strategy/Sources/Synchronization/Decoding/EventDecoder+Proteus.swift index ccac818cd17..2c6b296654a 100644 --- a/wire-ios-request-strategy/Sources/Synchronization/Decoding/EventDecoder+Proteus.swift +++ b/wire-ios-request-strategy/Sources/Synchronization/Decoding/EventDecoder+Proteus.swift @@ -18,7 +18,6 @@ import Foundation import WireCoreCrypto -import WireCryptobox import WireLogging private let zmLog = ZMSLog(tag: "EventDecoder") diff --git a/wire-ios-request-strategy/Sources/Synchronization/Decoding/EventDecoder.swift b/wire-ios-request-strategy/Sources/Synchronization/Decoding/EventDecoder.swift index 45c46ffc316..b7d9e483cc6 100644 --- a/wire-ios-request-strategy/Sources/Synchronization/Decoding/EventDecoder.swift +++ b/wire-ios-request-strategy/Sources/Synchronization/Decoding/EventDecoder.swift @@ -83,7 +83,7 @@ public final class EventDecoder: NSObject, EventDecoderProtocol { extension EventDecoder { /// Decrypts passed in events and stores them in chronological order in a persisted database, - /// it then saves the database and cryptobox + /// it then saves the database /// /// - Parameters: /// - events: Encrypted events diff --git a/wire-ios-sync-engine/Source/SessionManager/PushTokenService.swift b/wire-ios-sync-engine/Source/SessionManager/PushTokenService.swift index b833844e442..7c9ffe69496 100644 --- a/wire-ios-sync-engine/Source/SessionManager/PushTokenService.swift +++ b/wire-ios-sync-engine/Source/SessionManager/PushTokenService.swift @@ -85,12 +85,12 @@ public final class PushTokenService: PushTokenServiceInterface { do { for remoteToken in remoteTokens where remoteToken != excludedToken { - WireLogger.push.debug("unregister invalid token: \(remoteToken.deviceToken.safeForLoggingDescription)") + WireLogger.push.debug("unregister invalid token: <\(remoteToken.deviceToken.readableHash)>") var removeAction = RemovePushTokenAction(deviceToken: remoteToken.deviceTokenString) try await removeAction.perform(in: context) WireLogger.push .debug( - "unregister invalid token of type: \(remoteToken.deviceToken.safeForLoggingDescription), success" + "unregister invalid token of type: <\(remoteToken.deviceToken.readableHash)>, success" ) } } catch let error as RemovePushTokenAction.Failure { diff --git a/wire-ios-sync-engine/Source/Synchronization/ZMOperationLoop.m b/wire-ios-sync-engine/Source/Synchronization/ZMOperationLoop.m index 60d6d76785e..91f59eadfc1 100644 --- a/wire-ios-sync-engine/Source/Synchronization/ZMOperationLoop.m +++ b/wire-ios-sync-engine/Source/Synchronization/ZMOperationLoop.m @@ -19,7 +19,6 @@ @import WireUtilities; @import WireSystem; @import WireTransport; -@import WireCryptobox; @import WireDataModel; #import "ZMOperationLoop+Private.h" diff --git a/wire-ios-sync-engine/Tests/Source/E2EE/UserClientRequestFactoryTests.swift b/wire-ios-sync-engine/Tests/Source/E2EE/UserClientRequestFactoryTests.swift index 433022111fe..7ec361ac6e5 100644 --- a/wire-ios-sync-engine/Tests/Source/E2EE/UserClientRequestFactoryTests.swift +++ b/wire-ios-sync-engine/Tests/Source/E2EE/UserClientRequestFactoryTests.swift @@ -17,7 +17,6 @@ // import Foundation -import WireCryptobox import WireDataModel import WireDataModelSupport import WireMockTransport diff --git a/wire-ios-sync-engine/Tests/Source/MessagingTest.h b/wire-ios-sync-engine/Tests/Source/MessagingTest.h index 513ed6cd7d7..cb958556e42 100644 --- a/wire-ios-sync-engine/Tests/Source/MessagingTest.h +++ b/wire-ios-sync-engine/Tests/Source/MessagingTest.h @@ -33,7 +33,6 @@ @class ZMAssetClientMessage; @class LastUpdateEventRepository; -@import WireCryptobox; @import WireImages; @class UserClient; diff --git a/wire-ios-sync-engine/Tests/Source/Synchronization/SynchronizationMocks.swift b/wire-ios-sync-engine/Tests/Source/Synchronization/SynchronizationMocks.swift index 20df8dbdcdb..6cdbff981c9 100644 --- a/wire-ios-sync-engine/Tests/Source/Synchronization/SynchronizationMocks.swift +++ b/wire-ios-sync-engine/Tests/Source/Synchronization/SynchronizationMocks.swift @@ -18,7 +18,6 @@ import avs import Foundation -import WireCryptobox import WireDataModel @testable import WireSyncEngine diff --git a/wire-ios-sync-engine/Tests/Source/Synchronization/ZMOperationLoopTests.h b/wire-ios-sync-engine/Tests/Source/Synchronization/ZMOperationLoopTests.h index e7c7b56525d..34f7c01704a 100644 --- a/wire-ios-sync-engine/Tests/Source/Synchronization/ZMOperationLoopTests.h +++ b/wire-ios-sync-engine/Tests/Source/Synchronization/ZMOperationLoopTests.h @@ -17,7 +17,6 @@ // @import WireTransport; -@import WireCryptobox; @import WireDataModel; @import avs; diff --git a/wire-ios-sync-engine/Tests/Source/UserSession/ZMClientRegistrationStatusTests.swift b/wire-ios-sync-engine/Tests/Source/UserSession/ZMClientRegistrationStatusTests.swift index 05f32c4b31a..24f84ed9795 100644 --- a/wire-ios-sync-engine/Tests/Source/UserSession/ZMClientRegistrationStatusTests.swift +++ b/wire-ios-sync-engine/Tests/Source/UserSession/ZMClientRegistrationStatusTests.swift @@ -232,7 +232,7 @@ final class ZMClientRegistrationStatusTests: MessagingTest { } } - func testThatItInvalidatesSelfClientAndDeletesAndRecreatesCryptoBoxOnDidDetectCurrentClientDeletion() { + func testThatItInvalidatesSelfClient_OnDidDetectCurrentClientDeletion() { syncMOC.performAndWait { // given let selfUser = ZMUser.selfUser(in: self.syncMOC) diff --git a/wire-ios/Tests/Mocks/MockUserType+SelfLegalHoldSubject.swift b/wire-ios/Tests/Mocks/MockUserType+SelfLegalHoldSubject.swift index 6e90181aedd..9dbc4ca3512 100644 --- a/wire-ios/Tests/Mocks/MockUserType+SelfLegalHoldSubject.swift +++ b/wire-ios/Tests/Mocks/MockUserType+SelfLegalHoldSubject.swift @@ -17,7 +17,6 @@ // import Foundation -import WireCryptobox extension MockUserType: SelfLegalHoldSubject { @@ -36,11 +35,7 @@ extension MockUserType: SelfLegalHoldSubject { } var fingerprint: String? { - guard let preKey = legalHoldDataSource.legalHoldRequest?.lastPrekey, - let fingerprintData = EncryptionSessionsDirectory.fingerprint(fromPrekey: preKey.key) else { - return nil - } - return String(decoding: fingerprintData, as: UTF8.self) + nil } func legalHoldRequestWasCancelled() { diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.320-0.png index 7df76b995fc..cebca05541c 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.320-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.320-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a98f83ef922cc0305f872f3da585a6b8b121372f5651a5df3954c98900dbece6 -size 19949 +oid sha256:6ea16c8001dccd8356cc9b40e1ea77d8c8997f9dcd12bfed11f57f877760b8e2 +size 13481 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.375-0.png index fc8dc7b70c2..5cd15869619 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.375-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.375-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fbb41d98b61009829da0496657a53bf1d6454fcda49890612072d7bd3c0e212f -size 17745 +oid sha256:b7df28fc95d488e83f201f7cf5229b1c8df126f20b9413a45e2a1ccefc3578c8 +size 12165 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.414-0.png index 1fbcf81501e..9e81f4aaed6 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.414-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Other.414-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9250cfa2ed597b019569f3549d53ecaf0c9a4a09b70d0781d4c3be3f04693c76 -size 18261 +oid sha256:a1074f96c37c93fc1077167248962cd05a763f07aead73432141224e78d060e3 +size 12483 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.320-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.320-0.png index 1bcfba9af9b..2c0903f3a54 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.320-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.320-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e3e431481617d33e9fc27990462b80ad6253bb79021e1742c7312e22a3762ec7 -size 19616 +oid sha256:f29aca1203b0e8666fe86d7c5f52860ab91e19e2b415051c48a245885f4fc514 +size 13154 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.375-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.375-0.png index ac45e528431..6cb6b43fcf5 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.375-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.375-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:89144dd538fdd21dfa69a09be7fb996ec88c080484486dda87b848163018bb5c -size 17194 +oid sha256:8d3996487e95a59c65492172eefba75071730d1aad6a2c951964b0914b4dc6ac +size 11585 diff --git a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.414-0.png b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.414-0.png index 5adb73e191c..9978c048fea 100644 --- a/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.414-0.png +++ b/wire-ios/Wire-iOS Tests/ReferenceImages/ConversationSystemMessageTests/testDecryptionFailed_Self.414-0.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9c0cd11e8f6ac78d7b84911a51f715615fc8d7086f03a331fa992c0fb85ccb6e -size 17671 +oid sha256:e15a478f0b3093921bb885b27302bf801814d9285926ac719a6a65dd48b07247 +size 11867 diff --git a/wire-ios/Wire-iOS.xcodeproj/project.pbxproj b/wire-ios/Wire-iOS.xcodeproj/project.pbxproj index b5ca7348338..f3c018f9aa7 100644 --- a/wire-ios/Wire-iOS.xcodeproj/project.pbxproj +++ b/wire-ios/Wire-iOS.xcodeproj/project.pbxproj @@ -135,8 +135,6 @@ EE67F742296F0EBC001D7C88 /* WireCanvas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EE67F740296F0EBC001D7C88 /* WireCanvas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; EE7905F627F326EB00FCBF8C /* Wire Share Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 168A16A91D9597C2005CFA6C /* Wire Share Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; EEE25B2A29719A730008B894 /* cryptobox.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEE25B2729719A730008B894 /* cryptobox.xcframework */; }; - EEE25B3529719BD30008B894 /* WireCryptobox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEE25B3429719BD30008B894 /* WireCryptobox.framework */; }; - EEE25B3629719BD30008B894 /* WireCryptobox.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EEE25B3429719BD30008B894 /* WireCryptobox.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; EEE25B3829719C170008B894 /* WireDataModel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEE25B3729719C170008B894 /* WireDataModel.framework */; }; EEE25B3929719C170008B894 /* WireDataModel.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = EEE25B3729719C170008B894 /* WireDataModel.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; EEE25B3B29719C370008B894 /* WireLinkPreview.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EEE25B3A29719C370008B894 /* WireLinkPreview.framework */; }; @@ -234,7 +232,6 @@ dstSubfolderSpec = 10; files = ( 5996E8A72C19D090007A52F0 /* WireSyncEngine.framework in Embed Frameworks */, - EEE25B3629719BD30008B894 /* WireCryptobox.framework in Embed Frameworks */, EE33C48E296485FA00C058D1 /* WireShareEngine.framework in Embed Frameworks */, EE67F73F296F0E7D001D7C88 /* Ziphy.framework in Embed Frameworks */, EEE25B4229719C750008B894 /* WireRequestStrategy.framework in Embed Frameworks */, @@ -950,7 +947,6 @@ 0619A95C2D3FE78700876BDE /* WireAuthenticationUI in Frameworks */, EEE25B4129719C750008B894 /* WireRequestStrategy.framework in Frameworks */, EE543B4A2D564AC000CA96BA /* WireAuthentication in Frameworks */, - EEE25B3529719BD30008B894 /* WireCryptobox.framework in Frameworks */, 06EF6B552E8EBEF200A131A7 /* WireCallingUI in Frameworks */, 01C774272D9EECE100A2FF07 /* WireAVS in Frameworks */, CBE5BB862E2D4A9200AC731F /* WireMessagingAssembly in Frameworks */, diff --git a/wire-ios/Wire-iOS/Generated/Strings+Generated.swift b/wire-ios/Wire-iOS/Generated/Strings+Generated.swift index b509a0d1b5a..c4c8a0dedf4 100644 --- a/wire-ios/Wire-iOS/Generated/Strings+Generated.swift +++ b/wire-ios/Wire-iOS/Generated/Strings+Generated.swift @@ -2156,8 +2156,6 @@ internal enum L10n { internal static func other(_ p1: Any) -> String { return L10n.tr("Localizable", "content.system.cannot_decrypt.other", String(describing: p1), fallback: "A message from %@ could not be decrypted.") } - /// Fix future messages - internal static let resetSession = L10n.tr("Localizable", "content.system.cannot_decrypt.reset_session", fallback: "Fix future messages") /// A message from you could not be decrypted. internal static let `self` = L10n.tr("Localizable", "content.system.cannot_decrypt.self", fallback: "A message from you could not be decrypted.") } diff --git a/wire-ios/Wire-iOS/Resources/Localization/Base.lproj/Localizable.strings b/wire-ios/Wire-iOS/Resources/Localization/Base.lproj/Localizable.strings index 207ed41ebb6..b6e4f61cd44 100644 --- a/wire-ios/Wire-iOS/Resources/Localization/Base.lproj/Localizable.strings +++ b/wire-ios/Wire-iOS/Resources/Localization/Base.lproj/Localizable.strings @@ -660,7 +660,6 @@ "content.system.cannot_decrypt.self" = "A message from you could not be decrypted."; "content.system.cannot_decrypt.other" = "A message from %@ could not be decrypted."; -"content.system.cannot_decrypt.reset_session" = "Fix future messages"; "content.system.cannot_decrypt.error_details" = "(Fixed error: %d ID: %@)"; "content.system.cannot_decrypt_resolved.self" = "You can now decrypt messages from yourself. To recover lost messages, you need to resend them."; diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Components/ConversationCannotDecryptSystemMessageCell.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Components/ConversationCannotDecryptSystemMessageCell.swift index 8cdc77dbeca..e8c3b0c8da2 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Components/ConversationCannotDecryptSystemMessageCell.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Components/ConversationCannotDecryptSystemMessageCell.swift @@ -42,17 +42,4 @@ final class ConversationCannotDecryptSystemMessageCell: textLabel.linkTextAttributes = [:] } - // MARK: - UITextViewDelegate - - override func textView( - _ textView: UITextView, - shouldInteractWith url: URL, - in characterRange: NSRange, - interaction: UITextItemInteraction - ) -> Bool { - delegate?.perform(action: .resetSession, for: message!, view: self) - - return false - } - } diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Components/ConversationCannotDecryptSystemMessageCellDescription.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Components/ConversationCannotDecryptSystemMessageCellDescription.swift index b3801284721..b1a65c27f1a 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Components/ConversationCannotDecryptSystemMessageCellDescription.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/Components/ConversationCannotDecryptSystemMessageCellDescription.swift @@ -29,8 +29,6 @@ final class ConversationCannotDecryptSystemMessageCellDescription: ConversationM let configuration: View.Configuration - private static let resetSessionURL: URL = .init(string: "action://reset-session")! - var message: ZMConversationMessage? weak var delegate: ConversationMessageCellDelegate? weak var actionController: ConversationMessageActionController? @@ -89,7 +87,6 @@ final class ConversationCannotDecryptSystemMessageCellDescription: ConversationM ) -> NSAttributedString { let messageString = messageString(systemMessage.systemMessageType, sender: sender) - let resetSessionString = resetSessionString(accentColor: accentColor) let errorDetailsString = errorDetailsString( errorCode: systemMessage.decryptionErrorCode?.intValue ?? 0, clientIdentifier: systemMessage.senderClientID ?? "N/A" @@ -100,10 +97,6 @@ final class ConversationCannotDecryptSystemMessageCellDescription: ConversationM switch systemMessage.systemMessageType { case .decryptionFailed: components = [messageString] - - if systemMessage.isDecryptionErrorRecoverable { - components.append(resetSessionString) - } case .decryptionFailedResolved: components = [ messageString, @@ -153,19 +146,6 @@ final class ConversationCannotDecryptSystemMessageCellDescription: ConversationM return NSMutableAttributedString.markdown(from: localizationKey.localized(args: name), style: .systemMessage) } - private static func resetSessionString(accentColor: UIColor) -> NSAttributedString { - let string = L10n.Localizable.Content.System.CannotDecrypt.resetSession - - return NSAttributedString( - string: string.localizedUppercase, - attributes: [ - .link: resetSessionURL, - .foregroundColor: accentColor, - .font: UIFont.mediumSemiboldFont - ] - ) - } - private static func errorDetailsString(errorCode: Int, clientIdentifier: String) -> NSAttributedString { let string = L10n.Localizable.Content.System.CannotDecrypt.errorDetails(errorCode, clientIdentifier) diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageActionController.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageActionController.swift index ab0c9d1c5d2..06ee12a9c8f 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageActionController.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/ConfigurationMessageCell/ConversationMessageActionController.swift @@ -148,8 +148,7 @@ final class ConversationMessageActionController { return message.isSentBySelfUser && message.isCollapsingSupported case .present, - .openQuote, - .resetSession: + .openQuote: return false } } diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/MessageAction.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/MessageAction.swift index 19bfec3dd01..ac1c1d6a8d3 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/MessageAction.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/Cells/MessageAction.swift @@ -40,7 +40,6 @@ enum MessageAction: CaseIterable, Equatable { .sketchEmoji, .present, .openQuote, - .resetSession, .delete, .react("❤️") ] @@ -62,7 +61,6 @@ enum MessageAction: CaseIterable, Equatable { // Not included in ConversationMessageActionController.allMessageActions, for image viewer/open quote present, openQuote, - resetSession, react(Emoji.ID), visitLink, collapse @@ -102,7 +100,6 @@ enum MessageAction: CaseIterable, Equatable { return MessageActionLocale.collapse case .present, .openQuote, - .resetSession, .react: return nil } @@ -139,7 +136,6 @@ enum MessageAction: CaseIterable, Equatable { case .present, .openQuote, .digitallySign, - .resetSession, .react, .collapse: nil @@ -189,7 +185,6 @@ enum MessageAction: CaseIterable, Equatable { case .present, .openQuote, .digitallySign, - .resetSession, .react, .visitLink, .collapse: @@ -230,8 +225,7 @@ enum MessageAction: CaseIterable, Equatable { case .present, .sketchDraw, .sketchEmoji, - .openQuote, - .resetSession: + .openQuote: // no message related actions are not handled in ConversationMessageActionController nil } diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController+MessageAction.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController+MessageAction.swift index 0ceda253fab..59d46f1cca3 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController+MessageAction.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController+MessageAction.swift @@ -180,11 +180,6 @@ extension ConversationContentViewController { navigationController.modalPresentationStyle = .formSheet parent?.present(navigationController, animated: true) - case .resetSession: - guard let client = message.systemMessageData?.clients.first as? UserClient else { return } - activityIndicator.start() - userClientToken = UserClientChangeInfo.add(observer: self, for: client) - client.resetSession() case let .react(reaction): userSession.perform { let useCase = self.userSession.makeToggleMessageReactionUseCase() @@ -220,18 +215,6 @@ extension ConversationContentViewController { } } -// MARK: - UserClientObserver - -extension ConversationContentViewController: UserClientObserver { - - func userClientDidChange(_ changeInfo: UserClientChangeInfo) { - if changeInfo.sessionHasBeenReset { - userClientToken = nil - activityIndicator.stop() - } - } -} - // MARK: - SignatureObserver extension ConversationContentViewController: SignatureObserver { diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController.swift index 83aa85ecc22..e86503e50e1 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Conversation/Content/ConversationContentViewController.swift @@ -118,7 +118,6 @@ final class ConversationContentViewController: UIViewController { let selfProfileUIBuilder: SelfProfileViewControllerBuilderProtocol var connectionViewController: UserConnectionViewController? var digitalSignatureToken: Any? - var userClientToken: Any? var isDigitalSignatureVerificationShown: Bool = false private var mediaPlaybackManager: MediaPlaybackManager? diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory+Developer.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory+Developer.swift index a228925b267..954dd54994d 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory+Developer.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsCellDescriptorFactory+Developer.swift @@ -65,7 +65,6 @@ extension SettingsCellDescriptorFactory { ) developerCellDescriptors.append(SettingsShareDatabaseCellDescriptor()) - developerCellDescriptors.append(SettingsShareCryptoboxCellDescriptor()) developerCellDescriptors.append( Button( diff --git a/wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsShareDatabaseCellDescriptor.swift b/wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsShareDatabaseCellDescriptor.swift index 2b8b7586bdb..51b0ba513e3 100644 --- a/wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsShareDatabaseCellDescriptor.swift +++ b/wire-ios/Wire-iOS/Sources/UserInterface/Settings/CellDescriptors/SettingsShareDatabaseCellDescriptor.swift @@ -58,36 +58,3 @@ final class SettingsShareDatabaseCellDescriptor: SettingsButtonCellDescriptor { } } - -final class SettingsShareCryptoboxCellDescriptor: SettingsButtonCellDescriptor { - - let documentDelegate: DocumentDelegate - - init() { - let documentDelegate = DocumentDelegate() - self.documentDelegate = documentDelegate - - super.init(title: "Share Cryptobox", isDestructive: false) { _ in - guard let userSession = ZMUserSession.shared() else { return } - let fileURL = userSession.managedObjectContext.zm_storeURL! - .deletingLastPathComponent() - .deletingLastPathComponent() - .appending(path: "otr", directoryHint: .isDirectory) - let archiveURL = fileURL.appendingPathExtension("zip") - - try? FileManager.default.removeItem(at: archiveURL) - try? FileManager.default.zipItem( - at: fileURL, - to: archiveURL, - shouldKeepParent: false, - compressionMethod: .deflate - ) - - let shareDatabaseDocumentController = UIDocumentInteractionController(url: archiveURL) - shareDatabaseDocumentController.delegate = documentDelegate - shareDatabaseDocumentController.presentPreview(animated: true) - } - - } - -}