Skip to content

Commit cc99feb

Browse files
greyson-signalcody-signal
authored andcommitted
Allow use of the new CDSH service in staging.
1 parent e72be42 commit cc99feb

File tree

13 files changed

+353
-17
lines changed

13 files changed

+353
-17
lines changed

app/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ android {
149149
buildConfigField "String", "SIGNAL_CDN_URL", "\"https://cdn.signal.org\""
150150
buildConfigField "String", "SIGNAL_CDN2_URL", "\"https://cdn2.signal.org\""
151151
buildConfigField "String", "SIGNAL_CONTACT_DISCOVERY_URL", "\"https://api.directory.signal.org\""
152+
buildConfigField "String", "SIGNAL_CDSH_URL", "\"https://cdsh.staging.signal.org\""
152153
buildConfigField "String", "SIGNAL_SERVICE_STATUS_URL", "\"uptime.signal.org\""
153154
buildConfigField "String", "SIGNAL_KEY_BACKUP_URL", "\"https://api.backup.signal.org\""
154155
buildConfigField "String", "SIGNAL_SFU_URL", "\"https://sfu.voip.signal.org\""
@@ -157,6 +158,8 @@ android {
157158
buildConfigField "String", "CONTENT_PROXY_HOST", "\"contentproxy.signal.org\""
158159
buildConfigField "int", "CONTENT_PROXY_PORT", "443"
159160
buildConfigField "String", "SIGNAL_AGENT", "\"OWA\""
161+
buildConfigField "String", "CDSH_PUBLIC_KEY", "\"2fe57da347cd62431528daac5fbb290730fff684afc4cfc2ed90995f58cb3b74\""
162+
buildConfigField "String", "CDSH_CODE_HASH", "\"ec31a51880d19a5e9e0fed404740c1a3ff53a553125564b745acce475f0fded8\""
160163
buildConfigField "String", "CDS_MRENCLAVE", "\"c98e00a4e3ff977a56afefe7362a27e4961e4f19e211febfbb19b897e6b80b15\""
161164
buildConfigField "KbsEnclave", "KBS_ENCLAVE", "new KbsEnclave(\"fe7c1bfae98f9b073d220366ea31163ee82f6d04bead774f71ca8e5c40847bfe\"," +
162165
"\"fe7c1bfae98f9b073d220366ea31163ee82f6d04bead774f71ca8e5c40847bfe\", " +
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package org.thoughtcrime.securesms.contacts.sync;
2+
3+
import androidx.annotation.NonNull;
4+
import androidx.annotation.WorkerThread;
5+
6+
import org.signal.core.util.logging.Log;
7+
import org.thoughtcrime.securesms.BuildConfig;
8+
import org.thoughtcrime.securesms.contacts.sync.DirectoryHelper.DirectoryResult;
9+
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
10+
import org.thoughtcrime.securesms.util.SetUtil;
11+
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
12+
13+
import java.io.IOException;
14+
import java.util.ArrayList;
15+
import java.util.Collections;
16+
import java.util.HashSet;
17+
import java.util.List;
18+
import java.util.Map;
19+
import java.util.Set;
20+
import java.util.UUID;
21+
import java.util.stream.Collectors;
22+
23+
/**
24+
* Uses CDS to map E164's to UUIDs.
25+
*/
26+
class ContactDiscoveryV3 {
27+
28+
private static final String TAG = Log.tag(ContactDiscoveryV3.class);
29+
30+
private static final int MAX_NUMBERS = 20_500;
31+
32+
@WorkerThread
33+
static DirectoryResult getDirectoryResult(@NonNull Set<String> databaseNumbers, @NonNull Set<String> systemNumbers) throws IOException {
34+
Set<String> allNumbers = SetUtil.union(databaseNumbers, systemNumbers);
35+
FuzzyPhoneNumberHelper.InputResult inputResult = FuzzyPhoneNumberHelper.generateInput(allNumbers, databaseNumbers);
36+
Set<String> sanitizedNumbers = sanitizeNumbers(inputResult.getNumbers());
37+
Set<String> ignoredNumbers = new HashSet<>();
38+
39+
if (sanitizedNumbers.size() > MAX_NUMBERS) {
40+
Set<String> randomlySelected = randomlySelect(sanitizedNumbers, MAX_NUMBERS);
41+
42+
ignoredNumbers = SetUtil.difference(sanitizedNumbers, randomlySelected);
43+
sanitizedNumbers = randomlySelected;
44+
}
45+
46+
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
47+
48+
try {
49+
Map<String, UUID> results = accountManager.getRegisteredUsersWithCdsh(sanitizedNumbers, BuildConfig.CDSH_PUBLIC_KEY, BuildConfig.CDSH_CODE_HASH);
50+
FuzzyPhoneNumberHelper.OutputResultV2 outputResult = FuzzyPhoneNumberHelper.generateOutputV2(results, inputResult);
51+
52+
return new DirectoryResult(outputResult.getNumbers(), outputResult.getRewrites(), ignoredNumbers);
53+
} catch (IOException e) {
54+
Log.w(TAG, "Attestation error.", e);
55+
throw new IOException(e);
56+
}
57+
}
58+
59+
private static Set<String> sanitizeNumbers(@NonNull Set<String> numbers) {
60+
return numbers.stream().filter(number -> {
61+
try {
62+
return number.startsWith("+") && number.length() > 1 && number.charAt(1) != '0' && Long.parseLong(number.substring(1)) > 0;
63+
} catch (NumberFormatException e) {
64+
return false;
65+
}
66+
}).collect(Collectors.toSet());
67+
}
68+
69+
private static @NonNull Set<String> randomlySelect(@NonNull Set<String> numbers, int max) {
70+
List<String> list = new ArrayList<>(numbers);
71+
Collections.shuffle(list);
72+
73+
return new HashSet<>(list.subList(0, max));
74+
}
75+
}

app/src/main/java/org/thoughtcrime/securesms/contacts/sync/DirectoryHelper.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.thoughtcrime.securesms.sms.IncomingJoinedMessage;
4444
import org.thoughtcrime.securesms.storage.StorageSyncHelper;
4545
import org.thoughtcrime.securesms.util.CursorUtil;
46+
import org.thoughtcrime.securesms.util.FeatureFlags;
4647
import org.thoughtcrime.securesms.util.ProfileUtil;
4748
import org.thoughtcrime.securesms.util.SetUtil;
4849
import org.thoughtcrime.securesms.util.Stopwatch;
@@ -230,7 +231,12 @@ private static void refreshNumbers(@NonNull Context context, @NonNull Set<String
230231

231232
Stopwatch stopwatch = new Stopwatch("refresh");
232233

233-
DirectoryResult result = ContactDiscoveryV2.getDirectoryResult(context, databaseNumbers, systemNumbers);
234+
DirectoryResult result;
235+
if (FeatureFlags.cdsh()) {
236+
result = ContactDiscoveryV3.getDirectoryResult(databaseNumbers, systemNumbers);
237+
} else {
238+
result = ContactDiscoveryV2.getDirectoryResult(context, databaseNumbers, systemNumbers);
239+
}
234240

235241
stopwatch.split("network");
236242

app/src/main/java/org/thoughtcrime/securesms/push/SignalServiceNetworkAccess.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.whispersystems.libsignal.util.guava.Optional;
2222
import org.whispersystems.signalservice.api.push.TrustStore;
2323
import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl;
24+
import org.whispersystems.signalservice.internal.configuration.SignalCdshUrl;
2425
import org.whispersystems.signalservice.internal.configuration.SignalContactDiscoveryUrl;
2526
import org.whispersystems.signalservice.internal.configuration.SignalKeyBackupServiceUrl;
2627
import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
@@ -159,7 +160,6 @@ public SignalServiceNetworkAccess(Context context) {
159160
final SignalContactDiscoveryUrl omanGoogleDiscovery = new SignalContactDiscoveryUrl("https://www.google.com.om/directory", SERVICE_REFLECTOR_HOST, trustStore, GMAIL_CONNECTION_SPEC);
160161
final SignalContactDiscoveryUrl qatarGoogleDiscovery = new SignalContactDiscoveryUrl("https://www.google.com.qa/directory", SERVICE_REFLECTOR_HOST, trustStore, GMAIL_CONNECTION_SPEC);
161162

162-
163163
final SignalKeyBackupServiceUrl baseGoogleKbs = new SignalKeyBackupServiceUrl("https://www.google.com/backup", SERVICE_REFLECTOR_HOST, trustStore, GMAIL_CONNECTION_SPEC);
164164
final SignalKeyBackupServiceUrl baseAndroidKbs = new SignalKeyBackupServiceUrl("https://android.clients.google.com/backup", SERVICE_REFLECTOR_HOST, trustStore, PLAY_CONNECTION_SPEC);
165165
final SignalKeyBackupServiceUrl mapsOneAndroidKbs = new SignalKeyBackupServiceUrl("https://clients3.google.com/backup", SERVICE_REFLECTOR_HOST, trustStore, GMAPS_CONNECTION_SPEC);
@@ -204,6 +204,7 @@ public SignalServiceNetworkAccess(Context context) {
204204
new SignalContactDiscoveryUrl[] {egyptGoogleDiscovery, baseGoogleDiscovery, baseAndroidDiscovery, mapsOneAndroidDiscovery, mapsTwoAndroidDiscovery, mailAndroidDiscovery},
205205
new SignalKeyBackupServiceUrl[] {egyptGoogleKbs, baseGoogleKbs, baseAndroidKbs, mapsOneAndroidKbs, mapsTwoAndroidKbs, mailAndroidKbs},
206206
new SignalStorageUrl[] {egyptGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage},
207+
new SignalCdshUrl[] {new SignalCdshUrl(BuildConfig.SIGNAL_CDSH_URL, new SignalServiceTrustStore(context))},
207208
interceptors,
208209
dns,
209210
Optional.absent(),
@@ -215,6 +216,7 @@ public SignalServiceNetworkAccess(Context context) {
215216
new SignalContactDiscoveryUrl[] {uaeGoogleDiscovery, baseGoogleDiscovery, baseAndroidDiscovery, mapsOneAndroidDiscovery, mapsTwoAndroidDiscovery, mailAndroidDiscovery},
216217
new SignalKeyBackupServiceUrl[] {uaeGoogleKbs, baseGoogleKbs, baseAndroidKbs, mapsOneAndroidKbs, mapsTwoAndroidKbs, mailAndroidKbs},
217218
new SignalStorageUrl[] {uaeGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage},
219+
new SignalCdshUrl[] {new SignalCdshUrl(BuildConfig.SIGNAL_CDSH_URL, new SignalServiceTrustStore(context))},
218220
interceptors,
219221
dns,
220222
Optional.absent(),
@@ -226,6 +228,7 @@ public SignalServiceNetworkAccess(Context context) {
226228
new SignalContactDiscoveryUrl[] {omanGoogleDiscovery, baseGoogleDiscovery, baseAndroidDiscovery, mapsOneAndroidDiscovery, mapsTwoAndroidDiscovery, mailAndroidDiscovery},
227229
new SignalKeyBackupServiceUrl[] {omanGoogleKbs, baseGoogleKbs, baseAndroidKbs, mapsOneAndroidKbs, mapsTwoAndroidKbs, mailAndroidKbs},
228230
new SignalStorageUrl[] {omanGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage},
231+
new SignalCdshUrl[] {new SignalCdshUrl(BuildConfig.SIGNAL_CDSH_URL, new SignalServiceTrustStore(context))},
229232
interceptors,
230233
dns,
231234
Optional.absent(),
@@ -238,6 +241,7 @@ public SignalServiceNetworkAccess(Context context) {
238241
new SignalContactDiscoveryUrl[] {qatarGoogleDiscovery, baseGoogleDiscovery, baseAndroidDiscovery, mapsOneAndroidDiscovery, mapsTwoAndroidDiscovery, mailAndroidDiscovery},
239242
new SignalKeyBackupServiceUrl[] {qatarGoogleKbs, baseGoogleKbs, baseAndroidKbs, mapsOneAndroidKbs, mapsTwoAndroidKbs, mailAndroidKbs},
240243
new SignalStorageUrl[] {qatarGoogleStorage, baseGoogleStorage, baseAndroidStorage, mapsOneAndroidStorage, mapsTwoAndroidStorage, mailAndroidStorage},
244+
new SignalCdshUrl[] {new SignalCdshUrl(BuildConfig.SIGNAL_CDSH_URL, new SignalServiceTrustStore(context))},
241245
interceptors,
242246
dns,
243247
Optional.absent(),
@@ -249,6 +253,7 @@ public SignalServiceNetworkAccess(Context context) {
249253
Stream.of(fastUrls).map(url -> new SignalContactDiscoveryUrl(url, DIRECTORY_FASTLY_HOST, new DomainFrontingDigicertTrustStore(context), APP_CONNECTION_SPEC)).toArray(SignalContactDiscoveryUrl[]::new),
250254
Stream.of(fastUrls).map(url -> new SignalKeyBackupServiceUrl(url, KBS_FASTLY_HOST, new DomainFrontingDigicertTrustStore(context), APP_CONNECTION_SPEC)).toArray(SignalKeyBackupServiceUrl[]::new),
251255
Stream.of(fastUrls).map(url -> new SignalStorageUrl(url, STORAGE_FASTLY_HOST, new DomainFrontingDigicertTrustStore(context), APP_CONNECTION_SPEC)).toArray(SignalStorageUrl[]::new),
256+
new SignalCdshUrl[] {new SignalCdshUrl(BuildConfig.SIGNAL_CDSH_URL, new SignalServiceTrustStore(context))},
252257
interceptors,
253258
dns,
254259
Optional.absent(),
@@ -261,6 +266,7 @@ public SignalServiceNetworkAccess(Context context) {
261266
new SignalContactDiscoveryUrl[] {new SignalContactDiscoveryUrl(BuildConfig.SIGNAL_CONTACT_DISCOVERY_URL, new SignalServiceTrustStore(context))},
262267
new SignalKeyBackupServiceUrl[] { new SignalKeyBackupServiceUrl(BuildConfig.SIGNAL_KEY_BACKUP_URL, new SignalServiceTrustStore(context)) },
263268
new SignalStorageUrl[] {new SignalStorageUrl(BuildConfig.STORAGE_URL, new SignalServiceTrustStore(context))},
269+
new SignalCdshUrl[] {new SignalCdshUrl(BuildConfig.SIGNAL_CDSH_URL, new SignalServiceTrustStore(context))},
264270
interceptors,
265271
dns,
266272
SignalStore.proxy().isProxyEnabled() ? Optional.of(SignalStore.proxy().getProxy()) : Optional.absent(),

app/src/main/java/org/thoughtcrime/securesms/util/FeatureFlags.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public final class FeatureFlags {
8585
private static final String GROUP_CALL_RINGING = "android.calling.groupCallRinging";
8686
private static final String CHANGE_NUMBER_ENABLED = "android.changeNumber";
8787
private static final String DONOR_BADGES = "android.donorBadges";
88+
private static final String CDSH = "android.cdsh";
8889

8990
/**
9091
* We will only store remote values for flags in this set. If you want a flag to be controllable
@@ -121,7 +122,8 @@ public final class FeatureFlags {
121122
RETRY_RECEIPTS,
122123
SUGGEST_SMS_BLACKLIST,
123124
MAX_GROUP_CALL_RING_SIZE,
124-
GROUP_CALL_RINGING
125+
GROUP_CALL_RINGING,
126+
CDSH
125127
);
126128

127129
@VisibleForTesting
@@ -174,7 +176,8 @@ public final class FeatureFlags {
174176
RETRY_RECEIPTS,
175177
SENDER_KEY,
176178
MAX_GROUP_CALL_RING_SIZE,
177-
GROUP_CALL_RINGING
179+
GROUP_CALL_RINGING,
180+
CDSH
178181
);
179182

180183
/**
@@ -410,6 +413,10 @@ public static boolean donorBadges() {
410413
}
411414
}
412415

416+
public static boolean cdsh() {
417+
return Environment.IS_STAGING && getBoolean(CDSH, false);
418+
}
419+
413420
/** Only for rendering debug info. */
414421
public static synchronized @NonNull Map<String, Object> getMemoryValues() {
415422
return new TreeMap<>(REMOTE_VALUES);

app/witness-verifications.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -591,11 +591,11 @@ dependencyVerification {
591591
['org.threeten:threetenbp:1.3.6',
592592
'f4c23ffaaed717c3b99c003e0ee02d6d66377fd47d866fec7d971bd8644fc1a7'],
593593

594-
['org.whispersystems:signal-client-android:0.9.4',
595-
'5b4d8e0b37701caefe6089bdf09667716fea5829f105373e4bfce3041e7c6387'],
594+
['org.whispersystems:signal-client-android:0.9.5',
595+
'd63788841fe2c8d15a144c99abf188c1c3478d31701b5cdb4c19761676b9049d'],
596596

597-
['org.whispersystems:signal-client-java:0.9.4',
598-
'629fb84dbbf5663cbfda0cb87420b0f64ad9902088c575478b04009cce9cbf8a'],
597+
['org.whispersystems:signal-client-java:0.9.5',
598+
'f00784bf49e75744e1d6c128136a8849b42551b2075cc392f7fe237793a13f7d'],
599599

600600
['pl.tajchert:waitingdots:0.1.0',
601601
'2835d49e0787dbcb606c5a60021ced66578503b1e9fddcd7a5ef0cd5f095ba2c'],

dependencies.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
dependencyResolutionManagement {
22
versionCatalogs {
33
libs {
4-
version('signal-client', '0.9.4')
4+
version('signal-client', '0.9.5')
55
version('zkgroup', '0.7.0')
66
version('exoplayer', '2.15.0')
77
version('androidx-camera', '1.0.0-beta11')

device-transfer/lib/witness-verifications.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ dependencyVerification {
8181
['org.greenrobot:eventbus:3.0.0',
8282
'180d4212467df06f2fbc9c8d8a2984533ac79c87769ad883bc421612f0b4e17c'],
8383

84-
['org.whispersystems:signal-client-java:0.9.4',
85-
'629fb84dbbf5663cbfda0cb87420b0f64ad9902088c575478b04009cce9cbf8a'],
84+
['org.whispersystems:signal-client-java:0.9.5',
85+
'f00784bf49e75744e1d6c128136a8849b42551b2075cc392f7fe237793a13f7d'],
8686
]
8787
}

0 commit comments

Comments
 (0)