From 642d1984c441e8d54567a746c8eddeee5e7cca79 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Fri, 20 Aug 2021 14:03:11 -0400 Subject: [PATCH] Ensure all SignalServiceAddresses have UUIDs. --- .../securesms/database/RecipientDatabase.java | 12 +-- .../securesms/database/SessionDatabase.java | 4 + .../jobs/MultiDeviceContactUpdateJob.java | 6 +- .../securesms/jobs/PushMediaSendJob.java | 2 +- .../securesms/jobs/PushTextSendJob.java | 2 +- .../messages/IncomingMessageProcessor.java | 2 +- .../messages/MessageDecryptionUtil.java | 2 +- .../securesms/recipients/Recipient.java | 6 +- .../securesms/recipients/RecipientId.java | 4 +- .../securesms/recipients/RecipientUtil.java | 18 +--- .../storage/ContactRecordProcessor.java | 10 +- .../storage/StorageSyncValidations.java | 2 +- .../securesms/util/ProfileUtil.java | 11 +-- .../securesms/util/RecipientAccessList.kt | 4 +- .../api/SignalServiceMessageReceiver.java | 8 +- .../api/SignalServiceMessageSender.java | 91 +++++++------------ .../api/crypto/SignalServiceCipher.java | 32 ++----- .../api/messages/SignalServiceContent.java | 2 +- .../api/messages/SignalServiceEnvelope.java | 8 +- .../DeviceContactsOutputStream.java | 9 +- .../multidevice/SentTranscriptMessage.java | 5 +- .../api/push/SignalServiceAddress.java | 73 +++++---------- .../api/services/ProfileService.java | 13 ++- .../api/storage/SignalAccountRecord.java | 6 +- .../api/storage/SignalContactRecord.java | 4 +- .../signalservice/api/util/UuidUtil.java | 4 + .../internal/push/PushServiceSocket.java | 8 -- ...ignalServiceAddressProtobufSerializer.java | 18 ++-- .../main/proto/InternalSerialization.proto | 1 - ...lServiceAddressProtobufSerializerTest.java | 22 +---- 30 files changed, 134 insertions(+), 255 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java index 8bac0e8cfc..55cffb40b7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java @@ -792,7 +792,7 @@ public class RecipientDatabase extends Database { if (id < 0) { Log.w(TAG, "[applyStorageSyncContactInsert] Failed to insert. Possibly merging."); - recipientId = getAndPossiblyMerge(insert.getAddress().getUuid().get(), insert.getAddress().getNumber().get(), true); + recipientId = getAndPossiblyMerge(insert.getAddress().getUuid(), insert.getAddress().getNumber().get(), true); db.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(recipientId)); } else { recipientId = RecipientId.from(id); @@ -827,7 +827,7 @@ public class RecipientDatabase extends Database { RecipientId recipientId = getByColumn(STORAGE_SERVICE_ID, Base64.encodeBytes(update.getOld().getId().getRaw())).get(); Log.w(TAG, "[applyStorageSyncContactUpdate] Found user " + recipientId + ". Possibly merging."); - recipientId = getAndPossiblyMerge(update.getNew().getAddress().getUuid().orNull(), update.getNew().getAddress().getNumber().orNull(), true); + recipientId = getAndPossiblyMerge(update.getNew().getAddress().getUuid(), update.getNew().getAddress().getNumber().orNull(), true); Log.w(TAG, "[applyStorageSyncContactUpdate] Merged into " + recipientId); db.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(recipientId)); @@ -1019,13 +1019,10 @@ public class RecipientDatabase extends Database { private static @NonNull ContentValues getValuesForStorageContact(@NonNull SignalContactRecord contact, boolean isInsert) { ContentValues values = new ContentValues(); - if (contact.getAddress().getUuid().isPresent()) { - values.put(UUID, contact.getAddress().getUuid().get().toString()); - } - ProfileName profileName = ProfileName.fromParts(contact.getGivenName().orNull(), contact.getFamilyName().orNull()); String username = contact.getUsername().orNull(); + values.put(UUID, contact.getAddress().getUuid().toString()); values.put(PHONE, contact.getAddress().getNumber().orNull()); values.put(PROFILE_GIVEN_NAME, profileName.getGivenName()); values.put(PROFILE_FAMILY_NAME, profileName.getFamilyName()); @@ -2600,8 +2597,7 @@ public class RecipientDatabase extends Database { .map(b -> b.getNumber().get()) .toList(); List blockedUuid = Stream.of(blocked) - .filter(b -> b.getUuid().isPresent()) - .map(b -> b.getUuid().get().toString().toLowerCase()) + .map(b -> b.getUuid().toString().toLowerCase()) .toList(); SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SessionDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SessionDatabase.java index 5f94f38743..2670f08b8e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SessionDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SessionDatabase.java @@ -45,6 +45,10 @@ public class SessionDatabase extends Database { } public void store(@NonNull SignalProtocolAddress address, @NonNull SessionRecord record) { + if (address.getName().charAt(0) == '+') { + throw new IllegalArgumentException("Cannot insert an e164 into this table!"); + } + SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); try (SQLiteStatement statement = db.compileStatement("INSERT INTO " + TABLE_NAME + " (" + ADDRESS + ", " + DEVICE + ", " + RECORD + ") VALUES (?, ?, ?) " + diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java index 41791ad571..e72811b0d5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java @@ -379,10 +379,12 @@ public class MultiDeviceContactUpdateJob extends BaseJob { } } - private Optional getVerifiedMessage(Recipient recipient, Optional identity) throws InvalidNumberException { + private Optional getVerifiedMessage(Recipient recipient, Optional identity) + throws InvalidNumberException, IOException + { if (!identity.isPresent()) return Optional.absent(); - SignalServiceAddress destination = RecipientUtil.toSignalServiceAddressBestEffort(context, recipient); + SignalServiceAddress destination = RecipientUtil.toSignalServiceAddress(context, recipient); IdentityKey identityKey = identity.get().getIdentityKey(); VerifiedMessage.VerifiedState state; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java index a2581327ac..8b10ca374f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java @@ -220,7 +220,7 @@ public class PushMediaSendJob extends PushSendJob { .asExpirationUpdate(message.isExpirationUpdate()) .build(); - if (Util.equals(TextSecurePreferences.getLocalUuid(context), address.getUuid().orNull())) { + if (Util.equals(TextSecurePreferences.getLocalUuid(context), address.getUuid())) { Optional syncAccess = UnidentifiedAccessUtil.getAccessForSync(context); SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, mediaMessage, syncAccess); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java index 41b69857f3..f111747935 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java @@ -177,7 +177,7 @@ public class PushTextSendJob extends PushSendJob { .asEndSessionMessage(message.isEndSession()) .build(); - if (Util.equals(TextSecurePreferences.getLocalUuid(context), address.getUuid().orNull())) { + if (Util.equals(TextSecurePreferences.getLocalUuid(context), address.getUuid())) { Optional syncAccess = UnidentifiedAccessUtil.getAccessForSync(context); SignalServiceSyncMessage syncMessage = buildSelfSendSyncMessage(context, textSecureMessage, syncAccess); diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageProcessor.java index 4dd407f901..2f8d13b89d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/IncomingMessageProcessor.java @@ -82,7 +82,7 @@ public class IncomingMessageProcessor { * one was created. Otherwise null. */ public @Nullable String processEnvelope(@NonNull SignalServiceEnvelope envelope) { - if (envelope.hasSource()) { + if (envelope.hasSourceUuid()) { Recipient.externalHighTrustPush(context, envelope.getSourceAddress()); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java index e2418d72b1..6fc942e08a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/messages/MessageDecryptionUtil.java @@ -78,7 +78,7 @@ public final class MessageDecryptionUtil { */ public static @NonNull DecryptionResult decrypt(@NonNull Context context, @NonNull SignalServiceEnvelope envelope) { SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context); - SignalServiceAddress localAddress = new SignalServiceAddress(Optional.of(TextSecurePreferences.getLocalUuid(context)), Optional.of(TextSecurePreferences.getLocalNumber(context))); + SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalUuid(context), Optional.of(TextSecurePreferences.getLocalNumber(context))); SignalServiceCipher cipher = new SignalServiceCipher(localAddress, axolotlStore, ReentrantSessionLock.INSTANCE, UnidentifiedAccessUtil.getCertificateValidator()); List jobs = new LinkedList<>(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java index abd77785a3..29b7003ae3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/Recipient.java @@ -174,7 +174,7 @@ public class Recipient { */ @WorkerThread public static @NonNull Recipient externalPush(@NonNull Context context, @NonNull SignalServiceAddress signalServiceAddress) { - return externalPush(context, signalServiceAddress.getUuid().orNull(), signalServiceAddress.getNumber().orNull(), false); + return externalPush(context, signalServiceAddress.getUuid(), signalServiceAddress.getNumber().orNull(), false); } /** @@ -187,7 +187,7 @@ public class Recipient { if (address.getNumber().isPresent()) { return externalPush(context, null, address.getNumber().get(), false); } else { - return externalPush(context, address.getUuid().orNull(), null, false); + return externalPush(context, address.getUuid(), null, false); } } @@ -202,7 +202,7 @@ public class Recipient { */ @WorkerThread public static @NonNull Recipient externalHighTrustPush(@NonNull Context context, @NonNull SignalServiceAddress signalServiceAddress) { - return externalPush(context, signalServiceAddress.getUuid().orNull(), signalServiceAddress.getNumber().orNull(), true); + return externalPush(context, signalServiceAddress.getUuid(), signalServiceAddress.getNumber().orNull(), true); } /** diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java index 225a6d093f..e9e6e3efa8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientId.java @@ -54,7 +54,7 @@ public class RecipientId implements Parcelable, Comparable { @AnyThread public static @NonNull RecipientId from(@NonNull SignalServiceAddress address) { - return from(address.getUuid().orNull(), address.getNumber().orNull(), false); + return from(address.getUuid(), address.getNumber().orNull(), false); } /** @@ -77,7 +77,7 @@ public class RecipientId implements Parcelable, Comparable { */ @AnyThread public static @NonNull RecipientId fromHighTrust(@NonNull SignalServiceAddress address) { - return from(address.getUuid().orNull(), address.getNumber().orNull(), true); + return from(address.getUuid(), address.getNumber().orNull(), true); } /** diff --git a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java index 71567dd569..5baff4ee35 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/recipients/RecipientUtil.java @@ -37,22 +37,6 @@ public class RecipientUtil { private static final String TAG = Log.tag(RecipientUtil.class); - /** - * This method will do it's best to craft a fully-populated {@link SignalServiceAddress} based on - * the provided recipient. This includes performing a possible network request if no UUID is - * available. If the request to get a UUID fails, the exception is swallowed an an E164-only - * recipient is returned. - */ - @WorkerThread - public static @NonNull SignalServiceAddress toSignalServiceAddressBestEffort(@NonNull Context context, @NonNull Recipient recipient) { - try { - return toSignalServiceAddress(context, recipient); - } catch (IOException e) { - Log.w(TAG, "Failed to populate address!", e); - return new SignalServiceAddress(recipient.getUuid().orNull(), recipient.getE164().orNull()); - } - } - /** * This method will do it's best to craft a fully-populated {@link SignalServiceAddress} based on * the provided recipient. This includes performing a possible network request if no UUID is @@ -76,7 +60,7 @@ public class RecipientUtil { Log.i(TAG, "Successfully performed a UUID fetch for " + recipient.getId() + ". Registered: " + state); } - return new SignalServiceAddress(Optional.fromNullable(recipient.getUuid().orNull()), Optional.fromNullable(recipient.resolve().getE164().orNull())); + return new SignalServiceAddress(recipient.requireUuid(), Optional.fromNullable(recipient.resolve().getE164().orNull())); } public static @NonNull List toSignalServiceAddresses(@NonNull Context context, @NonNull List recipients) diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java index b8a157ce5b..932a5d5403 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java @@ -13,6 +13,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.storage.SignalContactRecord; +import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.storage.protos.ContactRecord.IdentityState; import java.util.Arrays; @@ -49,7 +50,10 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor getMatching(@NonNull SignalContactRecord remote, @NonNull StorageKeyGenerator keyGenerator) { SignalServiceAddress address = remote.getAddress(); - Optional byUuid = address.getUuid().isPresent() ? recipientDatabase.getByUuid(address.getUuid().get()) : Optional.absent(); + Optional byUuid = recipientDatabase.getByUuid(address.getUuid()); Optional byE164 = address.getNumber().isPresent() ? recipientDatabase.getByE164(address.getNumber().get()) : Optional.absent(); return byUuid.or(byE164).transform(recipientDatabase::getRecipientSettingsForSync) @@ -91,7 +95,7 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor unidentifiedAccess = getUnidentifiedAccess(context, recipient); Optional profileKey = ProfileKeyUtil.profileKeyOptional(recipient.getProfileKey()); - return profileService.getProfile(address, profileKey, unidentifiedAccess, requestType) - .map(p -> new Pair<>(recipient, p)) - .onErrorReturn(t -> new Pair<>(recipient, ServiceResponse.forUnknownError(t))); + return Single.fromCallable(() -> toSignalServiceAddress(context, recipient)) + .flatMap(address -> profileService.getProfile(address, profileKey, unidentifiedAccess, requestType).map(p -> new Pair<>(recipient, p))) + .onErrorReturn(t -> new Pair<>(recipient, ServiceResponse.forUnknownError(t))); } public static @Nullable String decryptString(@NonNull ProfileKey profileKey, @Nullable byte[] encryptedString) @@ -267,11 +266,11 @@ public final class ProfileUtil { return Optional.absent(); } - private static @NonNull SignalServiceAddress toSignalServiceAddress(@NonNull Context context, @NonNull Recipient recipient) { + private static @NonNull SignalServiceAddress toSignalServiceAddress(@NonNull Context context, @NonNull Recipient recipient) throws IOException { if (recipient.getRegistered() == RecipientDatabase.RegisteredState.NOT_REGISTERED) { return new SignalServiceAddress(recipient.getUuid().orNull(), recipient.getE164().orNull()); } else { - return RecipientUtil.toSignalServiceAddressBestEffort(context, recipient); + return RecipientUtil.toSignalServiceAddress(context, recipient); } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt b/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt index 8e82a8ee35..24b4fa4051 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/RecipientAccessList.kt @@ -25,8 +25,8 @@ class RecipientAccessList(private val recipients: List) : List unidentifiedAccess, SignalServiceProfile.RequestType requestType) { - Optional uuid = address.getUuid(); + UUID uuid = address.getUuid(); - if (uuid.isPresent() && profileKey.isPresent()) { + if (profileKey.isPresent()) { if (requestType == SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL) { - return socket.retrieveVersionedProfileAndCredential(uuid.get(), profileKey.get(), unidentifiedAccess); + return socket.retrieveVersionedProfileAndCredential(uuid, profileKey.get(), unidentifiedAccess); } else { - return FutureTransformers.map(socket.retrieveVersionedProfile(uuid.get(), profileKey.get(), unidentifiedAccess), profile -> { + return FutureTransformers.map(socket.retrieveVersionedProfile(uuid, profileKey.get(), unidentifiedAccess), profile -> { return new ProfileAndCredential(profile, SignalServiceProfile.RequestType.PROFILE, Optional.absent()); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java index 4704c979db..61a673b082 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java @@ -319,9 +319,8 @@ public class SignalServiceMessageSender { // TODO [greyson][session] Delete this when we delete the button if (message.isEndSession()) { - if (recipient.getUuid().isPresent()) { - store.deleteAllSessions(recipient.getUuid().get().toString()); - } + store.deleteAllSessions(recipient.getUuid().toString()); + if (recipient.getNumber().isPresent()) { store.deleteAllSessions(recipient.getNumber().get()); } @@ -746,16 +745,8 @@ public class SignalServiceMessageSender { if (message.getQuote().isPresent()) { DataMessage.Quote.Builder quoteBuilder = DataMessage.Quote.newBuilder() .setId(message.getQuote().get().getId()) - .setText(message.getQuote().get().getText()); - - if (message.getQuote().get().getAuthor().getUuid().isPresent()) { - quoteBuilder.setAuthorUuid(message.getQuote().get().getAuthor().getUuid().get().toString()); - } - - // TODO [Alan] PhoneNumberPrivacy: Do not set this number - if (message.getQuote().get().getAuthor().getNumber().isPresent()) { - quoteBuilder.setAuthorE164(message.getQuote().get().getAuthor().getNumber().get()); - } + .setText(message.getQuote().get().getText()) + .setAuthorUuid(message.getQuote().get().getAuthor().getUuid().toString()); if (!message.getQuote().get().getMentions().isEmpty()) { for (SignalServiceDataMessage.Mention mention : message.getQuote().get().getMentions()) { @@ -850,11 +841,8 @@ public class SignalServiceMessageSender { DataMessage.Reaction.Builder reactionBuilder = DataMessage.Reaction.newBuilder() .setEmoji(message.getReaction().get().getEmoji()) .setRemove(message.getReaction().get().isRemove()) - .setTargetSentTimestamp(message.getReaction().get().getTargetSentTimestamp()); - - if (message.getReaction().get().getTargetAuthor().getUuid().isPresent()) { - reactionBuilder.setTargetAuthorUuid(message.getReaction().get().getTargetAuthor().getUuid().get().toString()); - } + .setTargetSentTimestamp(message.getReaction().get().getTargetSentTimestamp()) + .setTargetAuthorUuid(message.getReaction().get().getTargetAuthor().getUuid().toString()); builder.setReaction(reactionBuilder.build()); builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.REACTIONS_VALUE, builder.getRequiredProtocolVersion())); @@ -1022,12 +1010,10 @@ public class SignalServiceMessageSender { if (result.getSuccess() != null) { SyncMessage.Sent.UnidentifiedDeliveryStatus.Builder builder = SyncMessage.Sent.UnidentifiedDeliveryStatus.newBuilder(); - if (result.getAddress().getUuid().isPresent()) { - builder = builder.setDestinationUuid(result.getAddress().getUuid().get().toString()); - } + builder.setDestinationUuid(result.getAddress().getUuid().toString()); if (result.getAddress().getNumber().isPresent()) { - builder = builder.setDestinationE164(result.getAddress().getNumber().get()); + builder.setDestinationE164(result.getAddress().getNumber().get()); } builder.setUnidentified(result.getSuccess().isUnidentified()); @@ -1037,8 +1023,11 @@ public class SignalServiceMessageSender { } if (recipient.isPresent()) { - if (recipient.get().getUuid().isPresent()) sentMessage.setDestinationUuid(recipient.get().getUuid().get().toString()); - if (recipient.get().getNumber().isPresent()) sentMessage.setDestinationE164(recipient.get().getNumber().get()); + sentMessage.setDestinationUuid(recipient.get().getUuid().toString()); + + if (recipient.get().getNumber().isPresent()) { + sentMessage.setDestinationE164(recipient.get().getNumber().get()); + } } if (dataMessage.getExpireTimer() > 0) { @@ -1062,9 +1051,7 @@ public class SignalServiceMessageSender { for (ReadMessage readMessage : readMessages) { SyncMessage.Read.Builder readBuilder = SyncMessage.Read.newBuilder().setTimestamp(readMessage.getTimestamp()); - if (readMessage.getSender().getUuid().isPresent()) { - readBuilder.setSenderUuid(readMessage.getSender().getUuid().get().toString()); - } + readBuilder.setSenderUuid(readMessage.getSender().getUuid().toString()); if (readMessage.getSender().getNumber().isPresent()) { readBuilder.setSenderE164(readMessage.getSender().getNumber().get()); @@ -1083,9 +1070,7 @@ public class SignalServiceMessageSender { for (ViewedMessage readMessage : readMessages) { SyncMessage.Viewed.Builder viewedBuilder = SyncMessage.Viewed.newBuilder().setTimestamp(readMessage.getTimestamp()); - if (readMessage.getSender().getUuid().isPresent()) { - viewedBuilder.setSenderUuid(readMessage.getSender().getUuid().get().toString()); - } + viewedBuilder.setSenderUuid(readMessage.getSender().getUuid().toString()); if (readMessage.getSender().getNumber().isPresent()) { viewedBuilder.setSenderE164(readMessage.getSender().getNumber().get()); @@ -1102,9 +1087,7 @@ public class SignalServiceMessageSender { SyncMessage.Builder builder = createSyncMessageBuilder(); SyncMessage.ViewOnceOpen.Builder viewOnceBuilder = SyncMessage.ViewOnceOpen.newBuilder().setTimestamp(readMessage.getTimestamp()); - if (readMessage.getSender().getUuid().isPresent()) { - viewOnceBuilder.setSenderUuid(readMessage.getSender().getUuid().get().toString()); - } + viewOnceBuilder.setSenderUuid(readMessage.getSender().getUuid().toString()); if (readMessage.getSender().getNumber().isPresent()) { viewOnceBuilder.setSenderE164(readMessage.getSender().getNumber().get()); @@ -1121,9 +1104,7 @@ public class SignalServiceMessageSender { SyncMessage.Blocked.Builder blockedMessage = SyncMessage.Blocked.newBuilder(); for (SignalServiceAddress address : blocked.getAddresses()) { - if (address.getUuid().isPresent()) { - blockedMessage.addUuids(address.getUuid().get().toString()); - } + blockedMessage.addUuids(address.getUuid().toString()); if (address.getNumber().isPresent()) { blockedMessage.addNumbers(address.getNumber().get()); } @@ -1223,9 +1204,7 @@ public class SignalServiceMessageSender { if (message.getPerson().get().getNumber().isPresent()) { responseMessage.setThreadE164(message.getPerson().get().getNumber().get()); } - if (message.getPerson().get().getUuid().isPresent()) { - responseMessage.setThreadUuid(message.getPerson().get().getUuid().get().toString()); - } + responseMessage.setThreadUuid(message.getPerson().get().getUuid().toString()); } switch (message.getType()) { @@ -1310,10 +1289,7 @@ public class SignalServiceMessageSender { verifiedMessageBuilder.setNullMessage(ByteString.copyFrom(nullMessage)); verifiedMessageBuilder.setIdentityKey(ByteString.copyFrom(verifiedMessage.getIdentityKey().serialize())); - - if (verifiedMessage.getDestination().getUuid().isPresent()) { - verifiedMessageBuilder.setDestinationUuid(verifiedMessage.getDestination().getUuid().get().toString()); - } + verifiedMessageBuilder.setDestinationUuid(verifiedMessage.getDestination().getUuid().toString()); if (verifiedMessage.getDestination().getNumber().isPresent()) { verifiedMessageBuilder.setDestinationE164(verifiedMessage.getDestination().getNumber().get()); @@ -1674,16 +1650,12 @@ public class SignalServiceMessageSender { Preconditions.checkArgument(recipients.size() == unidentifiedAccess.size(), "Unidentified access mismatch!"); - if (recipients.stream().anyMatch(r -> !r.getUuid().isPresent())) { - throw new IllegalArgumentException("All recipients must have a UUID!"); - } - Map accessByUuid = new HashMap<>(); Iterator addressIterator = recipients.iterator(); Iterator accessIterator = unidentifiedAccess.iterator(); while (addressIterator.hasNext()) { - accessByUuid.put(addressIterator.next().getUuid().get(), accessIterator.next()); + accessByUuid.put(addressIterator.next().getUuid(), accessIterator.next()); } for (int i = 0; i < RETRY_COUNT; i++) { @@ -1693,7 +1665,7 @@ public class SignalServiceMessageSender { .filter(a -> !sharedWith.contains(a)) .map(a -> UuidUtil.parseOrThrow(a.getName())) .distinct() - .map(uuid -> new SignalServiceAddress(uuid, null)) + .map(SignalServiceAddress::new) .collect(Collectors.toList()); if (needsSenderKey.size() > 0) { @@ -1701,7 +1673,7 @@ public class SignalServiceMessageSender { SenderKeyDistributionMessage message = getOrCreateNewGroupSession(distributionId); List> access = needsSenderKey.stream() .map(r -> { - UnidentifiedAccess targetAccess = accessByUuid.get(r.getUuid().get()); + UnidentifiedAccess targetAccess = accessByUuid.get(r.getUuid()); return Optional.of(new UnidentifiedAccessPair(targetAccess, targetAccess)); }) .collect(Collectors.toList()); @@ -1713,7 +1685,7 @@ public class SignalServiceMessageSender { .map(SendMessageResult::getAddress) .collect(Collectors.toList()); - Set successUuids = successes.stream().map(a -> a.getUuid().get().toString()).collect(Collectors.toSet()); + Set successUuids = successes.stream().map(a -> a.getUuid().toString()).collect(Collectors.toSet()); Set successAddresses = targetInfo.destinations.stream().filter(a -> successUuids.contains(a.getName())).collect(Collectors.toSet()); store.markSenderKeySharedWith(distributionId, successAddresses); @@ -1777,13 +1749,13 @@ public class SignalServiceMessageSender { } catch (GroupMismatchedDevicesException e) { Log.w(TAG, "[sendGroupMessage] Handling mismatched devices.", e); for (GroupMismatchedDevices mismatched : e.getMismatchedDevices()) { - SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parse(mismatched.getUuid()), Optional.absent()); + SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrThrow(mismatched.getUuid()), Optional.absent()); handleMismatchedDevices(socket, address, mismatched.getDevices()); } } catch (GroupStaleDevicesException e) { Log.w(TAG, "[sendGroupMessage] Handling stale devices.", e); for (GroupStaleDevices stale : e.getStaleDevices()) { - SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parse(stale.getUuid()), Optional.absent()); + SignalServiceAddress address = new SignalServiceAddress(UuidUtil.parseOrThrow(stale.getUuid()), Optional.absent()); handleStaleDevices(address, stale.getDevices()); } } @@ -1801,12 +1773,12 @@ public class SignalServiceMessageSender { for (SignalServiceAddress recipient : recipients) { List devices = recipientDevices.containsKey(recipient) ? recipientDevices.get(recipient) : new LinkedList<>(); - destinations.add(new SignalProtocolAddress(recipient.getUuid().get().toString(), SignalServiceAddress.DEFAULT_DEVICE_ID)); + destinations.add(new SignalProtocolAddress(recipient.getUuid().toString(), SignalServiceAddress.DEFAULT_DEVICE_ID)); devices.add(SignalServiceAddress.DEFAULT_DEVICE_ID); for (int deviceId : store.getSubDeviceSessions(recipient.getIdentifier())) { if (store.containsSession(new SignalProtocolAddress(recipient.getIdentifier(), deviceId))) { - destinations.add(new SignalProtocolAddress(recipient.getUuid().get().toString(), deviceId)); + destinations.add(new SignalProtocolAddress(recipient.getUuid().toString(), deviceId)); devices.add(deviceId); } } @@ -1832,13 +1804,13 @@ public class SignalServiceMessageSender { Set unregistered = response.getUnsentTargets(); List failures = unregistered.stream() - .map(uuid -> new SignalServiceAddress(uuid, null)) + .map(uuid -> new SignalServiceAddress(uuid)) .map(SendMessageResult::unregisteredFailure) .collect(Collectors.toList()); List success = recipients.keySet() .stream() - .filter(r -> !unregistered.contains(r.getUuid().get())) + .filter(r -> !unregistered.contains(r.getUuid())) .map(a -> SendMessageResult.success(a, recipients.get(a), true, store.isMultiDevice(), -1, Optional.of(content))) .collect(Collectors.toList()); @@ -2038,9 +2010,8 @@ public class SignalServiceMessageSender { List addresses = new ArrayList<>(devices.size()); for (int staleDeviceId : devices) { - if (recipient.getUuid().isPresent()) { - addresses.add(new SignalProtocolAddress(recipient.getUuid().get().toString(), staleDeviceId)); - } + addresses.add(new SignalProtocolAddress(recipient.getUuid().toString(), staleDeviceId)); + if (recipient.getNumber().isPresent()) { addresses.add(new SignalProtocolAddress(recipient.getNumber().get(), staleDeviceId)); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/crypto/SignalServiceCipher.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/crypto/SignalServiceCipher.java index be5ce8786e..8a5b248ba9 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/crypto/SignalServiceCipher.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/crypto/SignalServiceCipher.java @@ -36,7 +36,6 @@ import org.whispersystems.libsignal.SignalProtocolAddress; import org.whispersystems.libsignal.UntrustedIdentityException; import org.whispersystems.libsignal.groups.GroupCipher; import org.whispersystems.libsignal.protocol.CiphertextMessage; -import org.whispersystems.libsignal.protocol.PlaintextContent; import org.whispersystems.libsignal.protocol.PreKeySignalMessage; import org.whispersystems.libsignal.protocol.SignalMessage; import org.whispersystems.libsignal.state.SignalProtocolStore; @@ -52,12 +51,10 @@ import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.internal.push.OutgoingPushMessage; import org.whispersystems.signalservice.internal.push.PushTransportDetails; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; -import org.whispersystems.signalservice.internal.push.SignalServiceProtos.Envelope.Type; import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException; import org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer; import org.whispersystems.signalservice.internal.serialize.SignalServiceMetadataProtobufSerializer; import org.whispersystems.signalservice.internal.serialize.protos.SignalServiceContentProto; -import org.whispersystems.util.Base64; import java.util.List; @@ -96,7 +93,7 @@ public class SignalServiceCipher { PushTransportDetails transport = new PushTransportDetails(); SignalProtocolAddress localProtocolAddress = new SignalProtocolAddress(localAddress.getIdentifier(), SignalServiceAddress.DEFAULT_DEVICE_ID); SignalGroupCipher groupCipher = new SignalGroupCipher(sessionLock, new GroupCipher(signalProtocolStore, localProtocolAddress)); - SignalSealedSessionCipher sessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getUuid().orNull(), localAddress.getNumber().orNull(), 1)); + SignalSealedSessionCipher sessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getUuid(), localAddress.getNumber().orNull(), 1)); CiphertextMessage message = groupCipher.encrypt(distributionId.asUuid(), transport.getPaddedMessageBody(unpaddedMessage)); UnidentifiedSenderMessageContent messageContent = new UnidentifiedSenderMessageContent(message, senderCertificate, @@ -113,7 +110,7 @@ public class SignalServiceCipher { { if (unidentifiedAccess.isPresent()) { SignalSessionCipher sessionCipher = new SignalSessionCipher(sessionLock, new SessionCipher(signalProtocolStore, destination)); - SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getUuid().orNull(), localAddress.getNumber().orNull(), 1)); + SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getUuid(), localAddress.getNumber().orNull(), 1)); return content.processSealedSender(sessionCipher, sealedSessionCipher, destination, unidentifiedAccess.get().getUnidentifiedCertificate()); } else { @@ -182,26 +179,26 @@ public class SignalServiceCipher { byte[] paddedMessage; SignalServiceMetadata metadata; - if (!envelope.hasSource() && !envelope.isUnidentifiedSender()) { - throw new InvalidMessageStructureException("Non-UD envelope is missing a source!"); + if (!envelope.hasSourceUuid() && !envelope.isUnidentifiedSender()) { + throw new InvalidMessageStructureException("Non-UD envelope is missing a UUID!"); } if (envelope.isPreKeySignalMessage()) { - SignalProtocolAddress sourceAddress = getPreferredProtocolAddress(signalProtocolStore, envelope.getSourceAddress(), envelope.getSourceDevice()); + SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.getSourceUuid().get(), envelope.getSourceDevice()); SignalSessionCipher sessionCipher = new SignalSessionCipher(sessionLock, new SessionCipher(signalProtocolStore, sourceAddress)); paddedMessage = sessionCipher.decrypt(new PreKeySignalMessage(ciphertext)); metadata = new SignalServiceMetadata(envelope.getSourceAddress(), envelope.getSourceDevice(), envelope.getTimestamp(), envelope.getServerReceivedTimestamp(), envelope.getServerDeliveredTimestamp(), false, envelope.getServerGuid(), Optional.absent()); } else if (envelope.isSignalMessage()) { - SignalProtocolAddress sourceAddress = getPreferredProtocolAddress(signalProtocolStore, envelope.getSourceAddress(), envelope.getSourceDevice()); + SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.getSourceUuid().get(), envelope.getSourceDevice()); SignalSessionCipher sessionCipher = new SignalSessionCipher(sessionLock, new SessionCipher(signalProtocolStore, sourceAddress)); paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext)); metadata = new SignalServiceMetadata(envelope.getSourceAddress(), envelope.getSourceDevice(), envelope.getTimestamp(), envelope.getServerReceivedTimestamp(), envelope.getServerDeliveredTimestamp(), false, envelope.getServerGuid(), Optional.absent()); } else if (envelope.isUnidentifiedSender()) { - SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getUuid().orNull(), localAddress.getNumber().orNull(), SignalServiceAddress.DEFAULT_DEVICE_ID)); + SignalSealedSessionCipher sealedSessionCipher = new SignalSealedSessionCipher(sessionLock, new SealedSessionCipher(signalProtocolStore, localAddress.getUuid(), localAddress.getNumber().orNull(), SignalServiceAddress.DEFAULT_DEVICE_ID)); DecryptionResult result = sealedSessionCipher.decrypt(certificateValidator, ciphertext, envelope.getServerReceivedTimestamp()); - SignalServiceAddress resultAddress = new SignalServiceAddress(UuidUtil.parse(result.getSenderUuid()), result.getSenderE164()); + SignalServiceAddress resultAddress = new SignalServiceAddress(UuidUtil.parseOrThrow(result.getSenderUuid()), result.getSenderE164()); Optional groupId = result.getGroupId(); paddedMessage = result.getPaddedMessage(); @@ -233,19 +230,6 @@ public class SignalServiceCipher { } } - private static SignalProtocolAddress getPreferredProtocolAddress(SignalProtocolStore store, SignalServiceAddress address, int sourceDevice) { - SignalProtocolAddress uuidAddress = address.getUuid().isPresent() ? new SignalProtocolAddress(address.getUuid().get().toString(), sourceDevice) : null; - SignalProtocolAddress e164Address = address.getNumber().isPresent() ? new SignalProtocolAddress(address.getNumber().get(), sourceDevice) : null; - - if (uuidAddress != null && store.containsSession(uuidAddress)) { - return uuidAddress; - } else if (e164Address != null && store.containsSession(e164Address)) { - return e164Address; - } else { - return new SignalProtocolAddress(address.getIdentifier(), sourceDevice); - } - } - private static class Plaintext { private final SignalServiceMetadata metadata; private final byte[] data; diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceContent.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceContent.java index 90045a2157..9a6dad08ad 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceContent.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceContent.java @@ -1004,7 +1004,7 @@ public final class SignalServiceContent { return new SignalServiceDataMessage.Reaction(reaction.getEmoji(), reaction.getRemove(), - new SignalServiceAddress(uuid, null), + new SignalServiceAddress(uuid), reaction.getTargetSentTimestamp()); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceEnvelope.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceEnvelope.java index a5a6e05743..c68b1101c0 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceEnvelope.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/SignalServiceEnvelope.java @@ -70,9 +70,7 @@ public class SignalServiceEnvelope { .setServerTimestamp(serverReceivedTimestamp); if (sender.isPresent()) { - if (sender.get().getUuid().isPresent()) { - builder.setSourceUuid(sender.get().getUuid().get().toString()); - } + builder.setSourceUuid(sender.get().getUuid().toString()); if (sender.get().getNumber().isPresent()) { builder.setSourceE164(sender.get().getNumber().get()); @@ -125,8 +123,8 @@ public class SignalServiceEnvelope { /** * @return True if either a source E164 or UUID is present. */ - public boolean hasSource() { - return envelope.hasSourceE164() || envelope.hasSourceUuid(); + public boolean hasSourceUuid() { + return envelope.hasSourceUuid(); } /** diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java index 3166e9af4a..81f0039e93 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/DeviceContactsOutputStream.java @@ -37,9 +37,7 @@ public class DeviceContactsOutputStream extends ChunkedOutputStream { private void writeContactDetails(DeviceContact contact) throws IOException { SignalServiceProtos.ContactDetails.Builder contactDetails = SignalServiceProtos.ContactDetails.newBuilder(); - if (contact.getAddress().getUuid().isPresent()) { - contactDetails.setUuid(contact.getAddress().getUuid().get().toString()); - } + contactDetails.setUuid(contact.getAddress().getUuid().toString()); if (contact.getAddress().getNumber().isPresent()) { contactDetails.setNumber(contact.getAddress().getNumber().get()); @@ -71,12 +69,9 @@ public class DeviceContactsOutputStream extends ChunkedOutputStream { SignalServiceProtos.Verified.Builder verifiedBuilder = SignalServiceProtos.Verified.newBuilder() .setIdentityKey(ByteString.copyFrom(contact.getVerified().get().getIdentityKey().serialize())) + .setDestinationUuid(contact.getVerified().get().getDestination().getUuid().toString()) .setState(state); - if (contact.getVerified().get().getDestination().getUuid().isPresent()) { - verifiedBuilder.setDestinationUuid(contact.getVerified().get().getDestination().getUuid().get().toString()); - } - if (contact.getVerified().get().getDestination().getNumber().isPresent()) { verifiedBuilder.setDestinationE164(contact.getVerified().get().getDestination().getNumber().get()); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/SentTranscriptMessage.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/SentTranscriptMessage.java index 447599a965..6fa153de84 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/SentTranscriptMessage.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/messages/multidevice/SentTranscriptMessage.java @@ -43,9 +43,8 @@ public class SentTranscriptMessage { this.isRecipientUpdate = isRecipientUpdate; for (Map.Entry entry : unidentifiedStatus.entrySet()) { - if (entry.getKey().getUuid().isPresent()) { - unidentifiedStatusByUuid.put(entry.getKey().getUuid().get().toString(), entry.getValue()); - } + unidentifiedStatusByUuid.put(entry.getKey().getUuid().toString(), entry.getValue()); + if (entry.getKey().getNumber().isPresent()) { unidentifiedStatusByE164.put(entry.getKey().getNumber().get(), entry.getValue()); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/SignalServiceAddress.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/SignalServiceAddress.java index 3359e021a1..df908efafc 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/SignalServiceAddress.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/push/SignalServiceAddress.java @@ -7,9 +7,11 @@ package org.whispersystems.signalservice.api.push; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.libsignal.util.guava.Preconditions; import org.whispersystems.signalservice.api.util.OptionalUtil; import org.whispersystems.signalservice.api.util.UuidUtil; +import java.util.Objects; import java.util.UUID; /** @@ -19,63 +21,46 @@ public class SignalServiceAddress { public static final int DEFAULT_DEVICE_ID = 1; - private final Optional uuid; + private final UUID uuid; private final Optional e164; - private final Optional relay; /** * Construct a PushAddress. * * @param uuid The UUID of the user, if available. * @param e164 The phone number of the user, if available. - * @param relay The Signal service federated server this user is registered with (if not your own server). */ - public SignalServiceAddress(Optional uuid, Optional e164, Optional relay) { - if (!uuid.isPresent() && !e164.isPresent()) { - throw new AssertionError("Must have either a UUID or E164 number!"); - } - - this.uuid = uuid; + public SignalServiceAddress(UUID uuid, Optional e164) { + this.uuid = Preconditions.checkNotNull(uuid); this.e164 = e164; - this.relay = relay; + } + + public SignalServiceAddress(UUID uuid) { + this.uuid = Preconditions.checkNotNull(uuid); + this.e164 = Optional.absent(); } /** * Convenience constructor that will consider a UUID/E164 string absent if it is null or empty. */ public SignalServiceAddress(UUID uuid, String e164) { - this(Optional.fromNullable(uuid), OptionalUtil.absentIfEmpty(e164)); - } - - public SignalServiceAddress(Optional uuid, Optional e164) { - this(uuid, e164, Optional.absent()); + this(uuid, OptionalUtil.absentIfEmpty(e164)); } public Optional getNumber() { return e164; } - public Optional getUuid() { + public UUID getUuid() { return uuid; } public String getIdentifier() { - if (uuid.isPresent()) { - return uuid.get().toString(); - } else if (e164.isPresent()) { - return e164.get(); - } else { - throw new AssertionError("Given the checks in the constructor, this should not be possible."); - } - } - - public Optional getRelay() { - return relay; + return uuid.toString(); } public boolean matches(SignalServiceAddress other) { - return (uuid.isPresent() && other.uuid.isPresent() && uuid.get().equals(other.uuid.get())) || - (e164.isPresent() && other.e164.isPresent() && e164.get().equals(other.e164.get())); + return this.uuid.equals(other.uuid); } public static boolean isValidAddress(String rawUuid, String e164) { @@ -90,30 +75,14 @@ public class SignalServiceAddress { } } - @Override - public boolean equals(Object other) { - if (other == null || !(other instanceof SignalServiceAddress)) return false; - - SignalServiceAddress that = (SignalServiceAddress)other; - - return equals(this.uuid, that.uuid) && - equals(this.e164, that.e164) && - equals(this.relay, that.relay); + @Override public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final SignalServiceAddress that = (SignalServiceAddress) o; + return uuid.equals(that.uuid) && e164.equals(that.e164); } - @Override - public int hashCode() { - int hashCode = 0; - - if (this.uuid != null) hashCode ^= this.uuid.hashCode(); - if (this.e164 != null) hashCode ^= this.e164.hashCode(); - if (this.relay.isPresent()) hashCode ^= this.relay.get().hashCode(); - - return hashCode; - } - - private boolean equals(Optional one, Optional two) { - if (one.isPresent()) return two.isPresent() && one.get().equals(two.get()); - else return !two.isPresent(); + @Override public int hashCode() { + return Objects.hash(uuid, e164); } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/ProfileService.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/ProfileService.java index e0448b3022..02af01784d 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/ProfileService.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/services/ProfileService.java @@ -57,7 +57,7 @@ public final class ProfileService { Optional unidentifiedAccess, SignalServiceProfile.RequestType requestType) { - Optional uuid = address.getUuid(); + UUID uuid = address.getUuid(); SecureRandom random = new SecureRandom(); ProfileKeyCredentialRequestContext requestContext = null; @@ -65,20 +65,19 @@ public final class ProfileService { .setId(random.nextLong()) .setVerb("GET"); - if (uuid.isPresent() && profileKey.isPresent()) { - UUID target = uuid.get(); - ProfileKeyVersion profileKeyIdentifier = profileKey.get().getProfileKeyVersion(target); + if (profileKey.isPresent()) { + ProfileKeyVersion profileKeyIdentifier = profileKey.get().getProfileKeyVersion(uuid); String version = profileKeyIdentifier.serialize(); if (requestType == SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL) { - requestContext = clientZkProfileOperations.createProfileKeyCredentialRequestContext(random, target, profileKey.get()); + requestContext = clientZkProfileOperations.createProfileKeyCredentialRequestContext(random, uuid, profileKey.get()); ProfileKeyCredentialRequest request = requestContext.getRequest(); String credentialRequest = Hex.toStringCondensed(request.serialize()); - builder.setPath(String.format("/v1/profile/%s/%s/%s", target, version, credentialRequest)); + builder.setPath(String.format("/v1/profile/%s/%s/%s", uuid, version, credentialRequest)); } else { - builder.setPath(String.format("/v1/profile/%s/%s", target, version)); + builder.setPath(String.format("/v1/profile/%s/%s", uuid, version)); } } else { builder.setPath(String.format("/v1/profile/%s", address.getIdentifier())); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalAccountRecord.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalAccountRecord.java index 8a1fc93f6c..1f284026c2 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalAccountRecord.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalAccountRecord.java @@ -297,9 +297,9 @@ public final class SignalAccountRecord implements SignalRecord { private AccountRecord.PinnedConversation toRemote() { if (contact.isPresent()) { AccountRecord.PinnedConversation.Contact.Builder contactBuilder = AccountRecord.PinnedConversation.Contact.newBuilder(); - if (contact.get().getUuid().isPresent()) { - contactBuilder.setUuid(contact.get().getUuid().get().toString()); - } + + contactBuilder.setUuid(contact.get().getUuid().toString()); + if (contact.get().getNumber().isPresent()) { contactBuilder.setE164(contact.get().getNumber().get()); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalContactRecord.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalContactRecord.java index 3fa3586aa7..0ddca30a1f 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalContactRecord.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/storage/SignalContactRecord.java @@ -33,7 +33,7 @@ public final class SignalContactRecord implements SignalRecord { this.proto = proto; this.hasUnknownFields = ProtoUtil.hasUnknownFields(proto); - this.address = new SignalServiceAddress(UuidUtil.parseOrNull(proto.getServiceUuid()), proto.getServiceE164()); + this.address = new SignalServiceAddress(UuidUtil.parseOrUnknown(proto.getServiceUuid()), proto.getServiceE164()); this.givenName = OptionalUtil.absentIfEmpty(proto.getGivenName()); this.familyName = OptionalUtil.absentIfEmpty(proto.getFamilyName()); this.profileKey = OptionalUtil.absentIfEmpty(proto.getProfileKey()); @@ -207,7 +207,7 @@ public final class SignalContactRecord implements SignalRecord { this.id = StorageId.forContact(rawId); this.builder = ContactRecord.newBuilder(); - builder.setServiceUuid(address.getUuid().isPresent() ? address.getUuid().get().toString() : ""); + builder.setServiceUuid(address.getUuid().toString()); builder.setServiceE164(address.getNumber().or("")); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java index 8abc294799..0a304a61a7 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java @@ -27,6 +27,10 @@ public final class UuidUtil { return isUuid(uuid) ? parseOrThrow(uuid) : null; } + public static UUID parseOrUnknown(String uuid) { + return uuid == null || uuid.isEmpty() ? UNKNOWN_UUID : parseOrThrow(uuid); + } + public static UUID parseOrThrow(String uuid) { return UUID.fromString(uuid); } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java index 776ea3abd6..2bf7996662 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java @@ -560,10 +560,6 @@ public class PushServiceSocket { String path = String.format(PREKEY_DEVICE_PATH, destination.getIdentifier(), deviceId); - if (destination.getRelay().isPresent()) { - path = path + "?relay=" + destination.getRelay().get(); - } - String responseText = makeServiceRequest(path, "GET", null, NO_HEADERS, unidentifiedAccess); PreKeyResponse response = JsonUtil.fromJson(responseText, PreKeyResponse.class); List bundles = new LinkedList<>(); @@ -601,10 +597,6 @@ public class PushServiceSocket { try { String path = String.format(PREKEY_DEVICE_PATH, destination.getIdentifier(), String.valueOf(deviceId)); - if (destination.getRelay().isPresent()) { - path = path + "?relay=" + destination.getRelay().get(); - } - String responseText = makeServiceRequest(path, "GET", null); PreKeyResponse response = JsonUtil.fromJson(responseText, PreKeyResponse.class); diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializer.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializer.java index 89492b743c..bb90748bd7 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializer.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializer.java @@ -16,22 +16,20 @@ public final class SignalServiceAddressProtobufSerializer { public static AddressProto toProtobuf(SignalServiceAddress signalServiceAddress) { AddressProto.Builder builder = AddressProto.newBuilder(); + + builder.setUuid(ByteString.copyFrom(UuidUtil.toByteArray(signalServiceAddress.getUuid()))); + if(signalServiceAddress.getNumber().isPresent()){ builder.setE164(signalServiceAddress.getNumber().get()); } - if(signalServiceAddress.getUuid().isPresent()){ - builder.setUuid(ByteString.copyFrom(UuidUtil.toByteArray(signalServiceAddress.getUuid().get()))); - } - if(signalServiceAddress.getRelay().isPresent()){ - builder.setRelay(signalServiceAddress.getRelay().get()); - } + return builder.build(); } public static SignalServiceAddress fromProtobuf(AddressProto addressProto) { - Optional uuid = addressProto.hasUuid() ? Optional.of(UuidUtil.parseOrThrow(addressProto.getUuid().toByteArray())) : Optional.absent(); - Optional number = addressProto.hasE164() ? Optional.of(addressProto.getE164() ) : Optional.absent(); - Optional relay = addressProto.hasRelay() ? Optional.of(addressProto.getRelay() ) : Optional.absent(); - return new SignalServiceAddress(uuid, number, relay); + UUID uuid = UuidUtil.parseOrThrow(addressProto.getUuid().toByteArray()); + Optional number = addressProto.hasE164() ? Optional.of(addressProto.getE164()) : Optional.absent(); + + return new SignalServiceAddress(uuid, number); } } diff --git a/libsignal/service/src/main/proto/InternalSerialization.proto b/libsignal/service/src/main/proto/InternalSerialization.proto index 58488ffc65..4505894735 100644 --- a/libsignal/service/src/main/proto/InternalSerialization.proto +++ b/libsignal/service/src/main/proto/InternalSerialization.proto @@ -48,5 +48,4 @@ message MetadataProto { message AddressProto { optional bytes uuid = 1; optional string e164 = 2; - optional string relay = 3; } diff --git a/libsignal/service/src/test/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializerTest.java b/libsignal/service/src/test/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializerTest.java index 7b482633fb..2438467638 100644 --- a/libsignal/service/src/test/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializerTest.java +++ b/libsignal/service/src/test/java/org/whispersystems/signalservice/internal/serialize/SignalServiceAddressProtobufSerializerTest.java @@ -13,16 +13,7 @@ public final class SignalServiceAddressProtobufSerializerTest { @Test public void serialize_and_deserialize_uuid_address() { - SignalServiceAddress address = new SignalServiceAddress(Optional.fromNullable(UUID.randomUUID()), Optional.absent(), Optional.absent()); - AddressProto addressProto = org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer.toProtobuf(address); - SignalServiceAddress deserialized = org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer.fromProtobuf(addressProto); - - assertEquals(address, deserialized); - } - - @Test - public void serialize_and_deserialize_e164_address() { - SignalServiceAddress address = new SignalServiceAddress(Optional.absent(), Optional.of("+15552345678"), Optional.absent()); + SignalServiceAddress address = new SignalServiceAddress(UUID.randomUUID(), Optional.absent()); AddressProto addressProto = org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer.toProtobuf(address); SignalServiceAddress deserialized = org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer.fromProtobuf(addressProto); @@ -31,19 +22,10 @@ public final class SignalServiceAddressProtobufSerializerTest { @Test public void serialize_and_deserialize_both_address() { - SignalServiceAddress address = new SignalServiceAddress(Optional.fromNullable(UUID.randomUUID()), Optional.of("+15552345678"), Optional.absent()); + SignalServiceAddress address = new SignalServiceAddress(UUID.randomUUID(), Optional.of("+15552345678")); AddressProto addressProto = org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer.toProtobuf(address); SignalServiceAddress deserialized = org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer.fromProtobuf(addressProto); assertEquals(address, deserialized); } - - @Test - public void serialize_and_deserialize_both_address_with_relay() { - SignalServiceAddress address = new SignalServiceAddress(Optional.fromNullable(UUID.randomUUID()), Optional.of("+15552345678"), Optional.of("relay")); - AddressProto addressProto = org.whispersystems.signalservice.internal.serialize.SignalServiceAddressProtobufSerializer.toProtobuf(address); - SignalServiceAddress deserialized = SignalServiceAddressProtobufSerializer.fromProtobuf(addressProto); - - assertEquals(address, deserialized); - } }