78 lines
2.5 KiB
Swift
78 lines
2.5 KiB
Swift
//
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import LibSignalClient
|
|
|
|
protocol IdentityKeyChecker {
|
|
func serverHasSameKeyAsLocal(for identity: OWSIdentity, localIdentifier: ServiceId) async throws -> Bool
|
|
}
|
|
|
|
class IdentityKeyCheckerImpl: IdentityKeyChecker {
|
|
private let db: any DB
|
|
private let identityManager: OWSIdentityManager
|
|
private let profileFetcher: Shims.ProfileFetcher
|
|
|
|
init(
|
|
db: any DB,
|
|
identityManager: OWSIdentityManager,
|
|
profileFetcher: Shims.ProfileFetcher,
|
|
) {
|
|
self.db = db
|
|
self.identityManager = identityManager
|
|
self.profileFetcher = profileFetcher
|
|
}
|
|
|
|
func serverHasSameKeyAsLocal(for identity: OWSIdentity, localIdentifier: ServiceId) async throws -> Bool {
|
|
owsPrecondition((identity == .aci && localIdentifier is Aci) || (identity == .pni && localIdentifier is Pni))
|
|
|
|
let remoteIdentityKey = try await self.profileFetcher.fetchIdentityPublicKey(serviceId: localIdentifier)
|
|
let localIdentityKey = self.db.read(block: { tx -> IdentityKey? in
|
|
return self.identityManager.identityKeyPair(for: identity, tx: tx)?.keyPair.identityKey
|
|
})
|
|
return remoteIdentityKey == localIdentityKey
|
|
}
|
|
}
|
|
|
|
// MARK: - Dependencies
|
|
|
|
extension IdentityKeyCheckerImpl {
|
|
enum Shims {
|
|
typealias ProfileFetcher = _IdentityKeyCheckerImpl_ProfileFetcher_Shim
|
|
}
|
|
|
|
enum Wrappers {
|
|
typealias ProfileFetcher = _IdentityKeyCheckerImpl_ProfileFetcher_Wrapper
|
|
}
|
|
}
|
|
|
|
// MARK: ProfileFetcher
|
|
|
|
protocol _IdentityKeyCheckerImpl_ProfileFetcher_Shim {
|
|
func fetchIdentityPublicKey(serviceId: ServiceId) async throws -> IdentityKey
|
|
}
|
|
|
|
class _IdentityKeyCheckerImpl_ProfileFetcher_Wrapper: _IdentityKeyCheckerImpl_ProfileFetcher_Shim {
|
|
private let networkManager: NetworkManager
|
|
|
|
init(networkManager: NetworkManager) {
|
|
self.networkManager = networkManager
|
|
}
|
|
|
|
func fetchIdentityPublicKey(serviceId: ServiceId) async throws -> IdentityKey {
|
|
let request = OWSRequestFactory.getUnversionedProfileRequest(
|
|
serviceId: serviceId,
|
|
auth: .identified(.implicit()),
|
|
)
|
|
let response = try await networkManager.asyncRequest(request)
|
|
|
|
struct Response: Decodable {
|
|
var identityKey: Data
|
|
}
|
|
|
|
let decodedResponse = try JSONDecoder().decode(Response.self, from: response.responseBodyData ?? Data())
|
|
return try IdentityKey(bytes: decodedResponse.identityKey)
|
|
}
|
|
}
|