mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-05-08 17:29:02 +01:00
Add the ability to have separate ACI and PNI protocol stores.
This commit is contained in:
committed by
Cody Henthorne
parent
dd7a2834bc
commit
33f4bb0000
+1
-1
@@ -40,7 +40,7 @@ public class UntrustedSendDialog extends AlertDialog.Builder implements DialogIn
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
final TextSecureIdentityKeyStore identityStore = ApplicationDependencies.getIdentityStore();
|
final TextSecureIdentityKeyStore identityStore = ApplicationDependencies.getProtocolStore().aci().identities();
|
||||||
|
|
||||||
SimpleTask.run(() -> {
|
SimpleTask.run(() -> {
|
||||||
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||||
|
|||||||
+3
-3
@@ -43,9 +43,9 @@ public class UnverifiedSendDialog extends AlertDialog.Builder implements DialogI
|
|||||||
SimpleTask.run(() -> {
|
SimpleTask.run(() -> {
|
||||||
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||||
for (IdentityRecord identityRecord : untrustedRecords) {
|
for (IdentityRecord identityRecord : untrustedRecords) {
|
||||||
ApplicationDependencies.getIdentityStore().setVerified(identityRecord.getRecipientId(),
|
ApplicationDependencies.getProtocolStore().aci().identities().setVerified(identityRecord.getRecipientId(),
|
||||||
identityRecord.getIdentityKey(),
|
identityRecord.getIdentityKey(),
|
||||||
IdentityDatabase.VerifiedStatus.DEFAULT);
|
IdentityDatabase.VerifiedStatus.DEFAULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+1
-1
@@ -65,7 +65,7 @@ class ConversationSettingsRepository(
|
|||||||
|
|
||||||
fun getIdentity(recipientId: RecipientId, consumer: (IdentityRecord?) -> Unit) {
|
fun getIdentity(recipientId: RecipientId, consumer: (IdentityRecord?) -> Unit) {
|
||||||
SignalExecutors.BOUNDED.execute {
|
SignalExecutors.BOUNDED.execute {
|
||||||
consumer(ApplicationDependencies.getIdentityStore().getIdentityRecord(recipientId).orNull())
|
consumer(ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecord(recipientId).orNull())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ class WebRtcCallRepository {
|
|||||||
recipients = Collections.singletonList(recipient);
|
recipients = Collections.singletonList(recipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
consumer.accept(ApplicationDependencies.getIdentityStore().getIdentityRecords(recipients));
|
consumer.accept(ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecords(recipients));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1685,7 +1685,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
|
|||||||
.setView(R.layout.safety_number_changed_learn_more_dialog)
|
.setView(R.layout.safety_number_changed_learn_more_dialog)
|
||||||
.setPositiveButton(R.string.ConversationFragment_verify, (d, w) -> {
|
.setPositiveButton(R.string.ConversationFragment_verify, (d, w) -> {
|
||||||
SimpleTask.run(getLifecycle(), () -> {
|
SimpleTask.run(getLifecycle(), () -> {
|
||||||
return ApplicationDependencies.getIdentityStore().getIdentityRecord(recipient.getId());
|
return ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecord(recipient.getId());
|
||||||
}, identityRecord -> {
|
}, identityRecord -> {
|
||||||
if (identityRecord.isPresent()) {
|
if (identityRecord.isPresent()) {
|
||||||
startActivity(VerifyIdentityActivity.newIntent(requireContext(), identityRecord.get()));
|
startActivity(VerifyIdentityActivity.newIntent(requireContext(), identityRecord.get()));
|
||||||
|
|||||||
+4
-4
@@ -1949,7 +1949,7 @@ public class ConversationParentFragment extends Fragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
IdentityRecordList identityRecordList = ApplicationDependencies.getIdentityStore().getIdentityRecords(recipients);
|
IdentityRecordList identityRecordList = ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecords(recipients);
|
||||||
|
|
||||||
Log.i(TAG, String.format(Locale.US, "Loaded %d identities in %d ms", recipients.size(), System.currentTimeMillis() - startTime));
|
Log.i(TAG, String.format(Locale.US, "Loaded %d identities in %d ms", recipients.size(), System.currentTimeMillis() - startTime));
|
||||||
|
|
||||||
@@ -3934,9 +3934,9 @@ public class ConversationParentFragment extends Fragment
|
|||||||
SimpleTask.run(() -> {
|
SimpleTask.run(() -> {
|
||||||
try (SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
try (SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||||
for (IdentityRecord identityRecord : unverifiedIdentities) {
|
for (IdentityRecord identityRecord : unverifiedIdentities) {
|
||||||
ApplicationDependencies.getIdentityStore().setVerified(identityRecord.getRecipientId(),
|
ApplicationDependencies.getProtocolStore().aci().identities().setVerified(identityRecord.getRecipientId(),
|
||||||
identityRecord.getIdentityKey(),
|
identityRecord.getIdentityKey(),
|
||||||
VerifiedStatus.DEFAULT);
|
VerifiedStatus.DEFAULT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ class MultiselectForwardRepository(context: Context) {
|
|||||||
fun checkForBadIdentityRecords(shareContacts: List<ShareContact>, consumer: Consumer<List<IdentityRecord>>) {
|
fun checkForBadIdentityRecords(shareContacts: List<ShareContact>, consumer: Consumer<List<IdentityRecord>>) {
|
||||||
SignalExecutors.BOUNDED.execute {
|
SignalExecutors.BOUNDED.execute {
|
||||||
val recipients: List<Recipient> = shareContacts.map { Recipient.resolved(it.recipientId.get()) }
|
val recipients: List<Recipient> = shareContacts.map { Recipient.resolved(it.recipientId.get()) }
|
||||||
val identityRecordList: IdentityRecordList = ApplicationDependencies.getIdentityStore().getIdentityRecords(recipients)
|
val identityRecordList: IdentityRecordList = ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecords(recipients)
|
||||||
|
|
||||||
consumer.accept(identityRecordList.untrustedRecords)
|
consumer.accept(identityRecordList.untrustedRecords)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -68,7 +68,7 @@ final class SafetyNumberChangeRepository {
|
|||||||
|
|
||||||
List<Recipient> recipients = Stream.of(recipientIds).map(Recipient::resolved).toList();
|
List<Recipient> recipients = Stream.of(recipientIds).map(Recipient::resolved).toList();
|
||||||
|
|
||||||
List<ChangedRecipient> changedRecipients = Stream.of(ApplicationDependencies.getIdentityStore().getIdentityRecords(recipients).getIdentityRecords())
|
List<ChangedRecipient> changedRecipients = Stream.of(ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecords(recipients).getIdentityRecords())
|
||||||
.map(record -> new ChangedRecipient(Recipient.resolved(record.getRecipientId()), record))
|
.map(record -> new ChangedRecipient(Recipient.resolved(record.getRecipientId()), record))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ final class SafetyNumberChangeRepository {
|
|||||||
|
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
private TrustAndVerifyResult trustOrVerifyChangedRecipientsInternal(@NonNull List<ChangedRecipient> changedRecipients) {
|
private TrustAndVerifyResult trustOrVerifyChangedRecipientsInternal(@NonNull List<ChangedRecipient> changedRecipients) {
|
||||||
TextSecureIdentityKeyStore identityStore = ApplicationDependencies.getIdentityStore();
|
TextSecureIdentityKeyStore identityStore = ApplicationDependencies.getProtocolStore().aci().identities();
|
||||||
|
|
||||||
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||||
for (ChangedRecipient changedRecipient : changedRecipients) {
|
for (ChangedRecipient changedRecipient : changedRecipients) {
|
||||||
@@ -104,9 +104,9 @@ final class SafetyNumberChangeRepository {
|
|||||||
|
|
||||||
if (changedRecipient.isUnverified()) {
|
if (changedRecipient.isUnverified()) {
|
||||||
Log.d(TAG, "Setting " + identityRecord.getRecipientId() + " as verified");
|
Log.d(TAG, "Setting " + identityRecord.getRecipientId() + " as verified");
|
||||||
ApplicationDependencies.getIdentityStore().setVerified(identityRecord.getRecipientId(),
|
ApplicationDependencies.getProtocolStore().aci().identities().setVerified(identityRecord.getRecipientId(),
|
||||||
identityRecord.getIdentityKey(),
|
identityRecord.getIdentityKey(),
|
||||||
IdentityDatabase.VerifiedStatus.DEFAULT);
|
IdentityDatabase.VerifiedStatus.DEFAULT);
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "Setting " + identityRecord.getRecipientId() + " as approved");
|
Log.d(TAG, "Setting " + identityRecord.getRecipientId() + " as approved");
|
||||||
identityStore.setApproval(identityRecord.getRecipientId(), true);
|
identityStore.setApproval(identityRecord.getRecipientId(), true);
|
||||||
@@ -129,7 +129,7 @@ final class SafetyNumberChangeRepository {
|
|||||||
SignalProtocolAddress mismatchAddress = new SignalProtocolAddress(changedRecipient.getRecipient().requireServiceId(), SignalServiceAddress.DEFAULT_DEVICE_ID);
|
SignalProtocolAddress mismatchAddress = new SignalProtocolAddress(changedRecipient.getRecipient().requireServiceId(), SignalServiceAddress.DEFAULT_DEVICE_ID);
|
||||||
|
|
||||||
Log.d(TAG, "Saving identity for: " + changedRecipient.getRecipient().getId() + " " + changedRecipient.getIdentityRecord().getIdentityKey().hashCode());
|
Log.d(TAG, "Saving identity for: " + changedRecipient.getRecipient().getId() + " " + changedRecipient.getIdentityRecord().getIdentityKey().hashCode());
|
||||||
TextSecureIdentityKeyStore.SaveResult result = ApplicationDependencies.getIdentityStore().saveIdentity(mismatchAddress, changedRecipient.getIdentityRecord().getIdentityKey(), true);
|
TextSecureIdentityKeyStore.SaveResult result = ApplicationDependencies.getProtocolStore().aci().identities().saveIdentity(mismatchAddress, changedRecipient.getIdentityRecord().getIdentityKey(), true);
|
||||||
|
|
||||||
Log.d(TAG, "Saving identity result: " + result);
|
Log.d(TAG, "Saving identity result: " + result);
|
||||||
if (result == TextSecureIdentityKeyStore.SaveResult.NO_CHANGE) {
|
if (result == TextSecureIdentityKeyStore.SaveResult.NO_CHANGE) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class PreKeyUtil {
|
|||||||
private static final int BATCH_SIZE = 100;
|
private static final int BATCH_SIZE = 100;
|
||||||
|
|
||||||
public synchronized static List<PreKeyRecord> generatePreKeys(Context context) {
|
public synchronized static List<PreKeyRecord> generatePreKeys(Context context) {
|
||||||
PreKeyStore preKeyStore = ApplicationDependencies.getPreKeyStore();
|
PreKeyStore preKeyStore = ApplicationDependencies.getProtocolStore().aci();
|
||||||
List<PreKeyRecord> records = new LinkedList<>();
|
List<PreKeyRecord> records = new LinkedList<>();
|
||||||
int preKeyIdOffset = TextSecurePreferences.getNextPreKeyId(context);
|
int preKeyIdOffset = TextSecurePreferences.getNextPreKeyId(context);
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ public class PreKeyUtil {
|
|||||||
|
|
||||||
public synchronized static SignedPreKeyRecord generateSignedPreKey(Context context, IdentityKeyPair identityKeyPair, boolean active) {
|
public synchronized static SignedPreKeyRecord generateSignedPreKey(Context context, IdentityKeyPair identityKeyPair, boolean active) {
|
||||||
try {
|
try {
|
||||||
SignedPreKeyStore signedPreKeyStore = ApplicationDependencies.getPreKeyStore();
|
SignedPreKeyStore signedPreKeyStore = ApplicationDependencies.getProtocolStore().aci();
|
||||||
int signedPreKeyId = TextSecurePreferences.getNextSignedPreKeyId(context);
|
int signedPreKeyId = TextSecurePreferences.getNextSignedPreKeyId(context);
|
||||||
ECKeyPair keyPair = Curve.generateKeyPair();
|
ECKeyPair keyPair = Curve.generateKeyPair();
|
||||||
byte[] signature = Curve.calculateSignature(identityKeyPair.getPrivateKey(), keyPair.getPublicKey().serialize());
|
byte[] signature = Curve.calculateSignature(identityKeyPair.getPrivateKey(), keyPair.getPublicKey().serialize());
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public final class SenderKeyUtil {
|
|||||||
*/
|
*/
|
||||||
public static void rotateOurKey(@NonNull Context context, @NonNull DistributionId distributionId) {
|
public static void rotateOurKey(@NonNull Context context, @NonNull DistributionId distributionId) {
|
||||||
try (SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
try (SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||||
ApplicationDependencies.getSenderKeyStore().deleteAllFor(Recipient.self().requireServiceId(), distributionId);
|
ApplicationDependencies.getProtocolStore().aci().senderKeys().deleteAllFor(Recipient.self().requireServiceId(), distributionId);
|
||||||
SignalDatabase.senderKeyShared().deleteAllFor(distributionId);
|
SignalDatabase.senderKeyShared().deleteAllFor(distributionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,7 @@ public final class SenderKeyUtil {
|
|||||||
*/
|
*/
|
||||||
public static void clearAllState(@NonNull Context context) {
|
public static void clearAllState(@NonNull Context context) {
|
||||||
try (SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
try (SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||||
ApplicationDependencies.getSenderKeyStore().deleteAll();
|
ApplicationDependencies.getProtocolStore().aci().senderKeys().deleteAll();
|
||||||
SignalDatabase.senderKeyShared().deleteAll();
|
SignalDatabase.senderKeyShared().deleteAll();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,24 +15,24 @@ public class SessionUtil {
|
|||||||
public static boolean hasSession(@NonNull RecipientId id) {
|
public static boolean hasSession(@NonNull RecipientId id) {
|
||||||
SignalProtocolAddress axolotlAddress = new SignalProtocolAddress(Recipient.resolved(id).requireServiceId(), SignalServiceAddress.DEFAULT_DEVICE_ID);
|
SignalProtocolAddress axolotlAddress = new SignalProtocolAddress(Recipient.resolved(id).requireServiceId(), SignalServiceAddress.DEFAULT_DEVICE_ID);
|
||||||
|
|
||||||
return ApplicationDependencies.getSessionStore().containsSession(axolotlAddress);
|
return ApplicationDependencies.getProtocolStore().aci().containsSession(axolotlAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void archiveSiblingSessions(SignalProtocolAddress address) {
|
public static void archiveSiblingSessions(SignalProtocolAddress address) {
|
||||||
ApplicationDependencies.getSessionStore().archiveSiblingSessions(address);
|
ApplicationDependencies.getProtocolStore().aci().sessions().archiveSiblingSessions(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void archiveAllSessions() {
|
public static void archiveAllSessions() {
|
||||||
ApplicationDependencies.getSessionStore().archiveAllSessions();
|
ApplicationDependencies.getProtocolStore().aci().sessions().archiveAllSessions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void archiveSession(RecipientId recipientId, int deviceId) {
|
public static void archiveSession(RecipientId recipientId, int deviceId) {
|
||||||
ApplicationDependencies.getSessionStore().archiveSession(recipientId, deviceId);
|
ApplicationDependencies.getProtocolStore().aci().sessions().archiveSession(recipientId, deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean ratchetKeyMatches(@NonNull Recipient recipient, int deviceId, @NonNull ECPublicKey ratchetKey) {
|
public static boolean ratchetKeyMatches(@NonNull Recipient recipient, int deviceId, @NonNull ECPublicKey ratchetKey) {
|
||||||
SignalProtocolAddress address = new SignalProtocolAddress(recipient.resolve().requireServiceId(), deviceId);
|
SignalProtocolAddress address = new SignalProtocolAddress(recipient.resolve().requireServiceId(), deviceId);
|
||||||
SessionRecord session = ApplicationDependencies.getSessionStore().loadSession(address);
|
SessionRecord session = ApplicationDependencies.getProtocolStore().aci().loadSession(address);
|
||||||
|
|
||||||
return session.currentRatchetKeyMatches(ratchetKey);
|
return session.currentRatchetKeyMatches(ratchetKey);
|
||||||
}
|
}
|
||||||
|
|||||||
+39
-30
@@ -2,9 +2,9 @@ package org.thoughtcrime.securesms.crypto.storage;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.whispersystems.libsignal.IdentityKey;
|
import org.whispersystems.libsignal.IdentityKey;
|
||||||
import org.whispersystems.libsignal.IdentityKeyPair;
|
import org.whispersystems.libsignal.IdentityKeyPair;
|
||||||
@@ -12,14 +12,10 @@ import org.whispersystems.libsignal.InvalidKeyIdException;
|
|||||||
import org.whispersystems.libsignal.NoSessionException;
|
import org.whispersystems.libsignal.NoSessionException;
|
||||||
import org.whispersystems.libsignal.SignalProtocolAddress;
|
import org.whispersystems.libsignal.SignalProtocolAddress;
|
||||||
import org.whispersystems.libsignal.groups.state.SenderKeyRecord;
|
import org.whispersystems.libsignal.groups.state.SenderKeyRecord;
|
||||||
import org.whispersystems.libsignal.state.IdentityKeyStore;
|
|
||||||
import org.whispersystems.libsignal.state.PreKeyRecord;
|
import org.whispersystems.libsignal.state.PreKeyRecord;
|
||||||
import org.whispersystems.libsignal.state.PreKeyStore;
|
|
||||||
import org.whispersystems.libsignal.state.SessionRecord;
|
import org.whispersystems.libsignal.state.SessionRecord;
|
||||||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||||
import org.whispersystems.libsignal.state.SignedPreKeyStore;
|
import org.whispersystems.signalservice.api.SignalServiceAccountDataStore;
|
||||||
import org.whispersystems.signalservice.api.SignalServiceDataStore;
|
|
||||||
import org.whispersystems.signalservice.api.SignalServiceSessionStore;
|
|
||||||
import org.whispersystems.signalservice.api.push.DistributionId;
|
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -27,22 +23,32 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class SignalProtocolStoreImpl implements SignalServiceDataStore {
|
public class SignalServiceAccountDataStoreImpl implements SignalServiceAccountDataStore {
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final PreKeyStore preKeyStore;
|
private final TextSecurePreKeyStore preKeyStore;
|
||||||
private final SignedPreKeyStore signedPreKeyStore;
|
private final TextSecurePreKeyStore signedPreKeyStore;
|
||||||
private final IdentityKeyStore identityKeyStore;
|
private final TextSecureIdentityKeyStore identityKeyStore;
|
||||||
private final SignalServiceSessionStore sessionStore;
|
private final TextSecureSessionStore sessionStore;
|
||||||
private final SignalSenderKeyStore senderKeyStore;
|
private final SignalSenderKeyStore senderKeyStore;
|
||||||
|
|
||||||
public SignalProtocolStoreImpl(Context context) {
|
public SignalServiceAccountDataStoreImpl(@NonNull Context context,
|
||||||
|
@NonNull TextSecurePreKeyStore preKeyStore,
|
||||||
|
@NonNull TextSecureIdentityKeyStore identityKeyStore,
|
||||||
|
@NonNull TextSecureSessionStore sessionStore,
|
||||||
|
@NonNull SignalSenderKeyStore senderKeyStore)
|
||||||
|
{
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.preKeyStore = ApplicationDependencies.getPreKeyStore();
|
this.preKeyStore = preKeyStore;
|
||||||
this.signedPreKeyStore = ApplicationDependencies.getPreKeyStore();
|
this.signedPreKeyStore = preKeyStore;
|
||||||
this.identityKeyStore = ApplicationDependencies.getIdentityStore();
|
this.identityKeyStore = identityKeyStore;
|
||||||
this.sessionStore = ApplicationDependencies.getSessionStore();
|
this.sessionStore = sessionStore;
|
||||||
this.senderKeyStore = ApplicationDependencies.getSenderKeyStore();
|
this.senderKeyStore = senderKeyStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMultiDevice() {
|
||||||
|
return TextSecurePreferences.isMultiDevice(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -185,17 +191,20 @@ public class SignalProtocolStoreImpl implements SignalServiceDataStore {
|
|||||||
senderKeyStore.clearSenderKeySharedWith(addresses);
|
senderKeyStore.clearSenderKeySharedWith(addresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public @NonNull TextSecureIdentityKeyStore identities() {
|
||||||
public boolean isMultiDevice() {
|
return identityKeyStore;
|
||||||
return TextSecurePreferences.isMultiDevice(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public @NonNull TextSecurePreKeyStore preKeys() {
|
||||||
public Transaction beginTransaction() {
|
return preKeyStore;
|
||||||
SignalDatabase.getRawDatabase().beginTransaction();
|
|
||||||
return () -> {
|
|
||||||
SignalDatabase.getRawDatabase().setTransactionSuccessful();
|
|
||||||
SignalDatabase.getRawDatabase().endTransaction();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @NonNull TextSecureSessionStore sessions() {
|
||||||
|
return sessionStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @NonNull SignalSenderKeyStore senderKeys() {
|
||||||
|
return senderKeyStore;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+52
@@ -0,0 +1,52 @@
|
|||||||
|
package org.thoughtcrime.securesms.crypto.storage;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||||
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
|
import org.whispersystems.signalservice.api.SignalServiceDataStore;
|
||||||
|
import org.whispersystems.signalservice.api.push.AccountIdentifier;
|
||||||
|
|
||||||
|
public final class SignalServiceDataStoreImpl implements SignalServiceDataStore {
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
|
private final SignalServiceAccountDataStoreImpl aciStore;
|
||||||
|
private final SignalServiceAccountDataStoreImpl pniStore;
|
||||||
|
|
||||||
|
public SignalServiceDataStoreImpl(@NonNull Context context,
|
||||||
|
@NonNull SignalServiceAccountDataStoreImpl aciStore,
|
||||||
|
@NonNull SignalServiceAccountDataStoreImpl pniStore)
|
||||||
|
{
|
||||||
|
this.context = context;
|
||||||
|
this.aciStore = aciStore;
|
||||||
|
this.pniStore = pniStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SignalServiceAccountDataStoreImpl get(@NonNull AccountIdentifier accountIdentifier) {
|
||||||
|
if (accountIdentifier.equals(SignalStore.account().getAci())) {
|
||||||
|
return aciStore;
|
||||||
|
} else if (accountIdentifier.equals(SignalStore.account().getPni())) {
|
||||||
|
return pniStore;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("No matching store found for " + accountIdentifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SignalServiceAccountDataStoreImpl aci() {
|
||||||
|
return aciStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SignalServiceAccountDataStoreImpl pni() {
|
||||||
|
return pniStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isMultiDevice() {
|
||||||
|
return TextSecurePreferences.isMultiDevice(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -186,7 +186,7 @@ public class IdentityDatabase extends Database {
|
|||||||
EventBus.getDefault().post(record.get());
|
EventBus.getDefault().post(record.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationDependencies.getIdentityStore().invalidate(addressName);
|
ApplicationDependencies.getProtocolStore().aci().identities().invalidate(addressName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hadEntry && !keyMatches) {
|
if (hadEntry && !keyMatches) {
|
||||||
|
|||||||
@@ -789,7 +789,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||||||
|
|
||||||
fun applyStorageSyncContactUpdate(update: StorageRecordUpdate<SignalContactRecord>) {
|
fun applyStorageSyncContactUpdate(update: StorageRecordUpdate<SignalContactRecord>) {
|
||||||
val db = writableDatabase
|
val db = writableDatabase
|
||||||
val identityStore = ApplicationDependencies.getIdentityStore()
|
val identityStore = ApplicationDependencies.getProtocolStore().aci().identities()
|
||||||
val values = getValuesForStorageContact(update.new, false)
|
val values = getValuesForStorageContact(update.new, false)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -2525,7 +2525,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
|
|||||||
val e164Record = getRecord(byE164)
|
val e164Record = getRecord(byE164)
|
||||||
|
|
||||||
// Identities
|
// Identities
|
||||||
ApplicationDependencies.getIdentityStore().delete(e164Record.e164!!)
|
ApplicationDependencies.getProtocolStore().aci().identities().delete(e164Record.e164!!)
|
||||||
|
|
||||||
// Group Receipts
|
// Group Receipts
|
||||||
val groupReceiptValues = ContentValues()
|
val groupReceiptValues = ContentValues()
|
||||||
|
|||||||
+8
-49
@@ -11,10 +11,7 @@ import org.signal.zkgroup.receipts.ClientZkReceiptOperations;
|
|||||||
import org.thoughtcrime.securesms.KbsEnclave;
|
import org.thoughtcrime.securesms.KbsEnclave;
|
||||||
import org.thoughtcrime.securesms.components.TypingStatusRepository;
|
import org.thoughtcrime.securesms.components.TypingStatusRepository;
|
||||||
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.SignalSenderKeyStore;
|
import org.thoughtcrime.securesms.crypto.storage.SignalServiceDataStoreImpl;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore;
|
|
||||||
import org.thoughtcrime.securesms.crypto.storage.TextSecurePreKeyStore;
|
|
||||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
|
||||||
import org.thoughtcrime.securesms.database.DatabaseObserver;
|
import org.thoughtcrime.securesms.database.DatabaseObserver;
|
||||||
import org.thoughtcrime.securesms.database.PendingRetryReceiptCache;
|
import org.thoughtcrime.securesms.database.PendingRetryReceiptCache;
|
||||||
import org.thoughtcrime.securesms.groups.GroupsV2Authorization;
|
import org.thoughtcrime.securesms.groups.GroupsV2Authorization;
|
||||||
@@ -101,10 +98,7 @@ public class ApplicationDependencies {
|
|||||||
private static volatile PendingRetryReceiptCache pendingRetryReceiptCache;
|
private static volatile PendingRetryReceiptCache pendingRetryReceiptCache;
|
||||||
private static volatile SignalWebSocket signalWebSocket;
|
private static volatile SignalWebSocket signalWebSocket;
|
||||||
private static volatile MessageNotifier messageNotifier;
|
private static volatile MessageNotifier messageNotifier;
|
||||||
private static volatile TextSecureIdentityKeyStore identityStore;
|
private static volatile SignalServiceDataStoreImpl protocolStore;
|
||||||
private static volatile TextSecureSessionStore sessionStore;
|
|
||||||
private static volatile TextSecurePreKeyStore preKeyStore;
|
|
||||||
private static volatile SignalSenderKeyStore senderKeyStore;
|
|
||||||
private static volatile GiphyMp4Cache giphyMp4Cache;
|
private static volatile GiphyMp4Cache giphyMp4Cache;
|
||||||
private static volatile SimpleExoPlayerPool exoPlayerPool;
|
private static volatile SimpleExoPlayerPool exoPlayerPool;
|
||||||
private static volatile AudioManagerCompat audioManagerCompat;
|
private static volatile AudioManagerCompat audioManagerCompat;
|
||||||
@@ -525,48 +519,16 @@ public class ApplicationDependencies {
|
|||||||
return signalWebSocket;
|
return signalWebSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NonNull TextSecureIdentityKeyStore getIdentityStore() {
|
public static @NonNull SignalServiceDataStoreImpl getProtocolStore() {
|
||||||
if (identityStore == null) {
|
if (protocolStore == null) {
|
||||||
synchronized (LOCK) {
|
synchronized (LOCK) {
|
||||||
if (identityStore == null) {
|
if (protocolStore == null) {
|
||||||
identityStore = provider.provideIdentityStore();
|
protocolStore = provider.provideProtocolStore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return identityStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @NonNull TextSecureSessionStore getSessionStore() {
|
return protocolStore;
|
||||||
if (sessionStore == null) {
|
|
||||||
synchronized (LOCK) {
|
|
||||||
if (sessionStore == null) {
|
|
||||||
sessionStore = provider.provideSessionStore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sessionStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @NonNull TextSecurePreKeyStore getPreKeyStore() {
|
|
||||||
if (preKeyStore == null) {
|
|
||||||
synchronized (LOCK) {
|
|
||||||
if (preKeyStore == null) {
|
|
||||||
preKeyStore = provider.providePreKeyStore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return preKeyStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static @NonNull SignalSenderKeyStore getSenderKeyStore() {
|
|
||||||
if (senderKeyStore == null) {
|
|
||||||
synchronized (LOCK) {
|
|
||||||
if (senderKeyStore == null) {
|
|
||||||
senderKeyStore = provider.provideSenderKeyStore();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return senderKeyStore;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static @NonNull GiphyMp4Cache getGiphyMp4Cache() {
|
public static @NonNull GiphyMp4Cache getGiphyMp4Cache() {
|
||||||
@@ -663,10 +625,7 @@ public class ApplicationDependencies {
|
|||||||
@NonNull PendingRetryReceiptManager providePendingRetryReceiptManager();
|
@NonNull PendingRetryReceiptManager providePendingRetryReceiptManager();
|
||||||
@NonNull PendingRetryReceiptCache providePendingRetryReceiptCache();
|
@NonNull PendingRetryReceiptCache providePendingRetryReceiptCache();
|
||||||
@NonNull SignalWebSocket provideSignalWebSocket();
|
@NonNull SignalWebSocket provideSignalWebSocket();
|
||||||
@NonNull TextSecureIdentityKeyStore provideIdentityStore();
|
@NonNull SignalServiceDataStoreImpl provideProtocolStore();
|
||||||
@NonNull TextSecureSessionStore provideSessionStore();
|
|
||||||
@NonNull TextSecurePreKeyStore providePreKeyStore();
|
|
||||||
@NonNull SignalSenderKeyStore provideSenderKeyStore();
|
|
||||||
@NonNull GiphyMp4Cache provideGiphyMp4Cache();
|
@NonNull GiphyMp4Cache provideGiphyMp4Cache();
|
||||||
@NonNull SimpleExoPlayerPool provideExoPlayerPool();
|
@NonNull SimpleExoPlayerPool provideExoPlayerPool();
|
||||||
@NonNull AudioManagerCompat provideAndroidCallAudioManager();
|
@NonNull AudioManagerCompat provideAndroidCallAudioManager();
|
||||||
|
|||||||
+10
-20
@@ -1,7 +1,6 @@
|
|||||||
package org.thoughtcrime.securesms.dependencies;
|
package org.thoughtcrime.securesms.dependencies;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
|
|
||||||
@@ -14,7 +13,8 @@ import org.thoughtcrime.securesms.BuildConfig;
|
|||||||
import org.thoughtcrime.securesms.components.TypingStatusRepository;
|
import org.thoughtcrime.securesms.components.TypingStatusRepository;
|
||||||
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
||||||
import org.thoughtcrime.securesms.crypto.ReentrantSessionLock;
|
import org.thoughtcrime.securesms.crypto.ReentrantSessionLock;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
|
import org.thoughtcrime.securesms.crypto.storage.SignalServiceDataStoreImpl;
|
||||||
|
import org.thoughtcrime.securesms.crypto.storage.SignalServiceAccountDataStoreImpl;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.SignalSenderKeyStore;
|
import org.thoughtcrime.securesms.crypto.storage.SignalSenderKeyStore;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore;
|
import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.TextSecurePreKeyStore;
|
import org.thoughtcrime.securesms.crypto.storage.TextSecurePreKeyStore;
|
||||||
@@ -116,7 +116,7 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||||||
public @NonNull SignalServiceMessageSender provideSignalServiceMessageSender(@NonNull SignalWebSocket signalWebSocket) {
|
public @NonNull SignalServiceMessageSender provideSignalServiceMessageSender(@NonNull SignalWebSocket signalWebSocket) {
|
||||||
return new SignalServiceMessageSender(provideSignalServiceNetworkAccess().getConfiguration(),
|
return new SignalServiceMessageSender(provideSignalServiceNetworkAccess().getConfiguration(),
|
||||||
new DynamicCredentialsProvider(),
|
new DynamicCredentialsProvider(),
|
||||||
new SignalProtocolStoreImpl(context),
|
provideProtocolStore(),
|
||||||
ReentrantSessionLock.INSTANCE,
|
ReentrantSessionLock.INSTANCE,
|
||||||
BuildConfig.SIGNAL_AGENT,
|
BuildConfig.SIGNAL_AGENT,
|
||||||
signalWebSocket,
|
signalWebSocket,
|
||||||
@@ -274,23 +274,13 @@ public class ApplicationDependencyProvider implements ApplicationDependencies.Pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull TextSecureIdentityKeyStore provideIdentityStore() {
|
public @NonNull SignalServiceDataStoreImpl provideProtocolStore() {
|
||||||
return new TextSecureIdentityKeyStore(context);
|
SignalServiceAccountDataStoreImpl aci = new SignalServiceAccountDataStoreImpl(context,
|
||||||
}
|
new TextSecurePreKeyStore(context),
|
||||||
|
new TextSecureIdentityKeyStore(context),
|
||||||
@Override
|
new TextSecureSessionStore(context),
|
||||||
public @NonNull TextSecureSessionStore provideSessionStore() {
|
new SignalSenderKeyStore(context));
|
||||||
return new TextSecureSessionStore(context);
|
return new SignalServiceDataStoreImpl(context, aci, aci);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NonNull TextSecurePreKeyStore providePreKeyStore() {
|
|
||||||
return new TextSecurePreKeyStore(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NonNull SignalSenderKeyStore provideSenderKeyStore() {
|
|
||||||
return new SignalSenderKeyStore(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import androidx.annotation.NonNull;
|
|||||||
|
|
||||||
import org.signal.core.util.logging.Log;
|
import org.signal.core.util.logging.Log;
|
||||||
import org.thoughtcrime.securesms.crypto.PreKeyUtil;
|
import org.thoughtcrime.securesms.crypto.PreKeyUtil;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.jobmanager.Data;
|
import org.thoughtcrime.securesms.jobmanager.Data;
|
||||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||||
import org.whispersystems.libsignal.InvalidKeyIdException;
|
import org.whispersystems.libsignal.InvalidKeyIdException;
|
||||||
@@ -55,7 +55,7 @@ public class CleanPreKeysJob extends BaseJob {
|
|||||||
Log.i(TAG, "Cleaning prekeys...");
|
Log.i(TAG, "Cleaning prekeys...");
|
||||||
|
|
||||||
int activeSignedPreKeyId = PreKeyUtil.getActiveSignedPreKeyId(context);
|
int activeSignedPreKeyId = PreKeyUtil.getActiveSignedPreKeyId(context);
|
||||||
SignedPreKeyStore signedPreKeyStore = new SignalProtocolStoreImpl(context);
|
SignedPreKeyStore signedPreKeyStore = ApplicationDependencies.getProtocolStore().aci();
|
||||||
|
|
||||||
if (activeSignedPreKeyId < 0) return;
|
if (activeSignedPreKeyId < 0) return;
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ class MultiDeviceContactSyncJob(parameters: Parameters, private val attachmentPo
|
|||||||
else -> VerifiedStatus.DEFAULT
|
else -> VerifiedStatus.DEFAULT
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationDependencies.getIdentityStore().saveIdentityWithoutSideEffects(
|
ApplicationDependencies.getProtocolStore().aci().identities().saveIdentityWithoutSideEffects(
|
||||||
recipient.id,
|
recipient.id,
|
||||||
contact.verified.get().identityKey,
|
contact.verified.get().identityKey,
|
||||||
verifiedStatus,
|
verifiedStatus,
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<IdentityRecord> identityRecord = ApplicationDependencies.getIdentityStore().getIdentityRecord(recipient.getId());
|
Optional<IdentityRecord> identityRecord = ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecord(recipient.getId());
|
||||||
Optional<VerifiedMessage> verifiedMessage = getVerifiedMessage(recipient, identityRecord);
|
Optional<VerifiedMessage> verifiedMessage = getVerifiedMessage(recipient, identityRecord);
|
||||||
Map<RecipientId, Integer> inboxPositions = SignalDatabase.threads().getInboxPositions();
|
Map<RecipientId, Integer> inboxPositions = SignalDatabase.threads().getInboxPositions();
|
||||||
Set<RecipientId> archived = SignalDatabase.threads().getArchivedRecipients();
|
Set<RecipientId> archived = SignalDatabase.threads().getArchivedRecipients();
|
||||||
@@ -208,7 +208,7 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
|
|||||||
Set<RecipientId> archived = SignalDatabase.threads().getArchivedRecipients();
|
Set<RecipientId> archived = SignalDatabase.threads().getArchivedRecipients();
|
||||||
|
|
||||||
for (Recipient recipient : recipients) {
|
for (Recipient recipient : recipients) {
|
||||||
Optional<IdentityRecord> identity = ApplicationDependencies.getIdentityStore().getIdentityRecord(recipient.getId());
|
Optional<IdentityRecord> identity = ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecord(recipient.getId());
|
||||||
Optional<VerifiedMessage> verified = getVerifiedMessage(recipient, identity);
|
Optional<VerifiedMessage> verified = getVerifiedMessage(recipient, identity);
|
||||||
Optional<String> name = Optional.fromNullable(recipient.isSystemContact() ? recipient.getDisplayName(context) : recipient.getGroupName(context));
|
Optional<String> name = Optional.fromNullable(recipient.isSystemContact() ? recipient.getDisplayName(context) : recipient.getGroupName(context));
|
||||||
Optional<ProfileKey> profileKey = ProfileKeyUtil.profileKeyOptional(recipient.getProfileKey());
|
Optional<ProfileKey> profileKey = ProfileKeyUtil.profileKeyOptional(recipient.getProfileKey());
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ public class ResendMessageJob extends BaseJob {
|
|||||||
.map(device -> new SignalProtocolAddress(recipient.requireServiceId(), device))
|
.map(device -> new SignalProtocolAddress(recipient.requireServiceId(), device))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
ApplicationDependencies.getSenderKeyStore().markSenderKeySharedWith(distributionId, addresses);
|
ApplicationDependencies.getProtocolStore().aci().markSenderKeySharedWith(distributionId, addresses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ public class RetrieveProfileJob extends BaseJob {
|
|||||||
|
|
||||||
IdentityKey identityKey = new IdentityKey(Base64.decode(identityKeyValue), 0);
|
IdentityKey identityKey = new IdentityKey(Base64.decode(identityKeyValue), 0);
|
||||||
|
|
||||||
if (!ApplicationDependencies.getIdentityStore().getIdentityRecord(recipient.getId()).isPresent()) {
|
if (!ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecord(recipient.getId()).isPresent()) {
|
||||||
Log.w(TAG, "Still first use...");
|
Log.w(TAG, "Still first use...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ public final class SenderKeyDistributionSendJob extends BaseJob {
|
|||||||
.map(device -> new SignalProtocolAddress(recipient.requireServiceId(), device))
|
.map(device -> new SignalProtocolAddress(recipient.requireServiceId(), device))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
ApplicationDependencies.getSenderKeyStore().markSenderKeySharedWith(distributionId, addresses);
|
ApplicationDependencies.getProtocolStore().aci().markSenderKeySharedWith(distributionId, addresses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -561,7 +561,7 @@ public final class MessageContentProcessor {
|
|||||||
database.markAsMissedCall(smsMessageId.get(), message.getType() == OfferMessage.Type.VIDEO_CALL);
|
database.markAsMissedCall(smsMessageId.get(), message.getType() == OfferMessage.Type.VIDEO_CALL);
|
||||||
} else {
|
} else {
|
||||||
RemotePeer remotePeer = new RemotePeer(senderRecipient.getId(), new CallId(message.getId()));
|
RemotePeer remotePeer = new RemotePeer(senderRecipient.getId(), new CallId(message.getId()));
|
||||||
byte[] remoteIdentityKey = ApplicationDependencies.getIdentityStore().getIdentityRecord(senderRecipient.getId()).transform(record -> record.getIdentityKey().serialize()).orNull();
|
byte[] remoteIdentityKey = ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecord(senderRecipient.getId()).transform(record -> record.getIdentityKey().serialize()).orNull();
|
||||||
|
|
||||||
ApplicationDependencies.getSignalCallManager()
|
ApplicationDependencies.getSignalCallManager()
|
||||||
.receivedOffer(new WebRtcData.CallMetadata(remotePeer, content.getSenderDevice()),
|
.receivedOffer(new WebRtcData.CallMetadata(remotePeer, content.getSenderDevice()),
|
||||||
@@ -579,7 +579,7 @@ public final class MessageContentProcessor {
|
|||||||
{
|
{
|
||||||
log(String.valueOf(content), "handleCallAnswerMessage...");
|
log(String.valueOf(content), "handleCallAnswerMessage...");
|
||||||
RemotePeer remotePeer = new RemotePeer(senderRecipient.getId(), new CallId(message.getId()));
|
RemotePeer remotePeer = new RemotePeer(senderRecipient.getId(), new CallId(message.getId()));
|
||||||
byte[] remoteIdentityKey = ApplicationDependencies.getIdentityStore().getIdentityRecord(senderRecipient.getId()).transform(record -> record.getIdentityKey().serialize()).orNull();
|
byte[] remoteIdentityKey = ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecord(senderRecipient.getId()).transform(record -> record.getIdentityKey().serialize()).orNull();
|
||||||
|
|
||||||
ApplicationDependencies.getSignalCallManager()
|
ApplicationDependencies.getSignalCallManager()
|
||||||
.receivedAnswer(new WebRtcData.CallMetadata(remotePeer, content.getSenderDevice()),
|
.receivedAnswer(new WebRtcData.CallMetadata(remotePeer, content.getSenderDevice()),
|
||||||
@@ -707,7 +707,7 @@ public final class MessageContentProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (insertResult.isPresent()) {
|
if (insertResult.isPresent()) {
|
||||||
ApplicationDependencies.getSessionStore().deleteAllSessions(content.getSender().getIdentifier());
|
ApplicationDependencies.getProtocolStore().aci().deleteAllSessions(content.getSender().getIdentifier());
|
||||||
|
|
||||||
SecurityEvent.broadcastSecurityUpdateEvent(context);
|
SecurityEvent.broadcastSecurityUpdateEvent(context);
|
||||||
ApplicationDependencies.getMessageNotifier().updateNotification(context, insertResult.get().getThreadId());
|
ApplicationDependencies.getMessageNotifier().updateNotification(context, insertResult.get().getThreadId());
|
||||||
@@ -731,7 +731,7 @@ public final class MessageContentProcessor {
|
|||||||
long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient);
|
long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient);
|
||||||
|
|
||||||
if (!recipient.isGroup()) {
|
if (!recipient.isGroup()) {
|
||||||
ApplicationDependencies.getSessionStore().deleteAllSessions(recipient.requireServiceId());
|
ApplicationDependencies.getProtocolStore().aci().deleteAllSessions(recipient.requireServiceId());
|
||||||
|
|
||||||
SecurityEvent.broadcastSecurityUpdateEvent(context);
|
SecurityEvent.broadcastSecurityUpdateEvent(context);
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.signal.libsignal.metadata.SelfSendException;
|
|||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.crypto.ReentrantSessionLock;
|
import org.thoughtcrime.securesms.crypto.ReentrantSessionLock;
|
||||||
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl;
|
|
||||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
|
||||||
import org.thoughtcrime.securesms.groups.BadGroupIdException;
|
import org.thoughtcrime.securesms.groups.BadGroupIdException;
|
||||||
@@ -77,7 +76,7 @@ public final class MessageDecryptionUtil {
|
|||||||
* caller.
|
* caller.
|
||||||
*/
|
*/
|
||||||
public static @NonNull DecryptionResult decrypt(@NonNull Context context, @NonNull SignalServiceEnvelope envelope) {
|
public static @NonNull DecryptionResult decrypt(@NonNull Context context, @NonNull SignalServiceEnvelope envelope) {
|
||||||
SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context);
|
SignalProtocolStore axolotlStore = ApplicationDependencies.getProtocolStore().aci();
|
||||||
SignalServiceAddress localAddress = new SignalServiceAddress(Recipient.self().requireAci(), Recipient.self().requireE164());
|
SignalServiceAddress localAddress = new SignalServiceAddress(Recipient.self().requireAci(), Recipient.self().requireE164());
|
||||||
SignalServiceCipher cipher = new SignalServiceCipher(localAddress, SignalStore.account().getDeviceId(), axolotlStore, ReentrantSessionLock.INSTANCE, UnidentifiedAccessUtil.getCertificateValidator());
|
SignalServiceCipher cipher = new SignalServiceCipher(localAddress, SignalStore.account().getDeviceId(), axolotlStore, ReentrantSessionLock.INSTANCE, UnidentifiedAccessUtil.getCertificateValidator());
|
||||||
List<Job> jobs = new LinkedList<>();
|
List<Job> jobs = new LinkedList<>();
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@ final class RecipientDialogRepository {
|
|||||||
|
|
||||||
void getIdentity(@NonNull Consumer<IdentityRecord> callback) {
|
void getIdentity(@NonNull Consumer<IdentityRecord> callback) {
|
||||||
SignalExecutors.BOUNDED.execute(
|
SignalExecutors.BOUNDED.execute(
|
||||||
() -> callback.accept(ApplicationDependencies.getIdentityStore().getIdentityRecord(recipientId).orNull()));
|
() -> callback.accept(ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecord(recipientId).orNull()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void getRecipient(@NonNull RecipientCallback recipientCallback) {
|
void getRecipient(@NonNull RecipientCallback recipientCallback) {
|
||||||
|
|||||||
+1
-1
@@ -161,7 +161,7 @@ public final class RegistrationRepository {
|
|||||||
SignalStore.account().setFcmToken(registrationData.getFcmToken());
|
SignalStore.account().setFcmToken(registrationData.getFcmToken());
|
||||||
SignalStore.account().setFcmEnabled(registrationData.isFcm());
|
SignalStore.account().setFcmEnabled(registrationData.isFcm());
|
||||||
|
|
||||||
ApplicationDependencies.getIdentityStore()
|
ApplicationDependencies.getProtocolStore().aci().identities()
|
||||||
.saveIdentityWithoutSideEffects(selfId,
|
.saveIdentityWithoutSideEffects(selfId,
|
||||||
identityKey.getPublicKey(),
|
identityKey.getPublicKey(),
|
||||||
IdentityDatabase.VerifiedStatus.VERIFIED,
|
IdentityDatabase.VerifiedStatus.VERIFIED,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public final class IdentityUtil {
|
|||||||
final RecipientId recipientId = recipient.getId();
|
final RecipientId recipientId = recipient.getId();
|
||||||
|
|
||||||
SimpleTask.run(SignalExecutors.BOUNDED,
|
SimpleTask.run(SignalExecutors.BOUNDED,
|
||||||
() -> ApplicationDependencies.getIdentityStore().getIdentityRecord(recipientId),
|
() -> ApplicationDependencies.getProtocolStore().aci().identities().getIdentityRecord(recipientId),
|
||||||
future::set);
|
future::set);
|
||||||
|
|
||||||
return future;
|
return future;
|
||||||
@@ -144,10 +144,10 @@ public final class IdentityUtil {
|
|||||||
|
|
||||||
public static void saveIdentity(String user, IdentityKey identityKey) {
|
public static void saveIdentity(String user, IdentityKey identityKey) {
|
||||||
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||||
SessionStore sessionStore = ApplicationDependencies.getSessionStore();
|
SessionStore sessionStore = ApplicationDependencies.getProtocolStore().aci();
|
||||||
SignalProtocolAddress address = new SignalProtocolAddress(user, SignalServiceAddress.DEFAULT_DEVICE_ID);
|
SignalProtocolAddress address = new SignalProtocolAddress(user, SignalServiceAddress.DEFAULT_DEVICE_ID);
|
||||||
|
|
||||||
if (ApplicationDependencies.getIdentityStore().saveIdentity(address, identityKey)) {
|
if (ApplicationDependencies.getProtocolStore().aci().identities().saveIdentity(address, identityKey)) {
|
||||||
if (sessionStore.containsSession(address)) {
|
if (sessionStore.containsSession(address)) {
|
||||||
SessionRecord sessionRecord = sessionStore.loadSession(address);
|
SessionRecord sessionRecord = sessionStore.loadSession(address);
|
||||||
sessionRecord.archiveCurrentState();
|
sessionRecord.archiveCurrentState();
|
||||||
@@ -160,7 +160,7 @@ public final class IdentityUtil {
|
|||||||
|
|
||||||
public static void processVerifiedMessage(Context context, VerifiedMessage verifiedMessage) {
|
public static void processVerifiedMessage(Context context, VerifiedMessage verifiedMessage) {
|
||||||
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
try(SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||||
TextSecureIdentityKeyStore identityStore = ApplicationDependencies.getIdentityStore();
|
TextSecureIdentityKeyStore identityStore = ApplicationDependencies.getProtocolStore().aci().identities();
|
||||||
Recipient recipient = Recipient.externalPush(context, verifiedMessage.getDestination());
|
Recipient recipient = Recipient.externalPush(context, verifiedMessage.getDestination());
|
||||||
Optional<IdentityRecord> identityRecord = identityStore.getIdentityRecord(recipient.getId());
|
Optional<IdentityRecord> identityRecord = identityStore.getIdentityRecord(recipient.getId());
|
||||||
|
|
||||||
|
|||||||
@@ -541,7 +541,7 @@ public class VerifyDisplayFragment extends Fragment implements ViewTreeObserver.
|
|||||||
try (SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
try (SignalSessionLock.Lock unused = ReentrantSessionLock.INSTANCE.acquire()) {
|
||||||
if (verified) {
|
if (verified) {
|
||||||
Log.i(TAG, "Saving identity: " + recipientId);
|
Log.i(TAG, "Saving identity: " + recipientId);
|
||||||
ApplicationDependencies.getIdentityStore()
|
ApplicationDependencies.getProtocolStore().aci().identities()
|
||||||
.saveIdentityWithoutSideEffects(recipientId,
|
.saveIdentityWithoutSideEffects(recipientId,
|
||||||
remoteIdentity,
|
remoteIdentity,
|
||||||
IdentityDatabase.VerifiedStatus.VERIFIED,
|
IdentityDatabase.VerifiedStatus.VERIFIED,
|
||||||
@@ -549,7 +549,7 @@ public class VerifyDisplayFragment extends Fragment implements ViewTreeObserver.
|
|||||||
System.currentTimeMillis(),
|
System.currentTimeMillis(),
|
||||||
true);
|
true);
|
||||||
} else {
|
} else {
|
||||||
ApplicationDependencies.getIdentityStore().setVerified(recipientId, remoteIdentity, IdentityDatabase.VerifiedStatus.DEFAULT);
|
ApplicationDependencies.getProtocolStore().aci().identities().setVerified(recipientId, remoteIdentity, IdentityDatabase.VerifiedStatus.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationDependencies.getJobManager()
|
ApplicationDependencies.getJobManager()
|
||||||
|
|||||||
+2
-16
@@ -7,6 +7,7 @@ import org.signal.zkgroup.receipts.ClientZkReceiptOperations;
|
|||||||
import org.thoughtcrime.securesms.components.TypingStatusRepository;
|
import org.thoughtcrime.securesms.components.TypingStatusRepository;
|
||||||
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
import org.thoughtcrime.securesms.components.TypingStatusSender;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.SignalSenderKeyStore;
|
import org.thoughtcrime.securesms.crypto.storage.SignalSenderKeyStore;
|
||||||
|
import org.thoughtcrime.securesms.crypto.storage.SignalServiceDataStoreImpl;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore;
|
import org.thoughtcrime.securesms.crypto.storage.TextSecureIdentityKeyStore;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.TextSecurePreKeyStore;
|
import org.thoughtcrime.securesms.crypto.storage.TextSecurePreKeyStore;
|
||||||
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore;
|
||||||
@@ -179,22 +180,7 @@ public class MockApplicationDependencyProvider implements ApplicationDependencie
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NonNull TextSecureIdentityKeyStore provideIdentityStore() {
|
public @NonNull SignalServiceDataStoreImpl provideProtocolStore() {
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NonNull TextSecureSessionStore provideSessionStore() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NonNull TextSecurePreKeyStore providePreKeyStore() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NonNull SignalSenderKeyStore provideSenderKeyStore() {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
package org.whispersystems.signalservice.api;
|
||||||
|
|
||||||
|
import org.whispersystems.libsignal.state.SignalProtocolStore;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* And extension of the normal protocol store interface that has additional methods that are needed
|
||||||
|
* in the service layer, but not the protocol layer.
|
||||||
|
*/
|
||||||
|
public interface SignalServiceAccountDataStore extends SignalProtocolStore, SignalServiceSessionStore, SignalServiceSenderKeyStore {
|
||||||
|
/**
|
||||||
|
* @return True if the user has linked devices, otherwise false.
|
||||||
|
*/
|
||||||
|
boolean isMultiDevice();
|
||||||
|
}
|
||||||
+19
-14
@@ -1,25 +1,30 @@
|
|||||||
package org.whispersystems.signalservice.api;
|
package org.whispersystems.signalservice.api;
|
||||||
|
|
||||||
import org.whispersystems.libsignal.state.SignalProtocolStore;
|
import org.whispersystems.signalservice.api.push.AccountIdentifier;
|
||||||
|
|
||||||
import java.io.Closeable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* And extension of the normal protocol store interface that has additional methods that are needed
|
* And extension of the normal protocol store interface that has additional methods that are needed
|
||||||
* in the service layer, but not the protocol layer.
|
* in the service layer, but not the protocol layer.
|
||||||
*/
|
*/
|
||||||
public interface SignalServiceDataStore extends SignalProtocolStore, SignalServiceSessionStore, SignalServiceSenderKeyStore {
|
public interface SignalServiceDataStore {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return True if the active account has or is a linked device, otherwise false.
|
* @return A {@link SignalServiceAccountDataStore} for the specified account.
|
||||||
|
*/
|
||||||
|
SignalServiceAccountDataStore get(AccountIdentifier accountIdentifier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A {@link SignalServiceAccountDataStore} for the ACI account.
|
||||||
|
*/
|
||||||
|
SignalServiceAccountDataStore aci();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A {@link SignalServiceAccountDataStore} for the PNI account.
|
||||||
|
*/
|
||||||
|
SignalServiceAccountDataStore pni();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if the user has linked devices, otherwise false.
|
||||||
*/
|
*/
|
||||||
boolean isMultiDevice();
|
boolean isMultiDevice();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Begins a transaction to improve the performance of multiple storage operations happening in a row.
|
|
||||||
*/
|
|
||||||
Transaction beginTransaction();
|
|
||||||
|
|
||||||
interface Transaction extends Closeable {
|
|
||||||
void close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-7
@@ -148,12 +148,12 @@ public class SignalServiceMessageSender {
|
|||||||
|
|
||||||
private static final int RETRY_COUNT = 4;
|
private static final int RETRY_COUNT = 4;
|
||||||
|
|
||||||
private final PushServiceSocket socket;
|
private final PushServiceSocket socket;
|
||||||
private final SignalServiceDataStore store;
|
private final SignalServiceAccountDataStore store;
|
||||||
private final SignalSessionLock sessionLock;
|
private final SignalSessionLock sessionLock;
|
||||||
private final SignalServiceAddress localAddress;
|
private final SignalServiceAddress localAddress;
|
||||||
private final int localDeviceId;
|
private final int localDeviceId;
|
||||||
private final Optional<EventListener> eventListener;
|
private final Optional<EventListener> eventListener;
|
||||||
|
|
||||||
private final AttachmentService attachmentService;
|
private final AttachmentService attachmentService;
|
||||||
private final MessagingService messagingService;
|
private final MessagingService messagingService;
|
||||||
@@ -174,7 +174,7 @@ public class SignalServiceMessageSender {
|
|||||||
boolean automaticNetworkRetry)
|
boolean automaticNetworkRetry)
|
||||||
{
|
{
|
||||||
this.socket = new PushServiceSocket(urls, credentialsProvider, signalAgent, clientZkProfileOperations, automaticNetworkRetry);
|
this.socket = new PushServiceSocket(urls, credentialsProvider, signalAgent, clientZkProfileOperations, automaticNetworkRetry);
|
||||||
this.store = store;
|
this.store = store.aci();
|
||||||
this.sessionLock = sessionLock;
|
this.sessionLock = sessionLock;
|
||||||
this.localAddress = new SignalServiceAddress(credentialsProvider.getAci(), credentialsProvider.getE164());
|
this.localAddress = new SignalServiceAddress(credentialsProvider.getAci(), credentialsProvider.getE164());
|
||||||
this.localDeviceId = credentialsProvider.getDeviceId();
|
this.localDeviceId = credentialsProvider.getDeviceId();
|
||||||
|
|||||||
Reference in New Issue
Block a user