Search in sources :

Example 46 with ProfileKey

use of org.signal.zkgroup.profiles.ProfileKey in project Signal-Android by WhisperSystems.

the class ProfileKeySetTest method new_member_by_self_is_authoritative.

@Test
public void new_member_by_self_is_authoritative() {
    UUID newMember = UUID.randomUUID();
    ProfileKey profileKey = ProfileKeyUtil.createNew();
    ProfileKeySet profileKeySet = new ProfileKeySet();
    profileKeySet.addKeysFromGroupChange(changeBy(newMember).addMember(newMember, profileKey).build());
    assertTrue(profileKeySet.getProfileKeys().isEmpty());
    assertThat(profileKeySet.getAuthoritativeProfileKeys(), is(Collections.singletonMap(ACI.from(newMember), profileKey)));
}
Also used : UUID(java.util.UUID) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) Test(org.junit.Test)

Example 47 with ProfileKey

use of org.signal.zkgroup.profiles.ProfileKey in project Signal-Android by WhisperSystems.

the class ProfileKeySet method addMemberKey.

private void addMemberKey(@Nullable UUID changeSource, @NonNull ByteString memberUuidBytes, @NonNull ByteString profileKeyBytes) {
    UUID memberUuid = UuidUtil.fromByteString(memberUuidBytes);
    if (UuidUtil.UNKNOWN_UUID.equals(memberUuid)) {
        Log.w(TAG, "Seen unknown member UUID");
        return;
    }
    ProfileKey profileKey;
    try {
        profileKey = new ProfileKey(profileKeyBytes.toByteArray());
    } catch (InvalidInputException e) {
        Log.w(TAG, "Bad profile key in group");
        return;
    }
    if (memberUuid.equals(changeSource)) {
        authoritativeProfileKeys.put(ACI.from(memberUuid), profileKey);
        profileKeys.remove(ACI.from(memberUuid));
    } else {
        if (!authoritativeProfileKeys.containsKey(ACI.from(memberUuid))) {
            profileKeys.put(ACI.from(memberUuid), profileKey);
        }
    }
}
Also used : InvalidInputException(org.signal.zkgroup.InvalidInputException) UUID(java.util.UUID) ProfileKey(org.signal.zkgroup.profiles.ProfileKey)

Example 48 with ProfileKey

use of org.signal.zkgroup.profiles.ProfileKey in project Signal-Android by signalapp.

the class GroupCandidateHelper method recipientIdToCandidate.

/**
 * Given a recipient will create a {@link GroupCandidate} which may or may not have a profile key credential.
 * <p>
 * It will try to find missing profile key credentials from the server and persist locally.
 */
@WorkerThread
@NonNull
public GroupCandidate recipientIdToCandidate(@NonNull RecipientId recipientId) throws IOException {
    final Recipient recipient = Recipient.resolved(recipientId);
    ServiceId serviceId = recipient.getServiceId().orNull();
    if (serviceId == null) {
        throw new AssertionError("Non UUID members should have need detected by now");
    }
    Optional<ProfileKeyCredential> profileKeyCredential = Optional.fromNullable(recipient.getProfileKeyCredential());
    GroupCandidate candidate = new GroupCandidate(serviceId.uuid(), profileKeyCredential);
    if (!candidate.hasProfileKeyCredential()) {
        ProfileKey profileKey = ProfileKeyUtil.profileKeyOrNull(recipient.getProfileKey());
        if (profileKey != null) {
            Log.i(TAG, String.format("No profile key credential on recipient %s, fetching", recipient.getId()));
            Optional<ProfileKeyCredential> profileKeyCredentialOptional = signalServiceAccountManager.resolveProfileKeyCredential(serviceId, profileKey, Locale.getDefault());
            if (profileKeyCredentialOptional.isPresent()) {
                boolean updatedProfileKey = recipientDatabase.setProfileKeyCredential(recipient.getId(), profileKey, profileKeyCredentialOptional.get());
                if (!updatedProfileKey) {
                    Log.w(TAG, String.format("Failed to update the profile key credential on recipient %s", recipient.getId()));
                } else {
                    Log.i(TAG, String.format("Got new profile key credential for recipient %s", recipient.getId()));
                    candidate = candidate.withProfileKeyCredential(profileKeyCredentialOptional.get());
                }
            }
        }
    }
    return candidate;
}
Also used : ProfileKeyCredential(org.signal.zkgroup.profiles.ProfileKeyCredential) GroupCandidate(org.whispersystems.signalservice.api.groupsv2.GroupCandidate) Recipient(org.thoughtcrime.securesms.recipients.Recipient) ProfileKey(org.signal.zkgroup.profiles.ProfileKey) ServiceId(org.whispersystems.signalservice.api.push.ServiceId) WorkerThread(androidx.annotation.WorkerThread) NonNull(androidx.annotation.NonNull)

Example 49 with ProfileKey

use of org.signal.zkgroup.profiles.ProfileKey in project Signal-Android by signalapp.

the class ProfileKeySet method addMemberKey.

private void addMemberKey(@Nullable UUID changeSource, @NonNull ByteString memberUuidBytes, @NonNull ByteString profileKeyBytes) {
    UUID memberUuid = UuidUtil.fromByteString(memberUuidBytes);
    if (UuidUtil.UNKNOWN_UUID.equals(memberUuid)) {
        Log.w(TAG, "Seen unknown member UUID");
        return;
    }
    ProfileKey profileKey;
    try {
        profileKey = new ProfileKey(profileKeyBytes.toByteArray());
    } catch (InvalidInputException e) {
        Log.w(TAG, "Bad profile key in group");
        return;
    }
    if (memberUuid.equals(changeSource)) {
        authoritativeProfileKeys.put(ACI.from(memberUuid), profileKey);
        profileKeys.remove(ACI.from(memberUuid));
    } else {
        if (!authoritativeProfileKeys.containsKey(ACI.from(memberUuid))) {
            profileKeys.put(ACI.from(memberUuid), profileKey);
        }
    }
}
Also used : InvalidInputException(org.signal.zkgroup.InvalidInputException) UUID(java.util.UUID) ProfileKey(org.signal.zkgroup.profiles.ProfileKey)

Example 50 with ProfileKey

use of org.signal.zkgroup.profiles.ProfileKey in project Signal-Android by signalapp.

the class RetrieveProfileAvatarJob method onRun.

@Override
public void onRun() throws IOException {
    RecipientDatabase database = SignalDatabase.recipients();
    ProfileKey profileKey = ProfileKeyUtil.profileKeyOrNull(recipient.resolve().getProfileKey());
    if (profileKey == null) {
        Log.w(TAG, "Recipient profile key is gone!");
        return;
    }
    if (Util.equals(profileAvatar, recipient.resolve().getProfileAvatar())) {
        Log.w(TAG, "Already retrieved profile avatar: " + profileAvatar);
        return;
    }
    if (TextUtils.isEmpty(profileAvatar)) {
        Log.w(TAG, "Removing profile avatar (no url) for: " + recipient.getId().serialize());
        AvatarHelper.delete(context, recipient.getId());
        database.setProfileAvatar(recipient.getId(), profileAvatar);
        return;
    }
    File downloadDestination = File.createTempFile("avatar", "jpg", context.getCacheDir());
    try {
        SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver();
        InputStream avatarStream = receiver.retrieveProfileAvatar(profileAvatar, downloadDestination, profileKey, AvatarHelper.AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE);
        try {
            AvatarHelper.setAvatar(context, recipient.getId(), avatarStream);
            if (recipient.isSelf()) {
                SignalStore.misc().markHasEverHadAnAvatar();
            }
        } catch (AssertionError e) {
            throw new IOException("Failed to copy stream. Likely a Conscrypt issue.", e);
        }
    } catch (PushNetworkException e) {
        if (e.getCause() instanceof NonSuccessfulResponseCodeException) {
            Log.w(TAG, "Removing profile avatar (no image available) for: " + recipient.getId().serialize());
            AvatarHelper.delete(context, recipient.getId());
        } else {
            throw e;
        }
    } finally {
        if (downloadDestination != null)
            downloadDestination.delete();
    }
    database.setProfileAvatar(recipient.getId(), profileAvatar);
}
Also used : RecipientDatabase(org.thoughtcrime.securesms.database.RecipientDatabase) PushNetworkException(org.whispersystems.signalservice.api.push.exceptions.PushNetworkException) SignalServiceMessageReceiver(org.whispersystems.signalservice.api.SignalServiceMessageReceiver) InputStream(java.io.InputStream) NonSuccessfulResponseCodeException(org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException) IOException(java.io.IOException) File(java.io.File) ProfileKey(org.signal.zkgroup.profiles.ProfileKey)

Aggregations

ProfileKey (org.signal.zkgroup.profiles.ProfileKey)150 Test (org.junit.Test)102 UUID (java.util.UUID)90 DecryptedGroup (org.signal.storageservice.protos.groups.local.DecryptedGroup)50 ProtoTestUtils.randomProfileKey (org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.randomProfileKey)50 DecryptedGroupChange (org.signal.storageservice.protos.groups.local.DecryptedGroupChange)34 ProtoTestUtils.newProfileKey (org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.newProfileKey)28 ProtoTestUtils.withProfileKey (org.whispersystems.signalservice.api.groupsv2.ProtoTestUtils.withProfileKey)28 IOException (java.io.IOException)24 GroupChange (org.signal.storageservice.protos.groups.GroupChange)14 DecryptedMember (org.signal.storageservice.protos.groups.local.DecryptedMember)14 InvalidCiphertextException (org.whispersystems.signalservice.api.crypto.InvalidCiphertextException)12 InvalidInputException (org.signal.zkgroup.InvalidInputException)8 ProfileKeyCredential (org.signal.zkgroup.profiles.ProfileKeyCredential)8 Recipient (org.thoughtcrime.securesms.recipients.Recipient)8 InvalidKeyException (org.whispersystems.libsignal.InvalidKeyException)8 NonNull (androidx.annotation.NonNull)6 ByteArrayOutputStream (java.io.ByteArrayOutputStream)6 RecipientDatabase (org.thoughtcrime.securesms.database.RecipientDatabase)6 IdentityKey (org.whispersystems.libsignal.IdentityKey)6