Remove unused CDSv1 code
It’s been replaced by CDSv2.
This commit is contained in:
parent
fdbdc9716d
commit
6dede44db6
@ -775,7 +775,7 @@
|
||||
506A924F28FA232100A2EFC2 /* ContactDiscoveryManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506A924E28FA232100A2EFC2 /* ContactDiscoveryManager.swift */; };
|
||||
506A92512900888900A2EFC2 /* RecipientPickerContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 506A92502900888900A2EFC2 /* RecipientPickerContainerViewController.swift */; };
|
||||
506A9252290326A600A2EFC2 /* TextHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4521C3BF1F59F3BA00B4C582 /* TextHelper.swift */; };
|
||||
5075004628B09CE6001922C9 /* ContactDiscoveryOperationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C4BC6C22102D697004040C9 /* ContactDiscoveryOperationTest.swift */; };
|
||||
5075004628B09CE6001922C9 /* ContactDiscoveryE164CollectionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C4BC6C22102D697004040C9 /* ContactDiscoveryE164CollectionTest.swift */; };
|
||||
507CD5E529660D5100E47DAC /* ServiceId.swift in Sources */ = {isa = PBXBuildFile; fileRef = 507CD5E429660D5100E47DAC /* ServiceId.swift */; };
|
||||
508F0346296F72F4001D88D0 /* CustomCellBackgroundColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 508F0345296F72F4001D88D0 /* CustomCellBackgroundColor.swift */; };
|
||||
509913BE2913274100F34F8E /* PhoneNumberFinderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 509913BD2913274100F34F8E /* PhoneNumberFinderTests.swift */; };
|
||||
@ -1738,7 +1738,6 @@
|
||||
F9C5CCBB289453B300548EEE /* PhoneNumberUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C5C9D3289453B100548EEE /* PhoneNumberUtil.m */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CCBC289453B300548EEE /* PhoneNumber.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C5C9D4289453B100548EEE /* PhoneNumber.m */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CCBD289453B300548EEE /* UUIDBackfillTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C5C9D6289453B100548EEE /* UUIDBackfillTask.swift */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CCBE289453B300548EEE /* SGXContactDiscoveryOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C5C9D7289453B100548EEE /* SGXContactDiscoveryOperation.swift */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CCC0289453B300548EEE /* ContactDiscoveryTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C5C9D9289453B100548EEE /* ContactDiscoveryTask.swift */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CCC3289453B300548EEE /* ContactDiscoveryOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C5C9DC289453B100548EEE /* ContactDiscoveryOperation.swift */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CCC4289453B300548EEE /* OWSDisappearingMessagesConfiguration+SDS.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C5C9DD289453B100548EEE /* OWSDisappearingMessagesConfiguration+SDS.swift */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
@ -1989,7 +1988,6 @@
|
||||
F9C5CDBE289453B400548EEE /* RESTNetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C5CAEB289453B200548EEE /* RESTNetworkManager.swift */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CDBF289453B400548EEE /* OWSUploadOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C5CAEC289453B200548EEE /* OWSUploadOperation.m */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CDC0289453B400548EEE /* RESTNetworkManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F9C5CAED289453B200548EEE /* RESTNetworkManager.m */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CDC1289453B400548EEE /* ContactDiscoveryService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C5CAEE289453B200548EEE /* ContactDiscoveryService.swift */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CDC2289453B400548EEE /* HTTPEntities.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C5CAEF289453B200548EEE /* HTTPEntities.swift */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CDC3289453B400548EEE /* DeviceProvisioningService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C5CAF0289453B200548EEE /* DeviceProvisioningService.swift */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
F9C5CDC4289453B400548EEE /* NetworkInterfaceSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C5CAF1289453B200548EEE /* NetworkInterfaceSet.swift */; settings = {COMPILER_FLAGS = "-fcxx-modules"; }; };
|
||||
@ -3118,7 +3116,7 @@
|
||||
4C42960F231A1AA400D9D240 /* MessageSendingPerformanceTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageSendingPerformanceTest.swift; sourceTree = "<group>"; };
|
||||
4C46361022EB98EC00185951 /* CameraFirstCaptureSendFlow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraFirstCaptureSendFlow.swift; sourceTree = "<group>"; };
|
||||
4C4AE69F224AF21900D4AF6F /* SendMediaNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendMediaNavigationController.swift; sourceTree = "<group>"; };
|
||||
4C4BC6C22102D697004040C9 /* ContactDiscoveryOperationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactDiscoveryOperationTest.swift; sourceTree = "<group>"; };
|
||||
4C4BC6C22102D697004040C9 /* ContactDiscoveryE164CollectionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactDiscoveryE164CollectionTest.swift; sourceTree = "<group>"; };
|
||||
4C5250D121E7BD7D00CE3D95 /* PhoneNumberValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneNumberValidator.swift; sourceTree = "<group>"; };
|
||||
4C5250D321E7C51900CE3D95 /* PhoneNumberValidatorTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhoneNumberValidatorTest.swift; sourceTree = "<group>"; };
|
||||
4C63CBFF210A620B003AE45C /* SignalTSan.supp */ = {isa = PBXFileReference; lastKnownFileType = text; path = SignalTSan.supp; sourceTree = "<group>"; };
|
||||
@ -4256,7 +4254,6 @@
|
||||
F9C5C9D3289453B100548EEE /* PhoneNumberUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhoneNumberUtil.m; sourceTree = "<group>"; };
|
||||
F9C5C9D4289453B100548EEE /* PhoneNumber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PhoneNumber.m; sourceTree = "<group>"; };
|
||||
F9C5C9D6289453B100548EEE /* UUIDBackfillTask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UUIDBackfillTask.swift; sourceTree = "<group>"; };
|
||||
F9C5C9D7289453B100548EEE /* SGXContactDiscoveryOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SGXContactDiscoveryOperation.swift; sourceTree = "<group>"; };
|
||||
F9C5C9D9289453B100548EEE /* ContactDiscoveryTask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactDiscoveryTask.swift; sourceTree = "<group>"; };
|
||||
F9C5C9DC289453B100548EEE /* ContactDiscoveryOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactDiscoveryOperation.swift; sourceTree = "<group>"; };
|
||||
F9C5C9DD289453B100548EEE /* OWSDisappearingMessagesConfiguration+SDS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "OWSDisappearingMessagesConfiguration+SDS.swift"; sourceTree = "<group>"; };
|
||||
@ -4507,7 +4504,6 @@
|
||||
F9C5CAEB289453B200548EEE /* RESTNetworkManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RESTNetworkManager.swift; sourceTree = "<group>"; };
|
||||
F9C5CAEC289453B200548EEE /* OWSUploadOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSUploadOperation.m; sourceTree = "<group>"; };
|
||||
F9C5CAED289453B200548EEE /* RESTNetworkManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RESTNetworkManager.m; sourceTree = "<group>"; };
|
||||
F9C5CAEE289453B200548EEE /* ContactDiscoveryService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContactDiscoveryService.swift; sourceTree = "<group>"; };
|
||||
F9C5CAEF289453B200548EEE /* HTTPEntities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPEntities.swift; sourceTree = "<group>"; };
|
||||
F9C5CAF0289453B200548EEE /* DeviceProvisioningService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceProvisioningService.swift; sourceTree = "<group>"; };
|
||||
F9C5CAF1289453B200548EEE /* NetworkInterfaceSet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkInterfaceSet.swift; sourceTree = "<group>"; };
|
||||
@ -6291,8 +6287,8 @@
|
||||
5075004528B09CCC001922C9 /* Discovery */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4C4BC6C22102D697004040C9 /* ContactDiscoveryE164CollectionTest.swift */,
|
||||
50169694291B0627007AD709 /* ContactDiscoveryManagerTest.swift */,
|
||||
4C4BC6C22102D697004040C9 /* ContactDiscoveryOperationTest.swift */,
|
||||
500824CF292741D5005A5DC0 /* ContactDiscoveryV2OperationTest.swift */,
|
||||
);
|
||||
path = Discovery;
|
||||
@ -8444,7 +8440,6 @@
|
||||
F9C5C9D9289453B100548EEE /* ContactDiscoveryTask.swift */,
|
||||
5049FA2E28BEAABE00D6E099 /* ContactDiscoveryV2Connection.swift */,
|
||||
5049FA2D28BEAABE00D6E099 /* ContactDiscoveryV2Operation.swift */,
|
||||
F9C5C9D7289453B100548EEE /* SGXContactDiscoveryOperation.swift */,
|
||||
F9C5C9D6289453B100548EEE /* UUIDBackfillTask.swift */,
|
||||
);
|
||||
path = Discovery;
|
||||
@ -8813,7 +8808,6 @@
|
||||
children = (
|
||||
F9C5CADB289453B200548EEE /* Giphy */,
|
||||
F9C5CAE1289453B200548EEE /* Requests */,
|
||||
F9C5CAEE289453B200548EEE /* ContactDiscoveryService.swift */,
|
||||
505C2ED529971D4E00C23FB2 /* DeviceLimitExceededError.swift */,
|
||||
F9C5CAF0289453B200548EEE /* DeviceProvisioningService.swift */,
|
||||
F9C5CAEF289453B200548EEE /* HTTPEntities.swift */,
|
||||
@ -11465,7 +11459,6 @@
|
||||
F9C5CCE4289453B300548EEE /* Contact.swift in Sources */,
|
||||
506A924F28FA232100A2EFC2 /* ContactDiscoveryManager.swift in Sources */,
|
||||
F9C5CCC3289453B300548EEE /* ContactDiscoveryOperation.swift in Sources */,
|
||||
F9C5CDC1289453B400548EEE /* ContactDiscoveryService.swift in Sources */,
|
||||
F9C5CCC0289453B300548EEE /* ContactDiscoveryTask.swift in Sources */,
|
||||
5049FA3028BEAABE00D6E099 /* ContactDiscoveryV2Connection.swift in Sources */,
|
||||
5049FA2F28BEAABE00D6E099 /* ContactDiscoveryV2Operation.swift in Sources */,
|
||||
@ -11872,7 +11865,6 @@
|
||||
F9C5CC96289453B300548EEE /* SessionRecord.pb.swift in Sources */,
|
||||
F9C5CD35289453B300548EEE /* SessionRecordMigration.swift in Sources */,
|
||||
1700E34128BD41150073D949 /* SetAlgebra+SSK.swift in Sources */,
|
||||
F9C5CCBE289453B300548EEE /* SGXContactDiscoveryOperation.swift in Sources */,
|
||||
F9C5CCC6289453B300548EEE /* SignalAccount+SDS.swift in Sources */,
|
||||
F9C5CCD9289453B300548EEE /* SignalAccount.m in Sources */,
|
||||
F9C5CCC5289453B300548EEE /* SignalAccount.swift in Sources */,
|
||||
@ -12069,8 +12061,8 @@
|
||||
F9426273289B1B5500460798 /* BlockingManagerStateTests.swift in Sources */,
|
||||
F9426283289B1B5600460798 /* BlockingManagerTests.swift in Sources */,
|
||||
661396AF28BE881E00E0C4DF /* ChainedPromiseTest.swift in Sources */,
|
||||
5075004628B09CE6001922C9 /* ContactDiscoveryE164CollectionTest.swift in Sources */,
|
||||
50169695291B0627007AD709 /* ContactDiscoveryManagerTest.swift in Sources */,
|
||||
5075004628B09CE6001922C9 /* ContactDiscoveryOperationTest.swift in Sources */,
|
||||
500824D0292741D5005A5DC0 /* ContactDiscoveryV2OperationTest.swift in Sources */,
|
||||
F962B38C293F9F9F00765BD8 /* CRC32Test.swift in Sources */,
|
||||
509BBF7A28CA556700F4D8A0 /* Data+SSKTest.swift in Sources */,
|
||||
|
||||
@ -78,15 +78,8 @@ public class ContactDiscoveryError: NSError, UserErrorDescriptionProvider {
|
||||
case generic = 1
|
||||
case assertion
|
||||
|
||||
/// An error indicating that the current user has an expired auth token
|
||||
case unauthorized
|
||||
/// An error indicating that a hardcoded resource is unavailable. Best recourse is to update the app.
|
||||
case unexpectedResponse
|
||||
/// An error indicating response timeout.
|
||||
case timeout
|
||||
/// An error indicating that the failure was because of a rate limit
|
||||
case rateLimit
|
||||
|
||||
/// Any generic 4xx error that doesn't fit in the above categories
|
||||
case genericClientError
|
||||
/// Any generic 5xx error that doesn't fit in the above categories
|
||||
|
||||
@ -42,11 +42,7 @@ final class ContactDiscoveryTaskQueueImpl: ContactDiscoveryTaskQueue, Dependenci
|
||||
}
|
||||
|
||||
private static func createContactDiscoveryOperation(for e164s: Set<E164>, mode: ContactDiscoveryMode) -> ContactDiscoveryOperation {
|
||||
if !RemoteConfig.contactDiscoveryV2KillSwitch {
|
||||
return ContactDiscoveryV2CompatibilityOperation(e164sToLookup: e164s, mode: mode)
|
||||
} else {
|
||||
return SGXContactDiscoveryOperation(e164sToLookup: e164s, mode: mode)
|
||||
}
|
||||
return ContactDiscoveryV2CompatibilityOperation(e164sToLookup: e164s, mode: mode)
|
||||
}
|
||||
|
||||
private static func storeResults(
|
||||
|
||||
@ -1,232 +0,0 @@
|
||||
//
|
||||
// Copyright 2018 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import LibSignalClient
|
||||
|
||||
struct CDSRegisteredContact: Hashable {
|
||||
let signalUuid: UUID
|
||||
let e164PhoneNumber: E164
|
||||
}
|
||||
|
||||
/// Fetches contact info from the ContactDiscoveryService
|
||||
/// Intended to be used by ContactDiscoveryTaskQueue. You probably don't want to use this directly.
|
||||
class SGXContactDiscoveryOperation: ContactDiscoveryOperation {
|
||||
static let batchSize = 2048
|
||||
|
||||
private let e164sToLookup: Set<E164>
|
||||
required init(e164sToLookup: Set<E164>, mode: ContactDiscoveryMode) {
|
||||
self.e164sToLookup = e164sToLookup
|
||||
Logger.debug("with e164sToLookup.count: \(e164sToLookup.count)")
|
||||
}
|
||||
|
||||
func perform(on queue: DispatchQueue) -> Promise<Set<DiscoveredContactInfo>> {
|
||||
firstly { () -> Promise<[Set<CDSRegisteredContact>]> in
|
||||
// First, build a bunch of batch Promises
|
||||
let batchOperationPromises = Array(e164sToLookup)
|
||||
.chunked(by: Self.batchSize)
|
||||
.map { makeContactDiscoveryRequest(e164sToLookup: Array($0)) }
|
||||
|
||||
// Then, wait for them all to be fulfilled before joining the subsets together
|
||||
return Promise.when(fulfilled: batchOperationPromises)
|
||||
|
||||
}.map(on: queue) { (setArray) -> Set<DiscoveredContactInfo> in
|
||||
setArray.reduce(into: Set()) { (builder, cdsContactSubset) in
|
||||
builder.formUnion(cdsContactSubset.map {
|
||||
DiscoveredContactInfo(e164: $0.e164PhoneNumber, uuid: $0.signalUuid)
|
||||
})
|
||||
}
|
||||
}.recover(on: queue) { error -> Promise<Set<DiscoveredContactInfo>> in
|
||||
throw Self.prepareExternalError(from: error)
|
||||
}
|
||||
}
|
||||
|
||||
// Below, we have a bunch of then blocks being performed on a global concurrent queue
|
||||
// It might be worthwhile to audit and see if we can move these onto the queue passed into `perform(on:)`
|
||||
|
||||
private func makeContactDiscoveryRequest(e164sToLookup: [E164]) -> Promise<Set<CDSRegisteredContact>> {
|
||||
firstly { () -> Promise<RemoteAttestation.CDSAttestation> in
|
||||
RemoteAttestation.performForCDS()
|
||||
|
||||
}.then(on: DispatchQueue.global()) { (attestation: RemoteAttestation.CDSAttestation) -> Promise<(RemoteAttestation.CDSAttestation, ContactDiscoveryService.IntersectionResponse)> in
|
||||
let service = ContactDiscoveryService()
|
||||
let query = try self.buildIntersectionQuery(e164sToLookup: e164sToLookup,
|
||||
remoteAttestations: attestation.remoteAttestations)
|
||||
return service.getRegisteredSignalUsers(
|
||||
query: query,
|
||||
cookies: attestation.cookies,
|
||||
authUsername: attestation.auth.username,
|
||||
authPassword: attestation.auth.password,
|
||||
enclaveName: attestation.enclaveConfig.enclaveName,
|
||||
host: attestation.enclaveConfig.host,
|
||||
censorshipCircumventionPrefix: attestation.enclaveConfig.censorshipCircumventionPrefix
|
||||
).map {(attestation, $0)}
|
||||
|
||||
}.map(on: DispatchQueue.global()) { attestation, response -> Set<CDSRegisteredContact> in
|
||||
let allEnclaveAttestations = attestation.remoteAttestations
|
||||
let respondingEnclaveAttestation = allEnclaveAttestations.first(where: { $1.requestId == response.requestId })
|
||||
|
||||
guard let responseAttestion = respondingEnclaveAttestation?.value else {
|
||||
throw ContactDiscoveryError.assertionError(description: "Invalid responding enclave for requestId: \(response.requestId)")
|
||||
}
|
||||
|
||||
let plaintext = try Aes256GcmEncryptedData(
|
||||
nonce: response.iv,
|
||||
ciphertext: response.data,
|
||||
authenticationTag: response.mac
|
||||
).decrypt(key: responseAttestion.keys.serverKey.keyData)
|
||||
|
||||
// 16 bytes per UUID
|
||||
let contactCount = UInt(e164sToLookup.count)
|
||||
guard plaintext.count == contactCount * 16 else {
|
||||
throw ContactDiscoveryError.assertionError(description: "failed check: invalid byte count")
|
||||
}
|
||||
let dataParser = OWSDataParser(data: plaintext)
|
||||
let uuidsData = try dataParser.nextData(length: contactCount * 16, name: "uuids")
|
||||
|
||||
guard dataParser.isEmpty else {
|
||||
throw ContactDiscoveryError.assertionError(description: "failed check: dataParse.isEmpty")
|
||||
}
|
||||
|
||||
let uuids = type(of: self).uuidArray(from: uuidsData)
|
||||
|
||||
guard uuids.count == contactCount else {
|
||||
throw ContactDiscoveryError.assertionError(description: "failed check: uuids.count == contactCount")
|
||||
}
|
||||
|
||||
let unregisteredUuid = UUID(uuid: (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
|
||||
|
||||
var registeredContacts: Set<CDSRegisteredContact> = Set()
|
||||
|
||||
for (index, e164PhoneNumber) in e164sToLookup.enumerated() {
|
||||
let uuid = uuids[index]
|
||||
guard uuid != unregisteredUuid else {
|
||||
Logger.verbose("not a signal user: \(e164PhoneNumber)")
|
||||
continue
|
||||
}
|
||||
|
||||
Logger.verbose("Signal user. e164: \(e164PhoneNumber), uuid: \(uuid)")
|
||||
registeredContacts.insert(CDSRegisteredContact(signalUuid: uuid, e164PhoneNumber: e164PhoneNumber))
|
||||
}
|
||||
|
||||
return registeredContacts
|
||||
}
|
||||
}
|
||||
|
||||
func buildIntersectionQuery(e164sToLookup: [E164], remoteAttestations: [RemoteAttestation.CDSAttestation.Id: RemoteAttestation]) throws -> ContactDiscoveryService.IntersectionQuery {
|
||||
let noncePlainTextData = Randomness.generateRandomBytes(32)
|
||||
let addressPlainTextData = ContactDiscoveryE164Collection(e164sToLookup).encodedValues
|
||||
let queryData = Data.join([noncePlainTextData, addressPlainTextData])
|
||||
|
||||
let key = OWSAES256Key.generateRandom()
|
||||
let encryptionResult = try Aes256GcmEncryptedData.encrypt(queryData, key: key.keyData)
|
||||
assert(encryptionResult.ciphertext.count == e164sToLookup.count * 8 + 32)
|
||||
|
||||
let queryEnvelopes: [RemoteAttestation.CDSAttestation.Id: ContactDiscoveryService.IntersectionQuery.EnclaveEnvelope] = try remoteAttestations.mapValues { remoteAttestation in
|
||||
let perEnclaveKey = try Aes256GcmEncryptedData.encrypt(
|
||||
key.keyData,
|
||||
key: remoteAttestation.keys.clientKey.keyData,
|
||||
associatedData: remoteAttestation.requestId
|
||||
)
|
||||
|
||||
return ContactDiscoveryService.IntersectionQuery.EnclaveEnvelope(
|
||||
requestId: remoteAttestation.requestId,
|
||||
data: perEnclaveKey.ciphertext,
|
||||
iv: perEnclaveKey.nonce,
|
||||
mac: perEnclaveKey.authenticationTag
|
||||
)
|
||||
}
|
||||
|
||||
guard let commitment = Cryptography.computeSHA256Digest(queryData) else {
|
||||
throw ContactDiscoveryError.assertionError(description: "commitment was unexpectedly nil")
|
||||
}
|
||||
|
||||
return ContactDiscoveryService.IntersectionQuery(
|
||||
addressCount: UInt(e164sToLookup.count),
|
||||
commitment: commitment,
|
||||
data: encryptionResult.ciphertext,
|
||||
iv: encryptionResult.nonce,
|
||||
mac: encryptionResult.authenticationTag,
|
||||
envelopes: queryEnvelopes
|
||||
)
|
||||
}
|
||||
|
||||
class func uuidArray(from data: Data) -> [UUID] {
|
||||
return data.withUnsafeBytes {
|
||||
[uuid_t]($0.bindMemory(to: uuid_t.self))
|
||||
.map { UUID(uuid: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse the error and, if appropriate, construct an error appropriate to return upwards
|
||||
/// May return the provided error unchanged.
|
||||
class func prepareExternalError(from error: Error) -> Error {
|
||||
// Network connectivity failures should never be re-wrapped
|
||||
if error.isNetworkConnectivityFailure {
|
||||
return error
|
||||
}
|
||||
|
||||
let retryAfterDate = error.httpRetryAfterDate.map { min($0, Date(timeIntervalSinceNow: 60 * kMinuteInterval)) }
|
||||
|
||||
if let statusCode = error.httpStatusCode {
|
||||
switch statusCode {
|
||||
case 401:
|
||||
return ContactDiscoveryError(
|
||||
kind: .unauthorized,
|
||||
debugDescription: "User is unauthorized",
|
||||
retryable: false,
|
||||
retryAfterDate: retryAfterDate)
|
||||
case 404:
|
||||
return ContactDiscoveryError(
|
||||
kind: .unexpectedResponse,
|
||||
debugDescription: "Unknown enclaveID",
|
||||
retryable: false,
|
||||
retryAfterDate: retryAfterDate)
|
||||
case 408:
|
||||
return ContactDiscoveryError(
|
||||
kind: .timeout,
|
||||
debugDescription: "Server rejected due to a timeout",
|
||||
retryable: true,
|
||||
retryAfterDate: retryAfterDate)
|
||||
case 409:
|
||||
// Conflict on a discovery request indicates that the requestId specified by the client
|
||||
// has been dropped due to a delay or high request rate since the preceding corresponding
|
||||
// attestation request. The client should not retry the request automatically
|
||||
return ContactDiscoveryError(
|
||||
kind: .genericClientError,
|
||||
debugDescription: "RequestID conflict",
|
||||
retryable: false,
|
||||
retryAfterDate: retryAfterDate)
|
||||
case 429:
|
||||
return ContactDiscoveryError(
|
||||
kind: .rateLimit,
|
||||
debugDescription: "Rate limit",
|
||||
retryable: true,
|
||||
retryAfterDate: retryAfterDate)
|
||||
case 400..<500:
|
||||
return ContactDiscoveryError(
|
||||
kind: .genericClientError,
|
||||
debugDescription: "Client error (\(statusCode)): \(error.userErrorDescription)",
|
||||
retryable: false,
|
||||
retryAfterDate: retryAfterDate)
|
||||
case 500..<600:
|
||||
return ContactDiscoveryError(
|
||||
kind: .genericServerError,
|
||||
debugDescription: "Server error (\(statusCode)): \(error.userErrorDescription)",
|
||||
retryable: true,
|
||||
retryAfterDate: retryAfterDate)
|
||||
default:
|
||||
return ContactDiscoveryError(
|
||||
kind: .generic,
|
||||
debugDescription: "Unknown error (\(statusCode)): \(error.userErrorDescription)",
|
||||
retryable: false,
|
||||
retryAfterDate: retryAfterDate)
|
||||
}
|
||||
|
||||
} else {
|
||||
return error
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,122 +0,0 @@
|
||||
//
|
||||
// Copyright 2019 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct ContactDiscoveryService: Dependencies {
|
||||
|
||||
public struct IntersectionQuery: Codable {
|
||||
public let addressCount: UInt
|
||||
public let commitment: Data
|
||||
public let data: Data
|
||||
public let iv: Data
|
||||
public let mac: Data
|
||||
|
||||
public struct EnclaveEnvelope: Codable {
|
||||
public let requestId: Data
|
||||
public let data: Data
|
||||
public let iv: Data
|
||||
public let mac: Data
|
||||
}
|
||||
public let envelopes: [RemoteAttestation.CDSAttestation.Id: EnclaveEnvelope]
|
||||
}
|
||||
|
||||
public struct IntersectionResponse {
|
||||
let requestId: Data
|
||||
let data: Data
|
||||
let iv: Data
|
||||
let mac: Data
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
public func getRegisteredSignalUsers(query: ContactDiscoveryService.IntersectionQuery,
|
||||
cookies: [HTTPCookie],
|
||||
authUsername: String,
|
||||
authPassword: String,
|
||||
enclaveName: String,
|
||||
host: String,
|
||||
censorshipCircumventionPrefix: String) -> Promise<IntersectionResponse> {
|
||||
owsAssertDebug(authUsername.strippedOrNil != nil)
|
||||
owsAssertDebug(authPassword.strippedOrNil != nil)
|
||||
owsAssertDebug(enclaveName.strippedOrNil != nil)
|
||||
owsAssertDebug(host.strippedOrNil != nil)
|
||||
|
||||
return firstly(on: DispatchQueue.sharedUtility) { () -> Promise<HTTPResponse> in
|
||||
let urlSession = Self.signalService.urlSessionForCds(host: host,
|
||||
censorshipCircumventionPrefix: censorshipCircumventionPrefix)
|
||||
let request = self.buildIntersectionRequest(
|
||||
query: query,
|
||||
cookies: cookies,
|
||||
authUsername: authUsername,
|
||||
authPassword: authPassword,
|
||||
enclaveName: enclaveName
|
||||
)
|
||||
guard let requestUrl = request.url else {
|
||||
owsFailDebug("Missing requestUrl.")
|
||||
throw OWSHTTPError.missingRequest
|
||||
}
|
||||
return firstly {
|
||||
urlSession.promiseForTSRequest(request)
|
||||
}.recover(on: DispatchQueue.global()) { error -> Promise<HTTPResponse> in
|
||||
// OWSUrlSession should only throw OWSHTTPError or OWSAssertionError.
|
||||
if let httpError = error as? OWSHTTPError {
|
||||
throw httpError
|
||||
} else {
|
||||
owsFailDebug("Unexpected error: \(error)")
|
||||
throw OWSHTTPError.invalidRequest(requestUrl: requestUrl)
|
||||
}
|
||||
}
|
||||
}.map(on: DispatchQueue.sharedUtility) { (response: HTTPResponse) throws -> IntersectionResponse in
|
||||
guard let json = response.responseBodyJson else {
|
||||
throw OWSAssertionError("Invalid JSON")
|
||||
}
|
||||
guard let params = ParamParser(responseObject: json) else {
|
||||
throw ContactDiscoveryError.assertionError(description: "missing response dict")
|
||||
}
|
||||
return IntersectionResponse(
|
||||
requestId: try params.requiredBase64EncodedData(key: "requestId"),
|
||||
data: try params.requiredBase64EncodedData(key: "data"),
|
||||
iv: try params.requiredBase64EncodedData(key: "iv", byteCount: 12),
|
||||
mac: try params.requiredBase64EncodedData(key: "mac", byteCount: 16))
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
private func buildIntersectionRequest(query: IntersectionQuery,
|
||||
cookies: [HTTPCookie],
|
||||
authUsername: String,
|
||||
authPassword: String,
|
||||
enclaveName: String) -> TSRequest {
|
||||
let path = "v1/discovery/\(enclaveName)"
|
||||
let parameters: [String: Any] = [
|
||||
"addressCount": query.addressCount,
|
||||
"commitment": query.commitment.base64EncodedString(),
|
||||
"data": query.data.base64EncodedString(),
|
||||
"iv": query.iv.base64EncodedString(),
|
||||
"mac": query.mac.base64EncodedString(),
|
||||
"envelopes": query.envelopes.mapValues {
|
||||
[
|
||||
"requestId": $0.requestId.base64EncodedString(),
|
||||
"data": $0.data.base64EncodedString(),
|
||||
"iv": $0.iv.base64EncodedString(),
|
||||
"mac": $0.mac.base64EncodedString()
|
||||
]
|
||||
}
|
||||
]
|
||||
let request = TSRequest(url: URL(string: path)!, method: "PUT", parameters: parameters)
|
||||
|
||||
request.authUsername = authUsername
|
||||
request.authPassword = authPassword
|
||||
|
||||
// Set the cookie header.
|
||||
// OWSURLSession disables default cookie handling for all requests.
|
||||
assert(request.allHTTPHeaderFields?.count == 0)
|
||||
request.allHTTPHeaderFields = HTTPCookie.requestHeaderFields(with: cookies)
|
||||
|
||||
return request
|
||||
}
|
||||
}
|
||||
@ -278,8 +278,6 @@ fileprivate extension HTTPUtils {
|
||||
return httpError.isNetworkConnectivityError
|
||||
case GroupsV2Error.timeout:
|
||||
return true
|
||||
case let contactDiscoveryError as ContactDiscoveryError:
|
||||
return contactDiscoveryError.kind == .timeout
|
||||
case PaymentsError.timeout:
|
||||
return true
|
||||
default:
|
||||
|
||||
@ -135,7 +135,6 @@ typedef NS_ENUM(uint8_t, OWSIdentity);
|
||||
#pragma mark - Remote Attestation
|
||||
|
||||
+ (TSRequest *)remoteAttestationAuthRequestForKeyBackup;
|
||||
+ (TSRequest *)remoteAttestationAuthRequestForContactDiscovery;
|
||||
+ (TSRequest *)remoteAttestationAuthRequestForCDSI;
|
||||
|
||||
#pragma mark - KBS
|
||||
|
||||
@ -594,11 +594,6 @@ static NSString *_Nullable queryParamForIdentity(OWSIdentity identity)
|
||||
return [TSRequest requestWithUrl:[NSURL URLWithString:@"v1/backup/auth"] method:@"GET" parameters:@{}];
|
||||
}
|
||||
|
||||
+ (TSRequest *)remoteAttestationAuthRequestForContactDiscovery
|
||||
{
|
||||
return [TSRequest requestWithUrl:[NSURL URLWithString:@"v1/directory/auth"] method:@"GET" parameters:@{}];
|
||||
}
|
||||
|
||||
+ (TSRequest *)remoteAttestationAuthRequestForCDSI
|
||||
{
|
||||
return [TSRequest requestWithUrl:[NSURL URLWithString:@"v2/directory/auth"] method:@"GET" parameters:@{}];
|
||||
|
||||
@ -60,7 +60,6 @@ public enum SignalServiceType {
|
||||
case storageService
|
||||
case cdn0
|
||||
case cdn2
|
||||
case cds(host: String, censorshipCircumventionPrefix: String)
|
||||
case remoteAttestation(host: String, censorshipCircumventionPrefix: String)
|
||||
case kbs
|
||||
case updates
|
||||
@ -104,18 +103,6 @@ public extension OWSSignalServiceProtocol {
|
||||
buildUrlSession(for: SignalServiceType.type(forCdnNumber: cdnNumber))
|
||||
}
|
||||
|
||||
func urlSessionForCds(
|
||||
host: String,
|
||||
censorshipCircumventionPrefix: String
|
||||
) -> OWSURLSessionProtocol {
|
||||
buildUrlSession(
|
||||
for: .cds(
|
||||
host: host,
|
||||
censorshipCircumventionPrefix: censorshipCircumventionPrefix
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
func urlSessionForRemoteAttestation(
|
||||
host: String,
|
||||
censorshipCircumventionPrefix: String
|
||||
@ -189,13 +176,6 @@ extension SignalServiceType {
|
||||
shouldUseSignalCertificate: true,
|
||||
shouldHandleRemoteDeprecation: false
|
||||
)
|
||||
case .cds(let host, let censorshipCircumventionPrefix):
|
||||
return SignalServiceInfo(
|
||||
baseUrl: URL(string: host)!,
|
||||
censorshipCircumventionPathPrefix: censorshipCircumventionPrefix,
|
||||
shouldUseSignalCertificate: true,
|
||||
shouldHandleRemoteDeprecation: false
|
||||
)
|
||||
case .remoteAttestation(let host, let censorshipCircumventionPrefix):
|
||||
return SignalServiceInfo(
|
||||
baseUrl: URL(string: host)!,
|
||||
|
||||
@ -68,60 +68,6 @@ public extension RemoteAttestation {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - CDS
|
||||
|
||||
public extension RemoteAttestation {
|
||||
struct CDSAttestation {
|
||||
/// An opaque, server-specified identifier to link an attestation to its corresponding envelope
|
||||
public typealias Id = String
|
||||
|
||||
let cookies: [HTTPCookie]
|
||||
let auth: Auth
|
||||
let enclaveConfig: EnclaveConfig
|
||||
let remoteAttestations: [Id: RemoteAttestation]
|
||||
}
|
||||
|
||||
static func performForCDS() -> Promise<CDSAttestation> {
|
||||
return performAttestation(
|
||||
for: .contactDiscovery,
|
||||
config: EnclaveConfig(
|
||||
enclaveName: TSConstants.contactDiscoveryEnclaveName,
|
||||
mrenclave: TSConstants.contactDiscoveryMrEnclave,
|
||||
host: TSConstants.contactDiscoverySGXURL,
|
||||
censorshipCircumventionPrefix: TSConstants.contactDiscoveryCensorshipPrefix
|
||||
)
|
||||
).map { attestationResponse -> CDSAttestation in
|
||||
let attestationBody: [CDSAttestation.Id: [String: Any]] = try attestationResponse.responseBody.required(key: "attestations")
|
||||
|
||||
// The client MUST reject server responses with more than 3 Remote Attestation Responses attached,
|
||||
// for security reasons.
|
||||
guard (1..<4).contains(attestationBody.count) else {
|
||||
throw ParamParser.ParseError.invalidFormat("attestations", description: "invalid attestation count: \(attestationBody.count)")
|
||||
}
|
||||
|
||||
let attestations: [CDSAttestation.Id: RemoteAttestation] = try attestationBody.mapValues { attestationParams in
|
||||
let parser = ParamParser(dictionary: attestationParams)
|
||||
return try parseAttestationResponse(params: parser,
|
||||
clientEphemeralKeyPair: attestationResponse.clientEphemeralKeyPair,
|
||||
cookies: attestationResponse.cookies,
|
||||
enclaveName: attestationResponse.enclaveConfig.enclaveName,
|
||||
mrenclave: attestationResponse.enclaveConfig.mrenclave,
|
||||
auth: attestationResponse.auth)
|
||||
}
|
||||
|
||||
let attestation = CDSAttestation(cookies: attestationResponse.cookies,
|
||||
auth: attestationResponse.auth,
|
||||
enclaveConfig: attestationResponse.enclaveConfig,
|
||||
remoteAttestations: attestations)
|
||||
owsAssertDebug(attestation.auth.username.strippedOrNil != nil)
|
||||
owsAssertDebug(attestation.auth.password.strippedOrNil != nil)
|
||||
owsAssertDebug(attestation.enclaveConfig.enclaveName.strippedOrNil != nil)
|
||||
owsAssertDebug(attestation.enclaveConfig.host.strippedOrNil != nil)
|
||||
return attestation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - CSDI
|
||||
|
||||
extension RemoteAttestation {
|
||||
@ -302,13 +248,11 @@ public extension RemoteAttestation {
|
||||
|
||||
fileprivate extension RemoteAttestation {
|
||||
enum Service {
|
||||
case contactDiscovery
|
||||
case keyBackup
|
||||
case cdsi
|
||||
|
||||
func authRequest() -> TSRequest {
|
||||
switch self {
|
||||
case .contactDiscovery: return OWSRequestFactory.remoteAttestationAuthRequestForContactDiscovery()
|
||||
case .keyBackup: return OWSRequestFactory.remoteAttestationAuthRequestForKeyBackup()
|
||||
case .cdsi: return OWSRequestFactory.remoteAttestationAuthRequestForCDSI()
|
||||
}
|
||||
@ -397,11 +341,6 @@ fileprivate extension RemoteAttestation {
|
||||
"clientPublic": clientEphemeralKeyPair.publicKey.base64EncodedString()
|
||||
]
|
||||
|
||||
// When making requests to CDS, we need to tell the service to use IASv4
|
||||
if case .contactDiscovery = service {
|
||||
parameters["iasVersion"] = 4
|
||||
}
|
||||
|
||||
let request = TSRequest(url: URL(string: path)!,
|
||||
method: "PUT",
|
||||
parameters: parameters)
|
||||
|
||||
@ -47,8 +47,6 @@ public class TSConstants: NSObject {
|
||||
@objc
|
||||
public static var textSecureCDN2ServerURL: String { shared.textSecureCDN2ServerURL }
|
||||
@objc
|
||||
public static var contactDiscoverySGXURL: String { shared.contactDiscoverySGXURL }
|
||||
@objc
|
||||
public static var contactDiscoveryV2URL: String { shared.contactDiscoveryV2URL }
|
||||
@objc
|
||||
public static var keyBackupURL: String { shared.keyBackupURL }
|
||||
@ -75,14 +73,10 @@ public class TSConstants: NSObject {
|
||||
public static var serviceCensorshipPrefix: String { shared.serviceCensorshipPrefix }
|
||||
public static var cdn0CensorshipPrefix: String { shared.cdn0CensorshipPrefix }
|
||||
public static var cdn2CensorshipPrefix: String { shared.cdn2CensorshipPrefix }
|
||||
public static var contactDiscoveryCensorshipPrefix: String { shared.contactDiscoveryCensorshipPrefix }
|
||||
public static var keyBackupCensorshipPrefix: String { shared.keyBackupCensorshipPrefix }
|
||||
public static var storageServiceCensorshipPrefix: String { shared.storageServiceCensorshipPrefix }
|
||||
public static var contactDiscoveryV2CensorshipPrefix: String { shared.contactDiscoveryV2CensorshipPrefix }
|
||||
|
||||
@objc
|
||||
public static var contactDiscoveryEnclaveName: String { shared.contactDiscoveryMrEnclave.stringValue }
|
||||
public static var contactDiscoveryMrEnclave: MrEnclave { shared.contactDiscoveryMrEnclave }
|
||||
static var contactDiscoveryV2MrEnclave: MrEnclave { shared.contactDiscoveryV2MrEnclave }
|
||||
|
||||
static var keyBackupEnclave: KeyBackupEnclave { shared.keyBackupEnclave }
|
||||
@ -111,7 +105,6 @@ public protocol TSConstantsProtocol: AnyObject {
|
||||
var mainServiceUnidentifiedURL: String { get }
|
||||
var textSecureCDN0ServerURL: String { get }
|
||||
var textSecureCDN2ServerURL: String { get }
|
||||
var contactDiscoverySGXURL: String { get }
|
||||
var contactDiscoveryV2URL: String { get }
|
||||
var keyBackupURL: String { get }
|
||||
var storageServiceURL: String { get }
|
||||
@ -128,13 +121,10 @@ public protocol TSConstantsProtocol: AnyObject {
|
||||
var serviceCensorshipPrefix: String { get }
|
||||
var cdn0CensorshipPrefix: String { get }
|
||||
var cdn2CensorshipPrefix: String { get }
|
||||
var contactDiscoveryCensorshipPrefix: String { get }
|
||||
var keyBackupCensorshipPrefix: String { get }
|
||||
var storageServiceCensorshipPrefix: String { get }
|
||||
var contactDiscoveryV2CensorshipPrefix: String { get }
|
||||
|
||||
// SGX Backed Contact Discovery
|
||||
var contactDiscoveryMrEnclave: MrEnclave { get }
|
||||
var contactDiscoveryV2MrEnclave: MrEnclave { get }
|
||||
|
||||
var keyBackupEnclave: KeyBackupEnclave { get }
|
||||
@ -176,7 +166,6 @@ private class TSConstantsProduction: TSConstantsProtocol {
|
||||
public let mainServiceUnidentifiedURL = "https://ud-chat.signal.org"
|
||||
public let textSecureCDN0ServerURL = "https://cdn.signal.org"
|
||||
public let textSecureCDN2ServerURL = "https://cdn2.signal.org"
|
||||
public let contactDiscoverySGXURL = "https://api.directory.signal.org"
|
||||
public let contactDiscoveryV2URL = "wss://cdsi.signal.org"
|
||||
public let keyBackupURL = "https://api.backup.signal.org"
|
||||
public let storageServiceURL = "https://storage.signal.org"
|
||||
@ -193,12 +182,10 @@ private class TSConstantsProduction: TSConstantsProtocol {
|
||||
public let serviceCensorshipPrefix = "service"
|
||||
public let cdn0CensorshipPrefix = "cdn"
|
||||
public let cdn2CensorshipPrefix = "cdn2"
|
||||
public let contactDiscoveryCensorshipPrefix = "directory"
|
||||
public let keyBackupCensorshipPrefix = "backup"
|
||||
public let storageServiceCensorshipPrefix = "storage"
|
||||
public let contactDiscoveryV2CensorshipPrefix = "cdsi"
|
||||
|
||||
public var contactDiscoveryMrEnclave = MrEnclave("74778bb0f93ae1f78c26e67152bab0bbeb693cd56d1bb9b4e9244157acc58081")
|
||||
public let contactDiscoveryV2MrEnclave = MrEnclave("0f6fd79cdfdaa5b2e6337f534d3baf999318b0c462a7ac1f41297a3e4b424a57")
|
||||
|
||||
public let keyBackupEnclave = KeyBackupEnclave(
|
||||
@ -230,7 +217,6 @@ private class TSConstantsStaging: TSConstantsProtocol {
|
||||
public let mainServiceUnidentifiedURL = "https://ud-chat.staging.signal.org"
|
||||
public let textSecureCDN0ServerURL = "https://cdn-staging.signal.org"
|
||||
public let textSecureCDN2ServerURL = "https://cdn2-staging.signal.org"
|
||||
public let contactDiscoverySGXURL = "https://api-staging.directory.signal.org"
|
||||
public let contactDiscoveryV2URL = "wss://cdsi.staging.signal.org"
|
||||
public let keyBackupURL = "https://api-staging.backup.signal.org"
|
||||
public let storageServiceURL = "https://storage-staging.signal.org"
|
||||
@ -249,13 +235,11 @@ private class TSConstantsStaging: TSConstantsProtocol {
|
||||
public let serviceCensorshipPrefix = "service-staging"
|
||||
public let cdn0CensorshipPrefix = "cdn-staging"
|
||||
public let cdn2CensorshipPrefix = "cdn2-staging"
|
||||
public let contactDiscoveryCensorshipPrefix = "directory-staging"
|
||||
public let keyBackupCensorshipPrefix = "backup-staging"
|
||||
public let storageServiceCensorshipPrefix = "storage-staging"
|
||||
public let contactDiscoveryV2CensorshipPrefix = "cdsi-staging"
|
||||
|
||||
// CDS uses the same EnclaveName and MrEnclave
|
||||
public var contactDiscoveryMrEnclave = MrEnclave("74778bb0f93ae1f78c26e67152bab0bbeb693cd56d1bb9b4e9244157acc58081")
|
||||
public let contactDiscoveryV2MrEnclave = MrEnclave("0f6fd79cdfdaa5b2e6337f534d3baf999318b0c462a7ac1f41297a3e4b424a57")
|
||||
|
||||
public let keyBackupEnclave = KeyBackupEnclave(
|
||||
|
||||
@ -241,10 +241,6 @@ public class RemoteConfig: BaseFlags {
|
||||
getUIntValue(forFlag: .maxGroupCallRingSize, defaultValue: 16)
|
||||
}
|
||||
|
||||
public static var contactDiscoveryV2KillSwitch: Bool {
|
||||
isEnabled(.contactDiscoveryV2KillSwitch)
|
||||
}
|
||||
|
||||
public static var enableAutoAPNSRotation: Bool {
|
||||
return isEnabled(.enableAutoAPNSRotation, defaultValue: false)
|
||||
}
|
||||
@ -519,7 +515,6 @@ private struct Flags {
|
||||
case paypalOneTimeDonationKillSwitch
|
||||
case paypalGiftDonationKillSwitch
|
||||
case paypalMonthlyDonationKillSwitch
|
||||
case contactDiscoveryV2KillSwitch
|
||||
case enableAutoAPNSRotation
|
||||
case ringrtcNwPathMonitorTrialKillSwitch
|
||||
}
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
//
|
||||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import SignalServiceKit
|
||||
|
||||
class ContactDiscoveryE164CollectionTest: XCTestCase {
|
||||
func test_encodeNumber() throws {
|
||||
let phoneNumbers = [try XCTUnwrap(E164("+1011"))]
|
||||
let actual = ContactDiscoveryE164Collection(phoneNumbers).encodedValues
|
||||
let expected: Data = Data([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf3])
|
||||
|
||||
XCTAssertEqual(expected, actual)
|
||||
}
|
||||
|
||||
func test_encodeMultipleNumber() throws {
|
||||
let phoneNumbers = [ try XCTUnwrap(E164("+1011")), try XCTUnwrap(E164("+19875550123")) ]
|
||||
let actual = ContactDiscoveryE164Collection(phoneNumbers).encodedValues
|
||||
let expected: Data = Data([
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf3,
|
||||
0x00, 0x00, 0x00, 0x04, 0xa0, 0xac, 0xd3, 0xab
|
||||
])
|
||||
XCTAssertEqual(expected, actual)
|
||||
}
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
//
|
||||
// Copyright 2018 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
//
|
||||
|
||||
import XCTest
|
||||
@testable import SignalServiceKit
|
||||
|
||||
class ContactDiscoveryOperationTest: XCTestCase {
|
||||
func test_uuidArrayFromEmptyData() {
|
||||
let data = Data()
|
||||
let uuids = SGXContactDiscoveryOperation.uuidArray(from: data)
|
||||
XCTAssertEqual([], uuids)
|
||||
}
|
||||
|
||||
func test_uuidArrayFromZeroBytes() {
|
||||
let data = Data(repeating: 0x00, count: 16)
|
||||
let uuids = SGXContactDiscoveryOperation.uuidArray(from: data)
|
||||
XCTAssertEqual([UUID(uuidString: "00000000-0000-0000-0000-000000000000")], uuids)
|
||||
}
|
||||
|
||||
func test_uuidArrayFromBytes() {
|
||||
let bytes: [UInt8] = [
|
||||
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,
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
|
||||
]
|
||||
let data = Data(bytes)
|
||||
let uuids = SGXContactDiscoveryOperation.uuidArray(from: data)
|
||||
let expected = [UUID(uuidString: "00000000-0000-0000-0000-000000000000"),
|
||||
UUID(uuidString: "00000000-0000-0000-0000-000000000000"),
|
||||
UUID(uuidString: "01020304-0506-0708-090A-0B0C0D0E0F10")]
|
||||
XCTAssertEqual(expected, uuids)
|
||||
}
|
||||
|
||||
func test_encodeNumber() throws {
|
||||
let phoneNumbers = [try XCTUnwrap(E164("+1011"))]
|
||||
let actual = ContactDiscoveryE164Collection(phoneNumbers).encodedValues
|
||||
let expected: Data = Data([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf3])
|
||||
|
||||
XCTAssertEqual(expected, actual)
|
||||
}
|
||||
|
||||
func test_encodeMultipleNumber() throws {
|
||||
let phoneNumbers = [ try XCTUnwrap(E164("+1011")), try XCTUnwrap(E164("+15551231234")) ]
|
||||
let actual = ContactDiscoveryE164Collection(phoneNumbers).encodedValues
|
||||
let expected: Data = Data([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf3,
|
||||
0x00, 0x00, 0x00, 0x03, 0x9e, 0xec, 0xf5, 0x02])
|
||||
|
||||
XCTAssertEqual(expected, actual)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user