Eliminate noisy directory feedback

We observed IOExceptions loading the Contact Discovery IAS KeyStore. We will now throw an AssertionError upon any error
creating the IAS KeyStore, matching the behaviour for creation of the TrustStore used for the main Signal Service. NB: If
this assertion is hit, the user will not even be able to refresh their contacts with the old directory service.
This commit is contained in:
Jeffrey Griffin 2019-04-18 13:01:53 -07:00 committed by Greyson Parrelli
parent 42a8522e98
commit c274c1bb28

View File

@ -42,6 +42,7 @@ import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.ContactTokenDetails; import org.whispersystems.signalservice.api.push.ContactTokenDetails;
import org.whispersystems.signalservice.api.push.TrustStore; import org.whispersystems.signalservice.api.push.TrustStore;
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException; import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
import org.whispersystems.signalservice.internal.contacts.crypto.Quote; import org.whispersystems.signalservice.internal.contacts.crypto.Quote;
import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedQuoteException; import org.whispersystems.signalservice.internal.contacts.crypto.UnauthenticatedQuoteException;
@ -364,10 +365,11 @@ public class DirectoryHelper {
Set<String> sanitizedNumbers = sanitizeNumbers(eligibleContactNumbers); Set<String> sanitizedNumbers = sanitizeNumbers(eligibleContactNumbers);
List<Set<String>> batches = splitIntoBatches(sanitizedNumbers, CONTACT_DISCOVERY_BATCH_SIZE); List<Set<String>> batches = splitIntoBatches(sanitizedNumbers, CONTACT_DISCOVERY_BATCH_SIZE);
List<Future<Set<String>>> futures = new ArrayList<>(batches.size()); List<Future<Set<String>>> futures = new ArrayList<>(batches.size());
KeyStore iasKeyStore = getIasKeyStore(context);
for (Set<String> batch : batches) { for (Set<String> batch : batches) {
Future<Set<String>> future = SignalExecutors.IO.submit(() -> { Future<Set<String>> future = SignalExecutors.IO.submit(() -> {
return new HashSet<>(accountManager.getRegisteredUsers(getIasKeyStore(context), batch, BuildConfig.MRENCLAVE)); return new HashSet<>(accountManager.getRegisteredUsers(iasKeyStore, batch, BuildConfig.MRENCLAVE));
}); });
futures.add(future); futures.add(future);
} }
@ -414,6 +416,9 @@ public class DirectoryHelper {
} else if (e.getCause() instanceof PushNetworkException) { } else if (e.getCause() instanceof PushNetworkException) {
Log.w(TAG, "Failed due to poor network.", e); Log.w(TAG, "Failed due to poor network.", e);
return Optional.absent(); return Optional.absent();
} else if (e.getCause() instanceof NonSuccessfulResponseCodeException) {
Log.w(TAG, "Failed due to non successful response code.", e);
return Optional.absent();
} else { } else {
Log.w(TAG, "Failed for an unknown reason.", e); Log.w(TAG, "Failed for an unknown reason.", e);
accountManager.reportContactDiscoveryServiceUnexpectedError(buildErrorReason(e.getCause())); accountManager.reportContactDiscoveryServiceUnexpectedError(buildErrorReason(e.getCause()));
@ -432,15 +437,17 @@ public class DirectoryHelper {
e instanceof Quote.InvalidQuoteFormatException; e instanceof Quote.InvalidQuoteFormatException;
} }
private static KeyStore getIasKeyStore(@NonNull Context context) private static KeyStore getIasKeyStore(@NonNull Context context) {
throws CertificateException, NoSuchAlgorithmException, IOException, KeyStoreException try {
{ TrustStore contactTrustStore = new IasTrustStore(context);
TrustStore contactTrustStore = new IasTrustStore(context);
KeyStore keyStore = KeyStore.getInstance("BKS"); KeyStore keyStore = KeyStore.getInstance("BKS");
keyStore.load(contactTrustStore.getKeyStoreInputStream(), contactTrustStore.getKeyStorePassword().toCharArray()); keyStore.load(contactTrustStore.getKeyStoreInputStream(), contactTrustStore.getKeyStorePassword().toCharArray());
return keyStore; return keyStore;
} catch (KeyStoreException | CertificateException | IOException | NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
} }
private static String buildErrorReason(@Nullable Throwable t) { private static String buildErrorReason(@Nullable Throwable t) {