Skip to content

Commit

Permalink
Versioned Profiles support (disabled).
Browse files Browse the repository at this point in the history
  • Loading branch information
alan-signal authored and greyson-signal committed Feb 14, 2020
1 parent f10d1ea commit 7ecb50a
Show file tree
Hide file tree
Showing 67 changed files with 1,200 additions and 321 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Expand Up @@ -233,6 +233,7 @@ android {
buildConfigField "String", "KEY_BACKUP_ENCLAVE_NAME", "\"fe7c1bfae98f9b073d220366ea31163ee82f6d04bead774f71ca8e5c40847bfe\""
buildConfigField "String", "KEY_BACKUP_MRENCLAVE", "\"a3baab19ef6ce6f34ab9ebb25ba722725ae44a8872dc0ff08ad6d83a9489de87\""
buildConfigField "String", "UNIDENTIFIED_SENDER_TRUST_ROOT", "\"BXu6QIKVz5MA8gstzfOgRQGqyLqOwNKHL6INkv3IHWMF\""
buildConfigField "String", "ZKGROUP_SERVER_PUBLIC_PARAMS", "\"\""
buildConfigField "String[]", "LANGUAGES", "new String[]{\"" + autoResConfig().collect { s -> s.replace('-r', '_') }.join('", "') + '"}'
buildConfigField "int", "CANONICAL_VERSION_CODE", "$canonicalVersionCode"

Expand Down Expand Up @@ -305,6 +306,7 @@ android {
buildConfigField "String", "MRENCLAVE", "\"ba4ebb438bc07713819ee6c98d94037747006d7df63fc9e44d2d6f1fec962a79\""
buildConfigField "String", "KEY_BACKUP_ENCLAVE_NAME", "\"a1e9c1d3f352b5c4f0fc7a421b98119e60e5ff703c28fbea85c66bfa7306deab\""
buildConfigField "String", "UNIDENTIFIED_SENDER_TRUST_ROOT", "\"BbqY1DzohE4NUZoVF+L18oUPrK3kILllLEJh2UnPSsEx\""
buildConfigField "String", "ZKGROUP_SERVER_PUBLIC_PARAMS", "\"\""
}
release {
minifyEnabled true
Expand Down
Expand Up @@ -23,7 +23,6 @@
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.contacts.ContactAccessor;
import org.thoughtcrime.securesms.crypto.SessionUtil;
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult;
import org.thoughtcrime.securesms.database.RecipientDatabase;
Expand All @@ -37,19 +36,16 @@
import org.thoughtcrime.securesms.phonenumbers.PhoneNumberFormatter;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.thoughtcrime.securesms.recipients.RecipientUtil;
import org.thoughtcrime.securesms.service.IncomingMessageObserver;
import org.thoughtcrime.securesms.sms.IncomingJoinedMessage;
import org.thoughtcrime.securesms.util.ProfileUtil;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.SignalServiceMessagePipe;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
import org.whispersystems.signalservice.api.push.ContactTokenDetails;
import org.whispersystems.signalservice.api.util.UuidUtil;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.NotFoundException;
import org.whispersystems.signalservice.api.util.UuidUtil;

import java.io.IOException;
import java.util.Calendar;
Expand Down Expand Up @@ -343,25 +339,8 @@ private static boolean isValidContactNumber(@Nullable String number) {
}

private static boolean isUuidRegistered(@NonNull Context context, @NonNull Recipient recipient) throws IOException {
Optional<UnidentifiedAccessPair> unidentifiedAccess = UnidentifiedAccessUtil.getAccessFor(context, recipient);
SignalServiceMessagePipe authPipe = IncomingMessageObserver.getPipe();
SignalServiceMessagePipe unidentifiedPipe = IncomingMessageObserver.getUnidentifiedPipe();
SignalServiceMessagePipe pipe = unidentifiedPipe != null && unidentifiedAccess.isPresent() ? unidentifiedPipe : authPipe;
SignalServiceAddress address = RecipientUtil.toSignalServiceAddress(context, recipient);

if (pipe != null) {
try {
pipe.getProfile(address, unidentifiedAccess.get().getTargetUnidentifiedAccess());
return true;
} catch (NotFoundException e) {
return false;
} catch (IOException e) {
Log.w(TAG, "Websocket request failed. Falling back to REST.");
}
}

try {
ApplicationDependencies.getSignalServiceMessageReceiver().retrieveProfile(address, unidentifiedAccess.get().getTargetUnidentifiedAccess());
ProfileUtil.retrieveProfile(context, recipient, SignalServiceProfile.RequestType.PROFILE);
return true;
} catch (NotFoundException e) {
return false;
Expand Down
Expand Up @@ -18,6 +18,7 @@
import org.whispersystems.signalservice.api.storage.SignalContactRecord.IdentityState;
import org.whispersystems.signalservice.api.storage.SignalStorageManifest;
import org.whispersystems.signalservice.api.storage.SignalStorageRecord;
import org.whispersystems.signalservice.api.util.OptionalUtil;

import java.nio.ByteBuffer;
import java.util.ArrayList;
Expand Down Expand Up @@ -362,7 +363,7 @@ public static final class ContactUpdate {
private final SignalContactRecord oldContact;
private final SignalContactRecord newContact;

public ContactUpdate(@NonNull SignalContactRecord oldContact, @NonNull SignalContactRecord newContact) {
ContactUpdate(@NonNull SignalContactRecord oldContact, @NonNull SignalContactRecord newContact) {
this.oldContact = oldContact;
this.newContact = newContact;
}
Expand All @@ -377,6 +378,10 @@ SignalContactRecord getNewContact() {
return newContact;
}

public boolean profileKeyChanged() {
return !OptionalUtil.byteArrayEquals(oldContact.getProfileKey(), newContact.getProfileKey());
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down Expand Up @@ -494,7 +499,7 @@ public static class LocalWriteResult {
private final WriteOperationResult writeResult;
private final Map<RecipientId, byte[]> storageKeyUpdates;

public LocalWriteResult(WriteOperationResult writeResult, Map<RecipientId, byte[]> storageKeyUpdates) {
private LocalWriteResult(WriteOperationResult writeResult, Map<RecipientId, byte[]> storageKeyUpdates) {
this.writeResult = writeResult;
this.storageKeyUpdates = storageKeyUpdates;
}
Expand All @@ -510,17 +515,17 @@ public LocalWriteResult(WriteOperationResult writeResult, Map<RecipientId, byte[

private static final class ContactRecordMergeResult {
final Set<SignalContactRecord> localInserts;
final Set<ContactUpdate> localUpdates;
final Set<ContactUpdate> localUpdates;
final Set<SignalContactRecord> remoteInserts;
final Set<ContactUpdate> remoteUpdates;
final Set<ContactUpdate> remoteUpdates;

ContactRecordMergeResult(@NonNull Set<SignalContactRecord> localInserts,
@NonNull Set<ContactUpdate> localUpdates,
@NonNull Set<SignalContactRecord> remoteInserts,
@NonNull Set<ContactUpdate> remoteUpdates)
{
this.localInserts = localInserts;
this.localUpdates = localUpdates;
this.localInserts = localInserts;
this.localUpdates = localUpdates;
this.remoteInserts = remoteInserts;
this.remoteUpdates = remoteUpdates;
}
Expand Down
Expand Up @@ -3,17 +3,27 @@
import android.content.Context;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.signal.zkgroup.InvalidInputException;
import org.signal.zkgroup.profiles.ProfileKey;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.libsignal.util.guava.Optional;

import java.util.Locale;

public final class ProfileKeyUtil {

private static final String TAG = Log.tag(ProfileKeyUtil.class);

private ProfileKeyUtil() {
}

/**
* @deprecated Will inline later as part of Versioned profiles.
*/
/** @deprecated Use strongly typed {@link org.signal.zkgroup.profiles.ProfileKey}
* from {@link #getSelfProfileKey()}
* or {@code getSelfProfileKey().serialize()} if you need the bytes. */
@Deprecated
public static @NonNull byte[] getProfileKey(@NonNull Context context) {
byte[] profileKey = Recipient.self().getProfileKey();
Expand All @@ -22,4 +32,48 @@ private ProfileKeyUtil() {
}
return profileKey;
}

public static synchronized @NonNull ProfileKey getSelfProfileKey() {
try {
return new ProfileKey(Recipient.self().getProfileKey());
} catch (InvalidInputException e) {
throw new AssertionError(e);
}
}

public static @Nullable ProfileKey profileKeyOrNull(@Nullable byte[] profileKey) {
if (profileKey != null) {
try {
return new ProfileKey(profileKey);
} catch (InvalidInputException e) {
Log.w(TAG, String.format(Locale.US, "Seen non-null profile key of wrong length %d", profileKey.length), e);
}
}

return null;
}

public static @NonNull ProfileKey profileKeyOrThrow(@NonNull byte[] profileKey) {
try {
return new ProfileKey(profileKey);
} catch (InvalidInputException e) {
throw new AssertionError(e);
}
}

public static @NonNull Optional<ProfileKey> profileKeyOptional(@Nullable byte[] profileKey) {
return Optional.fromNullable(profileKeyOrNull(profileKey));
}

public static @NonNull Optional<ProfileKey> profileKeyOptionalOrThrow(@NonNull byte[] profileKey) {
return Optional.of(profileKeyOrThrow(profileKey));
}

public static @NonNull ProfileKey createNew() {
try {
return new ProfileKey(Util.getSecretBytes(32));
} catch (InvalidInputException e) {
throw new AssertionError(e);
}
}
}
Expand Up @@ -8,6 +8,7 @@

import org.signal.libsignal.metadata.certificate.CertificateValidator;
import org.signal.libsignal.metadata.certificate.InvalidCertificateException;
import org.signal.zkgroup.profiles.ProfileKey;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.logging.Log;
import org.thoughtcrime.securesms.recipients.Recipient;
Expand Down Expand Up @@ -42,7 +43,7 @@ public static Optional<UnidentifiedAccessPair> getAccessFor(@NonNull Context con
{
try {
byte[] theirUnidentifiedAccessKey = getTargetUnidentifiedAccessKey(recipient);
byte[] ourUnidentifiedAccessKey = getSelfUnidentifiedAccessKey(ProfileKeyUtil.getProfileKey(context));
byte[] ourUnidentifiedAccessKey = UnidentifiedAccess.deriveAccessKeyFrom(ProfileKeyUtil.getSelfProfileKey());
byte[] ourUnidentifiedAccessCertificate = recipient.resolve().isUuidSupported() && Recipient.self().isUuidSupported()
? TextSecurePreferences.getUnidentifiedAccessCertificate(context)
: TextSecurePreferences.getUnidentifiedAccessCertificateLegacy(context);
Expand Down Expand Up @@ -75,7 +76,7 @@ public static Optional<UnidentifiedAccessPair> getAccessFor(@NonNull Context con

public static Optional<UnidentifiedAccessPair> getAccessForSync(@NonNull Context context) {
try {
byte[] ourUnidentifiedAccessKey = getSelfUnidentifiedAccessKey(ProfileKeyUtil.getProfileKey(context));
byte[] ourUnidentifiedAccessKey = UnidentifiedAccess.deriveAccessKeyFrom(ProfileKeyUtil.getSelfProfileKey());
byte[] ourUnidentifiedAccessCertificate = Recipient.self().isUuidSupported() ? TextSecurePreferences.getUnidentifiedAccessCertificate(context)
: TextSecurePreferences.getUnidentifiedAccessCertificateLegacy(context);

Expand All @@ -97,12 +98,8 @@ public static Optional<UnidentifiedAccessPair> getAccessForSync(@NonNull Context
}
}

public static @NonNull byte[] getSelfUnidentifiedAccessKey(@NonNull byte[] selfProfileKey) {
return UnidentifiedAccess.deriveAccessKeyFrom(selfProfileKey);
}

private static @Nullable byte[] getTargetUnidentifiedAccessKey(@NonNull Recipient recipient) {
byte[] theirProfileKey = recipient.resolve().getProfileKey();
ProfileKey theirProfileKey = ProfileKeyUtil.profileKeyOrNull(recipient.resolve().getProfileKey());

switch (recipient.resolve().getUnidentifiedAccessMode()) {
case UNKNOWN:
Expand Down

0 comments on commit 7ecb50a

Please sign in to comment.