From 9e1326358176952c2fc7bfc807241db3edb8cc64 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Wed, 25 Jun 2025 11:24:57 -0700 Subject: [PATCH] Switch to swift-format for formatting instead of swiftformat swift-format is owned by the Swift project and is generally less opinionated than swiftformat (but better at formatting to a limited line length). --- .github/workflows/build_and_test.yml | 9 +- .swift-format | 9 + .swiftformat | 25 - bin/mac_setup.sh | 1 - justfile | 4 +- swift/.swiftlint.yml | 3 + swift/Benchmarks/Package.swift | 6 +- .../Benchmarks/GroupSendEndorsements.swift | 28 +- swift/Package.swift | 4 +- .../Sources/LibSignalClient/AccountKeys.swift | 21 +- swift/Sources/LibSignalClient/Address.swift | 21 +- swift/Sources/LibSignalClient/Aes256Ctr.swift | 38 +- swift/Sources/LibSignalClient/Aes256Gcm.swift | 76 ++- .../LibSignalClient/Aes256GcmSiv.swift | 4 +- .../Sources/LibSignalClient/AsyncUtils.swift | 14 +- .../Sources/LibSignalClient/BorrowUtils.swift | 6 +- swift/Sources/LibSignalClient/Cds2.swift | 14 +- swift/Sources/LibSignalClient/CdsTypes.swift | 21 +- .../LibSignalClient/ChatConnection+Fake.swift | 116 +++- .../LibSignalClient/ChatConnection.swift | 70 +- .../LibSignalClient/ChatListener.swift | 35 +- .../LibSignalClient/ChatServiceTypes.swift | 68 +- .../LibSignalClient/ComparableBackup.swift | 4 +- .../LibSignalClient/DataStoreInMemory.swift | 32 +- .../LibSignalClient/DataStoreProtocols.swift | 26 +- .../LibSignalClient/DataStoreUtils.swift | 76 ++- swift/Sources/LibSignalClient/Error.swift | 9 +- .../Sources/LibSignalClient/Fingerprint.swift | 20 +- .../Sources/LibSignalClient/HsmEnclave.swift | 16 +- .../Sources/LibSignalClient/IdentityKey.swift | 16 +- .../LibSignalClient/IncrementalMac.swift | 8 +- swift/Sources/LibSignalClient/IoUtils.swift | 5 +- swift/Sources/LibSignalClient/Kdf.swift | 14 +- swift/Sources/LibSignalClient/Kem.swift | 27 +- swift/Sources/LibSignalClient/Logging.swift | 31 +- swift/Sources/LibSignalClient/Media.swift | 5 +- .../LibSignalClient/MessageBackup.swift | 33 +- .../LibSignalClient/NativeHandleOwner.swift | 9 +- swift/Sources/LibSignalClient/Net.swift | 75 ++- .../Sources/LibSignalClient/PrivateKey.swift | 9 +- swift/Sources/LibSignalClient/Protocol.swift | 52 +- swift/Sources/LibSignalClient/PublicKey.swift | 8 +- .../LibSignalClient/RegistrationService.swift | 631 +++++------------- .../RegistrationServiceTypes.swift | 432 ++++++++++++ .../LibSignalClient/SealedSender.swift | 13 +- .../SealedSenderCertificates.swift | 51 +- swift/Sources/LibSignalClient/ServiceId.swift | 6 +- swift/Sources/LibSignalClient/Sgx.swift | 4 +- swift/Sources/LibSignalClient/Svr2.swift | 14 +- .../LibSignalClient/TokioAsyncContext.swift | 39 +- swift/Sources/LibSignalClient/Username.swift | 11 +- swift/Sources/LibSignalClient/Utils.swift | 133 +++- .../messages/CiphertextMessage.swift | 4 +- .../messages/PlaintextContent.swift | 29 +- .../messages/PreKeySignalMessage.swift | 4 +- .../SenderKeyDistributionMessage.swift | 18 +- .../messages/SenderKeyMessage.swift | 8 +- .../messages/SignalMessage.swift | 20 +- .../state/KyberPreKeyRecord.swift | 9 +- .../LibSignalClient/state/PreKeyBundle.swift | 72 +- .../LibSignalClient/state/PreKeyRecord.swift | 9 +- .../state/SenderKeyRecord.swift | 9 +- .../LibSignalClient/state/SessionRecord.swift | 21 +- .../state/SignedPreKeyRecord.swift | 27 +- .../zkgroup/BackupAuthCredential.swift | 5 +- .../BackupAuthCredentialPresentation.swift | 8 +- .../zkgroup/BackupAuthCredentialRequest.swift | 33 +- .../BackupAuthCredentialRequestContext.swift | 14 +- .../LibSignalClient/zkgroup/BackupLevel.swift | 6 +- .../LibSignalClient/zkgroup/ByteArray.swift | 12 +- .../zkgroup/CallLinkAuthCredential.swift | 33 +- .../CallLinkAuthCredentialPresentation.swift | 15 +- .../CallLinkAuthCredentialResponse.swift | 42 +- .../zkgroup/ClientZkAuthOperations.swift | 41 +- .../zkgroup/ClientZkGroupCipher.swift | 15 +- .../zkgroup/ClientZkProfileOperations.swift | 58 +- .../zkgroup/ClientZkReceiptOperations.swift | 54 +- .../zkgroup/CreateCallLinkCredential.swift | 33 +- ...CreateCallLinkCredentialPresentation.swift | 17 +- .../CreateCallLinkCredentialRequest.swift | 22 +- ...eateCallLinkCredentialRequestContext.swift | 14 +- .../zkgroup/GroupSendDerivedKeyPair.swift | 6 +- .../zkgroup/GroupSendEndorsement.swift | 5 +- .../GroupSendEndorsementsResponse.swift | 26 +- .../LibSignalClient/zkgroup/Randomness.swift | 8 +- .../zkgroup/ServerPublicParams.swift | 8 +- .../zkgroup/ServerSecretParams.swift | 4 +- .../zkgroup/ServerZkAuthOperations.swift | 44 +- .../zkgroup/ServerZkProfileOperations.swift | 42 +- .../zkgroup/ServerZkReceiptOperations.swift | 39 +- .../AccountEntropyTests.swift | 5 +- .../LibSignalClientTests/AsyncTests.swift | 45 +- .../LibSignalClientTests/BridgingTests.swift | 21 +- .../ChatServiceTests.swift | 120 +++- .../ClonableHandleOwnerTests.swift | 8 +- .../LibSignalClientTests/CryptoTests.swift | 158 ++++- .../HsmEnclaveTests.swift | 50 +- .../InMemorySignalProtocolStoreTests.swift | 15 +- .../IncrementalMacTests.swift | 4 +- .../Tests/LibSignalClientTests/IoTests.swift | 11 +- .../Tests/LibSignalClientTests/IoUtils.swift | 3 +- .../KeyTransparencyTests.swift | 19 +- .../MediaSanitizerTests.swift | 81 ++- .../MessageBackupTests.swift | 36 +- .../LibSignalClientTests/NativeTests.swift | 9 +- .../Tests/LibSignalClientTests/NetTests.swift | 25 +- .../LibSignalClientTests/PublicAPITests.swift | 248 +++---- .../RegistrationServiceTests.swift | 123 ++-- .../LibSignalClientTests/ServiceIdTests.swift | 39 +- .../LibSignalClientTests/SessionTests.swift | 88 ++- .../Tests/LibSignalClientTests/SgxTests.swift | 33 +- .../LibSignalClientTests/TestCaseBase.swift | 3 +- .../LibSignalClientTests/TestUtils.swift | 3 +- .../LibSignalClientTests/UsernameTests.swift | 15 +- .../LibSignalClientTests/ZKGroupTests.swift | 301 +++++++-- 115 files changed, 3244 insertions(+), 1455 deletions(-) create mode 100644 .swift-format delete mode 100644 .swiftformat create mode 100644 swift/Sources/LibSignalClient/RegistrationServiceTypes.swift diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 84af6fb88..d232dcbe8 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -415,8 +415,15 @@ jobs: - run: brew install protobuf swiftlint - name: Check formatting - run: swiftformat --swiftversion 5 --reporter github-actions-log --lint . + run: swift format --in-place --parallel --recursive . && git diff --exit-code . working-directory: swift + env: + # This is only here because we're on a macOS 15 runner, which defaults to Xcode 16.0, + # which contains a swift-format that fails on some of our Swift 6.0 code. + # Once we're on a later runner, this should be removed. + # We should know that immediately if this stays at 16.2, + # because the new runners usually only keep one previous Xcode major version. + DEVELOPER_DIR: /Applications/Xcode_16.2.app - name: Run lint run: swiftlint lint --strict --reporter github-actions-logging diff --git a/.swift-format b/.swift-format new file mode 100644 index 000000000..cba2e85e6 --- /dev/null +++ b/.swift-format @@ -0,0 +1,9 @@ +{ + "version": 1, + "lineLength": 120, + "indentation": { "spaces": 4 }, + "indentConditionalCompilationBlocks": false, + "lineBreakBeforeEachArgument": true, + "lineBreakBetweenDeclarationAttributes": true, + "prioritizeKeepingFunctionOutputTogether": true +} \ No newline at end of file diff --git a/.swiftformat b/.swiftformat deleted file mode 100644 index 20f4ce2c7..000000000 --- a/.swiftformat +++ /dev/null @@ -1,25 +0,0 @@ -#--header "\nCopyright {created.year} Signal Messenger, LLC.\nSPDX-License-Identifier: AGPL-3.0-only\n" ---disable hoistPatternLet -# Explicit self is better than implicit self. ---self insert -# Some arguments that it considers unused are used in doc comments, and replacing them with '_' is an error. ---stripunusedargs unnamed-only ---wraparguments before-first ---wrapcollections before-first -# Libsignal is a collection of many languages, remembering specific of each one is hard. Make it explicit. ---disable redundantinternal -# Ranges look better without spaces ---ranges no-space -# Pragmas should start at the begining of line. ---ifdef outdent ---indent 4 -# Patters are not redundant, they show the shape of thing, they show the shape of things. ---disable redundantPattern -# Leave try in the innermost position. ---disable hoistTry -# Explicit ACL even in extensions. ---extensionacl "on-declarations" -# Explicit is better than implicit. ---disable redundantNilInit -# Indentation for multi-line string literals. ---indentstrings true diff --git a/bin/mac_setup.sh b/bin/mac_setup.sh index 7974aa95c..711aa7bf6 100755 --- a/bin/mac_setup.sh +++ b/bin/mac_setup.sh @@ -18,7 +18,6 @@ brew "rocksdb" brew "ruby" brew "rustup" brew "shellcheck" -brew "swiftformat" brew "swiftlint" brew "taplo" brew "terraform" diff --git a/justfile b/justfile index 05e446834..cc95e420a 100644 --- a/justfile +++ b/justfile @@ -29,7 +29,7 @@ format-jni: (cd java && ./gradlew spotlessApply) format-ffi: - (cd swift && swiftformat --swiftversion 5 .) + (cd swift && swift format --in-place --parallel --recursive .) format-node: (cd node && npm run format) @@ -47,7 +47,7 @@ format-all: format-jni format-ffi format-node check-format-all: cargo fmt --all -- --check taplo fmt --check - (cd swift && swiftformat --swiftversion 5 . --lint) + @echo 'warning: `swift format` does not have a check mode' (cd node && npm run format-check) (cd java && ./gradlew spotlessCheck) diff --git a/swift/.swiftlint.yml b/swift/.swiftlint.yml index 364016e2c..a05bb8492 100644 --- a/swift/.swiftlint.yml +++ b/swift/.swiftlint.yml @@ -1,4 +1,5 @@ disabled_rules: +- closure_parameter_position # swift-format takes precedence here - cyclomatic_complexity - empty_enum_arguments - force_try @@ -6,6 +7,7 @@ disabled_rules: - function_parameter_count - identifier_name - line_length +- opening_brace # swift-format takes precedence here - redundant_optional_initialization - trailing_comma - type_body_length @@ -28,3 +30,4 @@ nesting: type_level: 2 excluded: - .build/** + - Benchmarks/.build/** diff --git a/swift/Benchmarks/Package.swift b/swift/Benchmarks/Package.swift index 51a11326c..4f914f27d 100644 --- a/swift/Benchmarks/Package.swift +++ b/swift/Benchmarks/Package.swift @@ -16,7 +16,7 @@ let package = Package( .macOS(.v10_15), .iOS(.v13), ], products: [ - .executable(name: "Benchmarks", targets: ["Benchmarks"]), + .executable(name: "Benchmarks", targets: ["Benchmarks"]) ], dependencies: [ .package(url: "https://github.com/google/swift-benchmark", from: "0.1.0"), @@ -27,12 +27,12 @@ let package = Package( name: "Benchmarks", dependencies: [ .product(name: "Benchmark", package: "swift-benchmark"), - .product(name: "LibSignalClient", package: "swift" /* the folder name, sigh */ ), + .product(name: "LibSignalClient", package: "swift" /* the folder name, sigh */), ], linkerSettings: [ .unsafeFlags(["-L\(rustReleaseBuildDir)"], .when(configuration: .release)), .unsafeFlags(["-L\(rustDebugBuildDir)"], .when(configuration: .debug)), ] - ), + ) ] ) diff --git a/swift/Benchmarks/Sources/Benchmarks/GroupSendEndorsements.swift b/swift/Benchmarks/Sources/Benchmarks/GroupSendEndorsements.swift index 6e64ceda1..09a5b1323 100644 --- a/swift/Benchmarks/Sources/Benchmarks/GroupSendEndorsements.swift +++ b/swift/Benchmarks/Sources/Benchmarks/GroupSendEndorsements.swift @@ -15,7 +15,9 @@ let groupSendEndorsementsSuite = BenchmarkSuite(name: "GroupSendEndorsements") { let groupParams = try! GroupSecretParams.generate() let now = UInt64(Date().timeIntervalSince1970) let startOfDay = now - now % SECONDS_PER_DAY - let expiration = Date(timeIntervalSince1970: TimeInterval(startOfDay)).addingTimeInterval(TimeInterval(2 * SECONDS_PER_DAY)) + let expiration = Date(timeIntervalSince1970: TimeInterval(startOfDay)).addingTimeInterval( + TimeInterval(2 * SECONDS_PER_DAY) + ) for groupSize in [10, 100, 1000] { let members = (0..(_ pin: Bytes) throws -> String /// - parameter encodedHash: An encoded string of the hash, as returned by `localHash` /// - returns: true if the pin matches the hash, false otherwise /// -public func verifyLocalPin(_ pin: Bytes, againstEncodedHash encodedHash: String) throws -> Bool { +public func verifyLocalPin(_ pin: Bytes, againstEncodedHash encodedHash: String) throws -> Bool +{ try encodedHash.withCString { hashPtr in try pin.withUnsafeBorrowedBuffer { buffer in try invokeFnReturningBool { @@ -104,11 +105,15 @@ public class PinHash: NativeHandleOwner, @unchecked Sen /// - parameter normalizedPin: A normalized, UTF-8 encoded byte representation of the pin to verify /// - parameter salt: A 32 byte salt /// - returns: A `PinHash` - public convenience init(normalizedPin: PinBytes, salt: SaltBytes) throws { + public convenience init( + normalizedPin: PinBytes, + salt: SaltBytes + ) throws { var result = SignalMutPointerPinHash() try normalizedPin.withUnsafeBorrowedBuffer { pinBytes in try salt.withUnsafeBytes { saltBytes in - try ByteArray(newContents: Data(saltBytes), expectedLength: 32).withUnsafePointerToSerialized { saltTuple in + try ByteArray(newContents: Data(saltBytes), expectedLength: 32).withUnsafePointerToSerialized { + saltTuple in try checkError(signal_pin_hash_from_salt(&result, pinBytes, saltTuple)) } } @@ -124,12 +129,18 @@ public class PinHash: NativeHandleOwner, @unchecked Sen /// - parameter username: The Basic Auth username used to authenticate with SVR2 /// - parameter mrenclave: The mrenclave where the hashed pin will be stored /// - returns: A `PinHash` - public convenience init(normalizedPin: PinBytes, username: String, mrenclave: MrenclaveBytes) throws { + public convenience init( + normalizedPin: PinBytes, + username: String, + mrenclave: MrenclaveBytes + ) throws { var result = SignalMutPointerPinHash() try normalizedPin.withUnsafeBorrowedBuffer { pinBytes in try mrenclave.withUnsafeBorrowedBuffer { mrenclaveBytes in try username.withCString { userBytes in - try checkError(signal_pin_hash_from_username_mrenclave(&result, pinBytes, userBytes, mrenclaveBytes)) + try checkError( + signal_pin_hash_from_username_mrenclave(&result, pinBytes, userBytes, mrenclaveBytes) + ) } } } diff --git a/swift/Sources/LibSignalClient/Address.swift b/swift/Sources/LibSignalClient/Address.swift index bef42f500..f0e880a71 100644 --- a/swift/Sources/LibSignalClient/Address.swift +++ b/swift/Sources/LibSignalClient/Address.swift @@ -14,11 +14,13 @@ public class ProtocolAddress: ClonableHandleOwner SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout SignalMutPointerProtocolAddress, + currentHandle: SignalConstPointerProtocolAddress + ) -> SignalFfiErrorRef? { return signal_address_clone(&newHandle, currentHandle) } - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_address_destroy(handle.pointer) } diff --git a/swift/Sources/LibSignalClient/Aes256Ctr.swift b/swift/Sources/LibSignalClient/Aes256Ctr.swift index d528a994d..e7db28a21 100644 --- a/swift/Sources/LibSignalClient/Aes256Ctr.swift +++ b/swift/Sources/LibSignalClient/Aes256Ctr.swift @@ -17,8 +17,12 @@ public class Aes256Ctr32: NativeHandleOwner { let handle = try key.withUnsafeBorrowedBuffer { keyBuffer in try nonce.withUnsafeBytes { nonceBytes in guard nonceBytes.count == Self.nonceLength else { - throw SignalError.invalidArgument("nonce must be \(Self.nonceLength) bytes (got \(nonceBytes.count))") + throw SignalError.invalidArgument( + "nonce must be \(Self.nonceLength) bytes (got \(nonceBytes.count))" + ) } + // swift-format-ignore + // (vertical alignment is clearer) let initialCounter = (UInt32(nonceBytes[12]) << 24) | (UInt32(nonceBytes[13]) << 16) | @@ -27,31 +31,37 @@ public class Aes256Ctr32: NativeHandleOwner { var nonceBufferWithoutCounter = SignalBorrowedBuffer(nonceBytes) nonceBufferWithoutCounter.length -= 4 var result = SignalMutPointerAes256Ctr32() - try checkError(signal_aes256_ctr32_new( - &result, - keyBuffer, - nonceBufferWithoutCounter, - initialCounter - )) + try checkError( + signal_aes256_ctr32_new( + &result, + keyBuffer, + nonceBufferWithoutCounter, + initialCounter + ) + ) return result } } self.init(owned: NonNull(handle)!) } - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_aes256_ctr32_destroy(handle.pointer) } public func process(_ message: inout Data) throws { try withNativeHandle { nativeHandle in try message.withUnsafeMutableBytes { messageBytes in - try checkError(signal_aes256_ctr32_process( - nativeHandle, - SignalBorrowedMutableBuffer(messageBytes), - 0, - UInt32(messageBytes.count) - )) + try checkError( + signal_aes256_ctr32_process( + nativeHandle, + SignalBorrowedMutableBuffer(messageBytes), + 0, + UInt32(messageBytes.count) + ) + ) } } } diff --git a/swift/Sources/LibSignalClient/Aes256Gcm.swift b/swift/Sources/LibSignalClient/Aes256Gcm.swift index 46a938f89..13b8763e5 100644 --- a/swift/Sources/LibSignalClient/Aes256Gcm.swift +++ b/swift/Sources/LibSignalClient/Aes256Gcm.swift @@ -92,12 +92,14 @@ public class Aes256GcmEncryption: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_aes256_gcm_encryption_destroy(handle.pointer) } public func encrypt(_ message: inout Data) throws { try withNativeHandle { nativeHandle in try message.withUnsafeMutableBytes { messageBytes in - try checkError(signal_aes256_gcm_encryption_update( - nativeHandle, - SignalBorrowedMutableBuffer(messageBytes), - 0, - UInt32(messageBytes.count) - )) + try checkError( + signal_aes256_gcm_encryption_update( + nativeHandle, + SignalBorrowedMutableBuffer(messageBytes), + 0, + UInt32(messageBytes.count) + ) + ) } } } @@ -158,12 +164,14 @@ public class Aes256GcmDecryption: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_aes256_gcm_decryption_destroy(handle.pointer) } public func decrypt(_ message: inout Data) throws { try withNativeHandle { nativeHandle in try message.withUnsafeMutableBytes { messageBytes in - try checkError(signal_aes256_gcm_decryption_update( - nativeHandle, - SignalBorrowedMutableBuffer(messageBytes), - 0, - UInt32(messageBytes.count) - )) + try checkError( + signal_aes256_gcm_decryption_update( + nativeHandle, + SignalBorrowedMutableBuffer(messageBytes), + 0, + UInt32(messageBytes.count) + ) + ) } } } @@ -192,11 +204,13 @@ public class Aes256GcmDecryption: NativeHandleOwner { self.init(owned: NonNull(handle)!) } - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_aes256_gcm_siv_destroy(handle.pointer) } diff --git a/swift/Sources/LibSignalClient/AsyncUtils.swift b/swift/Sources/LibSignalClient/AsyncUtils.swift index 44935b87f..80ae31031 100644 --- a/swift/Sources/LibSignalClient/AsyncUtils.swift +++ b/swift/Sources/LibSignalClient/AsyncUtils.swift @@ -120,7 +120,9 @@ private class Completer: CompleterBase { /// You must ensure that either the callback is called, or the result is passed to /// ``cleanUpUncompletedPromiseStruct(_:)``. func makePromiseStruct() -> Promise { - typealias RawPromiseCallback = @convention(c) (_ error: SignalFfiErrorRef?, _ value: sending UnsafeRawPointer?, _ context: UnsafeRawPointer?) -> Void + typealias RawPromiseCallback = @convention(c) ( + _ error: SignalFfiErrorRef?, _ value: sending UnsafeRawPointer?, _ context: UnsafeRawPointer? + ) -> Void let completeOpaque: RawPromiseCallback = { error, value, context in let completer: CompleterBase = Unmanaged.fromOpaque(context!).takeRetainedValue() completer.completeUnsafe(error, value) @@ -134,8 +136,14 @@ private class Completer: CompleterBase { // we know that Rust is already enforcing that the `bridge_fn` result is allowed to hop threads (Send), // and that it won't use or escape the C representation of that result besides passing it to the callback. // So first we build a promise struct---it doesn't matter which one---by reinterpreting the callback... - typealias RawPointerPromiseCallback = @convention(c) (_ error: SignalFfiErrorRef?, _ value: UnsafePointer?, _ context: UnsafeRawPointer?) -> Void - let rawPromiseStruct = SignalCPromiseRawPointer(complete: unsafeBitCast(completeOpaque, to: RawPointerPromiseCallback.self), context: Unmanaged.passRetained(self).toOpaque(), cancellation_id: 0) + typealias RawPointerPromiseCallback = @convention(c) ( + _ error: SignalFfiErrorRef?, _ value: UnsafePointer?, _ context: UnsafeRawPointer? + ) -> Void + let rawPromiseStruct = SignalCPromiseRawPointer( + complete: unsafeBitCast(completeOpaque, to: RawPointerPromiseCallback.self), + context: Unmanaged.passRetained(self).toOpaque(), + cancellation_id: 0 + ) // ...And then we reinterpret the entire struct, because all promise structs *also* have the same layout. // (Which we at least check a little bit here.) diff --git a/swift/Sources/LibSignalClient/BorrowUtils.swift b/swift/Sources/LibSignalClient/BorrowUtils.swift index fbbe9b17b..6c77c53ac 100644 --- a/swift/Sources/LibSignalClient/BorrowUtils.swift +++ b/swift/Sources/LibSignalClient/BorrowUtils.swift @@ -193,7 +193,8 @@ internal struct FixedLengthWrapper: BorrowForFfi { } extension BorrowForFfi { - static func fixed(_ serialized: ByteArray) -> Self where Self == FixedLengthWrapper { + static func fixed(_ serialized: ByteArray) -> Self + where Self == FixedLengthWrapper { .init(inner: serialized) } } @@ -229,7 +230,8 @@ internal struct ElementsWrapper: BorrowForFfi { } extension BorrowForFfi { - static func slice(_ input: [FfiType.Element]) -> Self where Self == ElementsWrapper { + static func slice(_ input: [FfiType.Element]) -> Self + where Self == ElementsWrapper { .init(inner: input) } } diff --git a/swift/Sources/LibSignalClient/Cds2.swift b/swift/Sources/LibSignalClient/Cds2.swift index 038c136b7..836796d82 100644 --- a/swift/Sources/LibSignalClient/Cds2.swift +++ b/swift/Sources/LibSignalClient/Cds2.swift @@ -19,12 +19,14 @@ public class Cds2Client: SgxClient { let handle = try attestationMessage.withUnsafeBorrowedBuffer { attestationMessageBuffer in try mrenclave.withUnsafeBorrowedBuffer { mrenclaveBuffer in var result = SignalMutPointerSgxClientState() - try checkError(signal_cds2_client_state_new( - &result, - mrenclaveBuffer, - attestationMessageBuffer, - UInt64(currentDate.timeIntervalSince1970 * 1000) - )) + try checkError( + signal_cds2_client_state_new( + &result, + mrenclaveBuffer, + attestationMessageBuffer, + UInt64(currentDate.timeIntervalSince1970 * 1000) + ) + ) return result } } diff --git a/swift/Sources/LibSignalClient/CdsTypes.swift b/swift/Sources/LibSignalClient/CdsTypes.swift index 65ef535d5..b2a6421aa 100644 --- a/swift/Sources/LibSignalClient/CdsTypes.swift +++ b/swift/Sources/LibSignalClient/CdsTypes.swift @@ -68,7 +68,9 @@ public class CdsiLookupRequest: NativeHandleOwner } } - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_lookup_request_destroy(handle.pointer) } } @@ -100,7 +102,9 @@ extension SignalConstPointerLookupRequest: SignalConstPointer { /// Returned by ``Net/cdsiLookup(auth:request:)`` when a request is successfully initiated. public class CdsiLookup { class NativeCdsiLookup: NativeHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_cdsi_lookup_destroy(handle.pointer) } } @@ -139,13 +143,18 @@ public class CdsiLookup { /// `SignalError.networkError` for a network-level connectivity issue, /// `SignalError.networkProtocolError` for a CDSI or attested connection protocol issue. public func complete() async throws -> CdsiLookupResponse { - let response: SignalFfiCdsiLookupResponse = try await self.asyncContext.invokeAsyncFunction { promise, asyncContext in + let response: SignalFfiCdsiLookupResponse = try await self.asyncContext.invokeAsyncFunction { + promise, + asyncContext in self.native.withNativeHandle { handle in signal_cdsi_lookup_complete(promise, asyncContext.const(), handle.const()) } } - return CdsiLookupResponse(entries: LookupResponseEntryList(owned: response.entries), debugPermitsUsed: response.debug_permits_used) + return CdsiLookupResponse( + entries: LookupResponseEntryList(owned: response.entries), + debugPermitsUsed: response.debug_permits_used + ) } } @@ -194,7 +203,9 @@ public class LookupResponseEntryList: Collection { } deinit { - signal_free_lookup_response_entry_list(SignalOwnedBufferOfFfiCdsiLookupResponseEntry(base: self.owned.baseAddress, length: self.owned.count)) + signal_free_lookup_response_entry_list( + SignalOwnedBufferOfFfiCdsiLookupResponseEntry(base: self.owned.baseAddress, length: self.owned.count) + ) } public typealias Index = UnsafeMutableBufferPointer.Index diff --git a/swift/Sources/LibSignalClient/ChatConnection+Fake.swift b/swift/Sources/LibSignalClient/ChatConnection+Fake.swift index e0389b39c..818447bd4 100644 --- a/swift/Sources/LibSignalClient/ChatConnection+Fake.swift +++ b/swift/Sources/LibSignalClient/ChatConnection+Fake.swift @@ -11,12 +11,15 @@ import SignalFfi extension AuthenticatedChatConnection { internal static func fakeConnect( - tokioAsyncContext: TokioAsyncContext, listener: any ChatConnectionListener, + tokioAsyncContext: TokioAsyncContext, + listener: any ChatConnectionListener, alerts: [String] = [] ) -> (AuthenticatedChatConnection, FakeChatRemote) { let (fakeChatConnection, listenerBridge) = failOnError { try FakeChatConnection.create( - tokioAsyncContext: tokioAsyncContext, listener: listener, alerts: alerts + tokioAsyncContext: tokioAsyncContext, + listener: listener, + alerts: alerts ) } @@ -25,11 +28,14 @@ extension AuthenticatedChatConnection { try fakeChatConnection.withNativeHandle { try checkError( signal_testing_fake_chat_connection_take_authenticated_chat( - &chatHandle, $0.const() - )) + &chatHandle, + $0.const() + ) + ) } let chat = AuthenticatedChatConnection( - fakeHandle: NonNull(chatHandle)!, tokioAsyncContext: tokioAsyncContext + fakeHandle: NonNull(chatHandle)!, + tokioAsyncContext: tokioAsyncContext ) listenerBridge.setConnection(chatConnection: chat) @@ -37,12 +43,15 @@ extension AuthenticatedChatConnection { try fakeChatConnection.withNativeHandle { try checkError( signal_testing_fake_chat_connection_take_remote( - &fakeRemoteHandle, $0.const() - )) + &fakeRemoteHandle, + $0.const() + ) + ) } let fakeRemote = FakeChatRemote( - handle: NonNull(fakeRemoteHandle)!, tokioAsyncContext: tokioAsyncContext + handle: NonNull(fakeRemoteHandle)!, + tokioAsyncContext: tokioAsyncContext ) return (chat, fakeRemote) } @@ -56,7 +65,9 @@ extension UnauthenticatedChatConnection { ) -> (UnauthenticatedChatConnection, FakeChatRemote) { let (fakeChatConnection, listenerBridge) = failOnError { try FakeChatConnection.create( - tokioAsyncContext: tokioAsyncContext, listener: listener, alerts: [] + tokioAsyncContext: tokioAsyncContext, + listener: listener, + alerts: [] ) } @@ -65,11 +76,15 @@ extension UnauthenticatedChatConnection { try fakeChatConnection.withNativeHandle { try checkError( signal_testing_fake_chat_connection_take_authenticated_chat( - &chatHandle, $0.const() - )) + &chatHandle, + $0.const() + ) + ) } let chat = UnauthenticatedChatConnection( - fakeHandle: NonNull(chatHandle)!, tokioAsyncContext: tokioAsyncContext, environment: .staging + fakeHandle: NonNull(chatHandle)!, + tokioAsyncContext: tokioAsyncContext, + environment: .staging ) listenerBridge.setConnection(chatConnection: chat) @@ -77,12 +92,15 @@ extension UnauthenticatedChatConnection { try fakeChatConnection.withNativeHandle { try checkError( signal_testing_fake_chat_connection_take_remote( - &fakeRemoteHandle, $0.const() - )) + &fakeRemoteHandle, + $0.const() + ) + ) } let fakeRemote = FakeChatRemote( - handle: NonNull(fakeRemoteHandle)!, tokioAsyncContext: tokioAsyncContext + handle: NonNull(fakeRemoteHandle)!, + tokioAsyncContext: tokioAsyncContext ) return (chat, fakeRemote) } @@ -118,7 +136,9 @@ private class SetChatLaterListenerBridge: ChatListenerBridge { } private class SetChatLaterUnauthListenerBridge: UnauthConnectionEventsListenerBridge { - override init(chatConnectionEventsListenerForTesting chatListener: any ConnectionEventsListener) { + override init( + chatConnectionEventsListenerForTesting chatListener: any ConnectionEventsListener + ) { super.init(chatConnectionEventsListenerForTesting: chatListener) } @@ -135,7 +155,8 @@ internal class FakeChatRemote: NativeHandleOwner, tokioAsyncContext: TokioAsyncContext + handle: NonNull, + tokioAsyncContext: TokioAsyncContext ) { self.tokioAsyncContext = tokioAsyncContext super.init(owned: handle) @@ -150,8 +171,10 @@ internal class FakeChatRemote: NativeHandleOwner fatalError("cannot be invoked directly") } - override class func destroyNativeHandle(_ nativeHandle: NonNull) -> SignalFfiErrorRef? { + override class func destroyNativeHandle( + _ nativeHandle: NonNull + ) -> SignalFfiErrorRef? { signal_fake_chat_server_destroy(nativeHandle.pointer) } @@ -253,7 +286,16 @@ internal class FakeChatResponse: NativeHandleOwner) -> SignalFfiErrorRef? { + override class func destroyNativeHandle( + _ nativeHandle: NonNull + ) -> SignalFfiErrorRef? { signal_fake_chat_response_destroy(nativeHandle.pointer) } } private class FakeChatConnection: NativeHandleOwner { static func create( - tokioAsyncContext: TokioAsyncContext, listener: any ChatConnectionListener, + tokioAsyncContext: TokioAsyncContext, + listener: any ChatConnectionListener, alerts: [String] ) throws -> (FakeChatConnection, SetChatLaterListenerBridge) { let listenerBridge = SetChatLaterListenerBridge( - chatConnectionListenerForTesting: listener) + chatConnectionListenerForTesting: listener + ) var listenerStruct = listenerBridge.makeListenerStruct() let chat = try FakeChatConnection.internalCreate(tokioAsyncContext, &listenerStruct, alerts) return (chat, listenerBridge) } static func create( - tokioAsyncContext: TokioAsyncContext, listener: any ConnectionEventsListener, + tokioAsyncContext: TokioAsyncContext, + listener: any ConnectionEventsListener, alerts: [String] ) throws -> (FakeChatConnection, SetChatLaterUnauthListenerBridge) { let listenerBridge = SetChatLaterUnauthListenerBridge( - chatConnectionEventsListenerForTesting: listener) + chatConnectionEventsListenerForTesting: listener + ) var listenerStruct = listenerBridge.makeListenerStruct() let chat = try FakeChatConnection.internalCreate(tokioAsyncContext, &listenerStruct, alerts) return (chat, listenerBridge) } - private static func internalCreate(_ tokioAsyncContext: TokioAsyncContext, _ listenerStruct: inout SignalFfiChatListenerStruct, _ alerts: [String]) throws -> FakeChatConnection { + private static func internalCreate( + _ tokioAsyncContext: TokioAsyncContext, + _ listenerStruct: inout SignalFfiChatListenerStruct, + _ alerts: [String] + ) throws -> FakeChatConnection { let connection: FakeChatConnection = try withUnsafePointer(to: &listenerStruct) { listener in try tokioAsyncContext.withNativeHandle { asyncContext in try invokeFnReturningNativeHandle { diff --git a/swift/Sources/LibSignalClient/ChatConnection.swift b/swift/Sources/LibSignalClient/ChatConnection.swift index 9d6c0e41a..1eb4dd6c3 100644 --- a/swift/Sources/LibSignalClient/ChatConnection.swift +++ b/swift/Sources/LibSignalClient/ChatConnection.swift @@ -22,7 +22,8 @@ public protocol ChatConnection: AnyObject { } public class ConnectionInfo: NativeHandleOwner, CustomStringConvertible { - override class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? + { // ChatConnectionInfo is an alias for ConnectionInfo, but Swift doesn't know that. return signal_connection_info_destroy(SignalMutPointerConnectionInfo(raw: handle.opaque)) } @@ -95,21 +96,29 @@ extension ChatConnection { /// Before an obtained instance can be used, it must be started by calling ``AuthenticatedChatConnection/start(listener:)``. public class AuthenticatedChatConnection: NativeHandleOwner< SignalMutPointerAuthenticatedChatConnection ->, ChatConnection, @unchecked Sendable { +>, ChatConnection, @unchecked Sendable +{ internal let tokioAsyncContext: TokioAsyncContext /// Initiates establishing of the underlying unauthenticated connection to the Chat Service. Once /// the connection is established, the returned object can be used to send and receive messages /// after ``AuthenticatedChatConnection/start(listener:)`` is called. internal init( - tokioAsyncContext: TokioAsyncContext, connectionManager: ConnectionManager, - username: String, password: String, receiveStories: Bool + tokioAsyncContext: TokioAsyncContext, + connectionManager: ConnectionManager, + username: String, + password: String, + receiveStories: Bool ) async throws { let nativeHandle = try await tokioAsyncContext.invokeAsyncFunction { promise, tokioAsyncContext in connectionManager.withNativeHandle { connectionManager in signal_authenticated_chat_connection_connect( - promise, tokioAsyncContext.const(), connectionManager.const(), username, - password, receiveStories + promise, + tokioAsyncContext.const(), + connectionManager.const(), + username, + password, + receiveStories ) } } @@ -127,7 +136,10 @@ public class AuthenticatedChatConnection: NativeHandleOwner< fatalError("should not be called directly for a ChatConnection") } - internal init(fakeHandle handle: NonNull, tokioAsyncContext: TokioAsyncContext) { + internal init( + fakeHandle handle: NonNull, + tokioAsyncContext: TokioAsyncContext + ) { self.tokioAsyncContext = tokioAsyncContext super.init(owned: handle) } @@ -144,8 +156,10 @@ public class AuthenticatedChatConnection: NativeHandleOwner< withUnsafePointer(to: &listenerStruct) { failOnError( signal_authenticated_chat_connection_init_listener( - chatConnection.const(), SignalConstPointerFfiChatListenerStruct(raw: $0) - )) + chatConnection.const(), + SignalConstPointerFfiChatListenerStruct(raw: $0) + ) + ) } } } @@ -157,7 +171,9 @@ public class AuthenticatedChatConnection: NativeHandleOwner< _ = try await self.tokioAsyncContext.invokeAsyncFunction { promise, tokioAsyncContext in withNativeHandle { chatConnection in signal_authenticated_chat_connection_disconnect( - promise, tokioAsyncContext.const(), chatConnection.const() + promise, + tokioAsyncContext.const(), + chatConnection.const() ) } } @@ -175,8 +191,11 @@ public class AuthenticatedChatConnection: NativeHandleOwner< withNativeHandle { chatService in internalRequest.withNativeHandle { request in signal_authenticated_chat_connection_send( - promise, tokioAsyncContext.const(), chatService.const(), - request.const(), timeoutMillis + promise, + tokioAsyncContext.const(), + chatService.const(), + request.const(), + timeoutMillis ) } } @@ -224,7 +243,8 @@ extension SignalConstPointerAuthenticatedChatConnection: SignalConstPointer { /// Before an obtained instance can be used, it must be started by calling ``UnauthenticatedChatConnection/start(listener:)``. public class UnauthenticatedChatConnection: NativeHandleOwner< SignalMutPointerUnauthenticatedChatConnection ->, ChatConnection, @unchecked Sendable { +>, ChatConnection, @unchecked Sendable +{ internal let tokioAsyncContext: TokioAsyncContext internal let environment: Net.Environment @@ -240,7 +260,9 @@ public class UnauthenticatedChatConnection: NativeHandleOwner< let nativeHandle = try await tokioAsyncContext.invokeAsyncFunction { promise, tokioAsyncContext in connectionManager.withNativeHandle { connectionManager in signal_unauthenticated_chat_connection_connect( - promise, tokioAsyncContext.const(), connectionManager.const() + promise, + tokioAsyncContext.const(), + connectionManager.const() ) } } @@ -277,13 +299,16 @@ public class UnauthenticatedChatConnection: NativeHandleOwner< public func start(listener: any ConnectionEventsListener) { withNativeHandle { chatConnection in var listenerStruct = UnauthConnectionEventsListenerBridge( - chatConnection: self, listener: listener + chatConnection: self, + listener: listener ).makeListenerStruct() withUnsafePointer(to: &listenerStruct) { failOnError( signal_unauthenticated_chat_connection_init_listener( - chatConnection.const(), SignalConstPointerFfiChatListenerStruct(raw: $0) - )) + chatConnection.const(), + SignalConstPointerFfiChatListenerStruct(raw: $0) + ) + ) } } } @@ -295,7 +320,9 @@ public class UnauthenticatedChatConnection: NativeHandleOwner< _ = try await self.tokioAsyncContext.invokeAsyncFunction { promise, tokioAsyncContext in withNativeHandle { chatConnection in signal_unauthenticated_chat_connection_disconnect( - promise, tokioAsyncContext.const(), chatConnection.const() + promise, + tokioAsyncContext.const(), + chatConnection.const() ) } } @@ -313,8 +340,11 @@ public class UnauthenticatedChatConnection: NativeHandleOwner< withNativeHandle { chatService in internalRequest.withNativeHandle { request in signal_unauthenticated_chat_connection_send( - promise, tokioAsyncContext.const(), chatService.const(), - request.const(), timeoutMillis + promise, + tokioAsyncContext.const(), + chatService.const(), + request.const(), + timeoutMillis ) } } diff --git a/swift/Sources/LibSignalClient/ChatListener.swift b/swift/Sources/LibSignalClient/ChatListener.swift index 4fd5862f5..fc4a569ab 100644 --- a/swift/Sources/LibSignalClient/ChatListener.swift +++ b/swift/Sources/LibSignalClient/ChatListener.swift @@ -22,7 +22,12 @@ public protocol ChatConnectionListener: ConnectionEventsListener Void) + func chatConnection( + _ chat: AuthenticatedChatConnection, + didReceiveIncomingMessage envelope: Data, + serverDeliveryTimestamp: UInt64, + sendAck: @escaping () throws -> Void + ) /// Called when the server indicates that there are no further messages in the message queue. /// @@ -53,7 +58,9 @@ extension AuthenticatedChatConnection: ChatListenerConnection {} internal class ChatListenerBridge { private class AckHandleOwner: NativeHandleOwner { - override class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_server_message_ack_destroy(handle.pointer) } } @@ -100,7 +107,8 @@ internal class ChatListenerBridge { let envelopeData = Data(bytes: envelope.base, count: envelope.length) bridge.chatListener.chatConnection( - chatConnection, didReceiveIncomingMessage: envelopeData, + chatConnection, + didReceiveIncomingMessage: envelopeData, serverDeliveryTimestamp: timestamp ) { _ = ackHandleOwner.withNativeHandle { ackHandle in signal_server_message_ack_send(ackHandle.const()) } } } @@ -195,16 +203,31 @@ internal class UnauthConnectionEventsListenerBridge { func makeListenerStruct() -> SignalFfiChatListenerStruct { let receivedIncomingMessage: SignalReceivedIncomingMessage = { _, _, _, _ in // Not used in the unauth chat listener - LoggerBridge.shared?.logger.log(level: .error, file: #fileID, line: #line, message: "unauth socket received an incoming request") + LoggerBridge.shared?.logger.log( + level: .error, + file: #fileID, + line: #line, + message: "unauth socket received an incoming request" + ) } let receivedQueueEmpty: SignalReceivedQueueEmpty = { _ in // Not used in the unauth chat listener - LoggerBridge.shared?.logger.log(level: .error, file: #fileID, line: #line, message: "unauth socket received a \"queue empty\" notification") + LoggerBridge.shared?.logger.log( + level: .error, + file: #fileID, + line: #line, + message: "unauth socket received a \"queue empty\" notification" + ) } let receivedAlerts: SignalReceivedAlerts = { _, alerts in // Not used in the unauth chat listener if alerts.lengths.length != 0 { - LoggerBridge.shared?.logger.log(level: .error, file: #fileID, line: #line, message: "unauth socket received \(alerts.lengths.length) alerts") + LoggerBridge.shared?.logger.log( + level: .error, + file: #fileID, + line: #line, + message: "unauth socket received \(alerts.lengths.length) alerts" + ) } } let connectionInterrupted: SignalConnectionInterrupted = { rawCtx, maybeError in diff --git a/swift/Sources/LibSignalClient/ChatServiceTypes.swift b/swift/Sources/LibSignalClient/ChatServiceTypes.swift index b0e9f4a8c..77dac9685 100644 --- a/swift/Sources/LibSignalClient/ChatServiceTypes.swift +++ b/swift/Sources/LibSignalClient/ChatServiceTypes.swift @@ -18,7 +18,13 @@ public struct ChatRequest: Equatable, Sendable { public var body: Data? public var timeout: TimeInterval - public init(method: String, pathAndQuery: String, headers: [String: String] = [:], body: Data? = nil, timeout: TimeInterval) { + public init( + method: String, + pathAndQuery: String, + headers: [String: String] = [:], + body: Data? = nil, + timeout: TimeInterval + ) { self.method = method self.pathAndQuery = pathAndQuery self.headers = headers @@ -44,7 +50,9 @@ public struct ChatRequest: Equatable, Sendable { var handle = SignalMutPointerHttpRequest(untyped: nil) if let body = request.body { try body.withUnsafeBorrowedBuffer { body in - try checkError(signal_http_request_new_with_body(&handle, request.method, request.pathAndQuery, body)) + try checkError( + signal_http_request_new_with_body(&handle, request.method, request.pathAndQuery, body) + ) } } else { try checkError(signal_http_request_new_without_body(&handle, request.method, request.pathAndQuery)) @@ -61,8 +69,8 @@ public struct ChatRequest: Equatable, Sendable { return signal_http_request_destroy(handle.pointer) } -// These testing endpoints aren't generated in device builds, to save on code size. -#if !os(iOS) || targetEnvironment(simulator) + // These testing endpoints aren't generated in device builds, to save on code size. + #if !os(iOS) || targetEnvironment(simulator) internal var method: String { failOnError { try withNativeHandle { request in @@ -109,7 +117,7 @@ public struct ChatRequest: Equatable, Sendable { } } } -#endif + #endif } } @@ -154,28 +162,40 @@ public struct ChatResponse: Equatable, Sendable { self.status = rawResponse.status self.message = String(cString: rawResponse.message) - self.headers = Dictionary(uniqueKeysWithValues: rawResponse.rawHeadersAsBuffer.lazy.map { (rawHeader: UnsafePointer?) -> (String, String) in - guard let rawHeader else { - fatalError("null in headers list") + self.headers = Dictionary( + uniqueKeysWithValues: rawResponse.rawHeadersAsBuffer.lazy.map { + (rawHeader: UnsafePointer?) -> (String, String) in + guard let rawHeader else { + fatalError("null in headers list") + } + let asciiColon = Int32(Character(":").asciiValue!) + guard let colonPtr = strchr(rawHeader, asciiColon) else { + fatalError("header returned without colon") + } + let nameCount = UnsafePointer(colonPtr) - rawHeader + guard + let name = UnsafeBufferPointer(start: rawHeader, count: nameCount).withMemoryRebound( + to: UInt8.self, + { + String(bytes: $0, encoding: .utf8) + } + ) + else { + fatalError("non-UTF-8 header name not rejected by Rust") + } + let value = String(cString: colonPtr + 1) + return (name, value) } - let asciiColon = Int32(Character(":").asciiValue!) - guard let colonPtr = strchr(rawHeader, asciiColon) else { - fatalError("header returned without colon") - } - let nameCount = UnsafePointer(colonPtr) - rawHeader - guard let name = UnsafeBufferPointer(start: rawHeader, count: nameCount).withMemoryRebound(to: UInt8.self, { - String(bytes: $0, encoding: .utf8) - }) else { - fatalError("non-UTF-8 header name not rejected by Rust") - } - let value = String(cString: colonPtr + 1) - return (name, value) - }) + ) // Avoid copying the body when possible! - self.body = Data(bytesNoCopy: rawResponse.body.base, count: rawResponse.body.length, deallocator: .custom { base, length in - signal_free_buffer(base, length) - }) + self.body = Data( + bytesNoCopy: rawResponse.body.base, + count: rawResponse.body.length, + deallocator: .custom { base, length in + signal_free_buffer(base, length) + } + ) // Clear it out so it doesn't get freed eagerly. rawResponse.body = .init() diff --git a/swift/Sources/LibSignalClient/ComparableBackup.swift b/swift/Sources/LibSignalClient/ComparableBackup.swift index 69c3ee5cc..54b6b9730 100644 --- a/swift/Sources/LibSignalClient/ComparableBackup.swift +++ b/swift/Sources/LibSignalClient/ComparableBackup.swift @@ -73,7 +73,9 @@ public class ComparableBackup: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_comparable_backup_destroy(handle.pointer) } } diff --git a/swift/Sources/LibSignalClient/DataStoreInMemory.swift b/swift/Sources/LibSignalClient/DataStoreInMemory.swift index 324bef8e6..67be67b0f 100644 --- a/swift/Sources/LibSignalClient/DataStoreInMemory.swift +++ b/swift/Sources/LibSignalClient/DataStoreInMemory.swift @@ -15,7 +15,9 @@ private struct SenderKeyName: Hashable { var distributionId: UUID } -open class InMemorySignalProtocolStore: IdentityKeyStore, PreKeyStore, SignedPreKeyStore, KyberPreKeyStore, SessionStore, SenderKeyStore { +open class InMemorySignalProtocolStore: IdentityKeyStore, PreKeyStore, SignedPreKeyStore, KyberPreKeyStore, + SessionStore, SenderKeyStore +{ private var publicKeys: [ProtocolAddress: IdentityKey] = [:] private var privateKey: IdentityKeyPair private var registrationId: UInt32 @@ -44,7 +46,11 @@ open class InMemorySignalProtocolStore: IdentityKeyStore, PreKeyStore, SignedPre return self.registrationId } - open func saveIdentity(_ identity: IdentityKey, for address: ProtocolAddress, context: StoreContext) throws -> IdentityChange { + open func saveIdentity( + _ identity: IdentityKey, + for address: ProtocolAddress, + context: StoreContext + ) throws -> IdentityChange { let oldIdentity = self.publicKeys.updateValue(identity, forKey: address) if oldIdentity == nil || oldIdentity == identity { return .newOrUnchanged @@ -53,11 +59,16 @@ open class InMemorySignalProtocolStore: IdentityKeyStore, PreKeyStore, SignedPre } } - open func isTrustedIdentity(_ identity: IdentityKey, for address: ProtocolAddress, direction: Direction, context: StoreContext) throws -> Bool { + open func isTrustedIdentity( + _ identity: IdentityKey, + for address: ProtocolAddress, + direction: Direction, + context: StoreContext + ) throws -> Bool { if let pk = publicKeys[address] { return pk == identity } else { - return true // tofu + return true // tofu } } @@ -126,11 +137,20 @@ open class InMemorySignalProtocolStore: IdentityKeyStore, PreKeyStore, SignedPre self.sessionMap[address] = record } - open func storeSenderKey(from sender: ProtocolAddress, distributionId: UUID, record: SenderKeyRecord, context: StoreContext) throws { + open func storeSenderKey( + from sender: ProtocolAddress, + distributionId: UUID, + record: SenderKeyRecord, + context: StoreContext + ) throws { self.senderKeyMap[SenderKeyName(sender: sender, distributionId: distributionId)] = record } - open func loadSenderKey(from sender: ProtocolAddress, distributionId: UUID, context: StoreContext) throws -> SenderKeyRecord? { + open func loadSenderKey( + from sender: ProtocolAddress, + distributionId: UUID, + context: StoreContext + ) throws -> SenderKeyRecord? { return self.senderKeyMap[SenderKeyName(sender: sender, distributionId: distributionId)] } } diff --git a/swift/Sources/LibSignalClient/DataStoreProtocols.swift b/swift/Sources/LibSignalClient/DataStoreProtocols.swift index e0d0106e2..23ddbb130 100644 --- a/swift/Sources/LibSignalClient/DataStoreProtocols.swift +++ b/swift/Sources/LibSignalClient/DataStoreProtocols.swift @@ -24,8 +24,17 @@ public protocol StoreContext {} public protocol IdentityKeyStore: AnyObject { func identityKeyPair(context: StoreContext) throws -> IdentityKeyPair func localRegistrationId(context: StoreContext) throws -> UInt32 - func saveIdentity(_ identity: IdentityKey, for address: ProtocolAddress, context: StoreContext) throws -> IdentityChange - func isTrustedIdentity(_ identity: IdentityKey, for address: ProtocolAddress, direction: Direction, context: StoreContext) throws -> Bool + func saveIdentity( + _ identity: IdentityKey, + for address: ProtocolAddress, + context: StoreContext + ) throws -> IdentityChange + func isTrustedIdentity( + _ identity: IdentityKey, + for address: ProtocolAddress, + direction: Direction, + context: StoreContext + ) throws -> Bool func identity(for address: ProtocolAddress, context: StoreContext) throws -> IdentityKey? } @@ -53,6 +62,15 @@ public protocol SessionStore: AnyObject { } public protocol SenderKeyStore: AnyObject { - func storeSenderKey(from sender: ProtocolAddress, distributionId: UUID, record: SenderKeyRecord, context: StoreContext) throws - func loadSenderKey(from sender: ProtocolAddress, distributionId: UUID, context: StoreContext) throws -> SenderKeyRecord? + func storeSenderKey( + from sender: ProtocolAddress, + distributionId: UUID, + record: SenderKeyRecord, + context: StoreContext + ) throws + func loadSenderKey( + from sender: ProtocolAddress, + distributionId: UUID, + context: StoreContext + ) throws -> SenderKeyRecord? } diff --git a/swift/Sources/LibSignalClient/DataStoreUtils.swift b/swift/Sources/LibSignalClient/DataStoreUtils.swift index 6a142d4a7..ea15adcda 100644 --- a/swift/Sources/LibSignalClient/DataStoreUtils.swift +++ b/swift/Sources/LibSignalClient/DataStoreUtils.swift @@ -6,12 +6,18 @@ import Foundation import SignalFfi -internal func withIdentityKeyStore(_ store: IdentityKeyStore, _ context: StoreContext, _ body: (SignalConstPointerFfiIdentityKeyStoreStruct) throws -> Result) throws -> Result { +internal func withIdentityKeyStore( + _ store: IdentityKeyStore, + _ context: StoreContext, + _ body: (SignalConstPointerFfiIdentityKeyStoreStruct) throws -> Result +) throws -> Result { func ffiShimGetIdentityKeyPair( storeCtx: UnsafeMutableRawPointer?, keyp: UnsafeMutablePointer? ) -> Int32 { - let storeContext = storeCtx!.assumingMemoryBound(to: ErrorHandlingContext<(IdentityKeyStore, StoreContext)>.self) + let storeContext = storeCtx!.assumingMemoryBound( + to: ErrorHandlingContext<(IdentityKeyStore, StoreContext)>.self + ) return storeContext.pointee.catchCallbackErrors { store, context in var privateKey = try store.identityKeyPair(context: context).privateKey keyp!.pointee = try cloneOrTakeHandle(from: &privateKey) @@ -23,7 +29,9 @@ internal func withIdentityKeyStore(_ store: IdentityKeyStore, _ context: storeCtx: UnsafeMutableRawPointer?, idp: UnsafeMutablePointer? ) -> Int32 { - let storeContext = storeCtx!.assumingMemoryBound(to: ErrorHandlingContext<(IdentityKeyStore, StoreContext)>.self) + let storeContext = storeCtx!.assumingMemoryBound( + to: ErrorHandlingContext<(IdentityKeyStore, StoreContext)>.self + ) return storeContext.pointee.catchCallbackErrors { store, context in let id = try store.localRegistrationId(context: context) idp!.pointee = id @@ -36,7 +44,9 @@ internal func withIdentityKeyStore(_ store: IdentityKeyStore, _ context: address: SignalConstPointerProtocolAddress, public_key: SignalConstPointerPublicKey ) -> Int32 { - let storeContext = storeCtx!.assumingMemoryBound(to: ErrorHandlingContext<(IdentityKeyStore, StoreContext)>.self) + let storeContext = storeCtx!.assumingMemoryBound( + to: ErrorHandlingContext<(IdentityKeyStore, StoreContext)>.self + ) return storeContext.pointee.catchCallbackErrors { store, context in var address = ProtocolAddress(borrowing: address) defer { cloneOrForgetAsNeeded(&address) } @@ -55,7 +65,9 @@ internal func withIdentityKeyStore(_ store: IdentityKeyStore, _ context: public_key: UnsafeMutablePointer?, address: SignalConstPointerProtocolAddress ) -> Int32 { - let storeContext = storeCtx!.assumingMemoryBound(to: ErrorHandlingContext<(IdentityKeyStore, StoreContext)>.self) + let storeContext = storeCtx!.assumingMemoryBound( + to: ErrorHandlingContext<(IdentityKeyStore, StoreContext)>.self + ) return storeContext.pointee.catchCallbackErrors { store, context in var address = ProtocolAddress(borrowing: address) defer { cloneOrForgetAsNeeded(&address) } @@ -75,7 +87,9 @@ internal func withIdentityKeyStore(_ store: IdentityKeyStore, _ context: public_key: SignalConstPointerPublicKey, raw_direction: UInt32 ) -> Int32 { - let storeContext = storeCtx!.assumingMemoryBound(to: ErrorHandlingContext<(IdentityKeyStore, StoreContext)>.self) + let storeContext = storeCtx!.assumingMemoryBound( + to: ErrorHandlingContext<(IdentityKeyStore, StoreContext)>.self + ) return storeContext.pointee.catchCallbackErrors { store, context in var address = ProtocolAddress(borrowing: address) defer { cloneOrForgetAsNeeded(&address) } @@ -112,7 +126,11 @@ internal func withIdentityKeyStore(_ store: IdentityKeyStore, _ context: } } -internal func withPreKeyStore(_ store: PreKeyStore, _ context: StoreContext, _ body: (SignalConstPointerFfiPreKeyStoreStruct) throws -> Result) throws -> Result { +internal func withPreKeyStore( + _ store: PreKeyStore, + _ context: StoreContext, + _ body: (SignalConstPointerFfiPreKeyStoreStruct) throws -> Result +) throws -> Result { func ffiShimStorePreKey( storeCtx: UnsafeMutableRawPointer?, id: UInt32, @@ -164,13 +182,19 @@ internal func withPreKeyStore(_ store: PreKeyStore, _ context: StoreCont } } -internal func withSignedPreKeyStore(_ store: SignedPreKeyStore, _ context: StoreContext, _ body: (SignalConstPointerFfiSignedPreKeyStoreStruct) throws -> Result) throws -> Result { +internal func withSignedPreKeyStore( + _ store: SignedPreKeyStore, + _ context: StoreContext, + _ body: (SignalConstPointerFfiSignedPreKeyStoreStruct) throws -> Result +) throws -> Result { func ffiShimStoreSignedPreKey( storeCtx: UnsafeMutableRawPointer?, id: UInt32, record: SignalConstPointerSignedPreKeyRecord ) -> Int32 { - let storeContext = storeCtx!.assumingMemoryBound(to: ErrorHandlingContext<(SignedPreKeyStore, StoreContext)>.self) + let storeContext = storeCtx!.assumingMemoryBound( + to: ErrorHandlingContext<(SignedPreKeyStore, StoreContext)>.self + ) return storeContext.pointee.catchCallbackErrors { store, context in var record = SignedPreKeyRecord(borrowing: record) defer { cloneOrForgetAsNeeded(&record) } @@ -184,7 +208,9 @@ internal func withSignedPreKeyStore(_ store: SignedPreKeyStore, _ contex recordp: UnsafeMutablePointer?, id: UInt32 ) -> Int32 { - let storeContext = storeCtx!.assumingMemoryBound(to: ErrorHandlingContext<(SignedPreKeyStore, StoreContext)>.self) + let storeContext = storeCtx!.assumingMemoryBound( + to: ErrorHandlingContext<(SignedPreKeyStore, StoreContext)>.self + ) return storeContext.pointee.catchCallbackErrors { store, context in var record = try store.loadSignedPreKey(id: id, context: context) recordp!.pointee = try cloneOrTakeHandle(from: &record) @@ -204,13 +230,19 @@ internal func withSignedPreKeyStore(_ store: SignedPreKeyStore, _ contex } } -internal func withKyberPreKeyStore(_ store: KyberPreKeyStore, _ context: StoreContext, _ body: (SignalConstPointerFfiKyberPreKeyStoreStruct) throws -> Result) throws -> Result { +internal func withKyberPreKeyStore( + _ store: KyberPreKeyStore, + _ context: StoreContext, + _ body: (SignalConstPointerFfiKyberPreKeyStoreStruct) throws -> Result +) throws -> Result { func ffiShimStoreKyberPreKey( storeCtx: UnsafeMutableRawPointer?, id: UInt32, record: SignalConstPointerKyberPreKeyRecord ) -> Int32 { - let storeContext = storeCtx!.assumingMemoryBound(to: ErrorHandlingContext<(KyberPreKeyStore, StoreContext)>.self) + let storeContext = storeCtx!.assumingMemoryBound( + to: ErrorHandlingContext<(KyberPreKeyStore, StoreContext)>.self + ) return storeContext.pointee.catchCallbackErrors { store, context in var record = KyberPreKeyRecord(borrowing: record) defer { cloneOrForgetAsNeeded(&record) } @@ -224,7 +256,9 @@ internal func withKyberPreKeyStore(_ store: KyberPreKeyStore, _ context: recordp: UnsafeMutablePointer?, id: UInt32 ) -> Int32 { - let storeContext = storeCtx!.assumingMemoryBound(to: ErrorHandlingContext<(KyberPreKeyStore, StoreContext)>.self) + let storeContext = storeCtx!.assumingMemoryBound( + to: ErrorHandlingContext<(KyberPreKeyStore, StoreContext)>.self + ) return storeContext.pointee.catchCallbackErrors { store, context in var record = try store.loadKyberPreKey(id: id, context: context) recordp!.pointee = try cloneOrTakeHandle(from: &record) @@ -236,7 +270,9 @@ internal func withKyberPreKeyStore(_ store: KyberPreKeyStore, _ context: storeCtx: UnsafeMutableRawPointer?, id: UInt32 ) -> Int32 { - let storeContext = storeCtx!.assumingMemoryBound(to: ErrorHandlingContext<(KyberPreKeyStore, StoreContext)>.self) + let storeContext = storeCtx!.assumingMemoryBound( + to: ErrorHandlingContext<(KyberPreKeyStore, StoreContext)>.self + ) return storeContext.pointee.catchCallbackErrors { store, context in try store.markKyberPreKeyUsed(id: id, context: context) return 0 @@ -256,7 +292,11 @@ internal func withKyberPreKeyStore(_ store: KyberPreKeyStore, _ context: } } -internal func withSessionStore(_ store: SessionStore, _ context: StoreContext, _ body: (SignalConstPointerFfiSessionStoreStruct) throws -> Result) throws -> Result { +internal func withSessionStore( + _ store: SessionStore, + _ context: StoreContext, + _ body: (SignalConstPointerFfiSessionStoreStruct) throws -> Result +) throws -> Result { func ffiShimStoreSession( storeCtx: UnsafeMutableRawPointer?, address: SignalConstPointerProtocolAddress, @@ -303,7 +343,11 @@ internal func withSessionStore(_ store: SessionStore, _ context: StoreCo } } -internal func withSenderKeyStore(_ store: SenderKeyStore, _ context: StoreContext, _ body: (SignalConstPointerFfiSenderKeyStoreStruct) throws -> Result) rethrows -> Result { +internal func withSenderKeyStore( + _ store: SenderKeyStore, + _ context: StoreContext, + _ body: (SignalConstPointerFfiSenderKeyStoreStruct) throws -> Result +) rethrows -> Result { func ffiShimStoreSenderKey( storeCtx: UnsafeMutableRawPointer?, sender: SignalConstPointerProtocolAddress, diff --git a/swift/Sources/LibSignalClient/Error.swift b/swift/Sources/LibSignalClient/Error.swift index 0b7afb808..40bfe8b89 100644 --- a/swift/Sources/LibSignalClient/Error.swift +++ b/swift/Sources/LibSignalClient/Error.swift @@ -294,7 +294,11 @@ internal func checkError(_ error: SignalFfiErrorRef?) throws { return err } - throw RegistrationError.registrationLock(timeRemaining: TimeInterval(timeRemaining), svr2Username: svr2Username, svr2Password: svr2Password) + throw RegistrationError.registrationLock( + timeRemaining: TimeInterval(timeRemaining), + svr2Username: svr2Username, + svr2Password: svr2Password + ) case SignalErrorCodeKeyTransparencyError: throw SignalError.keyTransparencyError(errStr) case SignalErrorCodeKeyTransparencyVerificationFailed: @@ -308,7 +312,8 @@ internal func failOnError(_ error: SignalFfiErrorRef?) { failOnError { try checkError(error) } } -internal func failOnError(_ fn: () throws -> Result, file: StaticString = #file, line: UInt32 = #line) -> Result { +internal func failOnError(_ fn: () throws -> Result, file: StaticString = #file, line: UInt32 = #line) -> Result +{ do { return try fn() } catch { diff --git a/swift/Sources/LibSignalClient/Fingerprint.swift b/swift/Sources/LibSignalClient/Fingerprint.swift index 8a9993287..c20c644c0 100644 --- a/swift/Sources/LibSignalClient/Fingerprint.swift +++ b/swift/Sources/LibSignalClient/Fingerprint.swift @@ -59,15 +59,17 @@ public struct NumericFingerprintGenerator: Sendable { .bytes(localIdentifier), .bytes(remoteIdentifier) ) { localKeyHandle, remoteKeyHandle, localBuffer, remoteBuffer in - try checkError(signal_fingerprint_new( - &obj, - UInt32(self.iterations), - UInt32(version), - localBuffer, - localKeyHandle.const(), - remoteBuffer, - remoteKeyHandle.const() - )) + try checkError( + signal_fingerprint_new( + &obj, + UInt32(self.iterations), + UInt32(version), + localBuffer, + localKeyHandle.const(), + remoteBuffer, + remoteKeyHandle.const() + ) + ) } let fprintStr = try invokeFnReturningString { diff --git a/swift/Sources/LibSignalClient/HsmEnclave.swift b/swift/Sources/LibSignalClient/HsmEnclave.swift index 1c3aeaf4b..35c4b17b2 100644 --- a/swift/Sources/LibSignalClient/HsmEnclave.swift +++ b/swift/Sources/LibSignalClient/HsmEnclave.swift @@ -54,11 +54,13 @@ public class HsmEnclaveClient: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_hsm_enclave_client_destroy(handle.pointer) } diff --git a/swift/Sources/LibSignalClient/IdentityKey.swift b/swift/Sources/LibSignalClient/IdentityKey.swift index 1a6d78647..54ecc9daa 100644 --- a/swift/Sources/LibSignalClient/IdentityKey.swift +++ b/swift/Sources/LibSignalClient/IdentityKey.swift @@ -24,7 +24,14 @@ public struct IdentityKey: Equatable, Sendable { public func verifyAlternateIdentity(_ other: IdentityKey, signature: Bytes) throws -> Bool { var result = false try withAllBorrowed(publicKey, other.publicKey, .bytes(signature)) { selfHandle, otherHandle, signatureBuffer in - try checkError(signal_identitykey_verify_alternate_identity(&result, selfHandle.const(), otherHandle.const(), signatureBuffer)) + try checkError( + signal_identitykey_verify_alternate_identity( + &result, + selfHandle.const(), + otherHandle.const(), + signatureBuffer + ) + ) } return result } @@ -74,7 +81,12 @@ public struct IdentityKeyPair: Sendable { return failOnError { try withAllBorrowed(self.publicKey, self.privateKey, other.publicKey) { publicKey, privateKey, other in try invokeFnReturningData { - signal_identitykeypair_sign_alternate_identity($0, publicKey.const(), privateKey.const(), other.const()) + signal_identitykeypair_sign_alternate_identity( + $0, + publicKey.const(), + privateKey.const(), + other.const() + ) } } } diff --git a/swift/Sources/LibSignalClient/IncrementalMac.swift b/swift/Sources/LibSignalClient/IncrementalMac.swift index b5dd64583..3160f9c6a 100644 --- a/swift/Sources/LibSignalClient/IncrementalMac.swift +++ b/swift/Sources/LibSignalClient/IncrementalMac.swift @@ -38,7 +38,9 @@ public class IncrementalMacContext: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_incremental_mac_destroy(handle.pointer) } @@ -97,7 +99,9 @@ public class ValidatingMacContext: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_validating_mac_destroy(handle.pointer) } diff --git a/swift/Sources/LibSignalClient/IoUtils.swift b/swift/Sources/LibSignalClient/IoUtils.swift index 26f13feb3..1d10cd8a7 100644 --- a/swift/Sources/LibSignalClient/IoUtils.swift +++ b/swift/Sources/LibSignalClient/IoUtils.swift @@ -6,7 +6,10 @@ import Foundation import SignalFfi -internal func withInputStream(_ stream: SignalInputStream, _ body: (SignalConstPointerFfiInputStreamStruct) throws -> Result) throws -> Result { +internal func withInputStream( + _ stream: SignalInputStream, + _ body: (SignalConstPointerFfiInputStreamStruct) throws -> Result +) throws -> Result { func ffiShimRead( stream_ctx: UnsafeMutableRawPointer?, pBuf: UnsafeMutablePointer?, diff --git a/swift/Sources/LibSignalClient/Kdf.swift b/swift/Sources/LibSignalClient/Kdf.swift index b55dcbc23..93152ffee 100644 --- a/swift/Sources/LibSignalClient/Kdf.swift +++ b/swift/Sources/LibSignalClient/Kdf.swift @@ -18,12 +18,14 @@ public func hkdf( try inputKeyMaterial.withUnsafeBorrowedBuffer { inputBuffer in try salt.withUnsafeBorrowedBuffer { saltBuffer in try info.withUnsafeBorrowedBuffer { infoBuffer in - try checkError(signal_hkdf_derive( - .init(outputBuffer), - inputBuffer, - infoBuffer, - saltBuffer - )) + try checkError( + signal_hkdf_derive( + .init(outputBuffer), + inputBuffer, + infoBuffer, + saltBuffer + ) + ) } } } diff --git a/swift/Sources/LibSignalClient/Kem.swift b/swift/Sources/LibSignalClient/Kem.swift index 7985d73ca..5f0bd8048 100644 --- a/swift/Sources/LibSignalClient/Kem.swift +++ b/swift/Sources/LibSignalClient/Kem.swift @@ -15,11 +15,16 @@ public class KEMKeyPair: ClonableHandleOwner, @unc } } - override internal class func cloneNativeHandle(_ newHandle: inout SignalMutPointerKyberKeyPair, currentHandle: SignalConstPointerKyberKeyPair) -> SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout SignalMutPointerKyberKeyPair, + currentHandle: SignalConstPointerKyberKeyPair + ) -> SignalFfiErrorRef? { return signal_kyber_key_pair_clone(&newHandle, currentHandle) } - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_kyber_key_pair_destroy(handle.pointer) } @@ -76,11 +81,16 @@ public class KEMPublicKey: ClonableHandleOwner, self.init(owned: NonNull(handle)!) } - override internal class func cloneNativeHandle(_ newHandle: inout SignalMutPointerKyberPublicKey, currentHandle: SignalConstPointerKyberPublicKey) -> SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout SignalMutPointerKyberPublicKey, + currentHandle: SignalConstPointerKyberPublicKey + ) -> SignalFfiErrorRef? { return signal_kyber_public_key_clone(&newHandle, currentHandle) } - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_kyber_public_key_destroy(handle.pointer) } @@ -139,11 +149,16 @@ public class KEMSecretKey: ClonableHandleOwner, self.init(owned: NonNull(handle)!) } - override internal class func cloneNativeHandle(_ newHandle: inout SignalMutPointerKyberSecretKey, currentHandle: SignalConstPointerKyberSecretKey) -> SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout SignalMutPointerKyberSecretKey, + currentHandle: SignalConstPointerKyberSecretKey + ) -> SignalFfiErrorRef? { return signal_kyber_secret_key_clone(&newHandle, currentHandle) } - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_kyber_secret_key_destroy(handle.pointer) } diff --git a/swift/Sources/LibSignalClient/Logging.swift b/swift/Sources/LibSignalClient/Logging.swift index 2a44fec41..a87d6579a 100644 --- a/swift/Sources/LibSignalClient/Logging.swift +++ b/swift/Sources/LibSignalClient/Logging.swift @@ -66,21 +66,24 @@ extension LibsignalLogger { public func setUpLibsignalLogging(level: LibsignalLogLevel) { let bridge = LoggerBridge(logger: self) let opaqueBridge = Unmanaged.passRetained(bridge) - let success = signal_init_logger(level.asFFI, SignalFfiLogger( - ctx: opaqueBridge.toOpaque(), - log: { ctx, ffiLevel, file, line, message in - let bridge: LoggerBridge = Unmanaged.fromOpaque(ctx!).takeUnretainedValue() - // Unknown log levels might have personal info in them, so map them to something low. - let level = LibsignalLogLevel(ffiLevel) ?? .debug - "".withCString { emptyStringPtr in - bridge.logger.log(level: level, file: file, line: line, message: message ?? emptyStringPtr) + let success = signal_init_logger( + level.asFFI, + SignalFfiLogger( + ctx: opaqueBridge.toOpaque(), + log: { ctx, ffiLevel, file, line, message in + let bridge: LoggerBridge = Unmanaged.fromOpaque(ctx!).takeUnretainedValue() + // Unknown log levels might have personal info in them, so map them to something low. + let level = LibsignalLogLevel(ffiLevel) ?? .debug + "".withCString { emptyStringPtr in + bridge.logger.log(level: level, file: file, line: line, message: message ?? emptyStringPtr) + } + }, + flush: { ctx in + let bridge: LoggerBridge = Unmanaged.fromOpaque(ctx!).takeUnretainedValue() + bridge.logger.flush() } - }, - flush: { ctx in - let bridge: LoggerBridge = Unmanaged.fromOpaque(ctx!).takeUnretainedValue() - bridge.logger.flush() - } - )) + ) + ) if success { // We save this for use within the Swift code as well, // but only if it was registered as the Rust logger successfully. diff --git a/swift/Sources/LibSignalClient/Media.swift b/swift/Sources/LibSignalClient/Media.swift index 272c04f6d..b2babb875 100644 --- a/swift/Sources/LibSignalClient/Media.swift +++ b/swift/Sources/LibSignalClient/Media.swift @@ -69,7 +69,10 @@ public func sanitizeWebp(input: SignalInputStream) throws { } public class SanitizedMetadata: ClonableHandleOwner { - override internal class func cloneNativeHandle(_ newHandle: inout OpaquePointer?, currentHandle: OpaquePointer?) -> SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout OpaquePointer?, + currentHandle: OpaquePointer? + ) -> SignalFfiErrorRef? { return signal_sanitized_metadata_clone(&newHandle, currentHandle) } diff --git a/swift/Sources/LibSignalClient/MessageBackup.swift b/swift/Sources/LibSignalClient/MessageBackup.swift index 720735202..a0133d262 100644 --- a/swift/Sources/LibSignalClient/MessageBackup.swift +++ b/swift/Sources/LibSignalClient/MessageBackup.swift @@ -34,7 +34,9 @@ public class MessageBackupKey: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_message_backup_key_destroy(handle.pointer) } @@ -96,7 +100,8 @@ extension SignalConstPointerMessageBackupKey: SignalConstPointer { public enum MessageBackupPurpose: UInt8, Sendable { // This needs to be kept in sync with the Rust version of the enum. - case deviceTransfer = 0, remoteBackup = 1 + case deviceTransfer = 0 + case remoteBackup = 1 } /// Validates a message backup file. @@ -115,13 +120,23 @@ public enum MessageBackupPurpose: UInt8, Sendable { /// /// - SeeAlso: ``OnlineBackupValidator`` public func validateMessageBackup( - key: MessageBackupKey, purpose: MessageBackupPurpose, length: UInt64, makeStream: () throws -> SignalInputStream + key: MessageBackupKey, + purpose: MessageBackupPurpose, + length: UInt64, + makeStream: () throws -> SignalInputStream ) throws -> MessageBackupUnknownFields { let outcome: ValidationOutcome = try withInputStream(try makeStream()) { firstInput in try withInputStream(try makeStream()) { secondInput in try key.withNativeHandle { key in try invokeFnReturningNativeHandle { - signal_message_backup_validator_validate($0, key.const(), firstInput, secondInput, length, purpose.rawValue) + signal_message_backup_validator_validate( + $0, + key.const(), + firstInput, + secondInput, + length, + purpose.rawValue + ) } } } @@ -170,7 +185,9 @@ public class OnlineBackupValidator: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_online_backup_validator_destroy(handle.pointer) } @@ -248,7 +265,9 @@ private class ValidationOutcome: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_message_backup_validation_outcome_destroy(handle.pointer) } } diff --git a/swift/Sources/LibSignalClient/NativeHandleOwner.swift b/swift/Sources/LibSignalClient/NativeHandleOwner.swift index 36c122bd7..e9a64b52f 100644 --- a/swift/Sources/LibSignalClient/NativeHandleOwner.swift +++ b/swift/Sources/LibSignalClient/NativeHandleOwner.swift @@ -152,7 +152,10 @@ public class ClonableHandleOwner: NativeHandleOwn handle = nil } - internal class func cloneNativeHandle(_: inout PointerType, currentHandle: PointerType.ConstPointer) -> SignalFfiErrorRef? { + internal class func cloneNativeHandle( + _: inout PointerType, + currentHandle: PointerType.ConstPointer + ) -> SignalFfiErrorRef? { fatalError("must be implemented by subclasses") } } @@ -173,7 +176,9 @@ internal func cloneOrForgetAsNeeded, Poi /// /// As an optimization, steals the handle if `handleOwner` has no other references. /// Checking this requires using `inout`; the reference itself won't be modified. -internal func cloneOrTakeHandle, PointerType>(from handleOwner: inout Owner) throws -> PointerType { +internal func cloneOrTakeHandle, PointerType>( + from handleOwner: inout Owner +) throws -> PointerType { if isKnownUniquelyReferenced(&handleOwner) { return handleOwner.takeNativeHandle() } diff --git a/swift/Sources/LibSignalClient/Net.swift b/swift/Sources/LibSignalClient/Net.swift index a5e9a2f14..0b807d835 100644 --- a/swift/Sources/LibSignalClient/Net.swift +++ b/swift/Sources/LibSignalClient/Net.swift @@ -46,8 +46,20 @@ public class Net { /// /// - Throws: if the scheme is unsupported or if the provided parameters are invalid for that scheme /// (e.g. Signal TLS proxies don't support authentication) - public func setProxy(scheme: String, host: String, port: UInt16? = nil, username: String? = nil, password: String? = nil) throws { - try self.connectionManager.setProxy(scheme: scheme, host: host, port: port, username: username, password: password) + public func setProxy( + scheme: String, + host: String, + port: UInt16? = nil, + username: String? = nil, + password: String? = nil + ) throws { + try self.connectionManager.setProxy( + scheme: scheme, + host: host, + port: port, + username: username, + password: password + ) } /// Sets the Signal TLS proxy host to be used for all new connections (until overridden). @@ -64,13 +76,20 @@ public class Net { // Support @ syntax to allow UNENCRYPTED_FOR_TESTING as a marker user. // This is not a stable feature of the API and may go away in the future; // the Rust layer will reject any other users anyway. But it's convenient for us. - let (username, host): (String?, String) = if let atSign = host.firstIndex(of: "@") { - (String(host[.. CdsiLookup { - let request = try CdsiLookupRequest(e164s: e164s, prevE164s: prevE164s, acisAndAccessKeys: acisAndAccessKeys, token: token) + let request = try CdsiLookupRequest( + e164s: e164s, + prevE164s: prevE164s, + acisAndAccessKeys: acisAndAccessKeys, + token: token + ) return try await self.cdsiLookup(auth: auth, request: request) } @@ -191,7 +215,14 @@ public class Net { let handle = try await self.asyncContext.invokeAsyncFunction { promise, asyncContext in self.connectionManager.withNativeHandle { connectionManager in request.withNativeHandle { request in - signal_cdsi_lookup_new(promise, asyncContext.const(), connectionManager.const(), auth.username, auth.password, request.const()) + signal_cdsi_lookup_new( + promise, + asyncContext.const(), + connectionManager.const(), + auth.username, + auth.password, + request.const() + ) } } } @@ -240,8 +271,18 @@ public class Net { /// /// - Returns: /// An object representing the established, but not yet active, connection. - public func connectAuthenticatedChat(username: String, password: String, receiveStories: Bool) async throws -> AuthenticatedChatConnection { - return try await AuthenticatedChatConnection(tokioAsyncContext: self.asyncContext, connectionManager: self.connectionManager, username: username, password: password, receiveStories: receiveStories) + public func connectAuthenticatedChat( + username: String, + password: String, + receiveStories: Bool + ) async throws -> AuthenticatedChatConnection { + return try await AuthenticatedChatConnection( + tokioAsyncContext: self.asyncContext, + connectionManager: self.connectionManager, + username: username, + password: password, + receiveStories: receiveStories + ) } /// Asynchronously establishes an unauthenticated connection to the remote @@ -265,7 +306,7 @@ public class Net { return try await UnauthenticatedChatConnection( tokioAsyncContext: self.asyncContext, connectionManager: - self.connectionManager, + self.connectionManager, environment: self.environment ) } @@ -299,7 +340,9 @@ extension Auth { internal class ConnectionManager: NativeHandleOwner { private class ProxyConfig: NativeHandleOwner { - override class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_connection_proxy_config_destroy(handle.pointer) } } @@ -363,7 +406,9 @@ internal class ConnectionManager: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_connection_manager_destroy(handle.pointer) } } diff --git a/swift/Sources/LibSignalClient/PrivateKey.swift b/swift/Sources/LibSignalClient/PrivateKey.swift index a530a9ba1..2a9e8dd5d 100644 --- a/swift/Sources/LibSignalClient/PrivateKey.swift +++ b/swift/Sources/LibSignalClient/PrivateKey.swift @@ -24,11 +24,16 @@ public class PrivateKey: ClonableHandleOwner, @unche } } - override internal class func cloneNativeHandle(_ newHandle: inout SignalMutPointerPrivateKey, currentHandle: SignalConstPointerPrivateKey) -> SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout SignalMutPointerPrivateKey, + currentHandle: SignalConstPointerPrivateKey + ) -> SignalFfiErrorRef? { return signal_privatekey_clone(&newHandle, currentHandle) } - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_privatekey_destroy(handle.pointer) } diff --git a/swift/Sources/LibSignalClient/Protocol.swift b/swift/Sources/LibSignalClient/Protocol.swift index d96da646f..5e8a41da9 100644 --- a/swift/Sources/LibSignalClient/Protocol.swift +++ b/swift/Sources/LibSignalClient/Protocol.swift @@ -18,7 +18,14 @@ public func signalEncrypt( try withSessionStore(sessionStore, context) { ffiSessionStore in try withIdentityKeyStore(identityStore, context) { ffiIdentityStore in try invokeFnReturningNativeHandle { - signal_encrypt_message($0, messageBuffer, addressHandle.const(), ffiSessionStore, ffiIdentityStore, UInt64(now.timeIntervalSince1970 * 1000)) + signal_encrypt_message( + $0, + messageBuffer, + addressHandle.const(), + ffiSessionStore, + ffiIdentityStore, + UInt64(now.timeIntervalSince1970 * 1000) + ) } } } @@ -36,7 +43,13 @@ public func signalDecrypt( try withSessionStore(sessionStore, context) { ffiSessionStore in try withIdentityKeyStore(identityStore, context) { ffiIdentityStore in try invokeFnReturningData { - signal_decrypt_message($0, messageHandle.const(), addressHandle.const(), ffiSessionStore, ffiIdentityStore) + signal_decrypt_message( + $0, + messageHandle.const(), + addressHandle.const(), + ffiSessionStore, + ffiIdentityStore + ) } } } @@ -61,7 +74,17 @@ public func signalDecryptPreKey( try withSignedPreKeyStore(signedPreKeyStore, context) { ffiSignedPreKeyStore in try withKyberPreKeyStore(kyberPreKeyStore, context) { ffiKyberPreKeyStore in try invokeFnReturningData { - signal_decrypt_pre_key_message($0, messageHandle.const(), addressHandle.const(), ffiSessionStore, ffiIdentityStore, ffiPreKeyStore, ffiSignedPreKeyStore, ffiKyberPreKeyStore, usePqRatchet) + signal_decrypt_pre_key_message( + $0, + messageHandle.const(), + addressHandle.const(), + ffiSessionStore, + ffiIdentityStore, + ffiPreKeyStore, + ffiSignedPreKeyStore, + ffiKyberPreKeyStore, + usePqRatchet + ) } } } @@ -83,7 +106,16 @@ public func processPreKeyBundle( return try withAllBorrowed(bundle, address) { bundleHandle, addressHandle in try withSessionStore(sessionStore, context) { ffiSessionStore in try withIdentityKeyStore(identityStore, context) { ffiIdentityStore in - try checkError(signal_process_prekey_bundle(bundleHandle.const(), addressHandle.const(), ffiSessionStore, ffiIdentityStore, UInt64(now.timeIntervalSince1970 * 1000), usePqRatchet)) + try checkError( + signal_process_prekey_bundle( + bundleHandle.const(), + addressHandle.const(), + ffiSessionStore, + ffiIdentityStore, + UInt64(now.timeIntervalSince1970 * 1000), + usePqRatchet + ) + ) } } } @@ -128,11 +160,13 @@ public func processSenderKeyDistributionMessage( ) throws { return try withAllBorrowed(sender, message) { senderHandle, messageHandle in try withSenderKeyStore(store, context) { - try checkError(signal_process_sender_key_distribution_message( - senderHandle.const(), - messageHandle.const(), - $0 - )) + try checkError( + signal_process_sender_key_distribution_message( + senderHandle.const(), + messageHandle.const(), + $0 + ) + ) } } } diff --git a/swift/Sources/LibSignalClient/PublicKey.swift b/swift/Sources/LibSignalClient/PublicKey.swift index de65dc310..92130599b 100644 --- a/swift/Sources/LibSignalClient/PublicKey.swift +++ b/swift/Sources/LibSignalClient/PublicKey.swift @@ -16,11 +16,15 @@ public class PublicKey: ClonableHandleOwner, @uncheck self.init(owned: NonNull(handle)!) } - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? + { return signal_publickey_destroy(handle.pointer) } - override internal class func cloneNativeHandle(_ newHandle: inout SignalMutPointerPublicKey, currentHandle: SignalConstPointerPublicKey) -> SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout SignalMutPointerPublicKey, + currentHandle: SignalConstPointerPublicKey + ) -> SignalFfiErrorRef? { return signal_publickey_clone(&newHandle, currentHandle) } diff --git a/swift/Sources/LibSignalClient/RegistrationService.swift b/swift/Sources/LibSignalClient/RegistrationService.swift index 9fcfad1d2..dc03b97c6 100644 --- a/swift/Sources/LibSignalClient/RegistrationService.swift +++ b/swift/Sources/LibSignalClient/RegistrationService.swift @@ -71,7 +71,9 @@ public enum RegistrationError: Error { public class RegistrationService: NativeHandleOwner, @unchecked Sendable { private let asyncContext: TokioAsyncContext - override internal class func destroyNativeHandle(_ nativeHandle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ nativeHandle: NonNull + ) -> SignalFfiErrorRef? { signal_registration_service_destroy(nativeHandle.pointer) } @@ -107,7 +109,10 @@ public class RegistrationService: NativeHandleOwner { - override internal class func destroyNativeHandle( - _ nativeHandle: NonNull - ) -> SignalFfiErrorRef? { - signal_registration_session_destroy(nativeHandle.pointer) - } - - public var allowedToRequestCode: Bool { - return failOnError { - try invokeFnReturningBool { out in - self.withNativeHandle { - signal_registration_session_get_allowed_to_request_code(out, $0.const()) - } - } - } - } - - public var verified: Bool { - return failOnError { - try invokeFnReturningBool { out in - self.withNativeHandle { - signal_registration_session_get_verified(out, $0.const()) - } - } - } - } - - public var nextSms: TimeInterval? { - return failOnError { - try invokeFnReturningOptionalInteger { out in - self.withNativeHandle { - signal_registration_session_get_next_sms_seconds(out, $0.const()) - } - }.map { TimeInterval($0) } - } - } - - public var nextCall: TimeInterval? { - return failOnError { - try invokeFnReturningOptionalInteger { out in - self.withNativeHandle { - signal_registration_session_get_next_call_seconds(out, $0.const()) - } - }.map { TimeInterval($0) } - } - } - - public var nextVerificationAttempt: TimeInterval? { - return failOnError { - try invokeFnReturningOptionalInteger { out in - self.withNativeHandle { - signal_registration_session_get_next_verification_attempt_seconds(out, $0.const()) - } - }.map { TimeInterval($0) } - } - } - - public var requestedInformation: Set { - return failOnError { - let items = try invokeFnReturningData { out in - self.withNativeHandle { - signal_registration_session_get_requested_information(out, $0.const()) - } - } - return Set(try items.map { try ChallengeOption(fromNative: $0) }) - } - } -} - -extension ChallengeOption { - internal init(fromNative value: UInt8) throws { - self = switch UInt32(value) { - case SignalChallengeOptionCaptcha.rawValue: - .captcha - case SignalChallengeOptionPushChallenge.rawValue: - .pushChallenge - default: - throw SignalError.internalError("unknown requested information") - } - } -} - -public class RegisterAccountResponse: NativeHandleOwner, @unchecked Sendable { - override internal class func destroyNativeHandle(_ nativeHandle: NonNull) -> SignalFfiErrorRef? { - signal_register_account_response_destroy(nativeHandle.pointer) - } - - public var aci: Aci { - return failOnError { - try self.withNativeHandle { native in - try invokeFnReturningServiceId { - signal_register_account_response_get_identity($0, native.const(), ServiceIdKind.aci.rawValue) - } - } - } - } - - public var pni: Pni { - return failOnError { - try self.withNativeHandle { native in - try invokeFnReturningServiceId { - signal_register_account_response_get_identity($0, native.const(), ServiceIdKind.pni.rawValue) - } - } - } - } - - public var number: String { - return failOnError { - try self.withNativeHandle { native in - try invokeFnReturningString { - signal_register_account_response_get_number($0, native.const()) - } - } - } - } - - public var usernameHash: Data? { - return failOnError { - try self.withNativeHandle { native in - try invokeFnReturningOptionalArray { - signal_register_account_response_get_username_hash($0, native.const()) - } - } - } - } - - public var usernameLinkHandle: UUID? { - return failOnError { - try self.withNativeHandle { native in - try invokeFnReturningOptionalUuid { - signal_register_account_response_get_username_link_handle($0, native.const()) - } - } - } - } - - public var storageCapable: Bool { - return failOnError { - try self.withNativeHandle { native in - try invokeFnReturningBool { - signal_register_account_response_get_storage_capable($0, native.const()) - } - } - } - } - - public var reregistration: Bool { - return failOnError { - try self.withNativeHandle { native in - try invokeFnReturningBool { - signal_register_account_response_get_reregistration($0, native.const()) - } - } - } - } - - public var entitlements: ([BadgeEntitlement], BackupEntitlement?) { - return failOnError { - try self.withNativeHandle { native in - let badges = try invokeFnReturningBadgeEntitlementArray { - signal_register_account_response_get_entitlement_badges($0, native.const()) - } - - let backup = try BackupEntitlement(fromResponse: native.const()) - - return (badges, backup) - } - } - } -} - -public struct BadgeEntitlement: Equatable { - public let id: String - public let visible: Bool - public let expiration: TimeInterval -} - -public struct BackupEntitlement: Equatable { - public let expiration: TimeInterval - public let level: UInt64 - public init(expiration: TimeInterval, level: UInt64) { - self.expiration = expiration - self.level = level - } - - fileprivate init?(fromResponse native: SignalConstPointerRegisterAccountResponse) throws { - let backupExpiration = try invokeFnReturningOptionalInteger { - signal_register_account_response_get_entitlement_backup_expiration_seconds($0, native) - } - guard case .some(let expiration) = backupExpiration else { - return nil - } - - let level = try invokeFnReturningOptionalInteger { - signal_register_account_response_get_entitlement_backup_level($0, native) - } - guard case .some(let level) = level else { - return nil - } - self.init(expiration: TimeInterval(expiration), level: level) - } -} - -public enum VerificationTransport: CustomStringConvertible { - case voice - case sms - - public var description: String { - return switch self { - case .voice: "voice" - case .sms: "sms" - } - } -} - -public enum Svr2CredentialsResult { - case match - case noMatch - case invalid -} - -public enum ChallengeOption: Hashable, Sendable { - case captcha - case pushChallenge -} - private class RegisterAccountRequst: NativeHandleOwner { override internal class func destroyNativeHandle( _ nativeHandle: NonNull @@ -662,41 +475,83 @@ private class RegisterAccountRequst: NativeHandleOwner, pniPqSignedPreKey: SignedPublicPreKey ) -> Self { - let request: Self = failOnError { try invokeFnReturningNativeHandle { - signal_register_account_request_create($0) - } } + let request: Self = failOnError { + try invokeFnReturningNativeHandle { + signal_register_account_request_create($0) + } + } failOnError { try request.withNativeHandle { native in - try checkError(accountPassword.withCString { - signal_register_account_request_set_account_password(native.const(), $0) - }) + try checkError( + accountPassword.withCString { + signal_register_account_request_set_account_password(native.const(), $0) + } + ) if let apnPushToken { - try checkError(apnPushToken.withCString { - signal_register_account_request_set_apn_push_token(native.const(), $0) - }) + try checkError( + apnPushToken.withCString { + signal_register_account_request_set_apn_push_token(native.const(), $0) + } + ) } if skipDeviceTransfer { try checkError(signal_register_account_request_set_skip_device_transfer(native.const())) } - try checkError(aciIdentityKey.withNativeHandle { - signal_register_account_request_set_identity_public_key(native.const(), ServiceIdKind.aci.rawValue, $0.const()) - }) - try checkError(pniIdentityKey.withNativeHandle { - signal_register_account_request_set_identity_public_key(native.const(), ServiceIdKind.pni.rawValue, $0.const()) - }) - try checkError(aciSignedPreKey.withNativeStruct { - signal_register_account_request_set_identity_signed_pre_key(native.const(), ServiceIdKind.aci.rawValue, $0) - }) - try checkError(pniSignedPreKey.withNativeStruct { - signal_register_account_request_set_identity_signed_pre_key(native.const(), ServiceIdKind.pni.rawValue, $0) - }) - try checkError(aciPqSignedPreKey.withNativeStruct { - signal_register_account_request_set_identity_pq_last_resort_pre_key(native.const(), ServiceIdKind.aci.rawValue, $0) - }) - try checkError(pniPqSignedPreKey.withNativeStruct { - signal_register_account_request_set_identity_pq_last_resort_pre_key(native.const(), ServiceIdKind.pni.rawValue, $0) - }) + try checkError( + aciIdentityKey.withNativeHandle { + signal_register_account_request_set_identity_public_key( + native.const(), + ServiceIdKind.aci.rawValue, + $0.const() + ) + } + ) + try checkError( + pniIdentityKey.withNativeHandle { + signal_register_account_request_set_identity_public_key( + native.const(), + ServiceIdKind.pni.rawValue, + $0.const() + ) + } + ) + try checkError( + aciSignedPreKey.withNativeStruct { + signal_register_account_request_set_identity_signed_pre_key( + native.const(), + ServiceIdKind.aci.rawValue, + $0 + ) + } + ) + try checkError( + pniSignedPreKey.withNativeStruct { + signal_register_account_request_set_identity_signed_pre_key( + native.const(), + ServiceIdKind.pni.rawValue, + $0 + ) + } + ) + try checkError( + aciPqSignedPreKey.withNativeStruct { + signal_register_account_request_set_identity_pq_last_resort_pre_key( + native.const(), + ServiceIdKind.aci.rawValue, + $0 + ) + } + ) + try checkError( + pniPqSignedPreKey.withNativeStruct { + signal_register_account_request_set_identity_pq_last_resort_pre_key( + native.const(), + ServiceIdKind.pni.rawValue, + $0 + ) + } + ) } } @@ -704,59 +559,6 @@ private class RegisterAccountRequst: NativeHandleOwner { - /// Constructs the set of attributes to pass to the server. - /// - Throws: ``SignalError/invalidArgument(_:)`` if the `unidentifiedAccessKey` is not 16 bytes. - public convenience init( - recoveryPassword: Data, - aciRegistrationId: UInt16, - pniRegistrationId: UInt16, - registrationLock: String?, - unidentifiedAccessKey: Data, - unrestrictedUnidentifiedAccess: Bool, - capabilities: [String], - discoverableByPhoneNumber: Bool - ) throws { - var uak = SignalUnidentifiedAccessKey(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) - try withUnsafeMutableBytes(of: &uak) { uakBytes in - if uakBytes.count != unidentifiedAccessKey.count { - throw SignalError.invalidArgument("unidentifiedAccessKey has \(unidentifiedAccessKey.count) bytes; expected \(uakBytes.count)") - } - uakBytes.copyBytes(from: unidentifiedAccessKey) - } - let nativeHandle = failOnError { - try recoveryPassword.withUnsafeBorrowedBuffer { recoveryPassword in - try registrationLock.withCString { registrationLock in - try withUnsafePointer(to: &uak) { unidentifiedAccessKey in - try capabilities.withUnsafeBorrowedBytestringArray { capabilities in - var nativeHandle = SignalMutPointerRegistrationAccountAttributes() - try checkError( - signal_registration_account_attributes_create( - &nativeHandle, - recoveryPassword, - aciRegistrationId, - pniRegistrationId, - registrationLock, - unidentifiedAccessKey, - unrestrictedUnidentifiedAccess, - capabilities, - discoverableByPhoneNumber - )) - return nativeHandle - } - } - } - } - } - self.init(owned: NonNull(nativeHandle)!) - } - - override internal class func destroyNativeHandle(_ nativeHandle: NonNull) -> SignalFfiErrorRef? { - signal_registration_account_attributes_destroy(nativeHandle.pointer) - } -} - extension SignalFfiConnectChatBridgeStruct { /// Constructs a ``SignalFfiConnectChatBridgeStruct`` that uses the given /// ``ConnectionManager`` to create chat connections. @@ -776,77 +578,40 @@ extension SignalFfiConnectChatBridgeStruct { } } -extension SignalFfiRegistrationCreateSessionRequest { - internal static func withNativeStruct( - e164: String, - pushToken: String?, - mcc: String?, - mnc: String?, - _ fn: (Self) throws -> Result - ) rethrows -> Result { - try e164.withCString { e164 in - try pushToken.withCString { pushToken in - try mcc.withCString { mcc in - try mnc.withCString { mnc in - let request = SignalFfiRegistrationCreateSessionRequest( - number: e164, push_token: pushToken, - mcc: mcc, mnc: mnc - ) - return try fn(request) - } - } - } - } - } -} - -/// Invoke a function returning an unsigned integral result where `nil` is bridged as the maximum value. -/// -/// Bridging `nil` as max isn't a convention we want to rely on generally. It's -/// true for the getters in this file, though, hence `fileprivate`. -private func invokeFnReturningOptionalInteger(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> Result? { - let output = try invokeFnReturningInteger(fn: fn) - return if output == Result.max { nil } else { output } -} - -private func invokeFnReturningBadgeEntitlementArray(fn: (_ out: UnsafeMutablePointer) -> SignalFfiErrorRef?) throws -> [BadgeEntitlement] { - var out = SignalOwnedBufferOfFfiRegisterResponseBadge() - try checkError(fn(&out)) - defer { signal_free_list_of_register_response_badges(out) } - - return UnsafeBufferPointer(start: out.base, count: out.length).map { - BadgeEntitlement(id: String(cString: $0.id), visible: $0.visible, expiration: TimeInterval($0.expiration_secs)) - } -} - // Exposed for testing. -internal func invokeFnReturningCheckSvr2CredentialsResponse(fn: (_ out: UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> [String: Svr2CredentialsResult] { - let entries = try invokeFnReturningSomeBytestringArray(fn: { out in - // This is just a named wrapper around a bytestring array. - var wrapper = SignalFfiCheckSvr2CredentialsResponse() - let err = fn(&wrapper) - // Copy the wrapped pointer into the provided output. The outer function - // will also take care of deallocating. - if err == nil { - out!.update(from: &wrapper.entries, count: 1) +internal func invokeFnReturningCheckSvr2CredentialsResponse( + fn: (_ out: UnsafeMutablePointer?) -> SignalFfiErrorRef? +) throws -> [String: Svr2CredentialsResult] { + let entries = try invokeFnReturningSomeBytestringArray( + fn: { out in + // This is just a named wrapper around a bytestring array. + var wrapper = SignalFfiCheckSvr2CredentialsResponse() + let err = fn(&wrapper) + // Copy the wrapped pointer into the provided output. The outer function + // will also take care of deallocating. + if err == nil { + out!.update(from: &wrapper.entries, count: 1) + } + return err + }, + transform: { view in + // The format for entries is a UTF-8 key with the value as a single byte at the end. + let key = String(decoding: view.dropLast(), as: Unicode.UTF8.self) + let valueByte = UInt32(view.last!) + let value = + switch SignalSvr2CredentialsResult(valueByte) { + case SignalSvr2CredentialsResultInvalid: + Svr2CredentialsResult.invalid + case SignalSvr2CredentialsResultMatch: + Svr2CredentialsResult.match + case SignalSvr2CredentialsResultNoMatch: + Svr2CredentialsResult.noMatch + default: + fatalError("unknown SVR2 credentials result value \(valueByte)") + } + return (key, value) } - return err - }, transform: { view in - // The format for entries is a UTF-8 key with the value as a single byte at the end. - let key = String(decoding: view.dropLast(), as: Unicode.UTF8.self) - let valueByte = UInt32(view.last!) - let value = switch SignalSvr2CredentialsResult(valueByte) { - case SignalSvr2CredentialsResultInvalid: - Svr2CredentialsResult.invalid - case SignalSvr2CredentialsResultMatch: - Svr2CredentialsResult.match - case SignalSvr2CredentialsResultNoMatch: - Svr2CredentialsResult.noMatch - default: - fatalError("unknown SVR2 credentials result value \(valueByte)") - } - return (key, value) - }) + ) return Dictionary(uniqueKeysWithValues: entries) } @@ -872,91 +637,3 @@ extension SignalConstPointerRegistrationService: SignalConstPointer { self.raw } } - -extension SignalMutPointerRegistrationSession: SignalMutPointer { - public typealias ConstPointer = SignalConstPointerRegistrationSession - - public init(untyped: OpaquePointer?) { - self.init(raw: untyped) - } - - public func toOpaque() -> OpaquePointer? { - self.raw - } - - public func const() -> Self.ConstPointer { - SignalConstPointerRegistrationSession(raw: self.raw) - } -} - -extension SignalConstPointerRegistrationSession: SignalConstPointer { - public func toOpaque() -> OpaquePointer? { - self.raw - } -} - -extension SignalMutPointerRegisterAccountResponse: SignalMutPointer { - public typealias ConstPointer = SignalConstPointerRegisterAccountResponse - - public init(untyped: OpaquePointer?) { - self.init(raw: untyped) - } - - public func toOpaque() -> OpaquePointer? { - self.raw - } - - public func const() -> Self.ConstPointer { - SignalConstPointerRegisterAccountResponse(raw: self.raw) - } -} - -extension SignalConstPointerRegisterAccountResponse: SignalConstPointer { - public func toOpaque() -> OpaquePointer? { - self.raw - } -} - -extension SignalMutPointerRegisterAccountRequest: SignalMutPointer { - public typealias ConstPointer = SignalConstPointerRegisterAccountRequest - - public init(untyped: OpaquePointer?) { - self.init(raw: untyped) - } - - public func toOpaque() -> OpaquePointer? { - self.raw - } - - public func const() -> Self.ConstPointer { - SignalConstPointerRegisterAccountRequest(raw: self.raw) - } -} - -extension SignalConstPointerRegisterAccountRequest: SignalConstPointer { - public func toOpaque() -> OpaquePointer? { - self.raw - } -} - -extension SignalMutPointerRegistrationAccountAttributes: SignalMutPointer { - public typealias ConstPointer = SignalConstPointerRegistrationAccountAttributes - - public init(untyped: OpaquePointer?) { - self.init(raw: untyped) - } - - public func toOpaque() -> OpaquePointer? { - self.raw - } - - public func const() -> Self.ConstPointer { - SignalConstPointerRegistrationAccountAttributes(raw: self.raw) - } -} - -extension SignalConstPointerRegistrationAccountAttributes: SignalConstPointer { - public func toOpaque() -> OpaquePointer? { - self.raw - } -} diff --git a/swift/Sources/LibSignalClient/RegistrationServiceTypes.swift b/swift/Sources/LibSignalClient/RegistrationServiceTypes.swift new file mode 100644 index 000000000..c2a933f70 --- /dev/null +++ b/swift/Sources/LibSignalClient/RegistrationServiceTypes.swift @@ -0,0 +1,432 @@ +// +// Copyright 2025 Signal Messenger, LLC. +// SPDX-License-Identifier: AGPL-3.0-only +// + +import Foundation +import SignalFfi + +public class RegistrationSessionState: NativeHandleOwner { + override internal class func destroyNativeHandle( + _ nativeHandle: NonNull + ) -> SignalFfiErrorRef? { + signal_registration_session_destroy(nativeHandle.pointer) + } + + public var allowedToRequestCode: Bool { + return failOnError { + try invokeFnReturningBool { out in + self.withNativeHandle { + signal_registration_session_get_allowed_to_request_code(out, $0.const()) + } + } + } + } + + public var verified: Bool { + return failOnError { + try invokeFnReturningBool { out in + self.withNativeHandle { + signal_registration_session_get_verified(out, $0.const()) + } + } + } + } + + public var nextSms: TimeInterval? { + return failOnError { + try invokeFnReturningOptionalInteger { out in + self.withNativeHandle { + signal_registration_session_get_next_sms_seconds(out, $0.const()) + } + }.map { TimeInterval($0) } + } + } + + public var nextCall: TimeInterval? { + return failOnError { + try invokeFnReturningOptionalInteger { out in + self.withNativeHandle { + signal_registration_session_get_next_call_seconds(out, $0.const()) + } + }.map { TimeInterval($0) } + } + } + + public var nextVerificationAttempt: TimeInterval? { + return failOnError { + try invokeFnReturningOptionalInteger { out in + self.withNativeHandle { + signal_registration_session_get_next_verification_attempt_seconds(out, $0.const()) + } + }.map { TimeInterval($0) } + } + } + + public var requestedInformation: Set { + return failOnError { + let items = try invokeFnReturningData { out in + self.withNativeHandle { + signal_registration_session_get_requested_information(out, $0.const()) + } + } + return Set(try items.map { try ChallengeOption(fromNative: $0) }) + } + } +} + +extension ChallengeOption { + internal init(fromNative value: UInt8) throws { + self = + switch UInt32(value) { + case SignalChallengeOptionCaptcha.rawValue: + .captcha + case SignalChallengeOptionPushChallenge.rawValue: + .pushChallenge + default: + throw SignalError.internalError("unknown requested information") + } + } +} + +public class RegisterAccountResponse: NativeHandleOwner, @unchecked Sendable { + override internal class func destroyNativeHandle( + _ nativeHandle: NonNull + ) -> SignalFfiErrorRef? { + signal_register_account_response_destroy(nativeHandle.pointer) + } + + public var aci: Aci { + return failOnError { + try self.withNativeHandle { native in + try invokeFnReturningServiceId { + signal_register_account_response_get_identity($0, native.const(), ServiceIdKind.aci.rawValue) + } + } + } + } + + public var pni: Pni { + return failOnError { + try self.withNativeHandle { native in + try invokeFnReturningServiceId { + signal_register_account_response_get_identity($0, native.const(), ServiceIdKind.pni.rawValue) + } + } + } + } + + public var number: String { + return failOnError { + try self.withNativeHandle { native in + try invokeFnReturningString { + signal_register_account_response_get_number($0, native.const()) + } + } + } + } + + public var usernameHash: Data? { + return failOnError { + try self.withNativeHandle { native in + try invokeFnReturningOptionalArray { + signal_register_account_response_get_username_hash($0, native.const()) + } + } + } + } + + public var usernameLinkHandle: UUID? { + return failOnError { + try self.withNativeHandle { native in + try invokeFnReturningOptionalUuid { + signal_register_account_response_get_username_link_handle($0, native.const()) + } + } + } + } + + public var storageCapable: Bool { + return failOnError { + try self.withNativeHandle { native in + try invokeFnReturningBool { + signal_register_account_response_get_storage_capable($0, native.const()) + } + } + } + } + + public var reregistration: Bool { + return failOnError { + try self.withNativeHandle { native in + try invokeFnReturningBool { + signal_register_account_response_get_reregistration($0, native.const()) + } + } + } + } + + public var entitlements: ([BadgeEntitlement], BackupEntitlement?) { + return failOnError { + try self.withNativeHandle { native in + let badges = try invokeFnReturningBadgeEntitlementArray { + signal_register_account_response_get_entitlement_badges($0, native.const()) + } + + let backup = try BackupEntitlement(fromResponse: native.const()) + + return (badges, backup) + } + } + } +} + +public struct BadgeEntitlement: Equatable { + public let id: String + public let visible: Bool + public let expiration: TimeInterval +} + +public struct BackupEntitlement: Equatable { + public let expiration: TimeInterval + public let level: UInt64 + public init(expiration: TimeInterval, level: UInt64) { + self.expiration = expiration + self.level = level + } + + fileprivate init?(fromResponse native: SignalConstPointerRegisterAccountResponse) throws { + let backupExpiration = try invokeFnReturningOptionalInteger { + signal_register_account_response_get_entitlement_backup_expiration_seconds($0, native) + } + guard case .some(let expiration) = backupExpiration else { + return nil + } + + let level = try invokeFnReturningOptionalInteger { + signal_register_account_response_get_entitlement_backup_level($0, native) + } + guard case .some(let level) = level else { + return nil + } + self.init(expiration: TimeInterval(expiration), level: level) + } +} + +public enum VerificationTransport: CustomStringConvertible { + case voice + case sms + + public var description: String { + return switch self { + case .voice: "voice" + case .sms: "sms" + } + } +} + +public enum Svr2CredentialsResult { + case match + case noMatch + case invalid +} + +public enum ChallengeOption: Hashable, Sendable { + case captcha + case pushChallenge +} + +/// Account attributes sent as part of a ``RegistrationService/registerAccount(accountPassword:skipDeviceTransfer:accountAttributes:apnPushToken:aciPublicKey:pniPublicKey:aciSignedPreKey:pniSignedPreKey:aciPqLastResortPreKey:pniPqLastResortPreKey:)`` request. +public class RegisterAccountAttributes: NativeHandleOwner { + /// Constructs the set of attributes to pass to the server. + /// - Throws: ``SignalError/invalidArgument(_:)`` if the `unidentifiedAccessKey` is not 16 bytes. + public convenience init( + recoveryPassword: Data, + aciRegistrationId: UInt16, + pniRegistrationId: UInt16, + registrationLock: String?, + unidentifiedAccessKey: Data, + unrestrictedUnidentifiedAccess: Bool, + capabilities: [String], + discoverableByPhoneNumber: Bool + ) throws { + var uak = SignalUnidentifiedAccessKey(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + try withUnsafeMutableBytes(of: &uak) { uakBytes in + if uakBytes.count != unidentifiedAccessKey.count { + throw SignalError.invalidArgument( + "unidentifiedAccessKey has \(unidentifiedAccessKey.count) bytes; expected \(uakBytes.count)" + ) + } + uakBytes.copyBytes(from: unidentifiedAccessKey) + } + let nativeHandle = failOnError { + try recoveryPassword.withUnsafeBorrowedBuffer { recoveryPassword in + try registrationLock.withCString { registrationLock in + try withUnsafePointer(to: &uak) { unidentifiedAccessKey in + try capabilities.withUnsafeBorrowedBytestringArray { capabilities in + var nativeHandle = SignalMutPointerRegistrationAccountAttributes() + try checkError( + signal_registration_account_attributes_create( + &nativeHandle, + recoveryPassword, + aciRegistrationId, + pniRegistrationId, + registrationLock, + unidentifiedAccessKey, + unrestrictedUnidentifiedAccess, + capabilities, + discoverableByPhoneNumber + ) + ) + return nativeHandle + } + } + } + } + } + self.init(owned: NonNull(nativeHandle)!) + } + + override internal class func destroyNativeHandle( + _ nativeHandle: NonNull + ) -> SignalFfiErrorRef? { + signal_registration_account_attributes_destroy(nativeHandle.pointer) + } +} + +extension SignalFfiRegistrationCreateSessionRequest { + internal static func withNativeStruct( + e164: String, + pushToken: String?, + mcc: String?, + mnc: String?, + _ fn: (Self) throws -> Result + ) rethrows -> Result { + try e164.withCString { e164 in + try pushToken.withCString { pushToken in + try mcc.withCString { mcc in + try mnc.withCString { mnc in + let request = SignalFfiRegistrationCreateSessionRequest( + number: e164, + push_token: pushToken, + mcc: mcc, + mnc: mnc + ) + return try fn(request) + } + } + } + } + } +} + +/// Invoke a function returning an unsigned integral result where `nil` is bridged as the maximum value. +/// +/// Bridging `nil` as max isn't a convention we want to rely on generally. It's +/// true for the getters in this file, though, hence `fileprivate`. +private func invokeFnReturningOptionalInteger( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef? +) throws -> Result? { + let output = try invokeFnReturningInteger(fn: fn) + return if output == Result.max { nil } else { output } +} + +private func invokeFnReturningBadgeEntitlementArray( + fn: (_ out: UnsafeMutablePointer) -> SignalFfiErrorRef? +) throws -> [BadgeEntitlement] { + var out = SignalOwnedBufferOfFfiRegisterResponseBadge() + try checkError(fn(&out)) + defer { signal_free_list_of_register_response_badges(out) } + + return UnsafeBufferPointer(start: out.base, count: out.length).map { + BadgeEntitlement(id: String(cString: $0.id), visible: $0.visible, expiration: TimeInterval($0.expiration_secs)) + } +} + +extension SignalMutPointerRegistrationSession: SignalMutPointer { + public typealias ConstPointer = SignalConstPointerRegistrationSession + + public init(untyped: OpaquePointer?) { + self.init(raw: untyped) + } + + public func toOpaque() -> OpaquePointer? { + self.raw + } + + public func const() -> Self.ConstPointer { + SignalConstPointerRegistrationSession(raw: self.raw) + } +} + +extension SignalConstPointerRegistrationSession: SignalConstPointer { + public func toOpaque() -> OpaquePointer? { + self.raw + } +} + +extension SignalMutPointerRegisterAccountResponse: SignalMutPointer { + public typealias ConstPointer = SignalConstPointerRegisterAccountResponse + + public init(untyped: OpaquePointer?) { + self.init(raw: untyped) + } + + public func toOpaque() -> OpaquePointer? { + self.raw + } + + public func const() -> Self.ConstPointer { + SignalConstPointerRegisterAccountResponse(raw: self.raw) + } +} + +extension SignalConstPointerRegisterAccountResponse: SignalConstPointer { + public func toOpaque() -> OpaquePointer? { + self.raw + } +} + +extension SignalMutPointerRegisterAccountRequest: SignalMutPointer { + public typealias ConstPointer = SignalConstPointerRegisterAccountRequest + + public init(untyped: OpaquePointer?) { + self.init(raw: untyped) + } + + public func toOpaque() -> OpaquePointer? { + self.raw + } + + public func const() -> Self.ConstPointer { + SignalConstPointerRegisterAccountRequest(raw: self.raw) + } +} + +extension SignalConstPointerRegisterAccountRequest: SignalConstPointer { + public func toOpaque() -> OpaquePointer? { + self.raw + } +} + +extension SignalMutPointerRegistrationAccountAttributes: SignalMutPointer { + public typealias ConstPointer = SignalConstPointerRegistrationAccountAttributes + + public init(untyped: OpaquePointer?) { + self.init(raw: untyped) + } + + public func toOpaque() -> OpaquePointer? { + self.raw + } + + public func const() -> Self.ConstPointer { + SignalConstPointerRegistrationAccountAttributes(raw: self.raw) + } +} + +extension SignalConstPointerRegistrationAccountAttributes: SignalConstPointer { + public func toOpaque() -> OpaquePointer? { + self.raw + } +} diff --git a/swift/Sources/LibSignalClient/SealedSender.swift b/swift/Sources/LibSignalClient/SealedSender.swift index 5f46814a0..15d6edb24 100644 --- a/swift/Sources/LibSignalClient/SealedSender.swift +++ b/swift/Sources/LibSignalClient/SealedSender.swift @@ -53,7 +53,8 @@ public class UnidentifiedSenderMessageContent: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_unidentified_sender_message_content_destroy(handle.pointer) } diff --git a/swift/Sources/LibSignalClient/SealedSenderCertificates.swift b/swift/Sources/LibSignalClient/SealedSenderCertificates.swift index 70383b97d..e2af7328f 100644 --- a/swift/Sources/LibSignalClient/SealedSenderCertificates.swift +++ b/swift/Sources/LibSignalClient/SealedSenderCertificates.swift @@ -20,12 +20,16 @@ public class ServerCertificate: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_server_certificate_destroy(handle.pointer) } @@ -113,24 +117,37 @@ public class SenderCertificate: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_sender_certificate_destroy(handle.pointer) } @@ -240,7 +257,9 @@ public class SenderCertificate: NativeHandleOwner Bool { var result = false try withAllBorrowed(self, trustRoot) { certificateHandle, trustRootHandle in - try checkError(signal_sender_certificate_validate(&result, certificateHandle.const(), trustRootHandle.const(), time)) + try checkError( + signal_sender_certificate_validate(&result, certificateHandle.const(), trustRootHandle.const(), time) + ) } return result } diff --git a/swift/Sources/LibSignalClient/ServiceId.swift b/swift/Sources/LibSignalClient/ServiceId.swift index d11a3f2b3..72526a252 100644 --- a/swift/Sources/LibSignalClient/ServiceId.swift +++ b/swift/Sources/LibSignalClient/ServiceId.swift @@ -9,6 +9,8 @@ import SignalFfi internal typealias ServiceIdStorage = SignalServiceIdFixedWidthBinaryBytes internal func == (_ lhs: ServiceIdStorage, _ rhs: ServiceIdStorage) -> Bool { + // swift-format-ignore + // (vertical alignment is clearer) return lhs.0 == rhs.0 && lhs.1 == rhs.1 && lhs.2 == rhs.2 && @@ -152,7 +154,9 @@ public class ServiceId: @unchecked Sendable { return try result.downcast(to: Self.self) } - internal func withPointerToFixedWidthBinary(_ callback: (UnsafePointer) throws -> R) rethrows -> R { + internal func withPointerToFixedWidthBinary( + _ callback: (UnsafePointer) throws -> R + ) rethrows -> R { return try callback(&self.storage) } diff --git a/swift/Sources/LibSignalClient/Sgx.swift b/swift/Sources/LibSignalClient/Sgx.swift index 1d07efe55..ea50b6d90 100644 --- a/swift/Sources/LibSignalClient/Sgx.swift +++ b/swift/Sources/LibSignalClient/Sgx.swift @@ -25,7 +25,9 @@ import SignalFfi /// which decrypts and verifies it, passing the plaintext back to the client for processing. /// public class SgxClient: NativeHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_sgx_client_state_destroy(handle.pointer) } diff --git a/swift/Sources/LibSignalClient/Svr2.swift b/swift/Sources/LibSignalClient/Svr2.swift index f07a803af..5bf009652 100644 --- a/swift/Sources/LibSignalClient/Svr2.swift +++ b/swift/Sources/LibSignalClient/Svr2.swift @@ -19,12 +19,14 @@ public class Svr2Client: SgxClient { let handle = try attestationMessage.withUnsafeBorrowedBuffer { attestationMessageBuffer in try mrenclave.withUnsafeBorrowedBuffer { mrenclaveBuffer in var result = SignalMutPointerSgxClientState() - try checkError(signal_svr2_client_new( - &result, - mrenclaveBuffer, - attestationMessageBuffer, - UInt64(currentDate.timeIntervalSince1970 * 1000) - )) + try checkError( + signal_svr2_client_new( + &result, + mrenclaveBuffer, + attestationMessageBuffer, + UInt64(currentDate.timeIntervalSince1970 * 1000) + ) + ) return result } } diff --git a/swift/Sources/LibSignalClient/TokioAsyncContext.swift b/swift/Sources/LibSignalClient/TokioAsyncContext.swift index e93c2d55c..0a81bb360 100644 --- a/swift/Sources/LibSignalClient/TokioAsyncContext.swift +++ b/swift/Sources/LibSignalClient/TokioAsyncContext.swift @@ -13,7 +13,9 @@ internal class TokioAsyncContext: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_tokio_async_context_destroy(handle.pointer) } @@ -88,7 +90,12 @@ internal class TokioAsyncContext: NativeHandleOwner, SignalMutPointerTokioAsyncContext) -> SignalFfiErrorRef? ) async throws -> Promise.Result { let cancellationHelper = CancellationHandoffHelper(context: self) - return try await withTaskCancellationHandler(operation: { - try await LibSignalClient.invokeAsyncFunction({ promise in - withNativeHandle { handle in - body(promise, handle) - } - }, saveCancellationId: { - cancellationHelper.setCancellationId($0) - }) - }, onCancel: { - cancellationHelper.cancel() - }) + return try await withTaskCancellationHandler( + operation: { + try await LibSignalClient.invokeAsyncFunction( + { promise in + withNativeHandle { handle in + body(promise, handle) + } + }, + saveCancellationId: { + cancellationHelper.setCancellationId($0) + } + ) + }, + onCancel: { + cancellationHelper.cancel() + } + ) } } diff --git a/swift/Sources/LibSignalClient/Username.swift b/swift/Sources/LibSignalClient/Username.swift index 0efefea85..cea5e8c25 100644 --- a/swift/Sources/LibSignalClient/Username.swift +++ b/swift/Sources/LibSignalClient/Username.swift @@ -33,11 +33,18 @@ public struct Username: Sendable { try self.init(username) } - public init(nickname: String, discriminator: String, withValidLengthWithin lengthRange: ClosedRange) throws { + public init(nickname: String, discriminator: String, withValidLengthWithin lengthRange: ClosedRange) throws + { self.hash = try nickname.withCString { nickname in try discriminator.withCString { discriminator in try invokeFnReturningFixedLengthArray { - signal_username_hash_from_parts($0, nickname, discriminator, lengthRange.lowerBound, lengthRange.upperBound) + signal_username_hash_from_parts( + $0, + nickname, + discriminator, + lengthRange.lowerBound, + lengthRange.upperBound + ) } } } diff --git a/swift/Sources/LibSignalClient/Utils.swift b/swift/Sources/LibSignalClient/Utils.swift index ffdb31be1..2760d44be 100644 --- a/swift/Sources/LibSignalClient/Utils.swift +++ b/swift/Sources/LibSignalClient/Utils.swift @@ -10,11 +10,19 @@ import SignalFfi import Security #endif -internal func invokeFnReturningString(fn: (UnsafeMutablePointer?>?) -> SignalFfiErrorRef?) throws -> String { +internal func invokeFnReturningString( + fn: (UnsafeMutablePointer?>?) -> SignalFfiErrorRef? +) throws + -> String +{ try invokeFnReturningOptionalString(fn: fn)! } -internal func invokeFnReturningOptionalString(fn: (UnsafeMutablePointer?>?) -> SignalFfiErrorRef?) throws -> String? { +internal func invokeFnReturningOptionalString( + fn: (UnsafeMutablePointer?>?) -> SignalFfiErrorRef? +) + throws -> String? +{ var output: UnsafePointer? try checkError(fn(&output)) if output == nil { @@ -25,7 +33,10 @@ internal func invokeFnReturningOptionalString(fn: (UnsafeMutablePointer(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?, transform: (UnsafeBufferPointer) -> Element) throws -> [Element] { +internal func invokeFnReturningSomeBytestringArray( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?, + transform: (UnsafeBufferPointer) -> Element +) throws -> [Element] { var array = SignalFfi.SignalBytestringArray() try checkError(fn(&array)) @@ -42,41 +53,64 @@ internal func invokeFnReturningSomeBytestringArray(fn: (UnsafeMutablePo return result } -internal func invokeFnReturningStringArray(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> [String] { +internal func invokeFnReturningStringArray( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef? +) throws + -> [String] +{ return try invokeFnReturningSomeBytestringArray(fn: fn) { String(decoding: $0, as: Unicode.UTF8.self) } } -internal func invokeFnReturningBytestringArray(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> [Data] { +internal func invokeFnReturningBytestringArray( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef? +) + throws -> [Data] +{ return try invokeFnReturningSomeBytestringArray(fn: fn) { Data($0) } } -internal func invokeFnReturningOptionalArray(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> Data? { +internal func invokeFnReturningOptionalArray( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef? +) + throws -> Data? +{ var output = SignalOwnedBuffer() try checkError(fn(&output)) return if output.base == nil { nil } else { - Data(bytesNoCopy: output.base, count: output.length, deallocator: .custom { base, length in - signal_free_buffer(base, length) - }) + Data( + bytesNoCopy: output.base, + count: output.length, + deallocator: .custom { base, length in + signal_free_buffer(base, length) + } + ) } } -internal func invokeFnReturningData(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> Data { +internal func invokeFnReturningData(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> Data +{ var output = SignalOwnedBuffer() try checkError(fn(&output)) guard let base = output.base else { return Data() } - return Data(bytesNoCopy: base, count: output.length, deallocator: .custom { base, length in - signal_free_buffer(base, length) - }) + return Data( + bytesNoCopy: base, + count: output.length, + deallocator: .custom { base, length in + signal_free_buffer(base, length) + } + ) } -internal func invokeFnReturningFixedLengthArray(fn: (UnsafeMutablePointer) -> SignalFfiErrorRef?) throws -> Data { +internal func invokeFnReturningFixedLengthArray( + fn: (UnsafeMutablePointer) -> SignalFfiErrorRef? +) throws -> Data { precondition(MemoryLayout.alignment == 1, "not a fixed-sized array (tuple) of UInt8") var output = Data(count: MemoryLayout.size) try output.withUnsafeMutableBytes { buffer in @@ -86,17 +120,23 @@ internal func invokeFnReturningFixedLengthArray(fn: (UnsafeMutabl return output } -internal func invokeFnReturningSerialized(fn: (UnsafeMutablePointer) -> SignalFfiErrorRef?) throws -> Result { +internal func invokeFnReturningSerialized( + fn: (UnsafeMutablePointer) -> SignalFfiErrorRef? +) throws -> Result { let output = try invokeFnReturningFixedLengthArray(fn: fn) return try Result(contents: output) } -internal func invokeFnReturningVariableLengthSerialized(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> Result { +internal func invokeFnReturningVariableLengthSerialized( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef? +) throws -> Result { let output = try invokeFnReturningData(fn: fn) return try Result(contents: output) } -internal func invokeFnReturningOptionalVariableLengthSerialized(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> Result? { +internal func invokeFnReturningOptionalVariableLengthSerialized( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef? +) throws -> Result? { let output = try invokeFnReturningData(fn: fn) if output.isEmpty { return nil @@ -110,7 +150,9 @@ internal func invokeFnReturningUuid(fn: (UnsafeMutablePointer?) -> Signa return UUID(uuid: output) } -internal func invokeFnReturningOptionalUuid(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> UUID? { +internal func invokeFnReturningOptionalUuid( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef? +) throws -> UUID? { var output: SignalOptionalUuid = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) try checkError(fn(&output)) let (isPresent, u0, u1, u2, u3, u4, u5, u6, u7, u8, u9, u10, u11, u12, u13, u14, u15) = output @@ -120,13 +162,17 @@ internal func invokeFnReturningOptionalUuid(fn: (UnsafeMutablePointer(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> Id { +internal func invokeFnReturningServiceId( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef? +) throws -> Id { var output: ServiceIdStorage = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) try checkError(fn(&output)) return try Id.parseFrom(fixedWidthBinary: output) } -internal func invokeFnReturningInteger(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> Result { +internal func invokeFnReturningInteger( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef? +) throws -> Result { var output: Result = 0 try checkError(fn(&output)) return output @@ -138,13 +184,17 @@ internal func invokeFnReturningBool(fn: (UnsafeMutablePointer?) -> SignalF return output } -internal func invokeFnReturningNativeHandle, PointerType>(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> Owner { +internal func invokeFnReturningNativeHandle, PointerType>( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef? +) throws -> Owner { var handle = PointerType(untyped: nil) try checkError(fn(&handle)) return Owner(owned: NonNull(handle)!) } -internal func invokeFnReturningOptionalNativeHandle, PointerType>(fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef?) throws -> Owner? { +internal func invokeFnReturningOptionalNativeHandle, PointerType>( + fn: (UnsafeMutablePointer?) -> SignalFfiErrorRef? +) throws -> Owner? { var handle = PointerType(untyped: nil) try checkError(fn(&handle)) return NonNull(handle).map { Owner(owned: $0) } @@ -178,7 +228,9 @@ internal func withUnsafeOptionalBorrowedSlice< } extension Sequence where Self.Element == String { - func withUnsafeBorrowedBytestringArray(_ body: (SignalBorrowedBytestringArray) throws -> Result) rethrows -> Result { + func withUnsafeBorrowedBytestringArray( + _ body: (SignalBorrowedBytestringArray) throws -> Result + ) rethrows -> Result { let lengths = self.map { $0.utf8.count } var concatenated = Data(capacity: lengths.reduce(0) { $0 + $1 }) for s in self { @@ -187,10 +239,12 @@ extension Sequence where Self.Element == String { return try concatenated.withUnsafeBorrowedBuffer { bytes in try lengths.withUnsafeBufferPointer { lengths in - try body(SignalBorrowedBytestringArray( - bytes: bytes, - lengths: SignalBorrowedSliceOfusize(base: lengths.baseAddress, length: lengths.count) - )) + try body( + SignalBorrowedBytestringArray( + bytes: bytes, + lengths: SignalBorrowedSliceOfusize(base: lengths.baseAddress, length: lengths.count) + ) + ) } } } @@ -211,9 +265,13 @@ extension SignalBorrowedMutableBuffer { extension Data { internal init(consuming buffer: SignalOwnedBuffer) { if let base = buffer.base { - self.init(bytesNoCopy: base, count: buffer.length, deallocator: .custom { base, length in - signal_free_buffer(base, length) - }) + self.init( + bytesNoCopy: base, + count: buffer.length, + deallocator: .custom { base, length in + signal_free_buffer(base, length) + } + ) } else { self.init() } @@ -227,16 +285,16 @@ internal func fillRandom(_ buffer: UnsafeMutableRawBufferPointer) throws { return } -#if canImport(Security) + #if canImport(Security) let result = SecRandomCopyBytes(kSecRandomDefault, buffer.count, baseAddress) guard result == errSecSuccess else { throw SignalError.internalError("SecRandomCopyBytes failed (error code \(result))") } -#else + #else for i in buffer.indices { buffer[i] = UInt8.random(in: .min ... .max) } -#endif + #endif } /// Wraps a store while providing a place to hang on to any user-thrown errors. @@ -258,7 +316,10 @@ internal struct ErrorHandlingContext { } } -internal func rethrowCallbackErrors(_ store: Store, _ body: (UnsafeMutablePointer>) throws -> Result) rethrows -> Result { +internal func rethrowCallbackErrors( + _ store: Store, + _ body: (UnsafeMutablePointer>) throws -> Result +) rethrows -> Result { var context = ErrorHandlingContext(store) do { return try withUnsafeMutablePointer(to: &context) { @@ -323,7 +384,9 @@ extension Data { } extension [String: String] { - internal func withBridgedStringMap(_ callback: (SignalMutPointerBridgedStringMap) throws -> Result) rethrows -> Result { + internal func withBridgedStringMap( + _ callback: (SignalMutPointerBridgedStringMap) throws -> Result + ) rethrows -> Result { var map = SignalMutPointerBridgedStringMap() failOnError(signal_bridged_string_map_new(&map, UInt32(clamping: self.count))) defer { signal_bridged_string_map_destroy(map) } diff --git a/swift/Sources/LibSignalClient/messages/CiphertextMessage.swift b/swift/Sources/LibSignalClient/messages/CiphertextMessage.swift index 70d4741b8..ff6a68392 100644 --- a/swift/Sources/LibSignalClient/messages/CiphertextMessage.swift +++ b/swift/Sources/LibSignalClient/messages/CiphertextMessage.swift @@ -34,7 +34,9 @@ public class CiphertextMessage: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_ciphertext_message_destroy(handle.pointer) } diff --git a/swift/Sources/LibSignalClient/messages/PlaintextContent.swift b/swift/Sources/LibSignalClient/messages/PlaintextContent.swift index f1d8733d2..44871b358 100644 --- a/swift/Sources/LibSignalClient/messages/PlaintextContent.swift +++ b/swift/Sources/LibSignalClient/messages/PlaintextContent.swift @@ -7,7 +7,9 @@ import Foundation import SignalFfi public class PlaintextContent: NativeHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_plaintext_content_destroy(handle.pointer) } @@ -71,7 +73,9 @@ extension SignalConstPointerPlaintextContent: SignalConstPointer { } public class DecryptionErrorMessage: NativeHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_decryption_error_message_destroy(handle.pointer) } @@ -83,16 +87,31 @@ public class DecryptionErrorMessage: NativeHandleOwner(originalMessageBytes bytes: Bytes, type: CiphertextMessage.MessageType, timestamp: UInt64, originalSenderDeviceId: UInt32) throws { + public convenience init( + originalMessageBytes bytes: Bytes, + type: CiphertextMessage.MessageType, + timestamp: UInt64, + originalSenderDeviceId: UInt32 + ) throws { var result = SignalMutPointerDecryptionErrorMessage() try bytes.withUnsafeBorrowedBuffer { - try checkError(signal_decryption_error_message_for_original_message(&result, $0, type.rawValue, timestamp, originalSenderDeviceId)) + try checkError( + signal_decryption_error_message_for_original_message( + &result, + $0, + type.rawValue, + timestamp, + originalSenderDeviceId + ) + ) } self.init(owned: NonNull(result)!) } // For testing - public static func extractFromSerializedContent(_ bytes: Bytes) throws -> DecryptionErrorMessage { + public static func extractFromSerializedContent( + _ bytes: Bytes + ) throws -> DecryptionErrorMessage { return try bytes.withUnsafeBorrowedBuffer { buffer in try invokeFnReturningNativeHandle { signal_decryption_error_message_extract_from_serialized_content($0, buffer) diff --git a/swift/Sources/LibSignalClient/messages/PreKeySignalMessage.swift b/swift/Sources/LibSignalClient/messages/PreKeySignalMessage.swift index 6a50e7cf8..aa5cedb5f 100644 --- a/swift/Sources/LibSignalClient/messages/PreKeySignalMessage.swift +++ b/swift/Sources/LibSignalClient/messages/PreKeySignalMessage.swift @@ -7,7 +7,9 @@ import Foundation import SignalFfi public class PreKeySignalMessage: NativeHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_pre_key_signal_message_destroy(handle.pointer) } diff --git a/swift/Sources/LibSignalClient/messages/SenderKeyDistributionMessage.swift b/swift/Sources/LibSignalClient/messages/SenderKeyDistributionMessage.swift index f294269ca..2f7265685 100644 --- a/swift/Sources/LibSignalClient/messages/SenderKeyDistributionMessage.swift +++ b/swift/Sources/LibSignalClient/messages/SenderKeyDistributionMessage.swift @@ -7,7 +7,9 @@ import Foundation import SignalFfi public class SenderKeyDistributionMessage: NativeHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_sender_key_distribution_message_destroy(handle.pointer) } @@ -21,12 +23,14 @@ public class SenderKeyDistributionMessage: NativeHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_sender_key_message_destroy(handle.pointer) } @@ -72,7 +74,9 @@ public class SenderKeyMessage: NativeHandleOwner Bool { var result = false try withAllBorrowed(self, key) { messageHandle, keyHandle in - try checkError(signal_sender_key_message_verify_signature(&result, messageHandle.const(), keyHandle.const())) + try checkError( + signal_sender_key_message_verify_signature(&result, messageHandle.const(), keyHandle.const()) + ) } return result } diff --git a/swift/Sources/LibSignalClient/messages/SignalMessage.swift b/swift/Sources/LibSignalClient/messages/SignalMessage.swift index ff5be6da1..8a18fc9d3 100644 --- a/swift/Sources/LibSignalClient/messages/SignalMessage.swift +++ b/swift/Sources/LibSignalClient/messages/SignalMessage.swift @@ -7,7 +7,9 @@ import Foundation import SignalFfi public class SignalMessage: NativeHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_message_destroy(handle.pointer) } @@ -81,13 +83,15 @@ public class SignalMessage: NativeHandleOwner { .bytes(macKey) ) { messageHandle, senderHandle, receiverHandle, macKey in var result = false - try checkError(signal_message_verify_mac( - &result, - messageHandle.const(), - senderHandle.const(), - receiverHandle.const(), - macKey - )) + try checkError( + signal_message_verify_mac( + &result, + messageHandle.const(), + senderHandle.const(), + receiverHandle.const(), + macKey + ) + ) return result } } diff --git a/swift/Sources/LibSignalClient/state/KyberPreKeyRecord.swift b/swift/Sources/LibSignalClient/state/KyberPreKeyRecord.swift index 6b7f78de0..8209e7822 100644 --- a/swift/Sources/LibSignalClient/state/KyberPreKeyRecord.swift +++ b/swift/Sources/LibSignalClient/state/KyberPreKeyRecord.swift @@ -7,11 +7,16 @@ import Foundation import SignalFfi public class KyberPreKeyRecord: ClonableHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_kyber_pre_key_record_destroy(handle.pointer) } - override internal class func cloneNativeHandle(_ newHandle: inout SignalMutPointerKyberPreKeyRecord, currentHandle: SignalConstPointerKyberPreKeyRecord) -> SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout SignalMutPointerKyberPreKeyRecord, + currentHandle: SignalConstPointerKyberPreKeyRecord + ) -> SignalFfiErrorRef? { return signal_kyber_pre_key_record_clone(&newHandle, currentHandle) } diff --git a/swift/Sources/LibSignalClient/state/PreKeyBundle.swift b/swift/Sources/LibSignalClient/state/PreKeyBundle.swift index b47b17cd2..c7b141bb3 100644 --- a/swift/Sources/LibSignalClient/state/PreKeyBundle.swift +++ b/swift/Sources/LibSignalClient/state/PreKeyBundle.swift @@ -7,7 +7,9 @@ import Foundation import SignalFfi public class PreKeyBundle: NativeHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_pre_key_bundle_destroy(handle.pointer) } @@ -36,21 +38,29 @@ public class PreKeyBundle: NativeHandleOwner { kyberPrekey, .bytes(signedPrekeySignature), .bytes(kyberPrekeySignature) - ) { prekeyHandle, signedPrekeyHandle, identityKeyHandle, kyberKeyHandle, ecSignatureBuffer, kyberSignatureBuffer in - try checkError(signal_pre_key_bundle_new( - &result, - registrationId, - deviceId, - prekeyId, - prekeyHandle.const(), - signedPrekeyId, - signedPrekeyHandle.const(), - ecSignatureBuffer, - identityKeyHandle.const(), - kyberPrekeyId, - kyberKeyHandle.const(), - kyberSignatureBuffer - )) + ) { + prekeyHandle, + signedPrekeyHandle, + identityKeyHandle, + kyberKeyHandle, + ecSignatureBuffer, + kyberSignatureBuffer in + try checkError( + signal_pre_key_bundle_new( + &result, + registrationId, + deviceId, + prekeyId, + prekeyHandle.const(), + signedPrekeyId, + signedPrekeyHandle.const(), + ecSignatureBuffer, + identityKeyHandle.const(), + kyberPrekeyId, + kyberKeyHandle.const(), + kyberSignatureBuffer + ) + ) } self.init(owned: NonNull(result)!) } @@ -78,20 +88,22 @@ public class PreKeyBundle: NativeHandleOwner { .bytes(signedPrekeySignature), .bytes(kyberPrekeySignature) ) { signedPrekeyHandle, identityKeyHandle, kyberKeyHandle, ecSignatureBuffer, kyberSignatureBuffer in - try checkError(signal_pre_key_bundle_new( - &result, - registrationId, - deviceId, - ~0, - SignalConstPointerPublicKey(), - signedPrekeyId, - signedPrekeyHandle.const(), - ecSignatureBuffer, - identityKeyHandle.const(), - kyberPrekeyId, - kyberKeyHandle.const(), - kyberSignatureBuffer - )) + try checkError( + signal_pre_key_bundle_new( + &result, + registrationId, + deviceId, + ~0, + SignalConstPointerPublicKey(), + signedPrekeyId, + signedPrekeyHandle.const(), + ecSignatureBuffer, + identityKeyHandle.const(), + kyberPrekeyId, + kyberKeyHandle.const(), + kyberSignatureBuffer + ) + ) } self.init(owned: NonNull(result)!) } diff --git a/swift/Sources/LibSignalClient/state/PreKeyRecord.swift b/swift/Sources/LibSignalClient/state/PreKeyRecord.swift index a930c6b66..855d26f05 100644 --- a/swift/Sources/LibSignalClient/state/PreKeyRecord.swift +++ b/swift/Sources/LibSignalClient/state/PreKeyRecord.swift @@ -7,11 +7,16 @@ import Foundation import SignalFfi public class PreKeyRecord: ClonableHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_pre_key_record_destroy(handle.pointer) } - override internal class func cloneNativeHandle(_ newHandle: inout SignalMutPointerPreKeyRecord, currentHandle: SignalConstPointerPreKeyRecord) -> SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout SignalMutPointerPreKeyRecord, + currentHandle: SignalConstPointerPreKeyRecord + ) -> SignalFfiErrorRef? { return signal_pre_key_record_clone(&newHandle, currentHandle) } diff --git a/swift/Sources/LibSignalClient/state/SenderKeyRecord.swift b/swift/Sources/LibSignalClient/state/SenderKeyRecord.swift index 88de7c415..81bb9e1b4 100644 --- a/swift/Sources/LibSignalClient/state/SenderKeyRecord.swift +++ b/swift/Sources/LibSignalClient/state/SenderKeyRecord.swift @@ -7,11 +7,16 @@ import Foundation import SignalFfi public class SenderKeyRecord: ClonableHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_sender_key_record_destroy(handle.pointer) } - override internal class func cloneNativeHandle(_ newHandle: inout SignalMutPointerSenderKeyRecord, currentHandle: SignalConstPointerSenderKeyRecord) -> SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout SignalMutPointerSenderKeyRecord, + currentHandle: SignalConstPointerSenderKeyRecord + ) -> SignalFfiErrorRef? { return signal_sender_key_record_clone(&newHandle, currentHandle) } diff --git a/swift/Sources/LibSignalClient/state/SessionRecord.swift b/swift/Sources/LibSignalClient/state/SessionRecord.swift index 4a3f9a93f..ea691a30e 100644 --- a/swift/Sources/LibSignalClient/state/SessionRecord.swift +++ b/swift/Sources/LibSignalClient/state/SessionRecord.swift @@ -7,11 +7,16 @@ import Foundation import SignalFfi public class SessionRecord: ClonableHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_session_record_destroy(handle.pointer) } - override internal class func cloneNativeHandle(_ newHandle: inout SignalMutPointerSessionRecord, currentHandle: SignalConstPointerSessionRecord) -> SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout SignalMutPointerSessionRecord, + currentHandle: SignalConstPointerSessionRecord + ) -> SignalFfiErrorRef? { return signal_session_record_clone(&newHandle, currentHandle) } @@ -41,7 +46,13 @@ public class SessionRecord: ClonableHandleOwner { public func hasCurrentState(now: Date) -> Bool { var result = false self.withNativeHandle { nativeHandle in - failOnError(signal_session_record_has_usable_sender_chain(&result, nativeHandle.const(), UInt64(now.timeIntervalSince1970 * 1000))) + failOnError( + signal_session_record_has_usable_sender_chain( + &result, + nativeHandle.const(), + UInt64(now.timeIntervalSince1970 * 1000) + ) + ) } return result } @@ -63,7 +74,9 @@ public class SessionRecord: ClonableHandleOwner { public func currentRatchetKeyMatches(_ key: PublicKey) throws -> Bool { var result = false try withAllBorrowed(self, key) { sessionHandle, keyHandle in - try checkError(signal_session_record_current_ratchet_key_matches(&result, sessionHandle.const(), keyHandle.const())) + try checkError( + signal_session_record_current_ratchet_key_matches(&result, sessionHandle.const(), keyHandle.const()) + ) } return result } diff --git a/swift/Sources/LibSignalClient/state/SignedPreKeyRecord.swift b/swift/Sources/LibSignalClient/state/SignedPreKeyRecord.swift index 653291aa4..08cce0397 100644 --- a/swift/Sources/LibSignalClient/state/SignedPreKeyRecord.swift +++ b/swift/Sources/LibSignalClient/state/SignedPreKeyRecord.swift @@ -7,11 +7,16 @@ import Foundation import SignalFfi public class SignedPreKeyRecord: ClonableHandleOwner { - override internal class func destroyNativeHandle(_ handle: NonNull) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { return signal_signed_pre_key_record_destroy(handle.pointer) } - override internal class func cloneNativeHandle(_ newHandle: inout SignalMutPointerSignedPreKeyRecord, currentHandle: SignalConstPointerSignedPreKeyRecord) -> SignalFfiErrorRef? { + override internal class func cloneNativeHandle( + _ newHandle: inout SignalMutPointerSignedPreKeyRecord, + currentHandle: SignalConstPointerSignedPreKeyRecord + ) -> SignalFfiErrorRef? { return signal_signed_pre_key_record_clone(&newHandle, currentHandle) } @@ -33,14 +38,16 @@ public class SignedPreKeyRecord: ClonableHandleOwner BackupAuthCredentialPresentation { + public func present( + serverParams: GenericServerPublicParams, + randomness: Randomness + ) -> BackupAuthCredentialPresentation { return failOnError { try withAllBorrowed(self, serverParams, randomness) { contents, serverParams, randomness in try invokeFnReturningVariableLengthSerialized { diff --git a/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialPresentation.swift b/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialPresentation.swift index d764f2fd7..70407940d 100644 --- a/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialPresentation.swift +++ b/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialPresentation.swift @@ -13,7 +13,13 @@ public class BackupAuthCredentialPresentation: ByteArray, @unchecked Sendable { public func verify(now: Date = Date(), serverParams: GenericServerSecretParams) throws { try withAllBorrowed(self, serverParams) { contents, serverParams in - try checkError(signal_backup_auth_credential_presentation_verify(contents, UInt64(now.timeIntervalSince1970), serverParams)) + try checkError( + signal_backup_auth_credential_presentation_verify( + contents, + UInt64(now.timeIntervalSince1970), + serverParams + ) + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialRequest.swift b/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialRequest.swift index faabc73a5..2aa140b7a 100644 --- a/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialRequest.swift +++ b/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialRequest.swift @@ -11,17 +11,42 @@ public class BackupAuthCredentialRequest: ByteArray, @unchecked Sendable { try super.init(contents, checkValid: signal_backup_auth_credential_request_check_valid_contents) } - public func issueCredential(timestamp: Date, backupLevel: BackupLevel, type: BackupCredentialType, params: GenericServerSecretParams) -> BackupAuthCredentialResponse { + public func issueCredential( + timestamp: Date, + backupLevel: BackupLevel, + type: BackupCredentialType, + params: GenericServerSecretParams + ) -> BackupAuthCredentialResponse { return failOnError { - self.issueCredential(timestamp: timestamp, backupLevel: backupLevel, type: type, params: params, randomness: try .generate()) + self.issueCredential( + timestamp: timestamp, + backupLevel: backupLevel, + type: type, + params: params, + randomness: try .generate() + ) } } - public func issueCredential(timestamp: Date, backupLevel: BackupLevel, type: BackupCredentialType, params: GenericServerSecretParams, randomness: Randomness) -> BackupAuthCredentialResponse { + public func issueCredential( + timestamp: Date, + backupLevel: BackupLevel, + type: BackupCredentialType, + params: GenericServerSecretParams, + randomness: Randomness + ) -> BackupAuthCredentialResponse { return failOnError { try withAllBorrowed(self, params, randomness) { contents, params, randomness in try invokeFnReturningVariableLengthSerialized { - signal_backup_auth_credential_request_issue_deterministic($0, contents, UInt64(timestamp.timeIntervalSince1970), backupLevel.rawValue, type.rawValue, params, randomness) + signal_backup_auth_credential_request_issue_deterministic( + $0, + contents, + UInt64(timestamp.timeIntervalSince1970), + backupLevel.rawValue, + type.rawValue, + params, + randomness + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialRequestContext.swift b/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialRequestContext.swift index 224914842..e22346a0e 100644 --- a/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialRequestContext.swift +++ b/swift/Sources/LibSignalClient/zkgroup/BackupAuthCredentialRequestContext.swift @@ -34,10 +34,20 @@ public class BackupAuthCredentialRequestContext: ByteArray, @unchecked Sendable } } - public func receive(_ response: BackupAuthCredentialResponse, timestamp: Date, params: GenericServerPublicParams) throws -> BackupAuthCredential { + public func receive( + _ response: BackupAuthCredentialResponse, + timestamp: Date, + params: GenericServerPublicParams + ) throws -> BackupAuthCredential { return try withAllBorrowed(self, response, params) { contents, response, params in try invokeFnReturningVariableLengthSerialized { - signal_backup_auth_credential_request_context_receive_response($0, contents, response, UInt64(timestamp.timeIntervalSince1970), params) + signal_backup_auth_credential_request_context_receive_response( + $0, + contents, + response, + UInt64(timestamp.timeIntervalSince1970), + params + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/BackupLevel.swift b/swift/Sources/LibSignalClient/zkgroup/BackupLevel.swift index 8173dbb40..9267f07d0 100644 --- a/swift/Sources/LibSignalClient/zkgroup/BackupLevel.swift +++ b/swift/Sources/LibSignalClient/zkgroup/BackupLevel.swift @@ -8,10 +8,12 @@ import SignalFfi public enum BackupLevel: UInt8, Sendable { // This must match the Rust version of the enum. - case free = 200, paid = 201 + case free = 200 + case paid = 201 } public enum BackupCredentialType: UInt8 { // This must match the Rust version of the enum. - case messages = 1, media = 2 + case messages = 1 + case media = 2 } diff --git a/swift/Sources/LibSignalClient/zkgroup/ByteArray.swift b/swift/Sources/LibSignalClient/zkgroup/ByteArray.swift index 2e29f3542..91c58f6d6 100644 --- a/swift/Sources/LibSignalClient/zkgroup/ByteArray.swift +++ b/swift/Sources/LibSignalClient/zkgroup/ByteArray.swift @@ -18,7 +18,9 @@ public class ByteArray { init(newContents: Data, expectedLength: Int, unrecoverable: Bool = false) throws { if newContents.count != expectedLength { - throw SignalError.invalidType("\(type(of: self)) uses \(expectedLength) bytes, but tried to deserialize from an array of \(newContents.count) bytes") + throw SignalError.invalidType( + "\(type(of: self)) uses \(expectedLength) bytes, but tried to deserialize from an array of \(newContents.count) bytes" + ) } self.contents = newContents } @@ -42,13 +44,17 @@ public class ByteArray { /// tuples representing a fixed-size array; using another type, or using the wrong size of /// array, is considered a programmer error and can result in arbitrary behavior (including /// violating type safety). So, uh, don't do that. - func withUnsafePointerToSerialized(_ callback: (UnsafePointer) throws -> Result) throws -> Result { + func withUnsafePointerToSerialized( + _ callback: (UnsafePointer) throws -> Result + ) throws -> Result { precondition(MemoryLayout.alignment == 1, "not a fixed-sized array (tuple) of UInt8") return try self.contents.withUnsafeBytes { buffer in let expectedSize = MemoryLayout.size guard expectedSize == buffer.count else { - throw SignalError.invalidType("\(type(of: self)) uses \(buffer.count) bytes, but was passed to a callback that uses \(expectedSize) bytes") + throw SignalError.invalidType( + "\(type(of: self)) uses \(buffer.count) bytes, but was passed to a callback that uses \(expectedSize) bytes" + ) } // Use assumingMemoryBound(to:) here rather than bindMemory(to:) diff --git a/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredential.swift b/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredential.swift index 120e285d3..b2b49d3ac 100644 --- a/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredential.swift +++ b/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredential.swift @@ -11,13 +11,30 @@ public class CallLinkAuthCredential: ByteArray, @unchecked Sendable { try super.init(contents, checkValid: signal_call_link_auth_credential_check_valid_contents) } - public func present(userId: Aci, redemptionTime: Date, serverParams: GenericServerPublicParams, callLinkParams: CallLinkSecretParams) -> CallLinkAuthCredentialPresentation { + public func present( + userId: Aci, + redemptionTime: Date, + serverParams: GenericServerPublicParams, + callLinkParams: CallLinkSecretParams + ) -> CallLinkAuthCredentialPresentation { return failOnError { - self.present(userId: userId, redemptionTime: redemptionTime, serverParams: serverParams, callLinkParams: callLinkParams, randomness: try .generate()) + self.present( + userId: userId, + redemptionTime: redemptionTime, + serverParams: serverParams, + callLinkParams: callLinkParams, + randomness: try .generate() + ) } } - public func present(userId: Aci, redemptionTime: Date, serverParams: GenericServerPublicParams, callLinkParams: CallLinkSecretParams, randomness: Randomness) -> CallLinkAuthCredentialPresentation { + public func present( + userId: Aci, + redemptionTime: Date, + serverParams: GenericServerPublicParams, + callLinkParams: CallLinkSecretParams, + randomness: Randomness + ) -> CallLinkAuthCredentialPresentation { return failOnError { try withAllBorrowed( self, @@ -27,7 +44,15 @@ public class CallLinkAuthCredential: ByteArray, @unchecked Sendable { randomness ) { contents, userId, serverParams, callLinkParams, randomness in try invokeFnReturningVariableLengthSerialized { - signal_call_link_auth_credential_present_deterministic($0, contents, userId, UInt64(redemptionTime.timeIntervalSince1970), serverParams, callLinkParams, randomness) + signal_call_link_auth_credential_present_deterministic( + $0, + contents, + userId, + UInt64(redemptionTime.timeIntervalSince1970), + serverParams, + callLinkParams, + randomness + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredentialPresentation.swift b/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredentialPresentation.swift index ac984f476..20a4fd766 100644 --- a/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredentialPresentation.swift +++ b/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredentialPresentation.swift @@ -11,9 +11,20 @@ public class CallLinkAuthCredentialPresentation: ByteArray, @unchecked Sendable try super.init(contents, checkValid: signal_call_link_auth_credential_presentation_check_valid_contents) } - public func verify(now: Date = Date(), serverParams: GenericServerSecretParams, callLinkParams: CallLinkPublicParams) throws { + public func verify( + now: Date = Date(), + serverParams: GenericServerSecretParams, + callLinkParams: CallLinkPublicParams + ) throws { try withAllBorrowed(self, serverParams, callLinkParams) { contents, serverParams, callLinkParams in - try checkError(signal_call_link_auth_credential_presentation_verify(contents, UInt64(now.timeIntervalSince1970), serverParams, callLinkParams)) + try checkError( + signal_call_link_auth_credential_presentation_verify( + contents, + UInt64(now.timeIntervalSince1970), + serverParams, + callLinkParams + ) + ) } } diff --git a/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredentialResponse.swift b/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredentialResponse.swift index d1e70ef7e..1b6ceda2c 100644 --- a/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredentialResponse.swift +++ b/swift/Sources/LibSignalClient/zkgroup/CallLinkAuthCredentialResponse.swift @@ -11,26 +11,56 @@ public class CallLinkAuthCredentialResponse: ByteArray, @unchecked Sendable { try super.init(contents, checkValid: signal_call_link_auth_credential_response_check_valid_contents) } - public static func issueCredential(userId: Aci, redemptionTime: Date, params: GenericServerSecretParams) -> CallLinkAuthCredentialResponse { + public static func issueCredential( + userId: Aci, + redemptionTime: Date, + params: GenericServerSecretParams + ) -> CallLinkAuthCredentialResponse { return failOnError { - self.issueCredential(userId: userId, redemptionTime: redemptionTime, params: params, randomness: try .generate()) + self.issueCredential( + userId: userId, + redemptionTime: redemptionTime, + params: params, + randomness: try .generate() + ) } } - public static func issueCredential(userId: Aci, redemptionTime: Date, params: GenericServerSecretParams, randomness: Randomness) -> CallLinkAuthCredentialResponse { + public static func issueCredential( + userId: Aci, + redemptionTime: Date, + params: GenericServerSecretParams, + randomness: Randomness + ) -> CallLinkAuthCredentialResponse { return failOnError { try withAllBorrowed(userId, params, randomness) { userId, params, randomness in try invokeFnReturningVariableLengthSerialized { - signal_call_link_auth_credential_response_issue_deterministic($0, userId, UInt64(redemptionTime.timeIntervalSince1970), params, randomness) + signal_call_link_auth_credential_response_issue_deterministic( + $0, + userId, + UInt64(redemptionTime.timeIntervalSince1970), + params, + randomness + ) } } } } - public func receive(userId: Aci, redemptionTime: Date, params: GenericServerPublicParams) throws -> CallLinkAuthCredential { + public func receive( + userId: Aci, + redemptionTime: Date, + params: GenericServerPublicParams + ) throws -> CallLinkAuthCredential { return try withAllBorrowed(self, userId, params) { contents, userId, params in try invokeFnReturningVariableLengthSerialized { - signal_call_link_auth_credential_response_receive($0, contents, userId, UInt64(redemptionTime.timeIntervalSince1970), params) + signal_call_link_auth_credential_response_receive( + $0, + contents, + userId, + UInt64(redemptionTime.timeIntervalSince1970), + params + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/ClientZkAuthOperations.swift b/swift/Sources/LibSignalClient/zkgroup/ClientZkAuthOperations.swift index 90343cca0..6d1db6929 100644 --- a/swift/Sources/LibSignalClient/zkgroup/ClientZkAuthOperations.swift +++ b/swift/Sources/LibSignalClient/zkgroup/ClientZkAuthOperations.swift @@ -16,13 +16,25 @@ public class ClientZkAuthOperations { /// Produces the `AuthCredentialWithPni` from a server-generated `AuthCredentialWithPniResponse`. /// /// - parameter redemptionTime: This is provided by the server as an integer, and should be passed through directly. - public func receiveAuthCredentialWithPniAsServiceId(aci: Aci, pni: Pni, redemptionTime: UInt64, authCredentialResponse: AuthCredentialWithPniResponse) throws -> AuthCredentialWithPni { + public func receiveAuthCredentialWithPniAsServiceId( + aci: Aci, + pni: Pni, + redemptionTime: UInt64, + authCredentialResponse: AuthCredentialWithPniResponse + ) throws -> AuthCredentialWithPni { return try self.serverPublicParams.withNativeHandle { serverPublicParams in try aci.withPointerToFixedWidthBinary { aci in try pni.withPointerToFixedWidthBinary { pni in try authCredentialResponse.withUnsafeBorrowedBuffer { authCredentialResponse in try invokeFnReturningVariableLengthSerialized { - signal_server_public_params_receive_auth_credential_with_pni_as_service_id($0, serverPublicParams.const(), aci, pni, redemptionTime, authCredentialResponse) + signal_server_public_params_receive_auth_credential_with_pni_as_service_id( + $0, + serverPublicParams.const(), + aci, + pni, + redemptionTime, + authCredentialResponse + ) } } } @@ -30,17 +42,34 @@ public class ClientZkAuthOperations { } } - public func createAuthCredentialPresentation(groupSecretParams: GroupSecretParams, authCredential: AuthCredentialWithPni) throws -> AuthCredentialPresentation { - return try self.createAuthCredentialPresentation(randomness: Randomness.generate(), groupSecretParams: groupSecretParams, authCredential: authCredential) + public func createAuthCredentialPresentation( + groupSecretParams: GroupSecretParams, + authCredential: AuthCredentialWithPni + ) throws -> AuthCredentialPresentation { + return try self.createAuthCredentialPresentation( + randomness: Randomness.generate(), + groupSecretParams: groupSecretParams, + authCredential: authCredential + ) } - public func createAuthCredentialPresentation(randomness: Randomness, groupSecretParams: GroupSecretParams, authCredential: AuthCredentialWithPni) throws -> AuthCredentialPresentation { + public func createAuthCredentialPresentation( + randomness: Randomness, + groupSecretParams: GroupSecretParams, + authCredential: AuthCredentialWithPni + ) throws -> AuthCredentialPresentation { return try self.serverPublicParams.withNativeHandle { contents in try randomness.withUnsafePointerToBytes { randomness in try groupSecretParams.withUnsafePointerToSerialized { groupSecretParams in try authCredential.withUnsafeBorrowedBuffer { authCredential in try invokeFnReturningVariableLengthSerialized { - signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic($0, contents.const(), randomness, groupSecretParams, authCredential) + signal_server_public_params_create_auth_credential_with_pni_presentation_deterministic( + $0, + contents.const(), + randomness, + groupSecretParams, + authCredential + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/ClientZkGroupCipher.swift b/swift/Sources/LibSignalClient/zkgroup/ClientZkGroupCipher.swift index ce6586022..58614217d 100644 --- a/swift/Sources/LibSignalClient/zkgroup/ClientZkGroupCipher.swift +++ b/swift/Sources/LibSignalClient/zkgroup/ClientZkGroupCipher.swift @@ -50,7 +50,12 @@ public class ClientZkGroupCipher { try profileKeyCiphertext.withUnsafePointerToSerialized { profileKeyCiphertext in try userId.withPointerToFixedWidthBinary { userId in try invokeFnReturningSerialized { - signal_group_secret_params_decrypt_profile_key($0, groupSecretParams, profileKeyCiphertext, userId) + signal_group_secret_params_decrypt_profile_key( + $0, + groupSecretParams, + profileKeyCiphertext, + userId + ) } } } @@ -66,7 +71,13 @@ public class ClientZkGroupCipher { try randomness.withUnsafePointerToBytes { randomness in try plaintext.withUnsafeBorrowedBuffer { plaintext in try invokeFnReturningData { - signal_group_secret_params_encrypt_blob_with_padding_deterministic($0, groupSecretParams, randomness, plaintext, 0) + signal_group_secret_params_encrypt_blob_with_padding_deterministic( + $0, + groupSecretParams, + randomness, + plaintext, + 0 + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/ClientZkProfileOperations.swift b/swift/Sources/LibSignalClient/zkgroup/ClientZkProfileOperations.swift index fdc413df6..62b876063 100644 --- a/swift/Sources/LibSignalClient/zkgroup/ClientZkProfileOperations.swift +++ b/swift/Sources/LibSignalClient/zkgroup/ClientZkProfileOperations.swift @@ -13,17 +13,34 @@ public class ClientZkProfileOperations { self.serverPublicParams = serverPublicParams } - public func createProfileKeyCredentialRequestContext(userId: Aci, profileKey: ProfileKey) throws -> ProfileKeyCredentialRequestContext { - return try self.createProfileKeyCredentialRequestContext(randomness: Randomness.generate(), userId: userId, profileKey: profileKey) + public func createProfileKeyCredentialRequestContext( + userId: Aci, + profileKey: ProfileKey + ) throws -> ProfileKeyCredentialRequestContext { + return try self.createProfileKeyCredentialRequestContext( + randomness: Randomness.generate(), + userId: userId, + profileKey: profileKey + ) } - public func createProfileKeyCredentialRequestContext(randomness: Randomness, userId: Aci, profileKey: ProfileKey) throws -> ProfileKeyCredentialRequestContext { + public func createProfileKeyCredentialRequestContext( + randomness: Randomness, + userId: Aci, + profileKey: ProfileKey + ) throws -> ProfileKeyCredentialRequestContext { return try self.serverPublicParams.withNativeHandle { serverPublicParams in try randomness.withUnsafePointerToBytes { randomness in try userId.withPointerToFixedWidthBinary { userId in try profileKey.withUnsafePointerToSerialized { profileKey in try invokeFnReturningSerialized { - signal_server_public_params_create_profile_key_credential_request_context_deterministic($0, serverPublicParams.const(), randomness, userId, profileKey) + signal_server_public_params_create_profile_key_credential_request_context_deterministic( + $0, + serverPublicParams.const(), + randomness, + userId, + profileKey + ) } } } @@ -40,24 +57,47 @@ public class ClientZkProfileOperations { try profileKeyCredentialRequestContext.withUnsafePointerToSerialized { requestContext in try profileKeyCredentialResponse.withUnsafePointerToSerialized { response in try invokeFnReturningSerialized { - signal_server_public_params_receive_expiring_profile_key_credential($0, serverPublicParams.const(), requestContext, response, UInt64(now.timeIntervalSince1970)) + signal_server_public_params_receive_expiring_profile_key_credential( + $0, + serverPublicParams.const(), + requestContext, + response, + UInt64(now.timeIntervalSince1970) + ) } } } } } - public func createProfileKeyCredentialPresentation(groupSecretParams: GroupSecretParams, profileKeyCredential: ExpiringProfileKeyCredential) throws -> ProfileKeyCredentialPresentation { - return try self.createProfileKeyCredentialPresentation(randomness: Randomness.generate(), groupSecretParams: groupSecretParams, profileKeyCredential: profileKeyCredential) + public func createProfileKeyCredentialPresentation( + groupSecretParams: GroupSecretParams, + profileKeyCredential: ExpiringProfileKeyCredential + ) throws -> ProfileKeyCredentialPresentation { + return try self.createProfileKeyCredentialPresentation( + randomness: Randomness.generate(), + groupSecretParams: groupSecretParams, + profileKeyCredential: profileKeyCredential + ) } - public func createProfileKeyCredentialPresentation(randomness: Randomness, groupSecretParams: GroupSecretParams, profileKeyCredential: ExpiringProfileKeyCredential) throws -> ProfileKeyCredentialPresentation { + public func createProfileKeyCredentialPresentation( + randomness: Randomness, + groupSecretParams: GroupSecretParams, + profileKeyCredential: ExpiringProfileKeyCredential + ) throws -> ProfileKeyCredentialPresentation { return try self.serverPublicParams.withNativeHandle { serverPublicParams in try randomness.withUnsafePointerToBytes { randomness in try groupSecretParams.withUnsafePointerToSerialized { groupSecretParams in try profileKeyCredential.withUnsafePointerToSerialized { profileKeyCredential in try invokeFnReturningVariableLengthSerialized { - signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic($0, serverPublicParams.const(), randomness, groupSecretParams, profileKeyCredential) + signal_server_public_params_create_expiring_profile_key_credential_presentation_deterministic( + $0, + serverPublicParams.const(), + randomness, + groupSecretParams, + profileKeyCredential + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/ClientZkReceiptOperations.swift b/swift/Sources/LibSignalClient/zkgroup/ClientZkReceiptOperations.swift index f760a8862..0d305d331 100644 --- a/swift/Sources/LibSignalClient/zkgroup/ClientZkReceiptOperations.swift +++ b/swift/Sources/LibSignalClient/zkgroup/ClientZkReceiptOperations.swift @@ -13,44 +13,78 @@ public class ClientZkReceiptOperations { self.serverPublicParams = serverPublicParams } - public func createReceiptCredentialRequestContext(receiptSerial: ReceiptSerial) throws -> ReceiptCredentialRequestContext { - return try self.createReceiptCredentialRequestContext(randomness: Randomness.generate(), receiptSerial: receiptSerial) + public func createReceiptCredentialRequestContext( + receiptSerial: ReceiptSerial + ) throws -> ReceiptCredentialRequestContext { + return try self.createReceiptCredentialRequestContext( + randomness: Randomness.generate(), + receiptSerial: receiptSerial + ) } - public func createReceiptCredentialRequestContext(randomness: Randomness, receiptSerial: ReceiptSerial) throws -> ReceiptCredentialRequestContext { + public func createReceiptCredentialRequestContext( + randomness: Randomness, + receiptSerial: ReceiptSerial + ) throws -> ReceiptCredentialRequestContext { return try self.serverPublicParams.withNativeHandle { serverPublicParams in try randomness.withUnsafePointerToBytes { randomness in try receiptSerial.withUnsafePointerToSerialized { receiptSerial in try invokeFnReturningSerialized { - signal_server_public_params_create_receipt_credential_request_context_deterministic($0, serverPublicParams.const(), randomness, receiptSerial) + signal_server_public_params_create_receipt_credential_request_context_deterministic( + $0, + serverPublicParams.const(), + randomness, + receiptSerial + ) } } } } } - public func receiveReceiptCredential(receiptCredentialRequestContext: ReceiptCredentialRequestContext, receiptCredentialResponse: ReceiptCredentialResponse) throws -> ReceiptCredential { + public func receiveReceiptCredential( + receiptCredentialRequestContext: ReceiptCredentialRequestContext, + receiptCredentialResponse: ReceiptCredentialResponse + ) throws -> ReceiptCredential { return try self.serverPublicParams.withNativeHandle { serverPublicParams in try receiptCredentialRequestContext.withUnsafePointerToSerialized { requestContext in try receiptCredentialResponse.withUnsafePointerToSerialized { response in try invokeFnReturningSerialized { - signal_server_public_params_receive_receipt_credential($0, serverPublicParams.const(), requestContext, response) + signal_server_public_params_receive_receipt_credential( + $0, + serverPublicParams.const(), + requestContext, + response + ) } } } } } - public func createReceiptCredentialPresentation(receiptCredential: ReceiptCredential) throws -> ReceiptCredentialPresentation { - return try self.createReceiptCredentialPresentation(randomness: Randomness.generate(), receiptCredential: receiptCredential) + public func createReceiptCredentialPresentation( + receiptCredential: ReceiptCredential + ) throws -> ReceiptCredentialPresentation { + return try self.createReceiptCredentialPresentation( + randomness: Randomness.generate(), + receiptCredential: receiptCredential + ) } - public func createReceiptCredentialPresentation(randomness: Randomness, receiptCredential: ReceiptCredential) throws -> ReceiptCredentialPresentation { + public func createReceiptCredentialPresentation( + randomness: Randomness, + receiptCredential: ReceiptCredential + ) throws -> ReceiptCredentialPresentation { return try self.serverPublicParams.withNativeHandle { serverPublicParams in try randomness.withUnsafePointerToBytes { randomness in try receiptCredential.withUnsafePointerToSerialized { receiptCredential in try invokeFnReturningSerialized { - signal_server_public_params_create_receipt_credential_presentation_deterministic($0, serverPublicParams.const(), randomness, receiptCredential) + signal_server_public_params_create_receipt_credential_presentation_deterministic( + $0, + serverPublicParams.const(), + randomness, + receiptCredential + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredential.swift b/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredential.swift index 113cb71ed..aeae7c728 100644 --- a/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredential.swift +++ b/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredential.swift @@ -11,13 +11,30 @@ public class CreateCallLinkCredential: ByteArray, @unchecked Sendable { try super.init(contents, checkValid: signal_create_call_link_credential_check_valid_contents) } - public func present(roomId: RoomId, userId: Aci, serverParams: GenericServerPublicParams, callLinkParams: CallLinkSecretParams) -> CreateCallLinkCredentialPresentation { + public func present( + roomId: RoomId, + userId: Aci, + serverParams: GenericServerPublicParams, + callLinkParams: CallLinkSecretParams + ) -> CreateCallLinkCredentialPresentation { return failOnError { - self.present(roomId: roomId, userId: userId, serverParams: serverParams, callLinkParams: callLinkParams, randomness: try .generate()) + self.present( + roomId: roomId, + userId: userId, + serverParams: serverParams, + callLinkParams: callLinkParams, + randomness: try .generate() + ) } } - public func present(roomId: RoomId, userId: Aci, serverParams: GenericServerPublicParams, callLinkParams: CallLinkSecretParams, randomness: Randomness) -> CreateCallLinkCredentialPresentation { + public func present( + roomId: RoomId, + userId: Aci, + serverParams: GenericServerPublicParams, + callLinkParams: CallLinkSecretParams, + randomness: Randomness + ) -> CreateCallLinkCredentialPresentation { return failOnError { try withUnsafeBorrowedBuffer { contents in try roomId.withUnsafeBorrowedBuffer { roomId in @@ -26,7 +43,15 @@ public class CreateCallLinkCredential: ByteArray, @unchecked Sendable { try callLinkParams.withUnsafeBorrowedBuffer { callLinkParams in try randomness.withUnsafePointerToBytes { randomness in try invokeFnReturningVariableLengthSerialized { - signal_create_call_link_credential_present_deterministic($0, contents, roomId, userId, serverParams, callLinkParams, randomness) + signal_create_call_link_credential_present_deterministic( + $0, + contents, + roomId, + userId, + serverParams, + callLinkParams, + randomness + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialPresentation.swift b/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialPresentation.swift index 4507bedf8..afe235a04 100644 --- a/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialPresentation.swift +++ b/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialPresentation.swift @@ -11,12 +11,25 @@ public class CreateCallLinkCredentialPresentation: ByteArray, @unchecked Sendabl try super.init(contents, checkValid: signal_create_call_link_credential_presentation_check_valid_contents) } - public func verify(roomId: RoomId, now: Date = Date(), serverParams: GenericServerSecretParams, callLinkParams: CallLinkPublicParams) throws { + public func verify( + roomId: RoomId, + now: Date = Date(), + serverParams: GenericServerSecretParams, + callLinkParams: CallLinkPublicParams + ) throws { try withUnsafeBorrowedBuffer { contents in try roomId.withUnsafeBorrowedBuffer { roomId in try serverParams.withUnsafeBorrowedBuffer { serverParams in try callLinkParams.withUnsafeBorrowedBuffer { callLinkParams in - try checkError(signal_create_call_link_credential_presentation_verify(contents, roomId, UInt64(now.timeIntervalSince1970), serverParams, callLinkParams)) + try checkError( + signal_create_call_link_credential_presentation_verify( + contents, + roomId, + UInt64(now.timeIntervalSince1970), + serverParams, + callLinkParams + ) + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialRequest.swift b/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialRequest.swift index 9dd456220..82db84c6b 100644 --- a/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialRequest.swift +++ b/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialRequest.swift @@ -11,20 +11,36 @@ public class CreateCallLinkCredentialRequest: ByteArray, @unchecked Sendable { try super.init(contents, checkValid: signal_create_call_link_credential_request_check_valid_contents) } - public func issueCredential(userId: Aci, timestamp: Date, params: GenericServerSecretParams) -> CreateCallLinkCredentialResponse { + public func issueCredential( + userId: Aci, + timestamp: Date, + params: GenericServerSecretParams + ) -> CreateCallLinkCredentialResponse { return failOnError { self.issueCredential(userId: userId, timestamp: timestamp, params: params, randomness: try .generate()) } } - public func issueCredential(userId: Aci, timestamp: Date, params: GenericServerSecretParams, randomness: Randomness) -> CreateCallLinkCredentialResponse { + public func issueCredential( + userId: Aci, + timestamp: Date, + params: GenericServerSecretParams, + randomness: Randomness + ) -> CreateCallLinkCredentialResponse { return failOnError { try withUnsafeBorrowedBuffer { contents in try userId.withPointerToFixedWidthBinary { userId in try params.withUnsafeBorrowedBuffer { params in try randomness.withUnsafePointerToBytes { randomness in try invokeFnReturningVariableLengthSerialized { - signal_create_call_link_credential_request_issue_deterministic($0, contents, userId, UInt64(timestamp.timeIntervalSince1970), params, randomness) + signal_create_call_link_credential_request_issue_deterministic( + $0, + contents, + userId, + UInt64(timestamp.timeIntervalSince1970), + params, + randomness + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialRequestContext.swift b/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialRequestContext.swift index f5664797a..5a6f802f4 100644 --- a/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialRequestContext.swift +++ b/swift/Sources/LibSignalClient/zkgroup/CreateCallLinkCredentialRequestContext.swift @@ -39,13 +39,23 @@ public class CreateCallLinkCredentialRequestContext: ByteArray, @unchecked Senda } } - public func receive(_ response: CreateCallLinkCredentialResponse, userId: Aci, params: GenericServerPublicParams) throws -> CreateCallLinkCredential { + public func receive( + _ response: CreateCallLinkCredentialResponse, + userId: Aci, + params: GenericServerPublicParams + ) throws -> CreateCallLinkCredential { return try withUnsafeBorrowedBuffer { contents in try response.withUnsafeBorrowedBuffer { response in try userId.withPointerToFixedWidthBinary { userId in try params.withUnsafeBorrowedBuffer { params in try invokeFnReturningVariableLengthSerialized { - signal_create_call_link_credential_request_context_receive_response($0, contents, response, userId, params) + signal_create_call_link_credential_request_context_receive_response( + $0, + contents, + response, + userId, + params + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/GroupSendDerivedKeyPair.swift b/swift/Sources/LibSignalClient/zkgroup/GroupSendDerivedKeyPair.swift index 96cdfafb3..e6a6141ab 100644 --- a/swift/Sources/LibSignalClient/zkgroup/GroupSendDerivedKeyPair.swift +++ b/swift/Sources/LibSignalClient/zkgroup/GroupSendDerivedKeyPair.swift @@ -28,7 +28,11 @@ public class GroupSendDerivedKeyPair: ByteArray, @unchecked Sendable { return failOnError { try params.withNativeHandle { params in try invokeFnReturningVariableLengthSerialized { - signal_group_send_derived_key_pair_for_expiration($0, UInt64(expiration.timeIntervalSince1970), params.const()) + signal_group_send_derived_key_pair_for_expiration( + $0, + UInt64(expiration.timeIntervalSince1970), + params.const() + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/GroupSendEndorsement.swift b/swift/Sources/LibSignalClient/zkgroup/GroupSendEndorsement.swift index c02569ba1..765545c88 100644 --- a/swift/Sources/LibSignalClient/zkgroup/GroupSendEndorsement.swift +++ b/swift/Sources/LibSignalClient/zkgroup/GroupSendEndorsement.swift @@ -72,7 +72,10 @@ public class GroupSendEndorsement: ByteArray, @unchecked Sendable { return slices.withUnsafeBufferPointer { slices in failOnError { try invokeFnReturningVariableLengthSerialized { - signal_group_send_endorsement_combine($0, SignalBorrowedSliceOfBuffers(base: slices.baseAddress, length: slices.count)) + signal_group_send_endorsement_combine( + $0, + SignalBorrowedSliceOfBuffers(base: slices.baseAddress, length: slices.count) + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/GroupSendEndorsementsResponse.swift b/swift/Sources/LibSignalClient/zkgroup/GroupSendEndorsementsResponse.swift index 77d7c676d..1d77cac30 100644 --- a/swift/Sources/LibSignalClient/zkgroup/GroupSendEndorsementsResponse.swift +++ b/swift/Sources/LibSignalClient/zkgroup/GroupSendEndorsementsResponse.swift @@ -45,7 +45,12 @@ public class GroupSendEndorsementsResponse: ByteArray, @unchecked Sendable { try keyPair.withUnsafeBorrowedBuffer { keyPair in try randomness.withUnsafePointerToBytes { randomness in try invokeFnReturningVariableLengthSerialized { - signal_group_send_endorsements_response_issue_deterministic($0, concatenated, keyPair, randomness) + signal_group_send_endorsements_response_issue_deterministic( + $0, + concatenated, + keyPair, + randomness + ) } } } @@ -99,7 +104,15 @@ public class GroupSendEndorsementsResponse: ByteArray, @unchecked Sendable { try groupParams.withUnsafePointerToSerialized { groupParams in try serverParams.withNativeHandle { serverParams in try invokeFnReturningBytestringArray { - signal_group_send_endorsements_response_receive_and_combine_with_service_ids($0, response, groupMembers, localUser, UInt64(now.timeIntervalSince1970), groupParams, serverParams.const()) + signal_group_send_endorsements_response_receive_and_combine_with_service_ids( + $0, + response, + groupMembers, + localUser, + UInt64(now.timeIntervalSince1970), + groupParams, + serverParams.const() + ) } } } @@ -137,7 +150,14 @@ public class GroupSendEndorsementsResponse: ByteArray, @unchecked Sendable { try localUser.withUnsafeBorrowedBuffer { localUser in try serverParams.withNativeHandle { serverParams in try invokeFnReturningBytestringArray { - signal_group_send_endorsements_response_receive_and_combine_with_ciphertexts($0, response, groupMembers, localUser, UInt64(now.timeIntervalSince1970), serverParams.const()) + signal_group_send_endorsements_response_receive_and_combine_with_ciphertexts( + $0, + response, + groupMembers, + localUser, + UInt64(now.timeIntervalSince1970), + serverParams.const() + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/Randomness.swift b/swift/Sources/LibSignalClient/zkgroup/Randomness.swift index 6810f92e1..54d20ce9f 100644 --- a/swift/Sources/LibSignalClient/zkgroup/Randomness.swift +++ b/swift/Sources/LibSignalClient/zkgroup/Randomness.swift @@ -13,14 +13,18 @@ public struct Randomness: Sendable { } static func generate() throws -> Randomness { - var bytes: SignalRandomnessBytes = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + var bytes: SignalRandomnessBytes = ( + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ) try withUnsafeMutableBytes(of: &bytes) { try fillRandom($0) } return Randomness(bytes) } - func withUnsafePointerToBytes(_ callback: (UnsafePointer) throws -> Result) rethrows -> Result { + func withUnsafePointerToBytes( + _ callback: (UnsafePointer) throws -> Result + ) rethrows -> Result { try withUnsafePointer(to: self.bytes, callback) } } diff --git a/swift/Sources/LibSignalClient/zkgroup/ServerPublicParams.swift b/swift/Sources/LibSignalClient/zkgroup/ServerPublicParams.swift index 05c3450c4..f490046c4 100644 --- a/swift/Sources/LibSignalClient/zkgroup/ServerPublicParams.swift +++ b/swift/Sources/LibSignalClient/zkgroup/ServerPublicParams.swift @@ -38,7 +38,9 @@ public class ServerPublicParams: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_server_public_params_destroy(handle.pointer) } } diff --git a/swift/Sources/LibSignalClient/zkgroup/ServerSecretParams.swift b/swift/Sources/LibSignalClient/zkgroup/ServerSecretParams.swift index 5d6024aec..25aca5717 100644 --- a/swift/Sources/LibSignalClient/zkgroup/ServerSecretParams.swift +++ b/swift/Sources/LibSignalClient/zkgroup/ServerSecretParams.swift @@ -65,7 +65,9 @@ public class ServerSecretParams: NativeHandleOwner) -> SignalFfiErrorRef? { + override internal class func destroyNativeHandle( + _ handle: NonNull + ) -> SignalFfiErrorRef? { signal_server_secret_params_destroy(handle.pointer) } } diff --git a/swift/Sources/LibSignalClient/zkgroup/ServerZkAuthOperations.swift b/swift/Sources/LibSignalClient/zkgroup/ServerZkAuthOperations.swift index 21cc3d852..d66fc2434 100644 --- a/swift/Sources/LibSignalClient/zkgroup/ServerZkAuthOperations.swift +++ b/swift/Sources/LibSignalClient/zkgroup/ServerZkAuthOperations.swift @@ -13,17 +13,38 @@ public class ServerZkAuthOperations { self.serverSecretParams = serverSecretParams } - public func issueAuthCredentialWithPniZkc(aci: Aci, pni: Pni, redemptionTime: UInt64) throws -> AuthCredentialWithPniResponse { - return try self.issueAuthCredentialWithPniZkc(randomness: Randomness.generate(), aci: aci, pni: pni, redemptionTime: redemptionTime) + public func issueAuthCredentialWithPniZkc( + aci: Aci, + pni: Pni, + redemptionTime: UInt64 + ) throws -> AuthCredentialWithPniResponse { + return try self.issueAuthCredentialWithPniZkc( + randomness: Randomness.generate(), + aci: aci, + pni: pni, + redemptionTime: redemptionTime + ) } - public func issueAuthCredentialWithPniZkc(randomness: Randomness, aci: Aci, pni: Pni, redemptionTime: UInt64) throws -> AuthCredentialWithPniResponse { + public func issueAuthCredentialWithPniZkc( + randomness: Randomness, + aci: Aci, + pni: Pni, + redemptionTime: UInt64 + ) throws -> AuthCredentialWithPniResponse { return try self.serverSecretParams.withNativeHandle { serverSecretParams in try randomness.withUnsafePointerToBytes { randomness in try aci.withPointerToFixedWidthBinary { aci in try pni.withPointerToFixedWidthBinary { pni in try invokeFnReturningVariableLengthSerialized { - signal_server_secret_params_issue_auth_credential_with_pni_zkc_deterministic($0, serverSecretParams.const(), randomness, aci, pni, redemptionTime) + signal_server_secret_params_issue_auth_credential_with_pni_zkc_deterministic( + $0, + serverSecretParams.const(), + randomness, + aci, + pni, + redemptionTime + ) } } } @@ -31,11 +52,22 @@ public class ServerZkAuthOperations { } } - public func verifyAuthCredentialPresentation(groupPublicParams: GroupPublicParams, authCredentialPresentation: AuthCredentialPresentation, now: Date = Date()) throws { + public func verifyAuthCredentialPresentation( + groupPublicParams: GroupPublicParams, + authCredentialPresentation: AuthCredentialPresentation, + now: Date = Date() + ) throws { try self.serverSecretParams.withNativeHandle { serverSecretParams in try groupPublicParams.withUnsafePointerToSerialized { groupPublicParams in try authCredentialPresentation.withUnsafeBorrowedBuffer { authCredentialPresentation in - try checkError(signal_server_secret_params_verify_auth_credential_presentation(serverSecretParams.const(), groupPublicParams, authCredentialPresentation, UInt64(now.timeIntervalSince1970))) + try checkError( + signal_server_secret_params_verify_auth_credential_presentation( + serverSecretParams.const(), + groupPublicParams, + authCredentialPresentation, + UInt64(now.timeIntervalSince1970) + ) + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/ServerZkProfileOperations.swift b/swift/Sources/LibSignalClient/zkgroup/ServerZkProfileOperations.swift index 098b30859..352f5041e 100644 --- a/swift/Sources/LibSignalClient/zkgroup/ServerZkProfileOperations.swift +++ b/swift/Sources/LibSignalClient/zkgroup/ServerZkProfileOperations.swift @@ -13,18 +13,43 @@ public class ServerZkProfileOperations { self.serverSecretParams = serverSecretParams } - public func issueExpiringProfileKeyCredential(profileKeyCredentialRequest: ProfileKeyCredentialRequest, userId: Aci, profileKeyCommitment: ProfileKeyCommitment, expiration: UInt64) throws -> ExpiringProfileKeyCredentialResponse { - return try self.issueExpiringProfileKeyCredential(randomness: Randomness.generate(), profileKeyCredentialRequest: profileKeyCredentialRequest, userId: userId, profileKeyCommitment: profileKeyCommitment, expiration: expiration) + public func issueExpiringProfileKeyCredential( + profileKeyCredentialRequest: ProfileKeyCredentialRequest, + userId: Aci, + profileKeyCommitment: ProfileKeyCommitment, + expiration: UInt64 + ) throws -> ExpiringProfileKeyCredentialResponse { + return try self.issueExpiringProfileKeyCredential( + randomness: Randomness.generate(), + profileKeyCredentialRequest: profileKeyCredentialRequest, + userId: userId, + profileKeyCommitment: profileKeyCommitment, + expiration: expiration + ) } - public func issueExpiringProfileKeyCredential(randomness: Randomness, profileKeyCredentialRequest: ProfileKeyCredentialRequest, userId: Aci, profileKeyCommitment: ProfileKeyCommitment, expiration: UInt64) throws -> ExpiringProfileKeyCredentialResponse { + public func issueExpiringProfileKeyCredential( + randomness: Randomness, + profileKeyCredentialRequest: ProfileKeyCredentialRequest, + userId: Aci, + profileKeyCommitment: ProfileKeyCommitment, + expiration: UInt64 + ) throws -> ExpiringProfileKeyCredentialResponse { return try self.serverSecretParams.withNativeHandle { serverSecretParams in try randomness.withUnsafePointerToBytes { randomness in try profileKeyCredentialRequest.withUnsafePointerToSerialized { request in try userId.withPointerToFixedWidthBinary { userId in try profileKeyCommitment.withUnsafePointerToSerialized { commitment in try invokeFnReturningSerialized { - signal_server_secret_params_issue_expiring_profile_key_credential_deterministic($0, serverSecretParams.const(), randomness, request, userId, commitment, expiration) + signal_server_secret_params_issue_expiring_profile_key_credential_deterministic( + $0, + serverSecretParams.const(), + randomness, + request, + userId, + commitment, + expiration + ) } } } @@ -41,7 +66,14 @@ public class ServerZkProfileOperations { try self.serverSecretParams.withNativeHandle { serverSecretParams in try groupPublicParams.withUnsafePointerToSerialized { groupPublicParams in try profileKeyCredentialPresentation.withUnsafeBorrowedBuffer { presentation in - try checkError(signal_server_secret_params_verify_profile_key_credential_presentation(serverSecretParams.const(), groupPublicParams, presentation, UInt64(now.timeIntervalSince1970))) + try checkError( + signal_server_secret_params_verify_profile_key_credential_presentation( + serverSecretParams.const(), + groupPublicParams, + presentation, + UInt64(now.timeIntervalSince1970) + ) + ) } } } diff --git a/swift/Sources/LibSignalClient/zkgroup/ServerZkReceiptOperations.swift b/swift/Sources/LibSignalClient/zkgroup/ServerZkReceiptOperations.swift index 353f422b0..75faa37c4 100644 --- a/swift/Sources/LibSignalClient/zkgroup/ServerZkReceiptOperations.swift +++ b/swift/Sources/LibSignalClient/zkgroup/ServerZkReceiptOperations.swift @@ -13,26 +13,53 @@ public class ServerZkReceiptOperations { self.serverSecretParams = serverSecretParams } - public func issueReceiptCredential(receiptCredentialRequest: ReceiptCredentialRequest, receiptExpirationTime: UInt64, receiptLevel: UInt64) throws -> ReceiptCredentialResponse { - return try self.issueReceiptCredential(randomness: Randomness.generate(), receiptCredentialRequest: receiptCredentialRequest, receiptExpirationTime: receiptExpirationTime, receiptLevel: receiptLevel) + public func issueReceiptCredential( + receiptCredentialRequest: ReceiptCredentialRequest, + receiptExpirationTime: UInt64, + receiptLevel: UInt64 + ) throws -> ReceiptCredentialResponse { + return try self.issueReceiptCredential( + randomness: Randomness.generate(), + receiptCredentialRequest: receiptCredentialRequest, + receiptExpirationTime: receiptExpirationTime, + receiptLevel: receiptLevel + ) } - public func issueReceiptCredential(randomness: Randomness, receiptCredentialRequest: ReceiptCredentialRequest, receiptExpirationTime: UInt64, receiptLevel: UInt64) throws -> ReceiptCredentialResponse { + public func issueReceiptCredential( + randomness: Randomness, + receiptCredentialRequest: ReceiptCredentialRequest, + receiptExpirationTime: UInt64, + receiptLevel: UInt64 + ) throws -> ReceiptCredentialResponse { return try self.serverSecretParams.withNativeHandle { serverSecretParams in try randomness.withUnsafePointerToBytes { randomness in try receiptCredentialRequest.withUnsafePointerToSerialized { receiptCredentialRequest in try invokeFnReturningSerialized { - signal_server_secret_params_issue_receipt_credential_deterministic($0, serverSecretParams.const(), randomness, receiptCredentialRequest, receiptExpirationTime, receiptLevel) + signal_server_secret_params_issue_receipt_credential_deterministic( + $0, + serverSecretParams.const(), + randomness, + receiptCredentialRequest, + receiptExpirationTime, + receiptLevel + ) } } } } } - public func verifyReceiptCredentialPresentation(receiptCredentialPresentation: ReceiptCredentialPresentation) throws { + public func verifyReceiptCredentialPresentation(receiptCredentialPresentation: ReceiptCredentialPresentation) throws + { try self.serverSecretParams.withNativeHandle { serverSecretParams in try receiptCredentialPresentation.withUnsafePointerToSerialized { receiptCredentialPresentation in - try checkError(signal_server_secret_params_verify_receipt_credential_presentation(serverSecretParams.const(), receiptCredentialPresentation)) + try checkError( + signal_server_secret_params_verify_receipt_credential_presentation( + serverSecretParams.const(), + receiptCredentialPresentation + ) + ) } } } diff --git a/swift/Tests/LibSignalClientTests/AccountEntropyTests.swift b/swift/Tests/LibSignalClientTests/AccountEntropyTests.swift index c7b00de66..3eb661112 100644 --- a/swift/Tests/LibSignalClientTests/AccountEntropyTests.swift +++ b/swift/Tests/LibSignalClientTests/AccountEntropyTests.swift @@ -17,7 +17,10 @@ class AccountEntropyTests: TestCaseBase { for _ in 0.., @unchecked Sendable { +private final class CancelCounter: NativeHandleOwner, @unchecked + Sendable +{ public convenience init(initialValue: UInt8 = 0) { var out = SignalMutPointerTestingFutureCancellationCounter() failOnError { @@ -96,12 +98,19 @@ private final class CancelCounter: NativeHandleOwner) -> SignalFfiErrorRef? { + override static func destroyNativeHandle( + _ nativeHandle: NonNull + ) -> SignalFfiErrorRef? { signal_testing_future_cancellation_counter_destroy(nativeHandle.pointer) } } @@ -109,7 +118,11 @@ private final class CancelCounter: NativeHandleOwner Void) { + func chatConnection( + _: AuthenticatedChatConnection, + didReceiveIncomingMessage envelope: Data, + serverDeliveryTimestamp: UInt64, + sendAck: () throws -> Void + ) { // This assumes a little-endian platform. XCTAssertEqual(envelope, withUnsafeBytes(of: serverDeliveryTimestamp) { Data($0) }) switch serverDeliveryTimestamp { @@ -263,13 +290,17 @@ final class ChatConnectionTests: TestCaseBase { // 3: {1000i64} // 5: {"x-signal-timestamp:1000"} // 4: 1 - fakeRemote.injectServerRequest(base64: "CgNQVVQSDy9hcGkvdjEvbWVzc2FnZRoI6AMAAAAAAAAqF3gtc2lnbmFsLXRpbWVzdGFtcDoxMDAwIAE=") + fakeRemote.injectServerRequest( + base64: "CgNQVVQSDy9hcGkvdjEvbWVzc2FnZRoI6AMAAAAAAAAqF3gtc2lnbmFsLXRpbWVzdGFtcDoxMDAwIAE=" + ) // 1: {"PUT"} // 2: {"/api/v1/message"} // 3: {2000i64} // 5: {"x-signal-timestamp:2000"} // 4: 2 - fakeRemote.injectServerRequest(base64: "CgNQVVQSDy9hcGkvdjEvbWVzc2FnZRoI0AcAAAAAAAAqF3gtc2lnbmFsLXRpbWVzdGFtcDoyMDAwIAI=") + fakeRemote.injectServerRequest( + base64: "CgNQVVQSDy9hcGkvdjEvbWVzc2FnZRoI0AcAAAAAAAAqF3gtc2lnbmFsLXRpbWVzdGFtcDoyMDAwIAI=" + ) // Sending an invalid message should not affect the listener at all, nor should it stop future requests. // 1: {"PUT"} @@ -289,15 +320,29 @@ final class ChatConnectionTests: TestCaseBase { func testAuthenticatedSending() async throws { class NoOpListener: ChatConnectionListener { - func chatConnection(_: AuthenticatedChatConnection, didReceiveIncomingMessage envelope: Data, serverDeliveryTimestamp: UInt64, sendAck: () throws -> Void) {} + func chatConnection( + _: AuthenticatedChatConnection, + didReceiveIncomingMessage envelope: Data, + serverDeliveryTimestamp: UInt64, + sendAck: () throws -> Void + ) {} func connectionWasInterrupted(_: AuthenticatedChatConnection, error: Error?) {} } let tokioAsyncContext = TokioAsyncContext() - let (chat, fakeRemote) = AuthenticatedChatConnection.fakeConnect(tokioAsyncContext: tokioAsyncContext, listener: NoOpListener()) + let (chat, fakeRemote) = AuthenticatedChatConnection.fakeConnect( + tokioAsyncContext: tokioAsyncContext, + listener: NoOpListener() + ) defer { withExtendedLifetime(chat) {} } - let request = ChatRequest(method: "PUT", pathAndQuery: "/some/path", headers: ["purpose": "test request"], body: Data([1, 1, 2, 3]), timeout: TimeInterval(5)) + let request = ChatRequest( + method: "PUT", + pathAndQuery: "/some/path", + headers: ["purpose": "test request"], + body: Data([1, 1, 2, 3]), + timeout: TimeInterval(5) + ) async let responseFuture = chat.send(request) let (requestFromServer, id) = try await fakeRemote.getNextIncomingRequest() @@ -326,10 +371,19 @@ final class ChatConnectionTests: TestCaseBase { func connectionWasInterrupted(_: UnauthenticatedChatConnection, error: Error?) {} } let tokioAsyncContext = TokioAsyncContext() - let (chat, fakeRemote) = UnauthenticatedChatConnection.fakeConnect(tokioAsyncContext: tokioAsyncContext, listener: NoOpListener()) + let (chat, fakeRemote) = UnauthenticatedChatConnection.fakeConnect( + tokioAsyncContext: tokioAsyncContext, + listener: NoOpListener() + ) defer { withExtendedLifetime(chat) {} } - let request = ChatRequest(method: "PUT", pathAndQuery: "/some/path", headers: ["purpose": "test request"], body: Data([1, 1, 2, 3]), timeout: TimeInterval(5)) + let request = ChatRequest( + method: "PUT", + pathAndQuery: "/some/path", + headers: ["purpose": "test request"], + body: Data([1, 1, 2, 3]), + timeout: TimeInterval(5) + ) async let responseFuture = chat.send(request) let (requestFromServer, id) = try await fakeRemote.getNextIncomingRequest() @@ -352,7 +406,7 @@ final class ChatConnectionTests: TestCaseBase { XCTAssertEqual(responseFromServer.headers, ["purpose": "test response"]) XCTAssertEqual(responseFromServer.body, Data([5])) } -#endif + #endif func testListenerCleanup() async throws { // Use the presence of the environment setting to know whether we should make network requests in our tests. diff --git a/swift/Tests/LibSignalClientTests/ClonableHandleOwnerTests.swift b/swift/Tests/LibSignalClientTests/ClonableHandleOwnerTests.swift index 682b3a83d..e39fc86e5 100644 --- a/swift/Tests/LibSignalClientTests/ClonableHandleOwnerTests.swift +++ b/swift/Tests/LibSignalClientTests/ClonableHandleOwnerTests.swift @@ -3,9 +3,10 @@ // SPDX-License-Identifier: AGPL-3.0-only // -@testable import LibSignalClient import XCTest +@testable import LibSignalClient + private struct FakeHandle { // We're using the tuple to guarantee in-memory layout for this test. // It's a little sketchy but it keeps the test from getting more complicated. @@ -14,7 +15,10 @@ private struct FakeHandle { } private class MockClonableHandleOwner: ClonableHandleOwner { - override class func cloneNativeHandle(_ newHandle: inout OpaquePointer?, currentHandle: OpaquePointer?) -> SignalFfiErrorRef? { + override class func cloneNativeHandle( + _ newHandle: inout OpaquePointer?, + currentHandle: OpaquePointer? + ) -> SignalFfiErrorRef? { XCTAssertFalse(UnsafePointer(currentHandle!).pointee) newHandle = OpaquePointer(UnsafePointer(currentHandle!) + 1) return nil diff --git a/swift/Tests/LibSignalClientTests/CryptoTests.swift b/swift/Tests/LibSignalClientTests/CryptoTests.swift index fec6a840f..36f623e37 100644 --- a/swift/Tests/LibSignalClientTests/CryptoTests.swift +++ b/swift/Tests/LibSignalClientTests/CryptoTests.swift @@ -3,9 +3,10 @@ // SPDX-License-Identifier: AGPL-3.0-only // -@testable import LibSignalClient import XCTest +@testable import LibSignalClient + class CryptoTests: TestCaseBase { func generateAesKey() -> [UInt8] { var key = Array(repeating: UInt8(0), count: 32) @@ -17,7 +18,10 @@ class CryptoTests: TestCaseBase { func testAesGcmSiv() { let ptext = Data([0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) - let expected_ctext = Data([0x1D, 0xE2, 0x29, 0x67, 0x23, 0x7A, 0x81, 0x32, 0x91, 0x21, 0x3F, 0x26, 0x7E, 0x3B, 0x45, 0x2F, 0x02, 0xD0, 0x1A, 0xE3, 0x3E, 0x4E, 0xC8, 0x54]) + let expected_ctext = Data([ + 0x1D, 0xE2, 0x29, 0x67, 0x23, 0x7A, 0x81, 0x32, 0x91, 0x21, 0x3F, 0x26, 0x7E, 0x3B, 0x45, 0x2F, 0x02, 0xD0, + 0x1A, 0xE3, 0x3E, 0x4E, 0xC8, 0x54, + ]) let ad: [UInt8] = [0x01] let key: [UInt8] = [ 0x01, @@ -74,7 +78,10 @@ class CryptoTests: TestCaseBase { let key = self.generateAesKey() let encryptedParts = try! Aes256GcmEncryptedData.encrypt(plainTextData, key: key) let encryptedData = encryptedParts.concatenate() - XCTAssertEqual(Aes256GcmEncryptedData.nonceLength + plainTextData.count + Aes256GcmEncryptedData.authenticationTagLength, encryptedData.count) + XCTAssertEqual( + Aes256GcmEncryptedData.nonceLength + plainTextData.count + Aes256GcmEncryptedData.authenticationTagLength, + encryptedData.count + ) let splitParts = try! Aes256GcmEncryptedData(concatenated: encryptedData) XCTAssertEqual(encryptedParts.nonce, splitParts.nonce) @@ -96,12 +103,30 @@ class CryptoTests: TestCaseBase { } func testAesGcmKat() { - let key: [UInt8] = [0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08] - let plaintext = Data([0xD9, 0x31, 0x32, 0x25, 0xF8, 0x84, 0x06, 0xE5, 0xA5, 0x59, 0x09, 0xC5, 0xAF, 0xF5, 0x26, 0x9A, 0x86, 0xA7, 0xA9, 0x53, 0x15, 0x34, 0xF7, 0xDA, 0x2E, 0x4C, 0x30, 0x3D, 0x8A, 0x31, 0x8A, 0x72, 0x1C, 0x3C, 0x0C, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2F, 0xCF, 0x0E, 0x24, 0x49, 0xA6, 0xB5, 0x25, 0xB1, 0x6A, 0xED, 0xF5, 0xAA, 0x0D, 0xE6, 0x57, 0xBA, 0x63, 0x7B, 0x39]) - let expectedCiphertext = Data([0x52, 0x2D, 0xC1, 0xF0, 0x99, 0x56, 0x7D, 0x07, 0xF4, 0x7F, 0x37, 0xA3, 0x2A, 0x84, 0x42, 0x7D, 0x64, 0x3A, 0x8C, 0xDC, 0xBF, 0xE5, 0xC0, 0xC9, 0x75, 0x98, 0xA2, 0xBD, 0x25, 0x55, 0xD1, 0xAA, 0x8C, 0xB0, 0x8E, 0x48, 0x59, 0x0D, 0xBB, 0x3D, 0xA7, 0xB0, 0x8B, 0x10, 0x56, 0x82, 0x88, 0x38, 0xC5, 0xF6, 0x1E, 0x63, 0x93, 0xBA, 0x7A, 0x0A, 0xBC, 0xC9, 0xF6, 0x62]) - let expectedTag = Data([0x76, 0xFC, 0x6E, 0xCE, 0x0F, 0x4E, 0x17, 0x68, 0xCD, 0xDF, 0x88, 0x53, 0xBB, 0x2D, 0x55, 0x1B]) + let key: [UInt8] = [ + 0xFE, 0xFF, 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, 0xFE, 0xFF, + 0xE9, 0x92, 0x86, 0x65, 0x73, 0x1C, 0x6D, 0x6A, 0x8F, 0x94, 0x67, 0x30, 0x83, 0x08, + ] + let plaintext = Data([ + 0xD9, 0x31, 0x32, 0x25, 0xF8, 0x84, 0x06, 0xE5, 0xA5, 0x59, 0x09, 0xC5, 0xAF, 0xF5, 0x26, 0x9A, 0x86, 0xA7, + 0xA9, 0x53, 0x15, 0x34, 0xF7, 0xDA, 0x2E, 0x4C, 0x30, 0x3D, 0x8A, 0x31, 0x8A, 0x72, 0x1C, 0x3C, 0x0C, 0x95, + 0x95, 0x68, 0x09, 0x53, 0x2F, 0xCF, 0x0E, 0x24, 0x49, 0xA6, 0xB5, 0x25, 0xB1, 0x6A, 0xED, 0xF5, 0xAA, 0x0D, + 0xE6, 0x57, 0xBA, 0x63, 0x7B, 0x39, + ]) + let expectedCiphertext = Data([ + 0x52, 0x2D, 0xC1, 0xF0, 0x99, 0x56, 0x7D, 0x07, 0xF4, 0x7F, 0x37, 0xA3, 0x2A, 0x84, 0x42, 0x7D, 0x64, 0x3A, + 0x8C, 0xDC, 0xBF, 0xE5, 0xC0, 0xC9, 0x75, 0x98, 0xA2, 0xBD, 0x25, 0x55, 0xD1, 0xAA, 0x8C, 0xB0, 0x8E, 0x48, + 0x59, 0x0D, 0xBB, 0x3D, 0xA7, 0xB0, 0x8B, 0x10, 0x56, 0x82, 0x88, 0x38, 0xC5, 0xF6, 0x1E, 0x63, 0x93, 0xBA, + 0x7A, 0x0A, 0xBC, 0xC9, 0xF6, 0x62, + ]) + let expectedTag = Data([ + 0x76, 0xFC, 0x6E, 0xCE, 0x0F, 0x4E, 0x17, 0x68, 0xCD, 0xDF, 0x88, 0x53, 0xBB, 0x2D, 0x55, 0x1B, + ]) let nonce: [UInt8] = [0xCA, 0xFE, 0xBA, 0xBE, 0xFA, 0xCE, 0xDB, 0xAD, 0xDE, 0xCA, 0xF8, 0x88] - let ad: [UInt8] = [0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF, 0xAB, 0xAD, 0xDA, 0xD2] + let ad: [UInt8] = [ + 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED, 0xFA, 0xCE, 0xDE, 0xAD, 0xBE, 0xEF, 0xAB, 0xAD, + 0xDA, 0xD2, + ] let gcmEnc = try! Aes256GcmEncryption(key: key, nonce: nonce, associatedData: ad) var ciphertext = plaintext @@ -148,9 +173,120 @@ class CryptoTests: TestCaseBase { } func testAesCtrKat() { - let key: [UInt8] = [0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4] - let plaintext = Data([0xFD, 0x4C, 0x14, 0x72, 0x9F, 0x50, 0x04, 0xBA, 0x49, 0xD8, 0x32, 0xAD, 0x7B, 0xE8, 0x7C, 0x18, 0xF4, 0xFA, 0xFB, 0x58, 0x96, 0x2B, 0x9A, 0x43, 0xC3, 0xBE, 0x41, 0x71, 0x3D, 0xED, 0x93, 0xDB, 0xF8, 0x54, 0xAC, 0x4C, 0xA2, 0x62, 0x85, 0xB7, 0xF7, 0x6E, 0x04, 0xB8, 0xF8, 0xD4, 0xE7, 0xD9, 0xF7, 0x54, 0x8F, 0x9B, 0x46, 0x5C, 0x8F, 0x71, 0x3C, 0x10, 0x6E, 0x9F, 0x63, 0xF5, 0x43, 0x05, 0x33, 0x1A, 0x49, 0x83, 0xA2, 0xF4, 0xB7, 0x18, 0xDE, 0x29, 0xFA, 0x79, 0x4D, 0xA1, 0x2E, 0xEE, 0x80, 0x86, 0x42, 0xFA, 0xEF, 0xF8, 0x27, 0x1A, 0x0E, 0xA2, 0x8E, 0x3C, 0xC8, 0x0E, 0xEB, 0x65, 0xA8, 0xEB, 0x61, 0xF6, 0x9D, 0x8B, 0xA9, 0x7F, 0x6B, 0xF9, 0x05, 0x44, 0x53, 0xF5, 0x5E, 0xFB, 0x8F, 0x94, 0x22, 0x08, 0x1F, 0x16, 0x20, 0xFE, 0x44, 0xAC, 0xF9, 0x9E, 0x81, 0x12, 0x2F, 0x73, 0xD3, 0xF9, 0x21, 0xD5, 0xE3, 0x39, 0x16, 0x54, 0xE9, 0x94, 0x79, 0x04, 0x98, 0x43, 0x75, 0xB7, 0x25, 0xFD, 0xFB, 0xA8, 0x95, 0xC5, 0xCD, 0xE3, 0xD2, 0x25, 0xD7, 0xBE, 0x3A, 0x21, 0x3C, 0x39, 0x65, 0x17, 0x8A, 0x7D, 0xC1, 0xE3, 0xB5, 0x52, 0xEC, 0x7B, 0x2F, 0xFD, 0x9C, 0x77, 0xEB, 0xCC, 0x24, 0x3C, 0x45, 0x00, 0xDF, 0xDF, 0xBE, 0x3B, 0x75, 0x54, 0xAA, 0x42, 0x7C, 0x01, 0x30, 0x5B, 0xEC, 0x48, 0xD7, 0x1A, 0xF2, 0x7C, 0x59, 0x11, 0xD1, 0xE6, 0x49, 0xC6, 0x20, 0xD2, 0x2C, 0xF5, 0xF3, 0xA5, 0xAE, 0xB9, 0x46, 0x86, 0x51, 0xDA, 0x79, 0x6F, 0x36, 0x95, 0x22, 0xFA, 0xF9, 0x1E, 0xFA, 0xBF, 0x0F, 0xEB, 0xD3, 0x3F, 0xCA, 0x41, 0xC9, 0x53, 0x46, 0x06, 0xA4, 0xEA, 0x01, 0x99, 0xB9, 0x04, 0xB2, 0x43, 0xBA, 0x9C, 0xB8, 0xF3, 0x7A, 0x79, 0x2D, 0xF0, 0x2E, 0xFA, 0xB8, 0xF0, 0xE2, 0xE0, 0xCF, 0x1D, 0x57, 0x9D, 0xAB, 0xA0, 0x42, 0xCF, 0xE4, 0xC9, 0x43, 0x0A, 0xD4, 0xED, 0xA7, 0x86, 0x05, 0x2F, 0xCF, 0x15, 0xE7, 0xAC, 0xFA, 0x27, 0x36, 0xAA, 0xB4, 0x59, 0x0F, 0x73, 0x67, 0x5F, 0xA1, 0x80, 0x5F, 0xE2, 0x38, 0x92, 0xC6, 0x3E, 0x0C, 0xD0, 0x1D, 0x00, 0x69, 0x35, 0xA6, 0xE3, 0xF8, 0xE1, 0x05, 0xA7, 0x54, 0x80, 0x3D, 0x00, 0xD9, 0x85, 0x7E, 0x49, 0x63, 0x6A, 0xB0, 0x34, 0x16, 0x41, 0x56, 0x85, 0x6D, 0x58, 0xA2, 0x44, 0xEA, 0xD4, 0x75, 0x30, 0x0D, 0x93, 0xB3, 0x1E, 0x44, 0xB5, 0xBE, 0x3B, 0xBF, 0x69, 0x94, 0xED, 0xB8, 0x95, 0x80, 0x4B, 0x4F, 0x1B, 0xAD, 0x43, 0xEC, 0xFE, 0x08, 0xB4, 0xE1, 0x30, 0x14, 0x8B, 0x66, 0x9F, 0xE6, 0x20, 0xE4, 0xF7, 0x30, 0x34, 0xFC, 0x3E, 0x74, 0x82, 0x37, 0x87, 0x0B, 0xEC, 0x3B, 0x1F, 0x51, 0x76, 0x84, 0x65, 0x4D, 0x1D, 0x6B, 0xC0, 0x74, 0xDD, 0xF7, 0xB7, 0x59, 0xA2, 0x40, 0x5F, 0x78, 0xED, 0x84, 0xD1, 0x00, 0x6D, 0x25, 0xAF, 0x9B, 0xBC, 0x12, 0xD6, 0xC6, 0x32, 0xF5, 0xD5, 0x43, 0xDA, 0x0C, 0xBE, 0x9E, 0xA8, 0x66, 0xB2, 0xC9, 0x21, 0x26, 0x00, 0x9C, 0x27, 0xAD, 0x59, 0x39, 0x4B, 0x76, 0x33, 0x7D, 0xE2, 0x46, 0xB5, 0x08, 0x95, 0x31, 0x7E, 0x2E, 0x34, 0x5D, 0xF3, 0x62, 0x9A, 0x5F, 0x62, 0x27, 0xF6, 0x45, 0x22, 0x86, 0x6E, 0x7A, 0x39, 0x12, 0x1C, 0xCC, 0x55, 0x2E, 0x3D, 0xAB, 0xC9, 0x89, 0xDC, 0xE0, 0x66, 0xDE, 0xA3, 0x55, 0xF7, 0x88, 0xC5, 0xD9, 0x2A, 0xDA, 0x09, 0x99, 0x17, 0xA2, 0x97, 0xCF, 0xEF, 0xA8, 0x67, 0xCE, 0x37, 0x65, 0x6F, 0xAC, 0x6A, 0x50, 0x79, 0x8C, 0x10, 0xB3, 0x94, 0xD5, 0xBA, 0x54, 0xF8, 0x5C, 0xF0, 0xF7, 0xEF, 0x1E, 0xED, 0xDF, 0xCA, 0x1E, 0x53, 0xE9, 0x3F, 0x13, 0x49, 0x88, 0x8C, 0xC7, 0x45, 0x19, 0x0C, 0x19, 0x6F, 0x84, 0xEC, 0xF0, 0x72, 0x12, 0x87, 0xCC, 0x59, 0x2D, 0x40, 0x6F, 0x0A, 0x6C, 0xC5, 0xA5, 0x52, 0x94, 0xBF, 0x7A, 0xA3, 0xB3, 0x5F, 0x6C, 0xEF, 0xC6, 0x1C, 0xAB, 0x79, 0x4B, 0x12, 0x44, 0x43, 0x12, 0xB5, 0xE5, 0x0E, 0xC0, 0x71, 0x2E, 0x22, 0x1C, 0xC9, 0x5E, 0x9E, 0x26, 0xE9, 0xC3, 0xD0, 0x00, 0x88, 0x1E, 0x79, 0x2A, 0xFC, 0xB5, 0x86, 0x41, 0xB1, 0xA9, 0x46, 0x13, 0xD6, 0x4E, 0xC7, 0x2F, 0x3D, 0xB9, 0xAB, 0x65, 0xBA, 0x07, 0xA4, 0xF0, 0x5B, 0x7E, 0x9E, 0xE7, 0xB3, 0x35, 0xD8, 0x6A, 0x06, 0xFC, 0xBD, 0xB8, 0xCB, 0xD6, 0x95, 0xAE, 0xEF, 0x53, 0x96, 0x4A, 0x96, 0x5F, 0xFE, 0x4C, 0x6D, 0x7B, 0x4E, 0x58, 0x0A, 0xB1, 0x39, 0xF8, 0x42, 0x2A, 0x70, 0x2E, 0x09, 0xEA, 0xCB, 0xEA, 0x5D, 0x51, 0x2C, 0x31, 0xA9, 0x55, 0xB3, 0xD6, 0x03, 0x10, 0xBE, 0x2B, 0xBD, 0xD7, 0x34, 0x84, 0xBA, 0xE6, 0x61, 0x27, 0x91, 0xA1, 0x9D, 0xA3, 0xC7, 0xB0, 0xFD, 0x14, 0x87, 0xE7, 0x21, 0x31, 0xA8, 0xF9, 0xCB, 0x80, 0x17, 0x90, 0xCE, 0x8A, 0x6E, 0x1E, 0x37, 0x86, 0x62, 0xCE, 0xDC, 0xD5, 0xEE, 0x82, 0xBD, 0x39, 0x05, 0x76, 0xAC, 0xFE, 0x53, 0x34, 0xEC, 0xD9, 0xD9, 0x07, 0x27, 0x3A, 0xEF, 0xE6, 0x70, 0x58, 0x91, 0x63, 0x88, 0x21, 0x06, 0x38, 0xE5, 0xE6, 0x0F, 0x20, 0xEE, 0x92, 0x38, 0x9B, 0x35, 0x33, 0xFD, 0x6A, 0xFF, 0xD3, 0x30, 0x95, 0xB2, 0x3D, 0x16, 0x9F, 0x09, 0x13, 0x65, 0x7F, 0x03, 0x3B, 0x8D, 0x5C, 0x4E, 0xA5, 0x17, 0xF1, 0x67, 0xC1, 0xD5, 0x3E, 0x03, 0x17, 0x87, 0xBB, 0xE6, 0xD5, 0xB5, 0x77, 0x24, 0x5F, 0xFF, 0x81, 0x51, 0xCD, 0x8F, 0xDC, 0xC5, 0xD6, 0xC3, 0x2D, 0xF7, 0x0F, 0xB8, 0x04, 0x3D, 0x42, 0xF8, 0x96, 0xCD, 0x51, 0x3B, 0x4C, 0x85, 0xCF, 0xF2, 0x92, 0x67, 0x6C, 0xF1, 0x3B, 0x6A, 0x19, 0x31, 0xE8, 0x77, 0x27, 0xA5, 0x61, 0x71, 0x1A, 0x31, 0x05, 0xD9, 0xF3, 0x51, 0x9B, 0x90, 0xC9, 0x42, 0x9B, 0x5C, 0xD3, 0xED, 0xAA, 0xE3, 0xEE, 0x33, 0x48, 0x26, 0xA3, 0xFD, 0x74, 0xD6, 0x17, 0x5B, 0x55, 0x89, 0xDB, 0x39, 0x2F, 0x95, 0x6A, 0x67, 0xC5, 0xE6, 0x7B, 0xE5, 0x96, 0x56, 0xF1, 0xCB, 0x37, 0xE5, 0x2C, 0x63, 0x6B, 0x26, 0x92, 0xA6, 0x0C, 0x20, 0x44, 0x32, 0x74, 0x72, 0xFA, 0x9A, 0xF6, 0x51, 0xAF, 0xBC, 0xF5, 0x5D, 0x83, 0x98, 0xA3, 0x1D, 0x34, 0x30, 0x74, 0x93, 0x1A, 0x72, 0xD5, 0x48, 0x33, 0xB2, 0x9E, 0xF2, 0x1F, 0xCB, 0x6E, 0xF4, 0x19, 0xBB, 0x56, 0x31, 0x35, 0x13, 0xE4, 0x6C, 0x65, 0xD8, 0x33, 0x67, 0x7D, 0xBB, 0x0F, 0x28, 0x13, 0xE9, 0xCE, 0x5E, 0xF7, 0x06, 0x76, 0x10, 0x2C, 0xA0, 0xD3, 0xC1, 0x4B, 0xBD, 0xD6, 0x59, 0xA7, 0x49, 0x8F, 0xA0, 0x8C, 0xD3, 0x59, 0xD4, 0x28, 0xA8, 0x03, 0xAE, 0xFC, 0xC6, 0x60, 0xE9, 0xFC, 0x70, 0x4E, 0x9B, 0xAC, 0xC5, 0xF1, 0xD2, 0x7F, 0x25, 0x28, 0xD4, 0x6B, 0x3F, 0xCA, 0xA2, 0xD4, 0x7D, 0xFA, 0x28, 0xBF, 0x4C]) - let expectedCiphertext = Data([0xF0, 0xC1, 0xDD, 0x48, 0xE5, 0x84, 0x3E, 0xB0, 0x3D, 0xE5, 0xAB, 0xB2, 0x98, 0x69, 0x7D, 0xC0, 0xF1, 0x03, 0xA9, 0xD0, 0xC2, 0x30, 0x62, 0x0B, 0xCD, 0x86, 0x46, 0x77, 0x58, 0x37, 0x9D, 0xAA, 0x01, 0xAE, 0x18, 0x08, 0x7D, 0x96, 0x09, 0x6A, 0x88, 0x14, 0xE9, 0x88, 0x08, 0xAB, 0x9B, 0x9C, 0x94, 0x39, 0x17, 0x27, 0x30, 0x54, 0x20, 0x1C, 0xA3, 0xCD, 0xF2, 0xD4, 0x9F, 0x3A, 0xC7, 0x89, 0x6D, 0x34, 0xDB, 0x1C, 0xB1, 0xD7, 0x95, 0x9B, 0x4D, 0xD5, 0x03, 0xF7, 0xB2, 0x5B, 0x33, 0x90, 0xE0, 0xDB, 0xCA, 0xCB, 0x15, 0xBB, 0xE8, 0x97, 0x82, 0x36, 0xD7, 0x5A, 0xE2, 0x4D, 0x7C, 0xA0, 0xC4, 0xD5, 0x16, 0x84, 0x6E, 0xC0, 0xCC, 0x0E, 0x05, 0xB5, 0x05, 0xB3, 0xD9, 0xD1, 0xC6, 0xE5, 0x01, 0x65, 0x91, 0x8C, 0x26, 0x67, 0x2E, 0xD1, 0x52, 0x52, 0x65, 0xB2, 0x9F, 0x63, 0x36, 0x13, 0x8C, 0xED, 0xCA, 0x58, 0xE7, 0xF4, 0x47, 0xA8, 0x1B, 0x94, 0x85, 0xF7, 0x43, 0xB5, 0xE0, 0x1F, 0xD5, 0xA5, 0x43, 0xF1, 0x8D, 0x93, 0x35, 0xC5, 0xE2, 0xD1, 0x9C, 0xAE, 0x82, 0x45, 0xA9, 0x22, 0x4A, 0x2B, 0xAA, 0xBD, 0xF7, 0x67, 0x0E, 0x47, 0xBD, 0x22, 0xCF, 0x46, 0x5D, 0xF8, 0x56, 0x36, 0x21, 0x12, 0x4A, 0x80, 0x91, 0x32, 0x5C, 0x67, 0x0E, 0x4F, 0x8F, 0xA0, 0x28, 0x68, 0x65, 0x05, 0xCE, 0xE8, 0x7D, 0x52, 0xD6, 0x3D, 0x19, 0x65, 0xE6, 0x5D, 0xAF, 0x61, 0xF5, 0xE1, 0xB0, 0x0A, 0xE3, 0x3D, 0x4E, 0x5A, 0x42, 0x49, 0x69, 0x50, 0xE8, 0xD7, 0x57, 0x10, 0xCF, 0x8C, 0x47, 0x71, 0x8F, 0x60, 0x71, 0x85, 0x0D, 0x11, 0xB5, 0x52, 0xE1, 0x9B, 0xA0, 0xFA, 0xBE, 0xF5, 0xCC, 0xC7, 0x81, 0x3B, 0xA4, 0xBD, 0x0B, 0x59, 0x36, 0x94, 0xB3, 0x17, 0xF0, 0x4F, 0xBE, 0x9C, 0xAF, 0x48, 0xAF, 0xF1, 0x4A, 0x45, 0x55, 0xF7, 0x8A, 0xB0, 0x56, 0xD4, 0x14, 0x87, 0x47, 0xC7, 0xBD, 0x5A, 0x8B, 0x6E, 0x4B, 0xC8, 0x5D, 0x42, 0xAA, 0xE4, 0xE2, 0x63, 0x4A, 0xD9, 0x02, 0x8E, 0x5F, 0x32, 0x34, 0x5A, 0x68, 0x13, 0xC2, 0x91, 0x58, 0x83, 0x62, 0xA7, 0xEC, 0xF6, 0xE0, 0xC3, 0xB3, 0xA3, 0xDB, 0x9D, 0xBA, 0xA8, 0x2D, 0x27, 0x54, 0x96, 0x2F, 0x5D, 0x9B, 0x3E, 0x0F, 0xD1, 0x66, 0xCB, 0x11, 0xB5, 0x25, 0x40, 0x81, 0x41, 0x7D, 0xAC, 0x0E, 0x35, 0xC0, 0x0B, 0x56, 0xEB, 0xEB, 0xD1, 0x21, 0x12, 0xAE, 0x20, 0x2C, 0x09, 0x4F, 0xE3, 0xB2, 0x42, 0x52, 0xF0, 0x78, 0x7F, 0xB0, 0x9C, 0x6C, 0x51, 0x03, 0x6C, 0xEA, 0xC6, 0xDD, 0xDE, 0x4A, 0xC5, 0x9A, 0xAD, 0xA7, 0xC7, 0x6B, 0xC7, 0x9E, 0x95, 0x0B, 0x66, 0xFF, 0xE6, 0xA0, 0x15, 0x45, 0x0E, 0x87, 0x70, 0xC8, 0xB2, 0xB4, 0x91, 0xCC, 0xEC, 0x76, 0x10, 0xBF, 0x9A, 0x7F, 0x52, 0x3E, 0x5A, 0x57, 0x9F, 0xF6, 0x4C, 0x62, 0x70, 0x0A, 0x7E, 0x83, 0x04, 0x13, 0x9C, 0x68, 0xCF, 0xDA, 0xB3, 0x4F, 0x7A, 0xD1, 0x8B, 0x89, 0x89, 0xA9, 0x80, 0x2E, 0xD9, 0xDD, 0x39, 0x3D, 0x88, 0x9C, 0xF4, 0xD5, 0x26, 0xC9, 0xB5, 0x3F, 0xDB, 0x0B, 0x78, 0xDC, 0xFA, 0xD4, 0x7B, 0x88, 0xC2, 0x3D, 0x69, 0x92, 0xE0, 0xE6, 0x3C, 0x31, 0xF8, 0x0D, 0x69, 0xB4, 0x27, 0xEA, 0x7E, 0x71, 0x94, 0x4A, 0x61, 0x01, 0x3A, 0x0C, 0x70, 0xB2, 0xE9, 0xCF, 0xE2, 0x33, 0xA6, 0x1C, 0xB4, 0x93, 0x9D, 0x2F, 0xDD, 0xE7, 0x5E, 0x6F, 0xF8, 0xFE, 0xE6, 0xB4, 0x5D, 0x48, 0x1A, 0xD0, 0xAD, 0x01, 0x10, 0x46, 0x9E, 0xDF, 0xFC, 0x01, 0xB1, 0xBF, 0x2E, 0x4F, 0x14, 0x14, 0xF9, 0x25, 0xD8, 0x6A, 0xD1, 0x98, 0xA2, 0x7A, 0x03, 0x88, 0x63, 0x7E, 0xDC, 0x7D, 0xD5, 0x47, 0xB8, 0xAE, 0xCA, 0x86, 0xEC, 0xCB, 0x3A, 0xD5, 0xC0, 0x61, 0x5A, 0xF8, 0x42, 0x80, 0x96, 0xC8, 0x14, 0x2D, 0x75, 0x23, 0x5C, 0x46, 0x59, 0x95, 0xE5, 0xEF, 0xF6, 0x22, 0x5E, 0x94, 0x91, 0x34, 0x57, 0x55, 0x1C, 0x1C, 0x18, 0x5E, 0x1D, 0x7B, 0xFA, 0x24, 0x37, 0xAB, 0x56, 0xDA, 0x49, 0x95, 0x48, 0x34, 0x62, 0x8A, 0xC4, 0x80, 0xD7, 0xBA, 0xDA, 0x35, 0xEC, 0xBC, 0x34, 0xDC, 0x6E, 0xFE, 0xB2, 0x60, 0x09, 0xC8, 0x2A, 0x0C, 0xC3, 0xF4, 0x77, 0x75, 0x7A, 0x91, 0xDC, 0x6D, 0x65, 0x2C, 0xE7, 0xED, 0xD8, 0x2C, 0xB8, 0x91, 0xBA, 0x3B, 0x49, 0xBF, 0xEB, 0x74, 0xBD, 0x2A, 0x35, 0xB3, 0xF5, 0xBC, 0xE7, 0x4A, 0x34, 0x35, 0x9D, 0xC0, 0x0D, 0xB8, 0xE0, 0x96, 0x1C, 0xB9, 0x75, 0x8C, 0xD9, 0x9E, 0xF2, 0x5C, 0xF7, 0x18, 0x97, 0x4D, 0x60, 0xED, 0x5E, 0x77, 0x33, 0xF5, 0x25, 0xC8, 0x1E, 0xDB, 0x04, 0x64, 0xC7, 0x93, 0x0A, 0xDD, 0x3E, 0x93, 0x36, 0xD8, 0x71, 0x5A, 0xEB, 0x37, 0xBB, 0x62, 0x48, 0x44, 0x24, 0x6A, 0x19, 0xD4, 0x33, 0xC0, 0xED, 0x61, 0x5C, 0x22, 0x1E, 0x5E, 0x89, 0x74, 0x5D, 0x24, 0x67, 0x74, 0x37, 0x73, 0x56, 0x06, 0x39, 0x89, 0x4B, 0x1A, 0xBD, 0x0F, 0x6E, 0x52, 0x89, 0xB5, 0x82, 0x6C, 0xEE, 0x5F, 0xCA, 0x76, 0xBD, 0xD6, 0xD0, 0xD4, 0xDD, 0x69, 0xFB, 0x4A, 0x50, 0xD7, 0xD8, 0x14, 0xA4, 0x8C, 0x7E, 0x35, 0x92, 0x0A, 0xBB, 0x8F, 0x0C, 0x1E, 0x60, 0xBA, 0x92, 0xD6, 0x12, 0xF4, 0xF4, 0xBF, 0x56, 0x95, 0xA0, 0x89, 0xDE, 0x63, 0x9B, 0xFB, 0xC6, 0xF3, 0x17, 0xF4, 0xFD, 0x89, 0x5D, 0x32, 0x57, 0xEF, 0xBE, 0x1D, 0x49, 0xE9, 0x44, 0xB8, 0x2B, 0xAD, 0xD4, 0xB2, 0x11, 0x64, 0xD4, 0xBA, 0xE7, 0xA8, 0x72, 0xF1, 0x83, 0xA3, 0xC8, 0x38, 0x5F, 0x54, 0xFD, 0xD8, 0xF4, 0x71, 0x67, 0x21, 0x32, 0xDD, 0x44, 0xE5, 0x1C, 0xCD, 0xCF, 0xE1, 0x83, 0xC0, 0xCE, 0x00, 0x03, 0x2A, 0x04, 0x88, 0x66, 0xAF, 0x6D, 0xFE, 0xA9, 0xE1, 0x5B, 0x58, 0xA1, 0x70, 0x93, 0x20, 0xE8, 0xFC, 0xA1, 0x6D, 0xEF, 0xEA, 0xB2, 0x33, 0x02, 0x7A, 0x9E, 0xA3, 0x11, 0x8A, 0x52, 0x1C, 0x94, 0xBE, 0x5C, 0x48, 0xA7, 0x2D, 0xE9, 0xC6, 0xFA, 0xBF, 0x21, 0x96, 0xE1, 0x23, 0xFC, 0x13, 0x56, 0xDE, 0xA2, 0x23, 0x71, 0x25, 0x99, 0x75, 0x8A, 0x2F, 0x6F, 0xFE, 0x91, 0x92, 0x1C, 0x1A, 0xCE, 0xE3, 0xEC, 0x6C, 0x7B, 0x7A, 0x29, 0xA1, 0xD3, 0xC5, 0xF8, 0x8A, 0xE6, 0xFB, 0x50, 0xB4, 0x2E, 0x36, 0xC0, 0x77, 0x37, 0x31, 0xE2, 0x8C, 0xA3, 0xC9, 0x3A, 0x18, 0x62, 0x7D, 0x28, 0x7E, 0xD5, 0xF5, 0x38, 0x69, 0x14, 0x21, 0xDF, 0xFD, 0x36, 0xE3, 0xBB, 0x87, 0x18, 0x54, 0xBC, 0x58, 0x5F, 0x36, 0x7E, 0xDB, 0xE7, 0x0B, 0x02, 0x9F, 0x81, 0xF3, 0x60, 0x59, 0x82, 0xEA, 0xFA, 0x41, 0x35, 0xE5, 0x4B, 0x78, 0xD0, 0xC6, 0xCD, 0xF1, 0x8A, 0xFE, 0x22, 0xFF, 0x73, 0x08, 0xDA, 0x70, 0x11, 0xF1, 0x5D, 0x35, 0x24, 0x90, 0x6F, 0x10, 0xFB, 0x6B, 0x78, 0x0F, 0xA9, 0xCC, 0x4B]) + let key: [UInt8] = [ + 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, 0x1F, 0x35, + 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4, + ] + let plaintext = Data([ + 0xFD, 0x4C, 0x14, 0x72, 0x9F, 0x50, 0x04, 0xBA, 0x49, 0xD8, 0x32, 0xAD, 0x7B, 0xE8, 0x7C, 0x18, 0xF4, 0xFA, + 0xFB, 0x58, 0x96, 0x2B, 0x9A, 0x43, 0xC3, 0xBE, 0x41, 0x71, 0x3D, 0xED, 0x93, 0xDB, 0xF8, 0x54, 0xAC, 0x4C, + 0xA2, 0x62, 0x85, 0xB7, 0xF7, 0x6E, 0x04, 0xB8, 0xF8, 0xD4, 0xE7, 0xD9, 0xF7, 0x54, 0x8F, 0x9B, 0x46, 0x5C, + 0x8F, 0x71, 0x3C, 0x10, 0x6E, 0x9F, 0x63, 0xF5, 0x43, 0x05, 0x33, 0x1A, 0x49, 0x83, 0xA2, 0xF4, 0xB7, 0x18, + 0xDE, 0x29, 0xFA, 0x79, 0x4D, 0xA1, 0x2E, 0xEE, 0x80, 0x86, 0x42, 0xFA, 0xEF, 0xF8, 0x27, 0x1A, 0x0E, 0xA2, + 0x8E, 0x3C, 0xC8, 0x0E, 0xEB, 0x65, 0xA8, 0xEB, 0x61, 0xF6, 0x9D, 0x8B, 0xA9, 0x7F, 0x6B, 0xF9, 0x05, 0x44, + 0x53, 0xF5, 0x5E, 0xFB, 0x8F, 0x94, 0x22, 0x08, 0x1F, 0x16, 0x20, 0xFE, 0x44, 0xAC, 0xF9, 0x9E, 0x81, 0x12, + 0x2F, 0x73, 0xD3, 0xF9, 0x21, 0xD5, 0xE3, 0x39, 0x16, 0x54, 0xE9, 0x94, 0x79, 0x04, 0x98, 0x43, 0x75, 0xB7, + 0x25, 0xFD, 0xFB, 0xA8, 0x95, 0xC5, 0xCD, 0xE3, 0xD2, 0x25, 0xD7, 0xBE, 0x3A, 0x21, 0x3C, 0x39, 0x65, 0x17, + 0x8A, 0x7D, 0xC1, 0xE3, 0xB5, 0x52, 0xEC, 0x7B, 0x2F, 0xFD, 0x9C, 0x77, 0xEB, 0xCC, 0x24, 0x3C, 0x45, 0x00, + 0xDF, 0xDF, 0xBE, 0x3B, 0x75, 0x54, 0xAA, 0x42, 0x7C, 0x01, 0x30, 0x5B, 0xEC, 0x48, 0xD7, 0x1A, 0xF2, 0x7C, + 0x59, 0x11, 0xD1, 0xE6, 0x49, 0xC6, 0x20, 0xD2, 0x2C, 0xF5, 0xF3, 0xA5, 0xAE, 0xB9, 0x46, 0x86, 0x51, 0xDA, + 0x79, 0x6F, 0x36, 0x95, 0x22, 0xFA, 0xF9, 0x1E, 0xFA, 0xBF, 0x0F, 0xEB, 0xD3, 0x3F, 0xCA, 0x41, 0xC9, 0x53, + 0x46, 0x06, 0xA4, 0xEA, 0x01, 0x99, 0xB9, 0x04, 0xB2, 0x43, 0xBA, 0x9C, 0xB8, 0xF3, 0x7A, 0x79, 0x2D, 0xF0, + 0x2E, 0xFA, 0xB8, 0xF0, 0xE2, 0xE0, 0xCF, 0x1D, 0x57, 0x9D, 0xAB, 0xA0, 0x42, 0xCF, 0xE4, 0xC9, 0x43, 0x0A, + 0xD4, 0xED, 0xA7, 0x86, 0x05, 0x2F, 0xCF, 0x15, 0xE7, 0xAC, 0xFA, 0x27, 0x36, 0xAA, 0xB4, 0x59, 0x0F, 0x73, + 0x67, 0x5F, 0xA1, 0x80, 0x5F, 0xE2, 0x38, 0x92, 0xC6, 0x3E, 0x0C, 0xD0, 0x1D, 0x00, 0x69, 0x35, 0xA6, 0xE3, + 0xF8, 0xE1, 0x05, 0xA7, 0x54, 0x80, 0x3D, 0x00, 0xD9, 0x85, 0x7E, 0x49, 0x63, 0x6A, 0xB0, 0x34, 0x16, 0x41, + 0x56, 0x85, 0x6D, 0x58, 0xA2, 0x44, 0xEA, 0xD4, 0x75, 0x30, 0x0D, 0x93, 0xB3, 0x1E, 0x44, 0xB5, 0xBE, 0x3B, + 0xBF, 0x69, 0x94, 0xED, 0xB8, 0x95, 0x80, 0x4B, 0x4F, 0x1B, 0xAD, 0x43, 0xEC, 0xFE, 0x08, 0xB4, 0xE1, 0x30, + 0x14, 0x8B, 0x66, 0x9F, 0xE6, 0x20, 0xE4, 0xF7, 0x30, 0x34, 0xFC, 0x3E, 0x74, 0x82, 0x37, 0x87, 0x0B, 0xEC, + 0x3B, 0x1F, 0x51, 0x76, 0x84, 0x65, 0x4D, 0x1D, 0x6B, 0xC0, 0x74, 0xDD, 0xF7, 0xB7, 0x59, 0xA2, 0x40, 0x5F, + 0x78, 0xED, 0x84, 0xD1, 0x00, 0x6D, 0x25, 0xAF, 0x9B, 0xBC, 0x12, 0xD6, 0xC6, 0x32, 0xF5, 0xD5, 0x43, 0xDA, + 0x0C, 0xBE, 0x9E, 0xA8, 0x66, 0xB2, 0xC9, 0x21, 0x26, 0x00, 0x9C, 0x27, 0xAD, 0x59, 0x39, 0x4B, 0x76, 0x33, + 0x7D, 0xE2, 0x46, 0xB5, 0x08, 0x95, 0x31, 0x7E, 0x2E, 0x34, 0x5D, 0xF3, 0x62, 0x9A, 0x5F, 0x62, 0x27, 0xF6, + 0x45, 0x22, 0x86, 0x6E, 0x7A, 0x39, 0x12, 0x1C, 0xCC, 0x55, 0x2E, 0x3D, 0xAB, 0xC9, 0x89, 0xDC, 0xE0, 0x66, + 0xDE, 0xA3, 0x55, 0xF7, 0x88, 0xC5, 0xD9, 0x2A, 0xDA, 0x09, 0x99, 0x17, 0xA2, 0x97, 0xCF, 0xEF, 0xA8, 0x67, + 0xCE, 0x37, 0x65, 0x6F, 0xAC, 0x6A, 0x50, 0x79, 0x8C, 0x10, 0xB3, 0x94, 0xD5, 0xBA, 0x54, 0xF8, 0x5C, 0xF0, + 0xF7, 0xEF, 0x1E, 0xED, 0xDF, 0xCA, 0x1E, 0x53, 0xE9, 0x3F, 0x13, 0x49, 0x88, 0x8C, 0xC7, 0x45, 0x19, 0x0C, + 0x19, 0x6F, 0x84, 0xEC, 0xF0, 0x72, 0x12, 0x87, 0xCC, 0x59, 0x2D, 0x40, 0x6F, 0x0A, 0x6C, 0xC5, 0xA5, 0x52, + 0x94, 0xBF, 0x7A, 0xA3, 0xB3, 0x5F, 0x6C, 0xEF, 0xC6, 0x1C, 0xAB, 0x79, 0x4B, 0x12, 0x44, 0x43, 0x12, 0xB5, + 0xE5, 0x0E, 0xC0, 0x71, 0x2E, 0x22, 0x1C, 0xC9, 0x5E, 0x9E, 0x26, 0xE9, 0xC3, 0xD0, 0x00, 0x88, 0x1E, 0x79, + 0x2A, 0xFC, 0xB5, 0x86, 0x41, 0xB1, 0xA9, 0x46, 0x13, 0xD6, 0x4E, 0xC7, 0x2F, 0x3D, 0xB9, 0xAB, 0x65, 0xBA, + 0x07, 0xA4, 0xF0, 0x5B, 0x7E, 0x9E, 0xE7, 0xB3, 0x35, 0xD8, 0x6A, 0x06, 0xFC, 0xBD, 0xB8, 0xCB, 0xD6, 0x95, + 0xAE, 0xEF, 0x53, 0x96, 0x4A, 0x96, 0x5F, 0xFE, 0x4C, 0x6D, 0x7B, 0x4E, 0x58, 0x0A, 0xB1, 0x39, 0xF8, 0x42, + 0x2A, 0x70, 0x2E, 0x09, 0xEA, 0xCB, 0xEA, 0x5D, 0x51, 0x2C, 0x31, 0xA9, 0x55, 0xB3, 0xD6, 0x03, 0x10, 0xBE, + 0x2B, 0xBD, 0xD7, 0x34, 0x84, 0xBA, 0xE6, 0x61, 0x27, 0x91, 0xA1, 0x9D, 0xA3, 0xC7, 0xB0, 0xFD, 0x14, 0x87, + 0xE7, 0x21, 0x31, 0xA8, 0xF9, 0xCB, 0x80, 0x17, 0x90, 0xCE, 0x8A, 0x6E, 0x1E, 0x37, 0x86, 0x62, 0xCE, 0xDC, + 0xD5, 0xEE, 0x82, 0xBD, 0x39, 0x05, 0x76, 0xAC, 0xFE, 0x53, 0x34, 0xEC, 0xD9, 0xD9, 0x07, 0x27, 0x3A, 0xEF, + 0xE6, 0x70, 0x58, 0x91, 0x63, 0x88, 0x21, 0x06, 0x38, 0xE5, 0xE6, 0x0F, 0x20, 0xEE, 0x92, 0x38, 0x9B, 0x35, + 0x33, 0xFD, 0x6A, 0xFF, 0xD3, 0x30, 0x95, 0xB2, 0x3D, 0x16, 0x9F, 0x09, 0x13, 0x65, 0x7F, 0x03, 0x3B, 0x8D, + 0x5C, 0x4E, 0xA5, 0x17, 0xF1, 0x67, 0xC1, 0xD5, 0x3E, 0x03, 0x17, 0x87, 0xBB, 0xE6, 0xD5, 0xB5, 0x77, 0x24, + 0x5F, 0xFF, 0x81, 0x51, 0xCD, 0x8F, 0xDC, 0xC5, 0xD6, 0xC3, 0x2D, 0xF7, 0x0F, 0xB8, 0x04, 0x3D, 0x42, 0xF8, + 0x96, 0xCD, 0x51, 0x3B, 0x4C, 0x85, 0xCF, 0xF2, 0x92, 0x67, 0x6C, 0xF1, 0x3B, 0x6A, 0x19, 0x31, 0xE8, 0x77, + 0x27, 0xA5, 0x61, 0x71, 0x1A, 0x31, 0x05, 0xD9, 0xF3, 0x51, 0x9B, 0x90, 0xC9, 0x42, 0x9B, 0x5C, 0xD3, 0xED, + 0xAA, 0xE3, 0xEE, 0x33, 0x48, 0x26, 0xA3, 0xFD, 0x74, 0xD6, 0x17, 0x5B, 0x55, 0x89, 0xDB, 0x39, 0x2F, 0x95, + 0x6A, 0x67, 0xC5, 0xE6, 0x7B, 0xE5, 0x96, 0x56, 0xF1, 0xCB, 0x37, 0xE5, 0x2C, 0x63, 0x6B, 0x26, 0x92, 0xA6, + 0x0C, 0x20, 0x44, 0x32, 0x74, 0x72, 0xFA, 0x9A, 0xF6, 0x51, 0xAF, 0xBC, 0xF5, 0x5D, 0x83, 0x98, 0xA3, 0x1D, + 0x34, 0x30, 0x74, 0x93, 0x1A, 0x72, 0xD5, 0x48, 0x33, 0xB2, 0x9E, 0xF2, 0x1F, 0xCB, 0x6E, 0xF4, 0x19, 0xBB, + 0x56, 0x31, 0x35, 0x13, 0xE4, 0x6C, 0x65, 0xD8, 0x33, 0x67, 0x7D, 0xBB, 0x0F, 0x28, 0x13, 0xE9, 0xCE, 0x5E, + 0xF7, 0x06, 0x76, 0x10, 0x2C, 0xA0, 0xD3, 0xC1, 0x4B, 0xBD, 0xD6, 0x59, 0xA7, 0x49, 0x8F, 0xA0, 0x8C, 0xD3, + 0x59, 0xD4, 0x28, 0xA8, 0x03, 0xAE, 0xFC, 0xC6, 0x60, 0xE9, 0xFC, 0x70, 0x4E, 0x9B, 0xAC, 0xC5, 0xF1, 0xD2, + 0x7F, 0x25, 0x28, 0xD4, 0x6B, 0x3F, 0xCA, 0xA2, 0xD4, 0x7D, 0xFA, 0x28, 0xBF, 0x4C, + ]) + let expectedCiphertext = Data([ + 0xF0, 0xC1, 0xDD, 0x48, 0xE5, 0x84, 0x3E, 0xB0, 0x3D, 0xE5, 0xAB, 0xB2, 0x98, 0x69, 0x7D, 0xC0, 0xF1, 0x03, + 0xA9, 0xD0, 0xC2, 0x30, 0x62, 0x0B, 0xCD, 0x86, 0x46, 0x77, 0x58, 0x37, 0x9D, 0xAA, 0x01, 0xAE, 0x18, 0x08, + 0x7D, 0x96, 0x09, 0x6A, 0x88, 0x14, 0xE9, 0x88, 0x08, 0xAB, 0x9B, 0x9C, 0x94, 0x39, 0x17, 0x27, 0x30, 0x54, + 0x20, 0x1C, 0xA3, 0xCD, 0xF2, 0xD4, 0x9F, 0x3A, 0xC7, 0x89, 0x6D, 0x34, 0xDB, 0x1C, 0xB1, 0xD7, 0x95, 0x9B, + 0x4D, 0xD5, 0x03, 0xF7, 0xB2, 0x5B, 0x33, 0x90, 0xE0, 0xDB, 0xCA, 0xCB, 0x15, 0xBB, 0xE8, 0x97, 0x82, 0x36, + 0xD7, 0x5A, 0xE2, 0x4D, 0x7C, 0xA0, 0xC4, 0xD5, 0x16, 0x84, 0x6E, 0xC0, 0xCC, 0x0E, 0x05, 0xB5, 0x05, 0xB3, + 0xD9, 0xD1, 0xC6, 0xE5, 0x01, 0x65, 0x91, 0x8C, 0x26, 0x67, 0x2E, 0xD1, 0x52, 0x52, 0x65, 0xB2, 0x9F, 0x63, + 0x36, 0x13, 0x8C, 0xED, 0xCA, 0x58, 0xE7, 0xF4, 0x47, 0xA8, 0x1B, 0x94, 0x85, 0xF7, 0x43, 0xB5, 0xE0, 0x1F, + 0xD5, 0xA5, 0x43, 0xF1, 0x8D, 0x93, 0x35, 0xC5, 0xE2, 0xD1, 0x9C, 0xAE, 0x82, 0x45, 0xA9, 0x22, 0x4A, 0x2B, + 0xAA, 0xBD, 0xF7, 0x67, 0x0E, 0x47, 0xBD, 0x22, 0xCF, 0x46, 0x5D, 0xF8, 0x56, 0x36, 0x21, 0x12, 0x4A, 0x80, + 0x91, 0x32, 0x5C, 0x67, 0x0E, 0x4F, 0x8F, 0xA0, 0x28, 0x68, 0x65, 0x05, 0xCE, 0xE8, 0x7D, 0x52, 0xD6, 0x3D, + 0x19, 0x65, 0xE6, 0x5D, 0xAF, 0x61, 0xF5, 0xE1, 0xB0, 0x0A, 0xE3, 0x3D, 0x4E, 0x5A, 0x42, 0x49, 0x69, 0x50, + 0xE8, 0xD7, 0x57, 0x10, 0xCF, 0x8C, 0x47, 0x71, 0x8F, 0x60, 0x71, 0x85, 0x0D, 0x11, 0xB5, 0x52, 0xE1, 0x9B, + 0xA0, 0xFA, 0xBE, 0xF5, 0xCC, 0xC7, 0x81, 0x3B, 0xA4, 0xBD, 0x0B, 0x59, 0x36, 0x94, 0xB3, 0x17, 0xF0, 0x4F, + 0xBE, 0x9C, 0xAF, 0x48, 0xAF, 0xF1, 0x4A, 0x45, 0x55, 0xF7, 0x8A, 0xB0, 0x56, 0xD4, 0x14, 0x87, 0x47, 0xC7, + 0xBD, 0x5A, 0x8B, 0x6E, 0x4B, 0xC8, 0x5D, 0x42, 0xAA, 0xE4, 0xE2, 0x63, 0x4A, 0xD9, 0x02, 0x8E, 0x5F, 0x32, + 0x34, 0x5A, 0x68, 0x13, 0xC2, 0x91, 0x58, 0x83, 0x62, 0xA7, 0xEC, 0xF6, 0xE0, 0xC3, 0xB3, 0xA3, 0xDB, 0x9D, + 0xBA, 0xA8, 0x2D, 0x27, 0x54, 0x96, 0x2F, 0x5D, 0x9B, 0x3E, 0x0F, 0xD1, 0x66, 0xCB, 0x11, 0xB5, 0x25, 0x40, + 0x81, 0x41, 0x7D, 0xAC, 0x0E, 0x35, 0xC0, 0x0B, 0x56, 0xEB, 0xEB, 0xD1, 0x21, 0x12, 0xAE, 0x20, 0x2C, 0x09, + 0x4F, 0xE3, 0xB2, 0x42, 0x52, 0xF0, 0x78, 0x7F, 0xB0, 0x9C, 0x6C, 0x51, 0x03, 0x6C, 0xEA, 0xC6, 0xDD, 0xDE, + 0x4A, 0xC5, 0x9A, 0xAD, 0xA7, 0xC7, 0x6B, 0xC7, 0x9E, 0x95, 0x0B, 0x66, 0xFF, 0xE6, 0xA0, 0x15, 0x45, 0x0E, + 0x87, 0x70, 0xC8, 0xB2, 0xB4, 0x91, 0xCC, 0xEC, 0x76, 0x10, 0xBF, 0x9A, 0x7F, 0x52, 0x3E, 0x5A, 0x57, 0x9F, + 0xF6, 0x4C, 0x62, 0x70, 0x0A, 0x7E, 0x83, 0x04, 0x13, 0x9C, 0x68, 0xCF, 0xDA, 0xB3, 0x4F, 0x7A, 0xD1, 0x8B, + 0x89, 0x89, 0xA9, 0x80, 0x2E, 0xD9, 0xDD, 0x39, 0x3D, 0x88, 0x9C, 0xF4, 0xD5, 0x26, 0xC9, 0xB5, 0x3F, 0xDB, + 0x0B, 0x78, 0xDC, 0xFA, 0xD4, 0x7B, 0x88, 0xC2, 0x3D, 0x69, 0x92, 0xE0, 0xE6, 0x3C, 0x31, 0xF8, 0x0D, 0x69, + 0xB4, 0x27, 0xEA, 0x7E, 0x71, 0x94, 0x4A, 0x61, 0x01, 0x3A, 0x0C, 0x70, 0xB2, 0xE9, 0xCF, 0xE2, 0x33, 0xA6, + 0x1C, 0xB4, 0x93, 0x9D, 0x2F, 0xDD, 0xE7, 0x5E, 0x6F, 0xF8, 0xFE, 0xE6, 0xB4, 0x5D, 0x48, 0x1A, 0xD0, 0xAD, + 0x01, 0x10, 0x46, 0x9E, 0xDF, 0xFC, 0x01, 0xB1, 0xBF, 0x2E, 0x4F, 0x14, 0x14, 0xF9, 0x25, 0xD8, 0x6A, 0xD1, + 0x98, 0xA2, 0x7A, 0x03, 0x88, 0x63, 0x7E, 0xDC, 0x7D, 0xD5, 0x47, 0xB8, 0xAE, 0xCA, 0x86, 0xEC, 0xCB, 0x3A, + 0xD5, 0xC0, 0x61, 0x5A, 0xF8, 0x42, 0x80, 0x96, 0xC8, 0x14, 0x2D, 0x75, 0x23, 0x5C, 0x46, 0x59, 0x95, 0xE5, + 0xEF, 0xF6, 0x22, 0x5E, 0x94, 0x91, 0x34, 0x57, 0x55, 0x1C, 0x1C, 0x18, 0x5E, 0x1D, 0x7B, 0xFA, 0x24, 0x37, + 0xAB, 0x56, 0xDA, 0x49, 0x95, 0x48, 0x34, 0x62, 0x8A, 0xC4, 0x80, 0xD7, 0xBA, 0xDA, 0x35, 0xEC, 0xBC, 0x34, + 0xDC, 0x6E, 0xFE, 0xB2, 0x60, 0x09, 0xC8, 0x2A, 0x0C, 0xC3, 0xF4, 0x77, 0x75, 0x7A, 0x91, 0xDC, 0x6D, 0x65, + 0x2C, 0xE7, 0xED, 0xD8, 0x2C, 0xB8, 0x91, 0xBA, 0x3B, 0x49, 0xBF, 0xEB, 0x74, 0xBD, 0x2A, 0x35, 0xB3, 0xF5, + 0xBC, 0xE7, 0x4A, 0x34, 0x35, 0x9D, 0xC0, 0x0D, 0xB8, 0xE0, 0x96, 0x1C, 0xB9, 0x75, 0x8C, 0xD9, 0x9E, 0xF2, + 0x5C, 0xF7, 0x18, 0x97, 0x4D, 0x60, 0xED, 0x5E, 0x77, 0x33, 0xF5, 0x25, 0xC8, 0x1E, 0xDB, 0x04, 0x64, 0xC7, + 0x93, 0x0A, 0xDD, 0x3E, 0x93, 0x36, 0xD8, 0x71, 0x5A, 0xEB, 0x37, 0xBB, 0x62, 0x48, 0x44, 0x24, 0x6A, 0x19, + 0xD4, 0x33, 0xC0, 0xED, 0x61, 0x5C, 0x22, 0x1E, 0x5E, 0x89, 0x74, 0x5D, 0x24, 0x67, 0x74, 0x37, 0x73, 0x56, + 0x06, 0x39, 0x89, 0x4B, 0x1A, 0xBD, 0x0F, 0x6E, 0x52, 0x89, 0xB5, 0x82, 0x6C, 0xEE, 0x5F, 0xCA, 0x76, 0xBD, + 0xD6, 0xD0, 0xD4, 0xDD, 0x69, 0xFB, 0x4A, 0x50, 0xD7, 0xD8, 0x14, 0xA4, 0x8C, 0x7E, 0x35, 0x92, 0x0A, 0xBB, + 0x8F, 0x0C, 0x1E, 0x60, 0xBA, 0x92, 0xD6, 0x12, 0xF4, 0xF4, 0xBF, 0x56, 0x95, 0xA0, 0x89, 0xDE, 0x63, 0x9B, + 0xFB, 0xC6, 0xF3, 0x17, 0xF4, 0xFD, 0x89, 0x5D, 0x32, 0x57, 0xEF, 0xBE, 0x1D, 0x49, 0xE9, 0x44, 0xB8, 0x2B, + 0xAD, 0xD4, 0xB2, 0x11, 0x64, 0xD4, 0xBA, 0xE7, 0xA8, 0x72, 0xF1, 0x83, 0xA3, 0xC8, 0x38, 0x5F, 0x54, 0xFD, + 0xD8, 0xF4, 0x71, 0x67, 0x21, 0x32, 0xDD, 0x44, 0xE5, 0x1C, 0xCD, 0xCF, 0xE1, 0x83, 0xC0, 0xCE, 0x00, 0x03, + 0x2A, 0x04, 0x88, 0x66, 0xAF, 0x6D, 0xFE, 0xA9, 0xE1, 0x5B, 0x58, 0xA1, 0x70, 0x93, 0x20, 0xE8, 0xFC, 0xA1, + 0x6D, 0xEF, 0xEA, 0xB2, 0x33, 0x02, 0x7A, 0x9E, 0xA3, 0x11, 0x8A, 0x52, 0x1C, 0x94, 0xBE, 0x5C, 0x48, 0xA7, + 0x2D, 0xE9, 0xC6, 0xFA, 0xBF, 0x21, 0x96, 0xE1, 0x23, 0xFC, 0x13, 0x56, 0xDE, 0xA2, 0x23, 0x71, 0x25, 0x99, + 0x75, 0x8A, 0x2F, 0x6F, 0xFE, 0x91, 0x92, 0x1C, 0x1A, 0xCE, 0xE3, 0xEC, 0x6C, 0x7B, 0x7A, 0x29, 0xA1, 0xD3, + 0xC5, 0xF8, 0x8A, 0xE6, 0xFB, 0x50, 0xB4, 0x2E, 0x36, 0xC0, 0x77, 0x37, 0x31, 0xE2, 0x8C, 0xA3, 0xC9, 0x3A, + 0x18, 0x62, 0x7D, 0x28, 0x7E, 0xD5, 0xF5, 0x38, 0x69, 0x14, 0x21, 0xDF, 0xFD, 0x36, 0xE3, 0xBB, 0x87, 0x18, + 0x54, 0xBC, 0x58, 0x5F, 0x36, 0x7E, 0xDB, 0xE7, 0x0B, 0x02, 0x9F, 0x81, 0xF3, 0x60, 0x59, 0x82, 0xEA, 0xFA, + 0x41, 0x35, 0xE5, 0x4B, 0x78, 0xD0, 0xC6, 0xCD, 0xF1, 0x8A, 0xFE, 0x22, 0xFF, 0x73, 0x08, 0xDA, 0x70, 0x11, + 0xF1, 0x5D, 0x35, 0x24, 0x90, 0x6F, 0x10, 0xFB, 0x6B, 0x78, 0x0F, 0xA9, 0xCC, 0x4B, + ]) let nonce: [UInt8] = [0xA6, 0xAA, 0xD9, 0xEC, 0xED, 0x14, 0xBF, 0x1C, 0x61, 0x91, 0x0D, 0xBA, 0, 0, 0, 35] var ciphertext = plaintext diff --git a/swift/Tests/LibSignalClientTests/HsmEnclaveTests.swift b/swift/Tests/LibSignalClientTests/HsmEnclaveTests.swift index d872288da..502d81648 100644 --- a/swift/Tests/LibSignalClientTests/HsmEnclaveTests.swift +++ b/swift/Tests/LibSignalClientTests/HsmEnclaveTests.swift @@ -10,14 +10,18 @@ class HsmEnclaveTests: TestCaseBase { func testCreateClient() { let validKey = IdentityKeyPair.generate().publicKey var hashes = HsmCodeHashList() - try! hashes.append(Data([ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ])) - try! hashes.append(Data([ - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - ])) + try! hashes.append( + Data([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]) + ) + try! hashes.append( + Data([ + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + ]) + ) let hsmEnclaveClient = try! HsmEnclaveClient(publicKey: validKey.keyBytes, codeHashes: hashes) let initialMessage = hsmEnclaveClient.initialRequest() XCTAssertEqual(112, initialMessage.count) @@ -32,10 +36,12 @@ class HsmEnclaveTests: TestCaseBase { func testCompleteHandshakeWithoutInitialRequest() { let validKey = IdentityKeyPair.generate().publicKey var hashes = HsmCodeHashList() - try! hashes.append(Data([ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ])) + try! hashes.append( + Data([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]) + ) let hsmEnclaveClient = try! HsmEnclaveClient(publicKey: validKey.keyBytes, codeHashes: hashes) let handshakeResponse: [UInt8] = [0x01, 0x02, 0x03] XCTAssertThrowsError(try hsmEnclaveClient.completeHandshake(handshakeResponse)) @@ -44,10 +50,12 @@ class HsmEnclaveTests: TestCaseBase { func testEstablishedSendFailsPriorToEstablishment() { let validKey = IdentityKeyPair.generate().publicKey var hashes = HsmCodeHashList() - try! hashes.append(Data([ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ])) + try! hashes.append( + Data([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]) + ) let hsmEnclaveClient = try! HsmEnclaveClient(publicKey: validKey.keyBytes, codeHashes: hashes) let plaintextToSend: [UInt8] = [0x01, 0x02, 0x03] XCTAssertThrowsError(try hsmEnclaveClient.establishedSend(plaintextToSend)) @@ -56,10 +64,12 @@ class HsmEnclaveTests: TestCaseBase { func testEstablishedRecvFailsPriorToEstablishment() { let validKey = IdentityKeyPair.generate().publicKey var hashes = HsmCodeHashList() - try! hashes.append(Data([ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ])) + try! hashes.append( + Data([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]) + ) let hsmEnclaveClient = try! HsmEnclaveClient(publicKey: validKey.keyBytes, codeHashes: hashes) let receivedCiphertext: [UInt8] = [0x01, 0x02, 0x03] XCTAssertThrowsError(try hsmEnclaveClient.establishedRecv(receivedCiphertext)) diff --git a/swift/Tests/LibSignalClientTests/InMemorySignalProtocolStoreTests.swift b/swift/Tests/LibSignalClientTests/InMemorySignalProtocolStoreTests.swift index 4c07dd367..f2f831d70 100644 --- a/swift/Tests/LibSignalClientTests/InMemorySignalProtocolStoreTests.swift +++ b/swift/Tests/LibSignalClientTests/InMemorySignalProtocolStoreTests.swift @@ -16,14 +16,17 @@ class InMemorySignalProtocolStoreTests: TestCaseBase { let firstIdentity = IdentityKeyPair.generate().identityKey XCTAssert( - try store.isTrustedIdentity(firstIdentity, for: address, direction: .sending, context: context)) + try store.isTrustedIdentity(firstIdentity, for: address, direction: .sending, context: context) + ) XCTAssertEqual( - try store.saveIdentity(firstIdentity, for: address, context: context), .newOrUnchanged + try store.saveIdentity(firstIdentity, for: address, context: context), + .newOrUnchanged ) // Idempotent XCTAssertEqual( - try store.saveIdentity(firstIdentity, for: address, context: context), .newOrUnchanged + try store.saveIdentity(firstIdentity, for: address, context: context), + .newOrUnchanged ) XCTAssert(try store.isTrustedIdentity(firstIdentity, for: address, direction: .sending, context: context)) XCTAssertEqual(try store.identity(for: address, context: context), firstIdentity) @@ -31,7 +34,8 @@ class InMemorySignalProtocolStoreTests: TestCaseBase { let secondIdentity = IdentityKeyPair.generate().identityKey XCTAssertFalse( - try store.isTrustedIdentity(secondIdentity, for: address, direction: .sending, context: context)) + try store.isTrustedIdentity(secondIdentity, for: address, direction: .sending, context: context) + ) XCTAssertEqual( try store.saveIdentity(secondIdentity, for: address, context: context), .replacedExisting @@ -43,7 +47,8 @@ class InMemorySignalProtocolStoreTests: TestCaseBase { ) XCTAssert( - try store.isTrustedIdentity(secondIdentity, for: address, direction: .sending, context: context)) + try store.isTrustedIdentity(secondIdentity, for: address, direction: .sending, context: context) + ) XCTAssertEqual(try store.identity(for: address, context: context), secondIdentity) } } diff --git a/swift/Tests/LibSignalClientTests/IncrementalMacTests.swift b/swift/Tests/LibSignalClientTests/IncrementalMacTests.swift index be4aa3f49..6747e3188 100644 --- a/swift/Tests/LibSignalClientTests/IncrementalMacTests.swift +++ b/swift/Tests/LibSignalClientTests/IncrementalMacTests.swift @@ -10,7 +10,9 @@ import XCTest class IncrementalMacTests: TestCaseBase { private let TEST_KEY = Data(base64Encoded: "qDSBRX7+zGmtE0LiHZwCl/cd679ckwS0wbLkM8Gnj5g=")! private let TEST_INPUT = ["this is a test", " input to the incremental ", "mac stream"].map { Data($0.utf8) } - private let TEST_DIGEST = Data(base64Encoded: "hIkvcGAOVJ+3KHlmep2WonPxRLaY/571p2BipWBhqQmIT22fQpGKnkdu1RjErI9xS9M/BFFSrgSYd/09Gw2yWg==")! + private let TEST_DIGEST = Data( + base64Encoded: "hIkvcGAOVJ+3KHlmep2WonPxRLaY/571p2BipWBhqQmIT22fQpGKnkdu1RjErI9xS9M/BFFSrgSYd/09Gw2yWg==" + )! private let CHUNK_SIZE = SizeChoice.bytes(32) func testIncrementalDigestCreation() throws { diff --git a/swift/Tests/LibSignalClientTests/IoTests.swift b/swift/Tests/LibSignalClientTests/IoTests.swift index 5d9182b0c..c32a4173c 100644 --- a/swift/Tests/LibSignalClientTests/IoTests.swift +++ b/swift/Tests/LibSignalClientTests/IoTests.swift @@ -3,13 +3,14 @@ // SPDX-License-Identifier: AGPL-3.0-only // -@testable import LibSignalClient -@testable import SignalFfi import XCTest +@testable import LibSignalClient +@testable import SignalFfi + class IoTests: TestCaseBase { -// These testing endpoints aren't generated in device builds, to save on code size. -#if !os(iOS) || targetEnvironment(simulator) + // These testing endpoints aren't generated in device builds, to save on code size. + #if !os(iOS) || targetEnvironment(simulator) func testReadIntoEmptyBuffer() throws { let input = Data("ABCDEFGHIJKLMNOPQRSTUVWXYZ".utf8) let inputStream = SignalInputStreamAdapter(input) @@ -20,5 +21,5 @@ class IoTests: TestCaseBase { } XCTAssertEqual(input, output) } -#endif + #endif } diff --git a/swift/Tests/LibSignalClientTests/IoUtils.swift b/swift/Tests/LibSignalClientTests/IoUtils.swift index 17db76c0e..9b297b7ed 100644 --- a/swift/Tests/LibSignalClientTests/IoUtils.swift +++ b/swift/Tests/LibSignalClientTests/IoUtils.swift @@ -60,5 +60,6 @@ func readResource(forName name: String) -> Data { contentsOf: URL(fileURLWithPath: #filePath) .deletingLastPathComponent() .appendingPathComponent("Resources") - .appendingPathComponent(name)) + .appendingPathComponent(name) + ) } diff --git a/swift/Tests/LibSignalClientTests/KeyTransparencyTests.swift b/swift/Tests/LibSignalClientTests/KeyTransparencyTests.swift index b7c58df38..0b3882af5 100644 --- a/swift/Tests/LibSignalClientTests/KeyTransparencyTests.swift +++ b/swift/Tests/LibSignalClientTests/KeyTransparencyTests.swift @@ -4,10 +4,11 @@ // import Foundation -@testable import LibSignalClient import SignalFfi import XCTest +@testable import LibSignalClient + class TestStore: KeyTransparency.Store { var distinguishedTreeHeads: [Data] = [] var accountData: [Aci: [Data]] = [:] @@ -58,11 +59,15 @@ final class KeyTransparencyTests: TestCaseBase { private var testAccount = TestAccount( aci: Aci(fromUUID: UUID(uuidString: "90c979fd-eab4-4a08-b6da-69dedeab9b29")!), - identityKey: try! IdentityKey(bytes: [UInt8](fromHexString: "05111f9464c1822c6a2405acf1c5a4366679dc3349fc8eb015c8d7260e3f771177")!), + identityKey: try! IdentityKey( + bytes: [UInt8](fromHexString: "05111f9464c1822c6a2405acf1c5a4366679dc3349fc8eb015c8d7260e3f771177")! + ), e164: "+18005550100", unidentifiedAccessKey: Data(fromHexString: "c6f7c258c24d69538ea553b4a943c8d9")!, - usernameHash: Data(fromHexString: - "d237a4b83b463ca7da58d4a16bf6a3ba104506eb412b235eb603ea10f467c655")! + usernameHash: Data( + fromHexString: + "d237a4b83b463ca7da58d4a16bf6a3ba104506eb412b235eb603ea10f467c655" + )! ) private class NoOpListener: ConnectionEventsListener { @@ -123,8 +128,8 @@ final class KeyTransparencyTests: TestCaseBase { XCTAssertEqual(2, store.accountData[self.testAccount.aci]!.count) } -// These testing endpoints aren't generated in device builds, to save on code size. -#if !os(iOS) || targetEnvironment(simulator) + // These testing endpoints aren't generated in device builds, to save on code size. + #if !os(iOS) || targetEnvironment(simulator) func testNonFatalErrorBridging() throws { do { try checkError(signal_testing_key_trans_non_fatal_verification_failure()) @@ -154,5 +159,5 @@ final class KeyTransparencyTests: TestCaseBase { XCTFail("unexpected exception thrown: \(error)") } } -#endif + #endif } diff --git a/swift/Tests/LibSignalClientTests/MediaSanitizerTests.swift b/swift/Tests/LibSignalClientTests/MediaSanitizerTests.swift index 13c5618c7..ebe510edc 100644 --- a/swift/Tests/LibSignalClientTests/MediaSanitizerTests.swift +++ b/swift/Tests/LibSignalClientTests/MediaSanitizerTests.swift @@ -11,14 +11,16 @@ import XCTest class Mp4SanitizerTests: TestCaseBase { func testEmptyMp4() { let input: [UInt8] = [] - XCTAssertThrowsError(try sanitizeMp4(input: SignalInputStreamAdapter(input), len: UInt64(input.count))) { error in + XCTAssertThrowsError(try sanitizeMp4(input: SignalInputStreamAdapter(input), len: UInt64(input.count))) { + error in if case SignalError.invalidMediaInput = error {} else { XCTFail("\(error)") } } } func testTruncatedMp4() { let input: [UInt8] = [0, 0, 0, 0] - XCTAssertThrowsError(try sanitizeMp4(input: SignalInputStreamAdapter(input), len: UInt64(input.count))) { error in + XCTAssertThrowsError(try sanitizeMp4(input: SignalInputStreamAdapter(input), len: UInt64(input.count))) { + error in if case SignalError.invalidMediaInput = error {} else { XCTFail("\(error)") } } } @@ -28,7 +30,12 @@ class Mp4SanitizerTests: TestCaseBase { let input = metadata + mdat() let sanitized = try sanitizeMp4(input: SignalInputStreamAdapter(input), len: UInt64(input.count)) - assertSanitizedMetadataEqual(sanitized, dataOffset: metadata.count, dataLen: input.count - metadata.count, metadata: nil) + assertSanitizedMetadataEqual( + sanitized, + dataOffset: metadata.count, + dataLen: input.count - metadata.count, + metadata: nil + ) } func testMinimalMp4() throws { @@ -36,7 +43,12 @@ class Mp4SanitizerTests: TestCaseBase { let input = ftyp() + mdat() + moov() let sanitized = try sanitizeMp4(input: SignalInputStreamAdapter(input), len: UInt64(input.count)) - assertSanitizedMetadataEqual(sanitized, dataOffset: ftyp().count, dataLen: input.count - metadata.count, metadata: metadata) + assertSanitizedMetadataEqual( + sanitized, + dataOffset: ftyp().count, + dataLen: input.count - metadata.count, + metadata: metadata + ) } func testMp4IoError() throws { @@ -75,66 +87,71 @@ class WebpSanitizerTests: TestCaseBase { private func ftyp() -> [UInt8] { var ftyp: [UInt8] = [] - ftyp.append(contentsOf: [0, 0, 0, 20]) // box size - ftyp.append(contentsOf: "ftyp".utf8) // box type - ftyp.append(contentsOf: "isom".utf8) // major_brand - ftyp.append(contentsOf: [0, 0, 0, 0]) // minor_version - ftyp.append(contentsOf: "isom".utf8) // compatible_brands + ftyp.append(contentsOf: [0, 0, 0, 20]) // box size + ftyp.append(contentsOf: "ftyp".utf8) // box type + ftyp.append(contentsOf: "isom".utf8) // major_brand + ftyp.append(contentsOf: [0, 0, 0, 0]) // minor_version + ftyp.append(contentsOf: "isom".utf8) // compatible_brands return ftyp } private func moov() -> [UInt8] { var moov: [UInt8] = [] // moov box header - moov.append(contentsOf: [0, 0, 0, 56]) // box size - moov.append(contentsOf: "moov".utf8) // box type + moov.append(contentsOf: [0, 0, 0, 56]) // box size + moov.append(contentsOf: "moov".utf8) // box type // trak box (inside moov box) - moov.append(contentsOf: [0, 0, 0, 48]) // box size - moov.append(contentsOf: "trak".utf8) // box type + moov.append(contentsOf: [0, 0, 0, 48]) // box size + moov.append(contentsOf: "trak".utf8) // box type // mdia box (inside trak box) - moov.append(contentsOf: [0, 0, 0, 40]) // box size - moov.append(contentsOf: "mdia".utf8) // box type + moov.append(contentsOf: [0, 0, 0, 40]) // box size + moov.append(contentsOf: "mdia".utf8) // box type // minf box (inside mdia box) - moov.append(contentsOf: [0, 0, 0, 32]) // box size - moov.append(contentsOf: "minf".utf8) // box type + moov.append(contentsOf: [0, 0, 0, 32]) // box size + moov.append(contentsOf: "minf".utf8) // box type // stbl box (inside minf box) - moov.append(contentsOf: [0, 0, 0, 24]) // box size - moov.append(contentsOf: "stbl".utf8) // box type + moov.append(contentsOf: [0, 0, 0, 24]) // box size + moov.append(contentsOf: "stbl".utf8) // box type // stco box (inside stbl box) - moov.append(contentsOf: [0, 0, 0, 16]) // box size - moov.append(contentsOf: "stco".utf8) // box type - moov.append(contentsOf: [0, 0, 0, 0]) // box version & flags - moov.append(contentsOf: [0, 0, 0, 0]) // entry count + moov.append(contentsOf: [0, 0, 0, 16]) // box size + moov.append(contentsOf: "stco".utf8) // box type + moov.append(contentsOf: [0, 0, 0, 0]) // box version & flags + moov.append(contentsOf: [0, 0, 0, 0]) // entry count return moov } private func mdat() -> [UInt8] { var mdat: [UInt8] = [] - mdat.append(contentsOf: [0, 0, 0, 8]) // box size - mdat.append(contentsOf: "mdat".utf8) // box type + mdat.append(contentsOf: [0, 0, 0, 8]) // box size + mdat.append(contentsOf: "mdat".utf8) // box type return mdat } private func webp() -> [UInt8] { var webp: [UInt8] = [] - webp.append(contentsOf: "RIFF") // chunk type - webp.append(contentsOf: [20, 0, 0, 0]) // chunk size - webp.append(contentsOf: "WEBP") // webp header + webp.append(contentsOf: "RIFF") // chunk type + webp.append(contentsOf: [20, 0, 0, 0]) // chunk size + webp.append(contentsOf: "WEBP") // webp header - webp.append(contentsOf: "VP8L") // chunk type - webp.append(contentsOf: [8, 0, 0, 0]) // chunk size - webp.append(contentsOf: [0x2F, 0, 0, 0, 0, 0x88, 0x88, 8]) // VP8L data + webp.append(contentsOf: "VP8L") // chunk type + webp.append(contentsOf: [8, 0, 0, 0]) // chunk size + webp.append(contentsOf: [0x2F, 0, 0, 0, 0, 0x88, 0x88, 8]) // VP8L data return webp } -private func assertSanitizedMetadataEqual(_ sanitized: SanitizedMetadata, dataOffset: Int, dataLen: Int, metadata: (any Sequence)?) { +private func assertSanitizedMetadataEqual( + _ sanitized: SanitizedMetadata, + dataOffset: Int, + dataLen: Int, + metadata: (any Sequence)? +) { if let metadata = metadata { XCTAssertNotNil(sanitized.metadata) XCTAssert(sanitized.metadata!.elementsEqual(metadata)) diff --git a/swift/Tests/LibSignalClientTests/MessageBackupTests.swift b/swift/Tests/LibSignalClientTests/MessageBackupTests.swift index 5af8c87fe..36ee8771c 100644 --- a/swift/Tests/LibSignalClientTests/MessageBackupTests.swift +++ b/swift/Tests/LibSignalClientTests/MessageBackupTests.swift @@ -71,9 +71,16 @@ class MessageBackupTests: TestCaseBase { func testInputThrowsAfter() { let bytes = readResource(forName: "new_account.binproto.encrypted") - let makeStream = { ThrowsAfterInputStream(inner: SignalInputStreamAdapter(bytes), readBeforeThrow: UInt64(bytes.count) - 1) } + let makeStream = { + ThrowsAfterInputStream(inner: SignalInputStreamAdapter(bytes), readBeforeThrow: UInt64(bytes.count) - 1) + } XCTAssertThrowsError( - try validateMessageBackup(key: MessageBackupKey.testKey(), purpose: .remoteBackup, length: UInt64(bytes.count), makeStream: makeStream) + try validateMessageBackup( + key: MessageBackupKey.testKey(), + purpose: .remoteBackup, + length: UInt64(bytes.count), + makeStream: makeStream + ) ) { error in if error is TestIoError {} else { XCTFail("\(error)") } } @@ -90,7 +97,9 @@ class MessageBackupTests: TestCaseBase { // 1: 1 // 2: 1731715200000 // 3: {`00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff`} - private let VALID_BACKUP_INFO: Data = .init(base64Encoded: "CAEQgOiTkrMyGiAAESIzRFVmd4iZqrvM3e7/ABEiM0RVZneImaq7zN3u/w==")! + private let VALID_BACKUP_INFO: Data = .init( + base64Encoded: "CAEQgOiTkrMyGiAAESIzRFVmd4iZqrvM3e7/ABEiM0RVZneImaq7zN3u/w==" + )! func testOnlineValidatorInvalidFrame() throws { let backup = try OnlineBackupValidator(backupInfo: VALID_BACKUP_INFO, purpose: .remoteBackup) @@ -106,13 +115,19 @@ class MessageBackupTests: TestCaseBase { XCTAssertFalse(AccountEntropyPool.isValid("invalid key")) XCTAssertTrue( AccountEntropyPool.isValid( - "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqr")) + "0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqr" + ) + ) } -#if !os(iOS) || targetEnvironment(simulator) + #if !os(iOS) || targetEnvironment(simulator) func testComparableBackup() throws { let bytes = readResource(forName: "canonical-backup.binproto") - let backup = try ComparableBackup(purpose: .remoteBackup, length: UInt64(bytes.count), stream: SignalInputStreamAdapter(bytes)) + let backup = try ComparableBackup( + purpose: .remoteBackup, + length: UInt64(bytes.count), + stream: SignalInputStreamAdapter(bytes) + ) let comparableString = backup.comparableString() let expected = String(data: readResource(forName: "canonical-backup.expected.json"), encoding: .utf8)! @@ -147,10 +162,15 @@ class MessageBackupTests: TestCaseBase { try backup.finalize() } -#endif + #endif static func validateBackup(bytes: some Collection) throws -> MessageBackupUnknownFields { - try validateMessageBackup(key: MessageBackupKey.testKey(), purpose: .remoteBackup, length: UInt64(bytes.count), makeStream: { SignalInputStreamAdapter(bytes) }) + try validateMessageBackup( + key: MessageBackupKey.testKey(), + purpose: .remoteBackup, + length: UInt64(bytes.count), + makeStream: { SignalInputStreamAdapter(bytes) } + ) } } diff --git a/swift/Tests/LibSignalClientTests/NativeTests.swift b/swift/Tests/LibSignalClientTests/NativeTests.swift index 00116f90e..512f3ee6d 100644 --- a/swift/Tests/LibSignalClientTests/NativeTests.swift +++ b/swift/Tests/LibSignalClientTests/NativeTests.swift @@ -4,16 +4,17 @@ // import Foundation -@testable import LibSignalClient import SignalFfi import XCTest +@testable import LibSignalClient + final class NativeTests: XCTestCase { -// These testing endpoints aren't generated in device builds, to save on code size. -#if !os(iOS) || targetEnvironment(simulator) + // These testing endpoints aren't generated in device builds, to save on code size. + #if !os(iOS) || targetEnvironment(simulator) func testTestingFnsAreAvailable() async throws { let output = try invokeFnReturningInteger(fn: SignalFfi.signal_test_only_fn_returns_123) XCTAssertEqual(output, 123) } -#endif + #endif } diff --git a/swift/Tests/LibSignalClientTests/NetTests.swift b/swift/Tests/LibSignalClientTests/NetTests.swift index 985f21972..9ead30947 100644 --- a/swift/Tests/LibSignalClientTests/NetTests.swift +++ b/swift/Tests/LibSignalClientTests/NetTests.swift @@ -30,14 +30,18 @@ final class NetTests { #expect(output.debug_permits_used == 123) let entryList = LookupResponseEntryList(owned: output.entries) - let expected = [SignalFfiCdsiLookupResponseEntry( - e164: 18_005_551_011, - aci, pni - ), SignalFfiCdsiLookupResponseEntry( - e164: 18_005_551_012, - nil, - pni - )] + let expected = [ + SignalFfiCdsiLookupResponseEntry( + e164: 18_005_551_011, + aci, + pni + ), + SignalFfiCdsiLookupResponseEntry( + e164: 18_005_551_012, + nil, + pni + ), + ] #expect(expected == Array(entryList)) } @@ -51,7 +55,10 @@ final class NetTests { do { try failWithError("Protocol") } catch SignalError.networkProtocolError(let message) { - #expect(message == "Protocol error: protocol error after establishing a connection: failed to decode frame as protobuf") + #expect( + message + == "Protocol error: protocol error after establishing a connection: failed to decode frame as protobuf" + ) } do { try failWithError("CdsiProtocol") diff --git a/swift/Tests/LibSignalClientTests/PublicAPITests.swift b/swift/Tests/LibSignalClientTests/PublicAPITests.swift index a73ece676..7070dfb87 100644 --- a/swift/Tests/LibSignalClientTests/PublicAPITests.swift +++ b/swift/Tests/LibSignalClientTests/PublicAPITests.swift @@ -9,8 +9,8 @@ import XCTest class PublicAPITests: TestCaseBase { func testHkdfSimple() { let ikm: [UInt8] = [ - 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, - 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, + 0x0B, 0x0B, 0x0B, 0x0B, ] let info: [UInt8] = [] let salt: [UInt8] = [] @@ -31,88 +31,11 @@ class PublicAPITests: TestCaseBase { let salt: [UInt8] = Array(0x60...0xAF) let info: [UInt8] = Array(0xB0...0xFF) let okm = Data([ - 0xB1, - 0x1E, - 0x39, - 0x8D, - 0xC8, - 0x03, - 0x27, - 0xA1, - 0xC8, - 0xE7, - 0xF7, - 0x8C, - 0x59, - 0x6A, - 0x49, - 0x34, - 0x4F, - 0x01, - 0x2E, - 0xDA, - 0x2D, - 0x4E, - 0xFA, - 0xD8, - 0xA0, - 0x50, - 0xCC, - 0x4C, - 0x19, - 0xAF, - 0xA9, - 0x7C, - 0x59, - 0x04, - 0x5A, - 0x99, - 0xCA, - 0xC7, - 0x82, - 0x72, - 0x71, - 0xCB, - 0x41, - 0xC6, - 0x5E, - 0x59, - 0x0E, - 0x09, - 0xDA, - 0x32, - 0x75, - 0x60, - 0x0C, - 0x2F, - 0x09, - 0xB8, - 0x36, - 0x77, - 0x93, - 0xA9, - 0xAC, - 0xA3, - 0xDB, - 0x71, - 0xCC, - 0x30, - 0xC5, - 0x81, - 0x79, - 0xEC, - 0x3E, - 0x87, - 0xC1, - 0x4C, - 0x01, - 0xD5, - 0xC1, - 0xF3, - 0x43, - 0x4F, - 0x1D, - 0x87, + 0xB1, 0x1E, 0x39, 0x8D, 0xC8, 0x03, 0x27, 0xA1, 0xC8, 0xE7, 0xF7, 0x8C, 0x59, 0x6A, 0x49, 0x34, 0x4F, 0x01, + 0x2E, 0xDA, 0x2D, 0x4E, 0xFA, 0xD8, 0xA0, 0x50, 0xCC, 0x4C, 0x19, 0xAF, 0xA9, 0x7C, 0x59, 0x04, 0x5A, 0x99, + 0xCA, 0xC7, 0x82, 0x72, 0x71, 0xCB, 0x41, 0xC6, 0x5E, 0x59, 0x0E, 0x09, 0xDA, 0x32, 0x75, 0x60, 0x0C, 0x2F, + 0x09, 0xB8, 0x36, 0x77, 0x93, 0xA9, 0xAC, 0xA3, 0xDB, 0x71, 0xCC, 0x30, 0xC5, 0x81, 0x79, 0xEC, 0x3E, 0x87, + 0xC1, 0x4C, 0x01, 0xD5, 0xC1, 0xF3, 0x43, 0x4F, 0x1D, 0x87, ]) let derived = try! hkdf( @@ -158,7 +81,7 @@ class PublicAPITests: TestCaseBase { let pk = sk.publicKey let pk_bytes = pk.serialize() - XCTAssertEqual(pk_bytes[0], 0x05) // DJB + XCTAssertEqual(pk_bytes[0], 0x05) // DJB XCTAssertEqual(pk_bytes.count, 33) let pk_raw = pk.keyBytes @@ -195,18 +118,48 @@ class PublicAPITests: TestCaseBase { } func testFingerprint() { - let ALICE_IDENTITY: [UInt8] = [0x05, 0x06, 0x86, 0x3B, 0xC6, 0x6D, 0x02, 0xB4, 0x0D, 0x27, 0xB8, 0xD4, 0x9C, 0xA7, 0xC0, 0x9E, 0x92, 0x39, 0x23, 0x6F, 0x9D, 0x7D, 0x25, 0xD6, 0xFC, 0xCA, 0x5C, 0xE1, 0x3C, 0x70, 0x64, 0xD8, 0x68] - let BOB_IDENTITY: [UInt8] = [0x05, 0xF7, 0x81, 0xB6, 0xFB, 0x32, 0xFE, 0xD9, 0xBA, 0x1C, 0xF2, 0xDE, 0x97, 0x8D, 0x4D, 0x5D, 0xA2, 0x8D, 0xC3, 0x40, 0x46, 0xAE, 0x81, 0x44, 0x02, 0xB5, 0xC0, 0xDB, 0xD9, 0x6F, 0xDA, 0x90, 0x7B] + let ALICE_IDENTITY: [UInt8] = [ + 0x05, 0x06, 0x86, 0x3B, 0xC6, 0x6D, 0x02, 0xB4, 0x0D, 0x27, 0xB8, 0xD4, 0x9C, 0xA7, 0xC0, 0x9E, 0x92, 0x39, + 0x23, 0x6F, 0x9D, 0x7D, 0x25, 0xD6, 0xFC, 0xCA, 0x5C, 0xE1, 0x3C, 0x70, 0x64, 0xD8, 0x68, + ] + let BOB_IDENTITY: [UInt8] = [ + 0x05, 0xF7, 0x81, 0xB6, 0xFB, 0x32, 0xFE, 0xD9, 0xBA, 0x1C, 0xF2, 0xDE, 0x97, 0x8D, 0x4D, 0x5D, 0xA2, 0x8D, + 0xC3, 0x40, 0x46, 0xAE, 0x81, 0x44, 0x02, 0xB5, 0xC0, 0xDB, 0xD9, 0x6F, 0xDA, 0x90, 0x7B, + ] let VERSION_1 = 1 let DISPLAYABLE_FINGERPRINT_V1 = "300354477692869396892869876765458257569162576843440918079131" - let ALICE_SCANNABLE_FINGERPRINT_V1 = Data([0x08, 0x01, 0x12, 0x22, 0x0A, 0x20, 0x1E, 0x30, 0x1A, 0x03, 0x53, 0xDC, 0xE3, 0xDB, 0xE7, 0x68, 0x4C, 0xB8, 0x33, 0x6E, 0x85, 0x13, 0x6C, 0xDC, 0x0E, 0xE9, 0x62, 0x19, 0x49, 0x4A, 0xDA, 0x30, 0x5D, 0x62, 0xA7, 0xBD, 0x61, 0xDF, 0x1A, 0x22, 0x0A, 0x20, 0xD6, 0x2C, 0xBF, 0x73, 0xA1, 0x15, 0x92, 0x01, 0x5B, 0x6B, 0x9F, 0x16, 0x82, 0xAC, 0x30, 0x6F, 0xEA, 0x3A, 0xAF, 0x38, 0x85, 0xB8, 0x4D, 0x12, 0xBC, 0xA6, 0x31, 0xE9, 0xD4, 0xFB, 0x3A, 0x4D]) - let BOB_SCANNABLE_FINGERPRINT_V1 = Data([0x08, 0x01, 0x12, 0x22, 0x0A, 0x20, 0xD6, 0x2C, 0xBF, 0x73, 0xA1, 0x15, 0x92, 0x01, 0x5B, 0x6B, 0x9F, 0x16, 0x82, 0xAC, 0x30, 0x6F, 0xEA, 0x3A, 0xAF, 0x38, 0x85, 0xB8, 0x4D, 0x12, 0xBC, 0xA6, 0x31, 0xE9, 0xD4, 0xFB, 0x3A, 0x4D, 0x1A, 0x22, 0x0A, 0x20, 0x1E, 0x30, 0x1A, 0x03, 0x53, 0xDC, 0xE3, 0xDB, 0xE7, 0x68, 0x4C, 0xB8, 0x33, 0x6E, 0x85, 0x13, 0x6C, 0xDC, 0x0E, 0xE9, 0x62, 0x19, 0x49, 0x4A, 0xDA, 0x30, 0x5D, 0x62, 0xA7, 0xBD, 0x61, 0xDF]) + let ALICE_SCANNABLE_FINGERPRINT_V1 = Data([ + 0x08, 0x01, 0x12, 0x22, 0x0A, 0x20, 0x1E, 0x30, 0x1A, 0x03, 0x53, 0xDC, 0xE3, 0xDB, 0xE7, 0x68, 0x4C, 0xB8, + 0x33, 0x6E, 0x85, 0x13, 0x6C, 0xDC, 0x0E, 0xE9, 0x62, 0x19, 0x49, 0x4A, 0xDA, 0x30, 0x5D, 0x62, 0xA7, 0xBD, + 0x61, 0xDF, 0x1A, 0x22, 0x0A, 0x20, 0xD6, 0x2C, 0xBF, 0x73, 0xA1, 0x15, 0x92, 0x01, 0x5B, 0x6B, 0x9F, 0x16, + 0x82, 0xAC, 0x30, 0x6F, 0xEA, 0x3A, 0xAF, 0x38, 0x85, 0xB8, 0x4D, 0x12, 0xBC, 0xA6, 0x31, 0xE9, 0xD4, 0xFB, + 0x3A, 0x4D, + ]) + let BOB_SCANNABLE_FINGERPRINT_V1 = Data([ + 0x08, 0x01, 0x12, 0x22, 0x0A, 0x20, 0xD6, 0x2C, 0xBF, 0x73, 0xA1, 0x15, 0x92, 0x01, 0x5B, 0x6B, 0x9F, 0x16, + 0x82, 0xAC, 0x30, 0x6F, 0xEA, 0x3A, 0xAF, 0x38, 0x85, 0xB8, 0x4D, 0x12, 0xBC, 0xA6, 0x31, 0xE9, 0xD4, 0xFB, + 0x3A, 0x4D, 0x1A, 0x22, 0x0A, 0x20, 0x1E, 0x30, 0x1A, 0x03, 0x53, 0xDC, 0xE3, 0xDB, 0xE7, 0x68, 0x4C, 0xB8, + 0x33, 0x6E, 0x85, 0x13, 0x6C, 0xDC, 0x0E, 0xE9, 0x62, 0x19, 0x49, 0x4A, 0xDA, 0x30, 0x5D, 0x62, 0xA7, 0xBD, + 0x61, 0xDF, + ]) let VERSION_2 = 2 let DISPLAYABLE_FINGERPRINT_V2 = DISPLAYABLE_FINGERPRINT_V1 - let ALICE_SCANNABLE_FINGERPRINT_V2 = Data([0x08, 0x02, 0x12, 0x22, 0x0A, 0x20, 0x1E, 0x30, 0x1A, 0x03, 0x53, 0xDC, 0xE3, 0xDB, 0xE7, 0x68, 0x4C, 0xB8, 0x33, 0x6E, 0x85, 0x13, 0x6C, 0xDC, 0x0E, 0xE9, 0x62, 0x19, 0x49, 0x4A, 0xDA, 0x30, 0x5D, 0x62, 0xA7, 0xBD, 0x61, 0xDF, 0x1A, 0x22, 0x0A, 0x20, 0xD6, 0x2C, 0xBF, 0x73, 0xA1, 0x15, 0x92, 0x01, 0x5B, 0x6B, 0x9F, 0x16, 0x82, 0xAC, 0x30, 0x6F, 0xEA, 0x3A, 0xAF, 0x38, 0x85, 0xB8, 0x4D, 0x12, 0xBC, 0xA6, 0x31, 0xE9, 0xD4, 0xFB, 0x3A, 0x4D]) - let BOB_SCANNABLE_FINGERPRINT_V2 = Data([0x08, 0x02, 0x12, 0x22, 0x0A, 0x20, 0xD6, 0x2C, 0xBF, 0x73, 0xA1, 0x15, 0x92, 0x01, 0x5B, 0x6B, 0x9F, 0x16, 0x82, 0xAC, 0x30, 0x6F, 0xEA, 0x3A, 0xAF, 0x38, 0x85, 0xB8, 0x4D, 0x12, 0xBC, 0xA6, 0x31, 0xE9, 0xD4, 0xFB, 0x3A, 0x4D, 0x1A, 0x22, 0x0A, 0x20, 0x1E, 0x30, 0x1A, 0x03, 0x53, 0xDC, 0xE3, 0xDB, 0xE7, 0x68, 0x4C, 0xB8, 0x33, 0x6E, 0x85, 0x13, 0x6C, 0xDC, 0x0E, 0xE9, 0x62, 0x19, 0x49, 0x4A, 0xDA, 0x30, 0x5D, 0x62, 0xA7, 0xBD, 0x61, 0xDF]) + let ALICE_SCANNABLE_FINGERPRINT_V2 = Data([ + 0x08, 0x02, 0x12, 0x22, 0x0A, 0x20, 0x1E, 0x30, 0x1A, 0x03, 0x53, 0xDC, 0xE3, 0xDB, 0xE7, 0x68, 0x4C, 0xB8, + 0x33, 0x6E, 0x85, 0x13, 0x6C, 0xDC, 0x0E, 0xE9, 0x62, 0x19, 0x49, 0x4A, 0xDA, 0x30, 0x5D, 0x62, 0xA7, 0xBD, + 0x61, 0xDF, 0x1A, 0x22, 0x0A, 0x20, 0xD6, 0x2C, 0xBF, 0x73, 0xA1, 0x15, 0x92, 0x01, 0x5B, 0x6B, 0x9F, 0x16, + 0x82, 0xAC, 0x30, 0x6F, 0xEA, 0x3A, 0xAF, 0x38, 0x85, 0xB8, 0x4D, 0x12, 0xBC, 0xA6, 0x31, 0xE9, 0xD4, 0xFB, + 0x3A, 0x4D, + ]) + let BOB_SCANNABLE_FINGERPRINT_V2 = Data([ + 0x08, 0x02, 0x12, 0x22, 0x0A, 0x20, 0xD6, 0x2C, 0xBF, 0x73, 0xA1, 0x15, 0x92, 0x01, 0x5B, 0x6B, 0x9F, 0x16, + 0x82, 0xAC, 0x30, 0x6F, 0xEA, 0x3A, 0xAF, 0x38, 0x85, 0xB8, 0x4D, 0x12, 0xBC, 0xA6, 0x31, 0xE9, 0xD4, 0xFB, + 0x3A, 0x4D, 0x1A, 0x22, 0x0A, 0x20, 0x1E, 0x30, 0x1A, 0x03, 0x53, 0xDC, 0xE3, 0xDB, 0xE7, 0x68, 0x4C, 0xB8, + 0x33, 0x6E, 0x85, 0x13, 0x6C, 0xDC, 0x0E, 0xE9, 0x62, 0x19, 0x49, 0x4A, 0xDA, 0x30, 0x5D, 0x62, 0xA7, 0xBD, + 0x61, 0xDF, + ]) // testVectorsVersion1 let aliceStableId = [UInt8]("+14152222222".utf8) @@ -269,8 +222,12 @@ class PublicAPITests: TestCaseBase { XCTAssertTrue(try! bobFingerprint2.scannable.compare(againstEncoding: aliceFingerprint2.scannable.encoding)) XCTAssertTrue(try! aliceFingerprint2.scannable.compare(againstEncoding: bobFingerprint2.scannable.encoding)) - XCTAssertThrowsError(try bobFingerprint2.scannable.compare(againstEncoding: aliceFingerprint.scannable.encoding)) - XCTAssertThrowsError(try bobFingerprint.scannable.compare(againstEncoding: aliceFingerprint2.scannable.encoding)) + XCTAssertThrowsError( + try bobFingerprint2.scannable.compare(againstEncoding: aliceFingerprint.scannable.encoding) + ) + XCTAssertThrowsError( + try bobFingerprint.scannable.compare(againstEncoding: aliceFingerprint2.scannable.encoding) + ) // testMismatchingFingerprints @@ -340,13 +297,24 @@ class PublicAPITests: TestCaseBase { let a_store = InMemorySignalProtocolStore() - let skdm = try! SenderKeyDistributionMessage(from: sender, distributionId: distribution_id, store: a_store, context: NullContext()) + let skdm = try! SenderKeyDistributionMessage( + from: sender, + distributionId: distribution_id, + store: a_store, + context: NullContext() + ) let skdm_bits = skdm.serialize() let skdm_r = try! SenderKeyDistributionMessage(bytes: skdm_bits) - let a_ctext = try! groupEncrypt([1, 2, 3], from: sender, distributionId: distribution_id, store: a_store, context: NullContext()).serialize() + let a_ctext = try! groupEncrypt( + [1, 2, 3], + from: sender, + distributionId: distribution_id, + store: a_store, + context: NullContext() + ).serialize() let b_store = InMemorySignalProtocolStore() try! processSenderKeyDistributionMessage( @@ -369,7 +337,11 @@ class PublicAPITests: TestCaseBase { super.init() } - override func loadSenderKey(from sender: ProtocolAddress, distributionId: UUID, context: StoreContext) throws -> SenderKeyRecord? { + override func loadSenderKey( + from sender: ProtocolAddress, + distributionId: UUID, + context: StoreContext + ) throws -> SenderKeyRecord? { XCTAssertIdentical(self.expectedContext, context as AnyObject) return try super.loadSenderKey(from: sender, distributionId: distributionId, context: context) } @@ -382,31 +354,44 @@ class PublicAPITests: TestCaseBase { let a_store = ContextUsingStore(expectedContext: ContextWithIdentity()) - let skdm = try! SenderKeyDistributionMessage(from: sender, distributionId: distribution_id, store: a_store, context: a_store.expectedContext) + let skdm = try! SenderKeyDistributionMessage( + from: sender, + distributionId: distribution_id, + store: a_store, + context: a_store.expectedContext + ) let skdm_bits = skdm.serialize() _ = try! SenderKeyDistributionMessage(bytes: skdm_bits) - _ = try! groupEncrypt([1, 2, 3], from: sender, distributionId: distribution_id, store: a_store, context: a_store.expectedContext).serialize() + _ = try! groupEncrypt( + [1, 2, 3], + from: sender, + distributionId: distribution_id, + store: a_store, + context: a_store.expectedContext + ).serialize() } func testSenderCertificates() { let senderCertBits = Data([ - 0x0A, 0xCD, 0x01, 0x0A, 0x0C, 0x2B, 0x31, 0x34, 0x31, 0x35, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x10, 0x2A, 0x19, - 0x2D, 0x63, 0xB5, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x22, 0x21, 0x05, 0xBB, 0x25, 0x64, 0x9C, 0x79, 0x4B, 0xB4, 0x6C, 0x8C, - 0x57, 0x97, 0x69, 0x3C, 0xC8, 0x05, 0xB1, 0xB8, 0x46, 0xDA, 0x91, 0x17, 0x6F, 0xEC, 0x6A, 0x3E, 0xF2, 0x1F, 0x41, 0x0B, - 0xE9, 0x60, 0x43, 0x2A, 0x69, 0x0A, 0x25, 0x08, 0x01, 0x12, 0x21, 0x05, 0x4F, 0xBF, 0xFA, 0x55, 0xEB, 0xD5, 0x23, 0xD2, - 0x55, 0x16, 0x96, 0x0C, 0xED, 0x28, 0x99, 0xF2, 0x6A, 0x72, 0xFE, 0x26, 0xD0, 0xE0, 0x2A, 0x9D, 0xAE, 0x81, 0x67, 0x1F, - 0x46, 0x5B, 0xA1, 0x1D, 0x12, 0x40, 0x7A, 0xBF, 0xDB, 0x83, 0x6C, 0x15, 0xCB, 0x3A, 0x8C, 0x61, 0x76, 0xB3, 0x30, 0x70, - 0xDF, 0xBC, 0x47, 0xEA, 0x4A, 0x90, 0x52, 0x35, 0x3A, 0xC4, 0x2F, 0xB8, 0x7E, 0x4E, 0x4D, 0x33, 0x4F, 0x69, 0xA5, 0xE0, - 0xD4, 0xAB, 0xD2, 0xDD, 0x81, 0x9F, 0x61, 0xA2, 0xC0, 0x2A, 0x51, 0xC2, 0x74, 0x51, 0xC9, 0x31, 0xAA, 0x85, 0x35, 0xF8, - 0x32, 0x8D, 0x1E, 0xC8, 0xCE, 0x7A, 0x2B, 0x9A, 0x9E, 0x01, 0x32, 0x24, 0x39, 0x64, 0x30, 0x36, 0x35, 0x32, 0x61, 0x33, - 0x2D, 0x64, 0x63, 0x63, 0x33, 0x2D, 0x34, 0x64, 0x31, 0x31, 0x2D, 0x39, 0x37, 0x35, 0x66, 0x2D, 0x37, 0x34, 0x64, 0x36, - 0x31, 0x35, 0x39, 0x38, 0x37, 0x33, 0x33, 0x66, 0x12, 0x40, 0x06, 0x8B, 0xF0, 0xC5, 0xE8, 0x99, 0x83, 0x81, 0x28, 0xBD, - 0x36, 0xD9, 0x2B, 0x01, 0xEC, 0xA9, 0x95, 0x9D, 0x00, 0xF2, 0xDB, 0x0B, 0xCB, 0xB6, 0x8B, 0x2A, 0x62, 0xD4, 0xDF, 0x46, - 0xDB, 0xB4, 0x50, 0x14, 0x9E, 0x9D, 0xCB, 0xC6, 0xBD, 0xDB, 0x2B, 0x28, 0x98, 0xFC, 0xD5, 0xFF, 0x5C, 0xAF, 0x1B, 0x8C, - 0xF7, 0x2B, 0x36, 0xFF, 0xFE, 0x2F, 0x55, 0xF3, 0xEC, 0xEB, 0xAB, 0x25, 0x47, 0x88, + 0x0A, 0xCD, 0x01, 0x0A, 0x0C, 0x2B, 0x31, 0x34, 0x31, 0x35, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x10, + 0x2A, 0x19, 0x2D, 0x63, 0xB5, 0x5F, 0x00, 0x00, 0x00, 0x00, 0x22, 0x21, 0x05, 0xBB, 0x25, 0x64, 0x9C, 0x79, + 0x4B, 0xB4, 0x6C, 0x8C, 0x57, 0x97, 0x69, 0x3C, 0xC8, 0x05, 0xB1, 0xB8, 0x46, 0xDA, 0x91, 0x17, 0x6F, 0xEC, + 0x6A, 0x3E, 0xF2, 0x1F, 0x41, 0x0B, 0xE9, 0x60, 0x43, 0x2A, 0x69, 0x0A, 0x25, 0x08, 0x01, 0x12, 0x21, 0x05, + 0x4F, 0xBF, 0xFA, 0x55, 0xEB, 0xD5, 0x23, 0xD2, 0x55, 0x16, 0x96, 0x0C, 0xED, 0x28, 0x99, 0xF2, 0x6A, 0x72, + 0xFE, 0x26, 0xD0, 0xE0, 0x2A, 0x9D, 0xAE, 0x81, 0x67, 0x1F, 0x46, 0x5B, 0xA1, 0x1D, 0x12, 0x40, 0x7A, 0xBF, + 0xDB, 0x83, 0x6C, 0x15, 0xCB, 0x3A, 0x8C, 0x61, 0x76, 0xB3, 0x30, 0x70, 0xDF, 0xBC, 0x47, 0xEA, 0x4A, 0x90, + 0x52, 0x35, 0x3A, 0xC4, 0x2F, 0xB8, 0x7E, 0x4E, 0x4D, 0x33, 0x4F, 0x69, 0xA5, 0xE0, 0xD4, 0xAB, 0xD2, 0xDD, + 0x81, 0x9F, 0x61, 0xA2, 0xC0, 0x2A, 0x51, 0xC2, 0x74, 0x51, 0xC9, 0x31, 0xAA, 0x85, 0x35, 0xF8, 0x32, 0x8D, + 0x1E, 0xC8, 0xCE, 0x7A, 0x2B, 0x9A, 0x9E, 0x01, 0x32, 0x24, 0x39, 0x64, 0x30, 0x36, 0x35, 0x32, 0x61, 0x33, + 0x2D, 0x64, 0x63, 0x63, 0x33, 0x2D, 0x34, 0x64, 0x31, 0x31, 0x2D, 0x39, 0x37, 0x35, 0x66, 0x2D, 0x37, 0x34, + 0x64, 0x36, 0x31, 0x35, 0x39, 0x38, 0x37, 0x33, 0x33, 0x66, 0x12, 0x40, 0x06, 0x8B, 0xF0, 0xC5, 0xE8, 0x99, + 0x83, 0x81, 0x28, 0xBD, 0x36, 0xD9, 0x2B, 0x01, 0xEC, 0xA9, 0x95, 0x9D, 0x00, 0xF2, 0xDB, 0x0B, 0xCB, 0xB6, + 0x8B, 0x2A, 0x62, 0xD4, 0xDF, 0x46, 0xDB, 0xB4, 0x50, 0x14, 0x9E, 0x9D, 0xCB, 0xC6, 0xBD, 0xDB, 0x2B, 0x28, + 0x98, 0xFC, 0xD5, 0xFF, 0x5C, 0xAF, 0x1B, 0x8C, 0xF7, 0x2B, 0x36, 0xFF, 0xFE, 0x2F, 0x55, 0xF3, 0xEC, 0xEB, + 0xAB, 0x25, 0x47, 0x88, ]) let senderCert = try! SenderCertificate(senderCertBits) @@ -433,7 +418,11 @@ class PublicAPITests: TestCaseBase { let aci = Aci(fromUUID: UUID()) let trustRoot = IdentityKeyPair.generate() let serverKeys = IdentityKeyPair.generate() - let serverCert = try! ServerCertificate(keyId: 1, publicKey: serverKeys.publicKey, trustRoot: trustRoot.privateKey) + let serverCert = try! ServerCertificate( + keyId: 1, + publicKey: serverKeys.publicKey, + trustRoot: trustRoot.privateKey + ) let senderAddr = try! SealedSenderAddress(aci: aci, deviceId: 1) let senderCert = try! SenderCertificate( sender: senderAddr, @@ -447,7 +436,12 @@ class PublicAPITests: TestCaseBase { XCTAssertEqual(aci, senderCert.senderAci) } - private func testRoundTrip(_ initial: Handle, serialize: (Handle) -> Data, deserialize: (Data) throws -> Handle, line: UInt = #line) { + private func testRoundTrip( + _ initial: Handle, + serialize: (Handle) -> Data, + deserialize: (Data) throws -> Handle, + line: UInt = #line + ) { let bytes = serialize(initial) let roundTripBytes = serialize(try! deserialize(bytes)) XCTAssertEqual(bytes, roundTripBytes, "\(Handle.self) did not round trip correctly", line: line) @@ -525,14 +519,36 @@ class PublicAPITests: TestCaseBase { } do { - let bundle = try! PreKeyBundle(registrationId: registrationId, deviceId: deviceId, signedPrekeyId: signedPreKeyId, signedPrekey: signedPreKey, signedPrekeySignature: signedPreKeySignature, identity: identityKeyPair.identityKey, kyberPrekeyId: kyberPreKeyId, kyberPrekey: kyberPreKey, kyberPrekeySignature: kyberPreKeySignature) + let bundle = try! PreKeyBundle( + registrationId: registrationId, + deviceId: deviceId, + signedPrekeyId: signedPreKeyId, + signedPrekey: signedPreKey, + signedPrekeySignature: signedPreKeySignature, + identity: identityKeyPair.identityKey, + kyberPrekeyId: kyberPreKeyId, + kyberPrekey: kyberPreKey, + kyberPrekeySignature: kyberPreKeySignature + ) checkConsistentFields(bundle) XCTAssertNil(bundle.preKeyId) XCTAssertNil(bundle.preKeyPublic) } do { - let bundle = try! PreKeyBundle(registrationId: registrationId, deviceId: deviceId, prekeyId: preKeyId, prekey: preKey, signedPrekeyId: signedPreKeyId, signedPrekey: signedPreKey, signedPrekeySignature: signedPreKeySignature, identity: identityKeyPair.identityKey, kyberPrekeyId: kyberPreKeyId, kyberPrekey: kyberPreKey, kyberPrekeySignature: kyberPreKeySignature) + let bundle = try! PreKeyBundle( + registrationId: registrationId, + deviceId: deviceId, + prekeyId: preKeyId, + prekey: preKey, + signedPrekeyId: signedPreKeyId, + signedPrekey: signedPreKey, + signedPrekeySignature: signedPreKeySignature, + identity: identityKeyPair.identityKey, + kyberPrekeyId: kyberPreKeyId, + kyberPrekey: kyberPreKey, + kyberPrekeySignature: kyberPreKeySignature + ) checkConsistentFields(bundle) XCTAssertEqual(bundle.preKeyId, preKeyId) XCTAssertEqual(bundle.preKeyPublic, preKey) diff --git a/swift/Tests/LibSignalClientTests/RegistrationServiceTests.swift b/swift/Tests/LibSignalClientTests/RegistrationServiceTests.swift index e7d902367..0dd8754e9 100644 --- a/swift/Tests/LibSignalClientTests/RegistrationServiceTests.swift +++ b/swift/Tests/LibSignalClientTests/RegistrationServiceTests.swift @@ -4,10 +4,11 @@ // import Foundation -@testable import LibSignalClient import SignalFfi import Testing +@testable import LibSignalClient + // These tests depend on test-only functions that aren't available on device builds to save on code size. #if !os(iOS) || targetEnvironment(simulator) @@ -51,14 +52,19 @@ class RegistrationServiceConversionTests { #expect(response.usernameHash == Data("username-hash".utf8)) #expect(response.usernameLinkHandle == UUID(uuidString: "55555555-5555-5555-5555-555555555555")) #expect(response.storageCapable == true) - #expect(response.entitlements.0 == [ - BadgeEntitlement(id: "first", visible: true, expiration: 123_456), - BadgeEntitlement(id: "second", visible: false, expiration: 555), - ]) + #expect( + response.entitlements.0 == [ + BadgeEntitlement(id: "first", visible: true, expiration: 123_456), + BadgeEntitlement(id: "second", visible: false, expiration: 555), + ] + ) #expect(response.entitlements.1 == BackupEntitlement(expiration: 888_888, level: 123)) #expect(response.reregistration == true) } + // swift-format-ignore + // The long lines are one-per-test-case; it's clearer to see the form like this. + // They'd get shorter if Swift added a `matches!` equivalent. @Test func errorConversion() { let retryLaterCase = ("RetryAfter42Seconds", { (e: Error) in if case SignalError.rateLimitedError(retryAfter: 42, message: "retry after 42s") = e { true } else { false }}) @@ -178,8 +184,9 @@ class RegistrationServiceConversionTests { ] #expect( - try invokeFnReturningCheckSvr2CredentialsResponse(fn: signal_testing_registration_service_check_svr2_credentials_response_convert) == - expectedEntries + try invokeFnReturningCheckSvr2CredentialsResponse( + fn: signal_testing_registration_service_check_svr2_credentials_response_convert + ) == expectedEntries ) } @@ -190,7 +197,9 @@ class RegistrationServiceConversionTests { try key.withNativeHandle { key in try signedPublicPreKey.withNativeStruct { signedPublicPreKey in - try checkError(signal_testing_signed_public_pre_key_check_bridges_correctly(key.const(), signedPublicPreKey)) + try checkError( + signal_testing_signed_public_pre_key_check_bridges_correctly(key.const(), signedPublicPreKey) + ) } } } @@ -204,7 +213,8 @@ class RegistrationServiceFakeChatTests { async let startCreateSessionRequest = RegistrationService.fakeCreateSession( fakeChatServer: server, - e164: "+18005550123", pushToken: "myPushToken" + e164: "+18005550123", + pushToken: "myPushToken" ) let fakeRemote = try await server.getNextRemote() @@ -219,14 +229,16 @@ class RegistrationServiceFakeChatTests { status: 200, message: "OK", headers: ["content-type": "application/json"], - body: Data(""" + body: Data( + """ { "allowedToRequestCode": true, "verified": false, "requestedInformation": ["pushChallenge", "captcha"], "id": "fake-session-A" } - """.utf8) + """.utf8 + ) ) ) @@ -236,11 +248,10 @@ class RegistrationServiceFakeChatTests { let sessionState = session.sessionState #expect(sessionState.verified == false) #expect( - sessionState.requestedInformation == - [ - .pushChallenge, - .captcha, - ] + sessionState.requestedInformation == [ + .pushChallenge, + .captcha, + ] ) async let requestVerification: () = session.requestVerificationCode( @@ -254,14 +265,15 @@ class RegistrationServiceFakeChatTests { #expect(secondRequest.method == "POST") #expect(secondRequest.pathAndQuery == "/v1/verification/session/fake-session-A/code") #expect( - secondRequest.body == - Data(""" + secondRequest.body + == Data( + """ {"transport":"voice","client":"libsignal test"} - """.utf8) + """.utf8 + ) ) #expect( - secondRequest.headers == - ["content-type": "application/json", "accept-language": "fr-CA"] + secondRequest.headers == ["content-type": "application/json", "accept-language": "fr-CA"] ) try fakeRemote.sendResponse( @@ -270,7 +282,8 @@ class RegistrationServiceFakeChatTests { status: 200, message: "OK", headers: ["content-type": "application/json"], - body: Data(""" + body: Data( + """ { "allowedToRequestCode": true, "verified": false, @@ -278,7 +291,8 @@ class RegistrationServiceFakeChatTests { "id": "fake-session-A" } """ - .utf8) + .utf8 + ) ) ) @@ -293,7 +307,8 @@ class RegistrationServiceFakeChatTests { async let startCreateSessionRequest = RegistrationService.fakeCreateSession( fakeChatServer: server, - e164: "+18005550123", pushToken: "myPushToken" + e164: "+18005550123", + pushToken: "myPushToken" ) let fakeRemote = try await server.getNextRemote() @@ -317,7 +332,8 @@ class RegistrationServiceFakeChatTests { "id": "fake-session-A" } """ - .utf8) + .utf8 + ) ) ) @@ -338,7 +354,7 @@ class RegistrationServiceFakeChatTests { registrationLock: "registration lock", unidentifiedAccessKey: unidentifiedAccessKey, unrestrictedUnidentifiedAccess: - true, + true, capabilities: ["capable"], discoverableByPhoneNumber: true ), @@ -360,8 +376,7 @@ class RegistrationServiceFakeChatTests { [ "content-type": "application/json", "authorization": "Basic " + Data("+18005550123:account password".utf8).base64EncodedString(), - ] == - secondRequest.headers + ] == secondRequest.headers ) let secondRequestBodyJson = try JSONSerialization.jsonObject(with: secondRequest.body) @@ -388,8 +403,12 @@ class RegistrationServiceFakeChatTests { #expect(accountAttributes["fetchesMessages"] as? Bool == false) } - #expect(Data(aciKeys.publicKey.serialize()).base64EncodedString() == secondRequestJson["aciIdentityKey"] as? String) - #expect(Data(pniKeys.publicKey.serialize()).base64EncodedString() == secondRequestJson["pniIdentityKey"] as? String) + #expect( + Data(aciKeys.publicKey.serialize()).base64EncodedString() == secondRequestJson["aciIdentityKey"] as? String + ) + #expect( + Data(pniKeys.publicKey.serialize()).base64EncodedString() == secondRequestJson["pniIdentityKey"] as? String + ) // We don't need to check all the keys, just one of each kind is enough. do { @@ -398,14 +417,20 @@ class RegistrationServiceFakeChatTests { } #expect(aciSignedPreKey["signature"] as? String == Data("EC signature".utf8).base64EncodedString()) #expect(aciSignedPreKey["keyId"] as? Double == 1) - #expect(aciSignedPreKey["publicKey"] as? String == Data(aciKeys.signedPreKey.publicKey.serialize()).base64EncodedString()) + #expect( + aciSignedPreKey["publicKey"] as? String + == Data(aciKeys.signedPreKey.publicKey.serialize()).base64EncodedString() + ) guard let aciPqLastResortPreKey = secondRequestJson["aciPqLastResortPreKey"] as? [String: Any] else { fatalError("aciSignedPreKey was \(String(describing: secondRequestJson["aciPqLastResortPreKey"]))") } #expect(aciPqLastResortPreKey["signature"] as? String == Data("KEM signature".utf8).base64EncodedString()) #expect(aciPqLastResortPreKey["keyId"] as? Double == 2) - #expect(aciPqLastResortPreKey["publicKey"] as? String == Data(aciKeys.pqLastResortPreKey.publicKey.serialize()).base64EncodedString()) + #expect( + aciPqLastResortPreKey["publicKey"] as? String + == Data(aciKeys.pqLastResortPreKey.publicKey.serialize()).base64EncodedString() + ) } try fakeRemote.sendResponse( @@ -414,7 +439,8 @@ class RegistrationServiceFakeChatTests { status: 200, message: "OK", headers: ["content-type": "application/json"], - body: Data(""" + body: Data( + """ { "uuid": "aabbaabb-5555-6666-8888-111111111111", "pni": "ddeeddee-5555-6666-8888-111111111111", @@ -437,7 +463,8 @@ class RegistrationServiceFakeChatTests { } } """ - .utf8) + .utf8 + ) ) ) @@ -458,13 +485,16 @@ class RegistrationServiceFakeChatTests { return RegisterAccountKeys( publicKey: PrivateKey.generate().publicKey, signedPreKey: SignedPublicPreKey( - keyId: 1, publicKey: PrivateKey.generate().publicKey, signature: Data("EC signature".utf8) + keyId: 1, + publicKey: PrivateKey.generate().publicKey, + signature: Data("EC signature".utf8) ), pqLastResortPreKey: SignedPublicPreKey( keyId: 2, publicKey: KEMKeyPair.generate().publicKey, signature: Data( - "KEM signature".utf8) + "KEM signature".utf8 + ) ) ) } @@ -479,13 +509,24 @@ extension RegistrationService { mcc: String? = nil, mnc: String? = nil ) async throws -> RegistrationService { - let registrationService: SignalMutPointerRegistrationService = try await fakeChatServer.asyncContext.invokeAsyncFunction { promise, asyncContext in - SignalFfiRegistrationCreateSessionRequest.withNativeStruct(e164: e164, pushToken: pushToken, mcc: mcc, mnc: mnc) { request in - fakeChatServer.withNativeHandle { fakeChatServer in - signal_testing_fake_registration_session_create_session(promise, asyncContext.const(), request, fakeChatServer.const()) + let registrationService: SignalMutPointerRegistrationService = try await fakeChatServer.asyncContext + .invokeAsyncFunction { promise, asyncContext in + SignalFfiRegistrationCreateSessionRequest.withNativeStruct( + e164: e164, + pushToken: pushToken, + mcc: mcc, + mnc: mnc + ) { request in + fakeChatServer.withNativeHandle { fakeChatServer in + signal_testing_fake_registration_session_create_session( + promise, + asyncContext.const(), + request, + fakeChatServer.const() + ) + } } } - } return RegistrationService(owned: NonNull(registrationService)!, asyncContext: fakeChatServer.asyncContext) } } diff --git a/swift/Tests/LibSignalClientTests/ServiceIdTests.swift b/swift/Tests/LibSignalClientTests/ServiceIdTests.swift index 5e4431a4d..3b355ab2a 100644 --- a/swift/Tests/LibSignalClientTests/ServiceIdTests.swift +++ b/swift/Tests/LibSignalClientTests/ServiceIdTests.swift @@ -4,9 +4,8 @@ // import Foundation -import XCTest - import LibSignalClient +import XCTest class ServiceIdTests: TestCaseBase { static let TEST_UUID_STRING = "e36fdce7-36da-4c6f-a21b-9afe2b754650" @@ -42,15 +41,21 @@ class ServiceIdTests: TestCaseBase { // swiftlint:disable force_cast func testParseFromString() throws { - _ = try! ServiceId.parseFrom( - serviceIdString: Self.TEST_UUID_STRING) as! Aci + _ = + try! ServiceId.parseFrom( + serviceIdString: Self.TEST_UUID_STRING + ) as! Aci let _: Aci = try! Aci.parseFrom( - serviceIdString: Self.TEST_UUID_STRING) + serviceIdString: Self.TEST_UUID_STRING + ) - _ = try! ServiceId.parseFrom( - serviceIdString: "PNI:" + Self.TEST_UUID_STRING) as! Pni + _ = + try! ServiceId.parseFrom( + serviceIdString: "PNI:" + Self.TEST_UUID_STRING + ) as! Pni let _: Pni = try! Pni.parseFrom( - serviceIdString: "PNI:" + Self.TEST_UUID_STRING) + serviceIdString: "PNI:" + Self.TEST_UUID_STRING + ) do { _ = try ServiceId.parseFrom(serviceIdString: "ACI:" + Self.TEST_UUID_STRING) @@ -63,15 +68,21 @@ class ServiceIdTests: TestCaseBase { } func testParseFromBinary() throws { - _ = try! ServiceId.parseFrom( - serviceIdBinary: Aci(fromUUID: UUID()).serviceIdBinary) as! Aci + _ = + try! ServiceId.parseFrom( + serviceIdBinary: Aci(fromUUID: UUID()).serviceIdBinary + ) as! Aci let _: Aci = try! Aci.parseFrom( - serviceIdBinary: Aci(fromUUID: UUID()).serviceIdBinary) + serviceIdBinary: Aci(fromUUID: UUID()).serviceIdBinary + ) - _ = try! ServiceId.parseFrom( - serviceIdBinary: Pni(fromUUID: UUID()).serviceIdBinary) as! Pni + _ = + try! ServiceId.parseFrom( + serviceIdBinary: Pni(fromUUID: UUID()).serviceIdBinary + ) as! Pni let _: Pni = try! Pni.parseFrom( - serviceIdBinary: Pni(fromUUID: UUID()).serviceIdBinary) + serviceIdBinary: Pni(fromUUID: UUID()).serviceIdBinary + ) do { _ = try ServiceId.parseFrom(serviceIdBinary: [0] + Self.TEST_UUID_BYTES) diff --git a/swift/Tests/LibSignalClientTests/SessionTests.swift b/swift/Tests/LibSignalClientTests/SessionTests.swift index 26683b70a..b3b8e9ad5 100644 --- a/swift/Tests/LibSignalClientTests/SessionTests.swift +++ b/swift/Tests/LibSignalClientTests/SessionTests.swift @@ -145,8 +145,12 @@ class SessionTests: TestCaseBase { let bob_identity_key_pair = try! bob_store.identityKeyPair(context: NullContext()) let bob_identity_key = bob_identity_key_pair.identityKey - let bob_signed_pre_key_signature = bob_identity_key_pair.privateKey.generateSignature(message: bob_signed_pre_key_public) - let bob_kyber_pre_key_signature = bob_identity_key_pair.privateKey.generateSignature(message: bob_kyber_pre_key_public) + let bob_signed_pre_key_signature = bob_identity_key_pair.privateKey.generateSignature( + message: bob_signed_pre_key_public + ) + let bob_kyber_pre_key_signature = bob_identity_key_pair.privateKey.generateSignature( + message: bob_kyber_pre_key_public + ) let prekey_id: UInt32 = 4570 let signed_prekey_id: UInt32 = 3006 @@ -199,14 +203,16 @@ class SessionTests: TestCaseBase { XCTAssertTrue(updated_session.hasCurrentState(now: Date(timeIntervalSinceReferenceDate: 0))) XCTAssertFalse(updated_session.hasCurrentState(now: Date(timeIntervalSinceReferenceDate: 60 * 60 * 24 * 90))) - XCTAssertThrowsError(try signalEncrypt( - message: ptext_a, - for: bob_address, - sessionStore: alice_store, - identityStore: alice_store, - now: Date(timeIntervalSinceReferenceDate: 60 * 60 * 24 * 90), - context: NullContext() - )) + XCTAssertThrowsError( + try signalEncrypt( + message: ptext_a, + for: bob_address, + sessionStore: alice_store, + identityStore: alice_store, + now: Date(timeIntervalSinceReferenceDate: 60 * 60 * 24 * 90), + context: NullContext() + ) + ) } func testSealedSenderSession() throws { @@ -220,7 +226,11 @@ class SessionTests: TestCaseBase { let trust_root = IdentityKeyPair.generate() let server_keys = IdentityKeyPair.generate() - let server_cert = try! ServerCertificate(keyId: 1, publicKey: server_keys.publicKey, trustRoot: trust_root.privateKey) + let server_cert = try! ServerCertificate( + keyId: 1, + publicKey: server_keys.publicKey, + trustRoot: trust_root.privateKey + ) let sender_addr = try! SealedSenderAddress( e164: "+14151111111", uuidString: alice_address.name, @@ -271,7 +281,11 @@ class SessionTests: TestCaseBase { context: NullContext() ) - let usmc = try! UnidentifiedSenderMessageContent(message: ciphertext, identityStore: bob_store, context: NullContext()) + let usmc = try! UnidentifiedSenderMessageContent( + message: ciphertext, + identityStore: bob_store, + context: NullContext() + ) XCTAssertEqual(usmc.messageType, .preKey) XCTAssertTrue(try! usmc.senderCertificate.validate(trustRoot: trust_root.publicKey, time: 31335)) XCTAssertEqual(usmc.senderCertificate.sender, sender_addr) @@ -353,7 +367,11 @@ class SessionTests: TestCaseBase { let trust_root = IdentityKeyPair.generate() let server_keys = IdentityKeyPair.generate() - let server_cert = try! ServerCertificate(keyId: 1, publicKey: server_keys.publicKey, trustRoot: trust_root.privateKey) + let server_cert = try! ServerCertificate( + keyId: 1, + publicKey: server_keys.publicKey, + trustRoot: trust_root.privateKey + ) let sender_addr = try! SealedSenderAddress( e164: "+14151111111", uuidString: alice_address.name, @@ -475,7 +493,11 @@ class SessionTests: TestCaseBase { let trust_root = IdentityKeyPair.generate() let server_keys = IdentityKeyPair.generate() - let server_cert = try! ServerCertificate(keyId: 1, publicKey: server_keys.publicKey, trustRoot: trust_root.privateKey) + let server_cert = try! ServerCertificate( + keyId: 1, + publicKey: server_keys.publicKey, + trustRoot: trust_root.privateKey + ) let sender_addr = try! SealedSenderAddress( e164: "+14151111111", uuidString: alice_address.name, @@ -541,7 +563,11 @@ class SessionTests: TestCaseBase { let trust_root = IdentityKeyPair.generate() let server_keys = IdentityKeyPair.generate() - let server_cert = try! ServerCertificate(keyId: 1, publicKey: server_keys.publicKey, trustRoot: trust_root.privateKey) + let server_cert = try! ServerCertificate( + keyId: 1, + publicKey: server_keys.publicKey, + trustRoot: trust_root.privateKey + ) let sender_addr = try! SealedSenderAddress( e164: "+14151111111", uuidString: alice_address.name, @@ -579,14 +605,16 @@ class SessionTests: TestCaseBase { groupId: [42] ) - let sent_message = Data(try! sealedSenderMultiRecipientEncrypt( - a_usmc, - for: [bob_address], - excludedRecipients: [eve_service_id, mallory_service_id], - identityStore: alice_store, - sessionStore: alice_store, - context: NullContext() - )) + let sent_message = Data( + try! sealedSenderMultiRecipientEncrypt( + a_usmc, + for: [bob_address], + excludedRecipients: [eve_service_id, mallory_service_id], + identityStore: alice_store, + sessionStore: alice_store, + context: NullContext() + ) + ) // Clients can't directly parse arbitrary SSv2 SentMessages, so just check that it contains // the excluded recipient service IDs followed by a device ID of 0. @@ -642,7 +670,11 @@ class SessionTests: TestCaseBase { let trust_root = IdentityKeyPair.generate() let server_keys = IdentityKeyPair.generate() - let server_cert = try! ServerCertificate(keyId: 1, publicKey: server_keys.publicKey, trustRoot: trust_root.privateKey) + let server_cert = try! ServerCertificate( + keyId: 1, + publicKey: server_keys.publicKey, + trustRoot: trust_root.privateKey + ) let sender_addr = try! SealedSenderAddress( e164: "+14151111111", uuidString: alice_address.name, @@ -708,8 +740,12 @@ private func initializeSessionsV4( let bob_identity_key_pair = try! bob_store.identityKeyPair(context: NullContext()) let bob_identity_key = bob_identity_key_pair.identityKey - let bob_signed_pre_key_signature = bob_identity_key_pair.privateKey.generateSignature(message: bob_signed_pre_key_public) - let bob_kyber_pre_key_signature = bob_identity_key_pair.privateKey.generateSignature(message: bob_kyber_pre_key_public) + let bob_signed_pre_key_signature = bob_identity_key_pair.privateKey.generateSignature( + message: bob_signed_pre_key_public + ) + let bob_kyber_pre_key_signature = bob_identity_key_pair.privateKey.generateSignature( + message: bob_kyber_pre_key_public + ) let prekey_id: UInt32 = 4570 let signed_prekey_id: UInt32 = 3006 diff --git a/swift/Tests/LibSignalClientTests/SgxTests.swift b/swift/Tests/LibSignalClientTests/SgxTests.swift index aa5433cff..c43eee0f3 100644 --- a/swift/Tests/LibSignalClientTests/SgxTests.swift +++ b/swift/Tests/LibSignalClientTests/SgxTests.swift @@ -18,7 +18,6 @@ class SgxTests: TestCaseBase { readResource(forName: "cds2handshakestart.data"), Date(timeIntervalSince1970: 1_655_857_680) ), - ( ServiceType.svr2, [UInt8](fromHexString: "38e01eff4fe357dc0b0e8ef7a44b4abc5489fbccba3a78780f3872c277f62bf3")!, @@ -27,18 +26,36 @@ class SgxTests: TestCaseBase { ), ] - static func build(serviceType: ServiceType, mrenclave: [UInt8], attestationMessage: Data, currentDate: Date) throws -> SgxClient { + static func build( + serviceType: ServiceType, + mrenclave: [UInt8], + attestationMessage: Data, + currentDate: Date + ) throws -> SgxClient { switch serviceType { case .cds2: - return try Cds2Client(mrenclave: mrenclave, attestationMessage: attestationMessage, currentDate: currentDate) + return try Cds2Client( + mrenclave: mrenclave, + attestationMessage: attestationMessage, + currentDate: currentDate + ) case .svr2: - return try Svr2Client(mrenclave: mrenclave, attestationMessage: attestationMessage, currentDate: currentDate) + return try Svr2Client( + mrenclave: mrenclave, + attestationMessage: attestationMessage, + currentDate: currentDate + ) } } func testCreateClient() { for (serviceType, mrenclave, attestationMessage, currentDate) in self.testCases { - let client = try! SgxTests.build(serviceType: serviceType, mrenclave: mrenclave, attestationMessage: attestationMessage, currentDate: currentDate) + let client = try! SgxTests.build( + serviceType: serviceType, + mrenclave: mrenclave, + attestationMessage: attestationMessage, + currentDate: currentDate + ) let initialMessage = client.initialRequest() XCTAssertEqual(serviceType == .svr2 ? 48 : 1632, initialMessage.count, String(describing: serviceType)) } @@ -53,7 +70,8 @@ class SgxTests: TestCaseBase { mrenclave: invalidMrenclave, attestationMessage: attestationMessage, currentDate: currentDate - ), String(describing: serviceType) + ), + String(describing: serviceType) ) } } @@ -67,7 +85,8 @@ class SgxTests: TestCaseBase { mrenclave: mrenclave, attestationMessage: invalidMessage, currentDate: currentDate - ), String(describing: serviceType) + ), + String(describing: serviceType) ) } } diff --git a/swift/Tests/LibSignalClientTests/TestCaseBase.swift b/swift/Tests/LibSignalClientTests/TestCaseBase.swift index 1b0ebd92e..aa11cf5ad 100644 --- a/swift/Tests/LibSignalClientTests/TestCaseBase.swift +++ b/swift/Tests/LibSignalClientTests/TestCaseBase.swift @@ -10,7 +10,8 @@ class TestCaseBase: XCTestCase { // Use a static stored property for one-time initialization. static let loggingInitialized: Bool = { struct LogToNSLog: LibsignalLogger { - func log(level: LibsignalLogLevel, file: UnsafePointer?, line: UInt32, message: UnsafePointer) { + func log(level: LibsignalLogLevel, file: UnsafePointer?, line: UInt32, message: UnsafePointer) + { let abbreviation: String switch level { case .error: abbreviation = "E" diff --git a/swift/Tests/LibSignalClientTests/TestUtils.swift b/swift/Tests/LibSignalClientTests/TestUtils.swift index 1859b2b8f..1bc68b5ba 100644 --- a/swift/Tests/LibSignalClientTests/TestUtils.swift +++ b/swift/Tests/LibSignalClientTests/TestUtils.swift @@ -3,9 +3,10 @@ // SPDX-License-Identifier: AGPL-3.0-only // -@testable import LibSignalClient import XCTest +@testable import LibSignalClient + class BadStore: InMemorySignalProtocolStore { enum Error: Swift.Error { case badness diff --git a/swift/Tests/LibSignalClientTests/UsernameTests.swift b/swift/Tests/LibSignalClientTests/UsernameTests.swift index 798aa93fe..fef1d06c8 100644 --- a/swift/Tests/LibSignalClientTests/UsernameTests.swift +++ b/swift/Tests/LibSignalClientTests/UsernameTests.swift @@ -46,12 +46,15 @@ class UsernameTests: TestCaseBase { func testValidUsernameHashing() throws { let username = try Username("he110.42") XCTAssertEqual(32, username.hash.count) - XCTAssertEqual(Data([ - 0xF6, 0x3F, 0x05, 0x21, 0xEB, 0x3A, 0xDF, 0xE1, - 0xD9, 0x36, 0xF4, 0xB6, 0x26, 0xB8, 0x95, 0x58, - 0x48, 0x35, 0x07, 0xFB, 0xDB, 0x83, 0x8F, 0xC5, - 0x54, 0xAF, 0x05, 0x91, 0x11, 0xCF, 0x32, 0x2E, - ]), username.hash) + XCTAssertEqual( + Data([ + 0xF6, 0x3F, 0x05, 0x21, 0xEB, 0x3A, 0xDF, 0xE1, + 0xD9, 0x36, 0xF4, 0xB6, 0x26, 0xB8, 0x95, 0x58, + 0x48, 0x35, 0x07, 0xFB, 0xDB, 0x83, 0x8F, 0xC5, + 0x54, 0xAF, 0x05, 0x91, 0x11, 0xCF, 0x32, 0x2E, + ]), + username.hash + ) } func testInvalidHash() throws { diff --git a/swift/Tests/LibSignalClientTests/ZKGroupTests.swift b/swift/Tests/LibSignalClientTests/ZKGroupTests.swift index 0e06cad7f..204d4568c 100644 --- a/swift/Tests/LibSignalClientTests/ZKGroupTests.swift +++ b/swift/Tests/LibSignalClientTests/ZKGroupTests.swift @@ -10,39 +10,53 @@ import Testing private let SECONDS_PER_DAY: UInt64 = 24 * 60 * 60 class ZKGroupTests { - let TEST_ARRAY_16: UUID = .init(uuid: (0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F)) + let TEST_ARRAY_16: UUID = .init( + uuid: (0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F) + ) - let TEST_ARRAY_16_1: UUID = .init(uuid: (0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73)) + let TEST_ARRAY_16_1: UUID = .init( + uuid: (0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73) + ) - let TEST_ARRAY_32: Randomness = .init(( - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F - )) + let TEST_ARRAY_32: Randomness = .init( + ( + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F + ) + ) let TEST_ARRAY_32_1 = Data([ 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, ]) - let TEST_ARRAY_32_2: Randomness = .init(( - 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, - 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7 - )) + let TEST_ARRAY_32_2: Randomness = .init( + ( + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7 + ) + ) - let TEST_ARRAY_32_3: Randomness = .init(( - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32 - )) + let TEST_ARRAY_32_3: Randomness = .init( + ( + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32 + ) + ) - let TEST_ARRAY_32_4: Randomness = .init(( - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33 - )) + let TEST_ARRAY_32_4: Randomness = .init( + ( + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33 + ) + ) - let TEST_ARRAY_32_5: Randomness = .init(( - 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22 - )) + let TEST_ARRAY_32_5: Randomness = .init( + ( + 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22 + ) + ) let authPresentationResult: [UInt8] = [ 0x01, 0x32, 0x2F, 0x91, 0x00, 0xDE, 0x07, 0x34, 0x55, 0x0A, 0x81, 0xDC, 0x81, 0x72, 0x4A, 0x81, @@ -126,13 +140,23 @@ class ZKGroupTests { // SERVER // Issue credential - let authCredentialResponse = try serverZkAuth.issueAuthCredentialWithPniZkc(randomness: self.TEST_ARRAY_32_2, aci: aci, pni: pni, redemptionTime: redemptionTime) + let authCredentialResponse = try serverZkAuth.issueAuthCredentialWithPniZkc( + randomness: self.TEST_ARRAY_32_2, + aci: aci, + pni: pni, + redemptionTime: redemptionTime + ) // CLIENT // Receive credential let clientZkAuthCipher = ClientZkAuthOperations(serverPublicParams: serverPublicParams) let clientZkGroupCipher = ClientZkGroupCipher(groupSecretParams: groupSecretParams) - let authCredential = try clientZkAuthCipher.receiveAuthCredentialWithPniAsServiceId(aci: aci, pni: pni, redemptionTime: redemptionTime, authCredentialResponse: authCredentialResponse) + let authCredential = try clientZkAuthCipher.receiveAuthCredentialWithPniAsServiceId( + aci: aci, + pni: pni, + redemptionTime: redemptionTime, + authCredentialResponse: authCredentialResponse + ) // Create and decrypt user entry let aciCiphertext = try clientZkGroupCipher.encrypt(aci) @@ -143,14 +167,22 @@ class ZKGroupTests { #expect(pni == pniPlaintext) // Create presentation - let presentation = try clientZkAuthCipher.createAuthCredentialPresentation(randomness: self.TEST_ARRAY_32_5, groupSecretParams: groupSecretParams, authCredential: authCredential) + let presentation = try clientZkAuthCipher.createAuthCredentialPresentation( + randomness: self.TEST_ARRAY_32_5, + groupSecretParams: groupSecretParams, + authCredential: authCredential + ) // Verify presentation let uuidCiphertextRecv = try presentation.getUuidCiphertext() #expect(aciCiphertext.serialize() == uuidCiphertextRecv.serialize()) #expect(try presentation.getPniCiphertext().serialize() == pniCiphertext.serialize()) #expect(try presentation.getRedemptionTime() == Date(timeIntervalSince1970: TimeInterval(redemptionTime))) - try serverZkAuth.verifyAuthCredentialPresentation(groupPublicParams: groupPublicParams, authCredentialPresentation: presentation, now: Date(timeIntervalSince1970: TimeInterval(redemptionTime))) + try serverZkAuth.verifyAuthCredentialPresentation( + groupPublicParams: groupPublicParams, + authCredentialPresentation: presentation, + now: Date(timeIntervalSince1970: TimeInterval(redemptionTime)) + ) } @Test @@ -177,19 +209,32 @@ class ZKGroupTests { let profileKeyCommitment = try profileKey.getCommitment(userId: userId) // Create context and request - let context = try clientZkProfileCipher.createProfileKeyCredentialRequestContext(randomness: self.TEST_ARRAY_32_3, userId: userId, profileKey: profileKey) + let context = try clientZkProfileCipher.createProfileKeyCredentialRequestContext( + randomness: self.TEST_ARRAY_32_3, + userId: userId, + profileKey: profileKey + ) let request = try context.getRequest() // SERVER let now = UInt64(Date().timeIntervalSince1970) let startOfDay = now - (now % SECONDS_PER_DAY) let expiration = startOfDay + 5 * SECONDS_PER_DAY - let response = try serverZkProfile.issueExpiringProfileKeyCredential(randomness: self.TEST_ARRAY_32_4, profileKeyCredentialRequest: request, userId: userId, profileKeyCommitment: profileKeyCommitment, expiration: expiration) + let response = try serverZkProfile.issueExpiringProfileKeyCredential( + randomness: self.TEST_ARRAY_32_4, + profileKeyCredentialRequest: request, + userId: userId, + profileKeyCommitment: profileKeyCommitment, + expiration: expiration + ) // CLIENT // Gets stored profile credential let clientZkGroupCipher = ClientZkGroupCipher(groupSecretParams: groupSecretParams) - let profileKeyCredential = try clientZkProfileCipher.receiveExpiringProfileKeyCredential(profileKeyCredentialRequestContext: context, profileKeyCredentialResponse: response) + let profileKeyCredential = try clientZkProfileCipher.receiveExpiringProfileKeyCredential( + profileKeyCredentialRequestContext: context, + profileKeyCredentialResponse: response + ) // Create encrypted UID and profile key let uuidCiphertext = try clientZkGroupCipher.encrypt(userId) @@ -197,21 +242,43 @@ class ZKGroupTests { #expect(plaintext == userId) let profileKeyCiphertext = try clientZkGroupCipher.encryptProfileKey(profileKey: profileKey, userId: userId) - let decryptedProfileKey = try clientZkGroupCipher.decryptProfileKey(profileKeyCiphertext: profileKeyCiphertext, userId: userId) + let decryptedProfileKey = try clientZkGroupCipher.decryptProfileKey( + profileKeyCiphertext: profileKeyCiphertext, + userId: userId + ) #expect(profileKey.serialize() == decryptedProfileKey.serialize()) #expect(Date(timeIntervalSince1970: TimeInterval(expiration)) == profileKeyCredential.expirationTime) - let presentation = try clientZkProfileCipher.createProfileKeyCredentialPresentation(randomness: self.TEST_ARRAY_32_5, groupSecretParams: groupSecretParams, profileKeyCredential: profileKeyCredential) + let presentation = try clientZkProfileCipher.createProfileKeyCredentialPresentation( + randomness: self.TEST_ARRAY_32_5, + groupSecretParams: groupSecretParams, + profileKeyCredential: profileKeyCredential + ) // Verify presentation - try serverZkProfile.verifyProfileKeyCredentialPresentation(groupPublicParams: groupPublicParams, profileKeyCredentialPresentation: presentation) - try serverZkProfile.verifyProfileKeyCredentialPresentation(groupPublicParams: groupPublicParams, profileKeyCredentialPresentation: presentation, now: Date(timeIntervalSince1970: TimeInterval(expiration - 5))) + try serverZkProfile.verifyProfileKeyCredentialPresentation( + groupPublicParams: groupPublicParams, + profileKeyCredentialPresentation: presentation + ) + try serverZkProfile.verifyProfileKeyCredentialPresentation( + groupPublicParams: groupPublicParams, + profileKeyCredentialPresentation: presentation, + now: Date(timeIntervalSince1970: TimeInterval(expiration - 5)) + ) #expect(throws: SignalError.self) { - try serverZkProfile.verifyProfileKeyCredentialPresentation(groupPublicParams: groupPublicParams, profileKeyCredentialPresentation: presentation, now: Date(timeIntervalSince1970: TimeInterval(expiration))) + try serverZkProfile.verifyProfileKeyCredentialPresentation( + groupPublicParams: groupPublicParams, + profileKeyCredentialPresentation: presentation, + now: Date(timeIntervalSince1970: TimeInterval(expiration)) + ) } #expect(throws: SignalError.self) { - try serverZkProfile.verifyProfileKeyCredentialPresentation(groupPublicParams: groupPublicParams, profileKeyCredentialPresentation: presentation, now: Date(timeIntervalSince1970: TimeInterval(expiration + 5))) + try serverZkProfile.verifyProfileKeyCredentialPresentation( + groupPublicParams: groupPublicParams, + profileKeyCredentialPresentation: presentation, + now: Date(timeIntervalSince1970: TimeInterval(expiration + 5)) + ) } let uuidCiphertextRecv = try presentation.getUuidCiphertext() @@ -342,18 +409,39 @@ class ZKGroupTests { // Server let now = UInt64(Date().timeIntervalSince1970) let startOfDay = now - (now % SECONDS_PER_DAY) - let response = request.issueCredential(userId: userId, timestamp: Date(timeIntervalSince1970: TimeInterval(startOfDay)), params: serverSecretParams, randomness: self.TEST_ARRAY_32_4) + let response = request.issueCredential( + userId: userId, + timestamp: Date(timeIntervalSince1970: TimeInterval(startOfDay)), + params: serverSecretParams, + randomness: self.TEST_ARRAY_32_4 + ) // Client let credential = try context.receive(response, userId: userId, params: serverPublicParams) - let presentation = credential.present(roomId: roomId, userId: userId, serverParams: serverPublicParams, callLinkParams: clientSecretParams, randomness: self.TEST_ARRAY_32_5) + let presentation = credential.present( + roomId: roomId, + userId: userId, + serverParams: serverPublicParams, + callLinkParams: clientSecretParams, + randomness: self.TEST_ARRAY_32_5 + ) // Server try presentation.verify(roomId: roomId, serverParams: serverSecretParams, callLinkParams: clientPublicParams) - try presentation.verify(roomId: roomId, now: Date(timeIntervalSince1970: TimeInterval(startOfDay + SECONDS_PER_DAY)), serverParams: serverSecretParams, callLinkParams: clientPublicParams) + try presentation.verify( + roomId: roomId, + now: Date(timeIntervalSince1970: TimeInterval(startOfDay + SECONDS_PER_DAY)), + serverParams: serverSecretParams, + callLinkParams: clientPublicParams + ) #expect(throws: SignalError.self) { - try presentation.verify(roomId: roomId, now: Date(timeIntervalSince1970: TimeInterval(startOfDay + 30 * 60 * 60)), serverParams: serverSecretParams, callLinkParams: clientPublicParams) + try presentation.verify( + roomId: roomId, + now: Date(timeIntervalSince1970: TimeInterval(startOfDay + 30 * 60 * 60)), + serverParams: serverSecretParams, + callLinkParams: clientPublicParams + ) } } @@ -370,18 +458,41 @@ class ZKGroupTests { let now = UInt64(Date().timeIntervalSince1970) let startOfDay = now - (now % SECONDS_PER_DAY) let redemptionTime = Date(timeIntervalSince1970: TimeInterval(startOfDay)) - let response = CallLinkAuthCredentialResponse.issueCredential(userId: userId, redemptionTime: redemptionTime, params: serverSecretParams, randomness: self.TEST_ARRAY_32_4) + let response = CallLinkAuthCredentialResponse.issueCredential( + userId: userId, + redemptionTime: redemptionTime, + params: serverSecretParams, + randomness: self.TEST_ARRAY_32_4 + ) // Client - let credential = try response.receive(userId: userId, redemptionTime: redemptionTime, params: serverPublicParams) - let presentation = credential.present(userId: userId, redemptionTime: redemptionTime, serverParams: serverPublicParams, callLinkParams: clientSecretParams, randomness: self.TEST_ARRAY_32_5) + let credential = try response.receive( + userId: userId, + redemptionTime: redemptionTime, + params: serverPublicParams + ) + let presentation = credential.present( + userId: userId, + redemptionTime: redemptionTime, + serverParams: serverPublicParams, + callLinkParams: clientSecretParams, + randomness: self.TEST_ARRAY_32_5 + ) // Server try presentation.verify(serverParams: serverSecretParams, callLinkParams: clientPublicParams) - try presentation.verify(now: Date(timeIntervalSince1970: TimeInterval(startOfDay + SECONDS_PER_DAY)), serverParams: serverSecretParams, callLinkParams: clientPublicParams) + try presentation.verify( + now: Date(timeIntervalSince1970: TimeInterval(startOfDay + SECONDS_PER_DAY)), + serverParams: serverSecretParams, + callLinkParams: clientPublicParams + ) #expect(throws: SignalError.self) { - try presentation.verify(now: Date(timeIntervalSince1970: TimeInterval(startOfDay + 3 * SECONDS_PER_DAY)), serverParams: serverSecretParams, callLinkParams: clientPublicParams) + try presentation.verify( + now: Date(timeIntervalSince1970: TimeInterval(startOfDay + 3 * SECONDS_PER_DAY)), + serverParams: serverSecretParams, + callLinkParams: clientPublicParams + ) } // Client @@ -390,7 +501,9 @@ class ZKGroupTests { @Test func deriveProfileKey() throws { - let expectedAccessKey = Data([0x5A, 0x72, 0x3A, 0xCE, 0xE5, 0x2C, 0x5E, 0xA0, 0x2B, 0x92, 0xA3, 0xA3, 0x60, 0xC0, 0x95, 0x95]) + let expectedAccessKey = Data([ + 0x5A, 0x72, 0x3A, 0xCE, 0xE5, 0x2C, 0x5E, 0xA0, 0x2B, 0x92, 0xA3, 0xA3, 0x60, 0xC0, 0x95, 0x95, + ]) let profileKeyBytes = Data(repeating: 0x02, count: 32) let result = try ProfileKey(contents: profileKeyBytes).deriveAccessKey() @@ -410,8 +523,13 @@ class ZKGroupTests { // These are expectations; if the contents of a credential or derivation of a backup ID // changes, they will need to be updated. - let serializedBackupID = Data([0xA2, 0x89, 0x62, 0xC7, 0xF9, 0xAC, 0x91, 0x0F, 0x66, 0xE4, 0xBC, 0xB3, 0x3F, 0x2C, 0xEF, 0x06]) - let serializedRequestCredential = Data(base64Encoded: "AISCxQa8OsFqphsQPxqtzJk5+jndpE3SJG6bfazQB399rN6N8Dv5DAwvY4N36Uj0qGf0cV5a/8rf5nkxLeVNnF3ojRSO8xaZOpKJOvWSDJIGn6EeMl2jOjx+IQg8d8M0AQ==")! + let serializedBackupID = Data([ + 0xA2, 0x89, 0x62, 0xC7, 0xF9, 0xAC, 0x91, 0x0F, 0x66, 0xE4, 0xBC, 0xB3, 0x3F, 0x2C, 0xEF, 0x06, + ]) + let serializedRequestCredential = Data( + base64Encoded: + "AISCxQa8OsFqphsQPxqtzJk5+jndpE3SJG6bfazQB399rN6N8Dv5DAwvY4N36Uj0qGf0cV5a/8rf5nkxLeVNnF3ojRSO8xaZOpKJOvWSDJIGn6EeMl2jOjx+IQg8d8M0AQ==" + )! let backupLevel = BackupLevel.free let credentialType = BackupCredentialType.messages @@ -420,12 +538,21 @@ class ZKGroupTests { let request = context.getRequest() let serverSecretParams = GenericServerSecretParams.generate(randomness: self.TEST_ARRAY_32) let serverPublicParams = serverSecretParams.getPublicParams() - #expect(request.serialize() == serializedRequestCredential, Comment(rawValue: Data(request.serialize()).base64EncodedString())) + #expect( + request.serialize() == serializedRequestCredential, + Comment(rawValue: Data(request.serialize()).base64EncodedString()) + ) let now = UInt64(Date().timeIntervalSince1970) let startOfDay = now - (now % SECONDS_PER_DAY) let redemptionTime = Date(timeIntervalSince1970: TimeInterval(startOfDay)) - let response = request.issueCredential(timestamp: redemptionTime, backupLevel: backupLevel, type: credentialType, params: serverSecretParams, randomness: self.TEST_ARRAY_32_2) + let response = request.issueCredential( + timestamp: redemptionTime, + backupLevel: backupLevel, + type: credentialType, + params: serverSecretParams, + randomness: self.TEST_ARRAY_32_2 + ) let credential = try context.receive(response, timestamp: redemptionTime, params: serverPublicParams) #expect(credential.backupID == serializedBackupID, Comment(rawValue: credential.backupID.hexString)) #expect(credential.backupLevel == backupLevel) @@ -450,7 +577,13 @@ class ZKGroupTests { let now = UInt64(Date().timeIntervalSince1970) let startOfDay = now - (now % SECONDS_PER_DAY) let redemptionTime = Date(timeIntervalSince1970: TimeInterval(startOfDay)) - let response = request.issueCredential(timestamp: redemptionTime, backupLevel: backupLevel, type: credentialType, params: serverSecretParams, randomness: self.TEST_ARRAY_32_2) + let response = request.issueCredential( + timestamp: redemptionTime, + backupLevel: backupLevel, + type: credentialType, + params: serverSecretParams, + randomness: self.TEST_ARRAY_32_2 + ) // Client let credential = try context.receive(response, timestamp: redemptionTime, params: serverPublicParams) @@ -461,16 +594,25 @@ class ZKGroupTests { // Server try presentation.verify(serverParams: serverSecretParams) - try presentation.verify(now: Date(timeIntervalSince1970: TimeInterval(startOfDay + SECONDS_PER_DAY)), serverParams: serverSecretParams) + try presentation.verify( + now: Date(timeIntervalSince1970: TimeInterval(startOfDay + SECONDS_PER_DAY)), + serverParams: serverSecretParams + ) // credential should be expired after 2 days #expect(throws: SignalError.self) { - try presentation.verify(now: Date(timeIntervalSince1970: TimeInterval(startOfDay + 1 + SECONDS_PER_DAY * 2)), serverParams: serverSecretParams) + try presentation.verify( + now: Date(timeIntervalSince1970: TimeInterval(startOfDay + 1 + SECONDS_PER_DAY * 2)), + serverParams: serverSecretParams + ) } // future credential should be invalid #expect(throws: SignalError.self) { - try presentation.verify(now: Date(timeIntervalSince1970: TimeInterval(startOfDay - 1 - SECONDS_PER_DAY)), serverParams: serverSecretParams) + try presentation.verify( + now: Date(timeIntervalSince1970: TimeInterval(startOfDay - 1 - SECONDS_PER_DAY)), + serverParams: serverSecretParams + ) } } @@ -535,9 +677,9 @@ class ZKGroupTests { serverParams: serverPublicParams ) #expect( - receivedEndorsements.endorsements.map { $0.serialize() } == repeatReceivedEndorsements.endorsements.map { $0.serialize() } + receivedEndorsements.endorsements.map { $0.serialize() } + == repeatReceivedEndorsements.endorsements.map { $0.serialize() } ) - #expect(receivedEndorsements.combinedEndorsement.serialize() == repeatReceivedEndorsements.combinedEndorsement.serialize()) #expect(throws: SignalError.self, "missing local user") { try response.receive( @@ -599,11 +741,15 @@ class ZKGroupTests { let everybodyButMallory = receivedEndorsements .combinedEndorsement .byRemoving(receivedEndorsements.endorsements[3]) - let fullEverybodyButMalloryToken = everybodyButMallory + let fullEverybodyButMalloryToken = + everybodyButMallory .toFullToken(groupParams: groupSecretParams, expiration: response.expiration) // SERVER - let everybodyButMalloryKey = GroupSendDerivedKeyPair.forExpiration(fullEverybodyButMalloryToken.expiration, params: serverSecretParams) + let everybodyButMalloryKey = GroupSendDerivedKeyPair.forExpiration( + fullEverybodyButMalloryToken.expiration, + params: serverSecretParams + ) try fullEverybodyButMalloryToken.verify( userIds: [bobAci, eveAci], @@ -615,10 +761,16 @@ class ZKGroupTests { do { // CLIENT let bobAndEve = GroupSendEndorsement.combine(receivedEndorsements.endorsements[1...2]) - let fullBobAndEveToken = bobAndEve.toFullToken(groupParams: groupSecretParams, expiration: response.expiration) + let fullBobAndEveToken = bobAndEve.toFullToken( + groupParams: groupSecretParams, + expiration: response.expiration + ) // SERVER - let bobAndEveKey = GroupSendDerivedKeyPair.forExpiration(fullBobAndEveToken.expiration, params: serverSecretParams) + let bobAndEveKey = GroupSendDerivedKeyPair.forExpiration( + fullBobAndEveToken.expiration, + params: serverSecretParams + ) try fullBobAndEveToken.verify(userIds: [bobAci, eveAci], keyPair: bobAndEveKey) } @@ -627,7 +779,10 @@ class ZKGroupTests { do { // CLIENT let bobEndorsement = receivedEndorsements.endorsements[1] - let fullBobToken = bobEndorsement.toFullToken(groupParams: groupSecretParams, expiration: response.expiration) + let fullBobToken = bobEndorsement.toFullToken( + groupParams: groupSecretParams, + expiration: response.expiration + ) // SERVER let bobKey = GroupSendDerivedKeyPair.forExpiration(fullBobToken.expiration, params: serverSecretParams) @@ -667,8 +822,17 @@ class ZKGroupTests { // CLIENT // Gets stored endorsements // Just don't crash (this did crash on a lower-end Android phone once). - _ = try response.receive(groupMembers: members, localUser: members[0], groupParams: groupSecretParams, serverParams: serverPublicParams) - _ = try response.receive(groupMembers: encryptedMembers, localUser: encryptedMembers[0], serverParams: serverPublicParams) + _ = try response.receive( + groupMembers: members, + localUser: members[0], + groupParams: groupSecretParams, + serverParams: serverPublicParams + ) + _ = try response.receive( + groupMembers: encryptedMembers, + localUser: encryptedMembers[0], + serverParams: serverPublicParams + ) } @Test @@ -702,7 +866,16 @@ class ZKGroupTests { // CLIENT // Gets stored endorsements // Just don't crash. - _ = try response.receive(groupMembers: [member], localUser: member, groupParams: groupSecretParams, serverParams: serverPublicParams) - _ = try response.receive(groupMembers: [encryptedMember], localUser: encryptedMember, serverParams: serverPublicParams) + _ = try response.receive( + groupMembers: [member], + localUser: member, + groupParams: groupSecretParams, + serverParams: serverPublicParams + ) + _ = try response.receive( + groupMembers: [encryptedMember], + localUser: encryptedMember, + serverParams: serverPublicParams + ) } }