]> nmode's Git Repositories - signal-cli/commitdiff
Extract IdentityHelper
authorAsamK <asamk@gmx.de>
Tue, 12 Oct 2021 20:14:39 +0000 (22:14 +0200)
committerAsamK <asamk@gmx.de>
Tue, 12 Oct 2021 20:14:39 +0000 (22:14 +0200)
lib/src/main/java/org/asamk/signal/manager/Manager.java
lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java
lib/src/main/java/org/asamk/signal/manager/helper/IdentityHelper.java [new file with mode: 0644]
src/main/java/org/asamk/signal/ReceiveMessageHandler.java
src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java

index 3cfeb4f7680eb381eb452251f7500cb7b7b91c99..733e3dccc285fe831e966e03c646ef5c207fa1c2 100644 (file)
@@ -22,7 +22,6 @@ import org.asamk.signal.manager.storage.identities.TrustNewIdentity;
 import org.asamk.signal.manager.storage.recipients.Contact;
 import org.asamk.signal.manager.storage.recipients.Profile;
 import org.asamk.signal.manager.storage.recipients.RecipientAddress;
 import org.asamk.signal.manager.storage.recipients.Contact;
 import org.asamk.signal.manager.storage.recipients.Profile;
 import org.asamk.signal.manager.storage.recipients.RecipientAddress;
-import org.whispersystems.libsignal.IdentityKey;
 import org.whispersystems.libsignal.InvalidKeyException;
 import org.whispersystems.libsignal.util.Pair;
 import org.whispersystems.libsignal.util.guava.Optional;
 import org.whispersystems.libsignal.InvalidKeyException;
 import org.whispersystems.libsignal.util.Pair;
 import org.whispersystems.libsignal.util.guava.Optional;
@@ -228,8 +227,6 @@ public interface Manager extends Closeable {
 
     boolean trustIdentityAllKeys(RecipientIdentifier.Single recipient);
 
 
     boolean trustIdentityAllKeys(RecipientIdentifier.Single recipient);
 
-    String computeSafetyNumber(SignalServiceAddress theirAddress, IdentityKey theirIdentityKey);
-
     SignalServiceAddress resolveSignalServiceAddress(SignalServiceAddress address);
 
     @Override
     SignalServiceAddress resolveSignalServiceAddress(SignalServiceAddress address);
 
     @Override
index a14f2d1f793451db9c69028064654bb372380f57..d2ffaaabe577d8c6d2a7bf749a24fe70712ce457 100644 (file)
@@ -38,6 +38,7 @@ import org.asamk.signal.manager.helper.AttachmentHelper;
 import org.asamk.signal.manager.helper.ContactHelper;
 import org.asamk.signal.manager.helper.GroupHelper;
 import org.asamk.signal.manager.helper.GroupV2Helper;
 import org.asamk.signal.manager.helper.ContactHelper;
 import org.asamk.signal.manager.helper.GroupHelper;
 import org.asamk.signal.manager.helper.GroupV2Helper;
+import org.asamk.signal.manager.helper.IdentityHelper;
 import org.asamk.signal.manager.helper.IncomingMessageHandler;
 import org.asamk.signal.manager.helper.PinHelper;
 import org.asamk.signal.manager.helper.PreKeyHelper;
 import org.asamk.signal.manager.helper.IncomingMessageHandler;
 import org.asamk.signal.manager.helper.PinHelper;
 import org.asamk.signal.manager.helper.PreKeyHelper;
@@ -59,15 +60,10 @@ import org.asamk.signal.manager.storage.stickers.Sticker;
 import org.asamk.signal.manager.storage.stickers.StickerPackId;
 import org.asamk.signal.manager.util.KeyUtils;
 import org.asamk.signal.manager.util.StickerUtils;
 import org.asamk.signal.manager.storage.stickers.StickerPackId;
 import org.asamk.signal.manager.util.KeyUtils;
 import org.asamk.signal.manager.util.StickerUtils;
-import org.asamk.signal.manager.util.Utils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.whispersystems.libsignal.IdentityKey;
 import org.whispersystems.libsignal.InvalidKeyException;
 import org.whispersystems.libsignal.ecc.ECPublicKey;
 import org.whispersystems.libsignal.InvalidKeyException;
 import org.whispersystems.libsignal.ecc.ECPublicKey;
-import org.whispersystems.libsignal.fingerprint.Fingerprint;
-import org.whispersystems.libsignal.fingerprint.FingerprintParsingException;
-import org.whispersystems.libsignal.fingerprint.FingerprintVersionMismatchException;
 import org.whispersystems.libsignal.util.Pair;
 import org.whispersystems.libsignal.util.guava.Optional;
 import org.whispersystems.signalservice.api.SignalSessionLock;
 import org.whispersystems.libsignal.util.Pair;
 import org.whispersystems.libsignal.util.guava.Optional;
 import org.whispersystems.signalservice.api.SignalSessionLock;
@@ -98,9 +94,7 @@ import java.net.URISyntaxException;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.security.SignatureException;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.security.SignatureException;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
-import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -112,7 +106,6 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.locks.ReentrantLock;
-import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import static org.asamk.signal.manager.config.ServiceConfig.capabilities;
 import java.util.stream.Collectors;
 
 import static org.asamk.signal.manager.config.ServiceConfig.capabilities;
@@ -138,6 +131,7 @@ public class ManagerImpl implements Manager {
     private final ContactHelper contactHelper;
     private final IncomingMessageHandler incomingMessageHandler;
     private final PreKeyHelper preKeyHelper;
     private final ContactHelper contactHelper;
     private final IncomingMessageHandler incomingMessageHandler;
     private final PreKeyHelper preKeyHelper;
+    private final IdentityHelper identityHelper;
 
     private final Context context;
     private boolean hasCaughtUpWithOldMessages = false;
 
     private final Context context;
     private boolean hasCaughtUpWithOldMessages = false;
@@ -238,6 +232,11 @@ public class ManagerImpl implements Manager {
                 syncHelper,
                 this::getRecipientProfile,
                 jobExecutor);
                 syncHelper,
                 this::getRecipientProfile,
                 jobExecutor);
+        this.identityHelper = new IdentityHelper(account,
+                dependencies,
+                this::resolveSignalServiceAddress,
+                syncHelper,
+                profileHelper);
     }
 
     @Override
     }
 
     @Override
@@ -1042,7 +1041,7 @@ public class ManagerImpl implements Manager {
         return toGroup(groupHelper.getGroup(groupId));
     }
 
         return toGroup(groupHelper.getGroup(groupId));
     }
 
-    public GroupInfo getGroupInfo(GroupId groupId) {
+    private GroupInfo getGroupInfo(GroupId groupId) {
         return groupHelper.getGroup(groupId);
     }
 
         return groupHelper.getGroup(groupId);
     }
 
@@ -1063,8 +1062,9 @@ public class ManagerImpl implements Manager {
         final var address = account.getRecipientStore().resolveRecipientAddress(identityInfo.getRecipientId());
         return new Identity(address,
                 identityInfo.getIdentityKey(),
         final var address = account.getRecipientStore().resolveRecipientAddress(identityInfo.getRecipientId());
         return new Identity(address,
                 identityInfo.getIdentityKey(),
-                computeSafetyNumber(address.toSignalServiceAddress(), identityInfo.getIdentityKey()),
-                computeSafetyNumberForScanning(address.toSignalServiceAddress(), identityInfo.getIdentityKey()),
+                identityHelper.computeSafetyNumber(identityInfo.getRecipientId(), identityInfo.getIdentityKey()),
+                identityHelper.computeSafetyNumberForScanning(identityInfo.getRecipientId(),
+                        identityInfo.getIdentityKey()).getSerialized(),
                 identityInfo.getTrustLevel(),
                 identityInfo.getDateAdded());
     }
                 identityInfo.getTrustLevel(),
                 identityInfo.getDateAdded());
     }
@@ -1094,9 +1094,7 @@ public class ManagerImpl implements Manager {
         } catch (UnregisteredUserException e) {
             return false;
         }
         } catch (UnregisteredUserException e) {
             return false;
         }
-        return trustIdentity(recipientId,
-                identityKey -> Arrays.equals(identityKey.serialize(), fingerprint),
-                TrustLevel.TRUSTED_VERIFIED);
+        return identityHelper.trustIdentityVerified(recipientId, fingerprint);
     }
 
     /**
     }
 
     /**
@@ -1113,10 +1111,7 @@ public class ManagerImpl implements Manager {
         } catch (UnregisteredUserException e) {
             return false;
         }
         } catch (UnregisteredUserException e) {
             return false;
         }
-        var address = resolveSignalServiceAddress(recipientId);
-        return trustIdentity(recipientId,
-                identityKey -> safetyNumber.equals(computeSafetyNumber(address, identityKey)),
-                TrustLevel.TRUSTED_VERIFIED);
+        return identityHelper.trustIdentityVerifiedSafetyNumber(recipientId, safetyNumber);
     }
 
     /**
     }
 
     /**
@@ -1133,15 +1128,7 @@ public class ManagerImpl implements Manager {
         } catch (UnregisteredUserException e) {
             return false;
         }
         } catch (UnregisteredUserException e) {
             return false;
         }
-        var address = resolveSignalServiceAddress(recipientId);
-        return trustIdentity(recipientId, identityKey -> {
-            final var fingerprint = computeSafetyNumberFingerprint(address, identityKey);
-            try {
-                return fingerprint != null && fingerprint.getScannableFingerprint().compareTo(safetyNumber);
-            } catch (FingerprintVersionMismatchException | FingerprintParsingException e) {
-                return false;
-            }
-        }, TrustLevel.TRUSTED_VERIFIED);
+        return identityHelper.trustIdentityVerifiedSafetyNumber(recipientId, safetyNumber);
     }
 
     /**
     }
 
     /**
@@ -1157,66 +1144,13 @@ public class ManagerImpl implements Manager {
         } catch (UnregisteredUserException e) {
             return false;
         }
         } catch (UnregisteredUserException e) {
             return false;
         }
-        return trustIdentity(recipientId, identityKey -> true, TrustLevel.TRUSTED_UNVERIFIED);
-    }
-
-    private boolean trustIdentity(
-            RecipientId recipientId, Function<IdentityKey, Boolean> verifier, TrustLevel trustLevel
-    ) {
-        var identity = account.getIdentityKeyStore().getIdentity(recipientId);
-        if (identity == null) {
-            return false;
-        }
-
-        if (!verifier.apply(identity.getIdentityKey())) {
-            return false;
-        }
-
-        account.getIdentityKeyStore().setIdentityTrustLevel(recipientId, identity.getIdentityKey(), trustLevel);
-        try {
-            var address = resolveSignalServiceAddress(recipientId);
-            syncHelper.sendVerifiedMessage(address, identity.getIdentityKey(), trustLevel);
-        } catch (IOException e) {
-            logger.warn("Failed to send verification sync message: {}", e.getMessage());
-        }
-
-        return true;
+        return identityHelper.trustIdentityAllKeys(recipientId);
     }
 
     private void handleIdentityFailure(
             final RecipientId recipientId, final SendMessageResult.IdentityFailure identityFailure
     ) {
     }
 
     private void handleIdentityFailure(
             final RecipientId recipientId, final SendMessageResult.IdentityFailure identityFailure
     ) {
-        final var identityKey = identityFailure.getIdentityKey();
-        if (identityKey != null) {
-            final var newIdentity = account.getIdentityKeyStore().saveIdentity(recipientId, identityKey, new Date());
-            if (newIdentity) {
-                account.getSessionStore().archiveSessions(recipientId);
-            }
-        } else {
-            // Retrieve profile to get the current identity key from the server
-            profileHelper.refreshRecipientProfile(recipientId);
-        }
-    }
-
-    @Override
-    public String computeSafetyNumber(SignalServiceAddress theirAddress, IdentityKey theirIdentityKey) {
-        final Fingerprint fingerprint = computeSafetyNumberFingerprint(theirAddress, theirIdentityKey);
-        return fingerprint == null ? null : fingerprint.getDisplayableFingerprint().getDisplayText();
-    }
-
-    private byte[] computeSafetyNumberForScanning(SignalServiceAddress theirAddress, IdentityKey theirIdentityKey) {
-        final Fingerprint fingerprint = computeSafetyNumberFingerprint(theirAddress, theirIdentityKey);
-        return fingerprint == null ? null : fingerprint.getScannableFingerprint().getSerialized();
-    }
-
-    private Fingerprint computeSafetyNumberFingerprint(
-            final SignalServiceAddress theirAddress, final IdentityKey theirIdentityKey
-    ) {
-        return Utils.computeSafetyNumber(capabilities.isUuid(),
-                account.getSelfAddress(),
-                account.getIdentityKeyPair().getPublicKey(),
-                theirAddress,
-                theirIdentityKey);
+        this.identityHelper.handleIdentityFailure(recipientId, identityFailure);
     }
 
     @Override
     }
 
     @Override
@@ -1291,5 +1225,4 @@ public class ManagerImpl implements Manager {
         }
         account = null;
     }
         }
         account = null;
     }
-
 }
 }
diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/IdentityHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/IdentityHelper.java
new file mode 100644 (file)
index 0000000..531870d
--- /dev/null
@@ -0,0 +1,135 @@
+package org.asamk.signal.manager.helper;
+
+import org.asamk.signal.manager.SignalDependencies;
+import org.asamk.signal.manager.TrustLevel;
+import org.asamk.signal.manager.storage.SignalAccount;
+import org.asamk.signal.manager.storage.recipients.RecipientId;
+import org.asamk.signal.manager.util.Utils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.whispersystems.libsignal.IdentityKey;
+import org.whispersystems.libsignal.fingerprint.Fingerprint;
+import org.whispersystems.libsignal.fingerprint.FingerprintParsingException;
+import org.whispersystems.libsignal.fingerprint.FingerprintVersionMismatchException;
+import org.whispersystems.libsignal.fingerprint.ScannableFingerprint;
+import org.whispersystems.signalservice.api.messages.SendMessageResult;
+import org.whispersystems.signalservice.api.push.SignalServiceAddress;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.function.Function;
+
+import static org.asamk.signal.manager.config.ServiceConfig.capabilities;
+
+public class IdentityHelper {
+
+    private final static Logger logger = LoggerFactory.getLogger(IdentityHelper.class);
+
+    private final SignalAccount account;
+    private final SignalDependencies dependencies;
+    private final SignalServiceAddressResolver addressResolver;
+    private final SyncHelper syncHelper;
+    private final ProfileHelper profileHelper;
+
+    public IdentityHelper(
+            final SignalAccount account,
+            final SignalDependencies dependencies,
+            final SignalServiceAddressResolver addressResolver,
+            final SyncHelper syncHelper,
+            final ProfileHelper profileHelper
+    ) {
+        this.account = account;
+        this.dependencies = dependencies;
+        this.addressResolver = addressResolver;
+        this.syncHelper = syncHelper;
+        this.profileHelper = profileHelper;
+    }
+
+    public boolean trustIdentityVerified(RecipientId recipientId, byte[] fingerprint) {
+        return trustIdentity(recipientId,
+                identityKey -> Arrays.equals(identityKey.serialize(), fingerprint),
+                TrustLevel.TRUSTED_VERIFIED);
+    }
+
+    public boolean trustIdentityVerifiedSafetyNumber(RecipientId recipientId, String safetyNumber) {
+        return trustIdentity(recipientId,
+                identityKey -> safetyNumber.equals(computeSafetyNumber(recipientId, identityKey)),
+                TrustLevel.TRUSTED_VERIFIED);
+    }
+
+    public boolean trustIdentityVerifiedSafetyNumber(RecipientId recipientId, byte[] safetyNumber) {
+        return trustIdentity(recipientId, identityKey -> {
+            final var fingerprint = computeSafetyNumberForScanning(recipientId, identityKey);
+            try {
+                return fingerprint != null && fingerprint.compareTo(safetyNumber);
+            } catch (FingerprintVersionMismatchException | FingerprintParsingException e) {
+                return false;
+            }
+        }, TrustLevel.TRUSTED_VERIFIED);
+    }
+
+    public boolean trustIdentityAllKeys(RecipientId recipientId) {
+        return trustIdentity(recipientId, identityKey -> true, TrustLevel.TRUSTED_UNVERIFIED);
+    }
+
+    public String computeSafetyNumber(RecipientId recipientId, IdentityKey theirIdentityKey) {
+        var address = addressResolver.resolveSignalServiceAddress(recipientId);
+        final Fingerprint fingerprint = computeSafetyNumberFingerprint(address, theirIdentityKey);
+        return fingerprint == null ? null : fingerprint.getDisplayableFingerprint().getDisplayText();
+    }
+
+    public ScannableFingerprint computeSafetyNumberForScanning(RecipientId recipientId, IdentityKey theirIdentityKey) {
+        var address = addressResolver.resolveSignalServiceAddress(recipientId);
+        final Fingerprint fingerprint = computeSafetyNumberFingerprint(address, theirIdentityKey);
+        return fingerprint == null ? null : fingerprint.getScannableFingerprint();
+    }
+
+    private Fingerprint computeSafetyNumberFingerprint(
+            final SignalServiceAddress theirAddress, final IdentityKey theirIdentityKey
+    ) {
+        return Utils.computeSafetyNumber(capabilities.isUuid(),
+                account.getSelfAddress(),
+                account.getIdentityKeyPair().getPublicKey(),
+                theirAddress,
+                theirIdentityKey);
+    }
+
+    private boolean trustIdentity(
+            RecipientId recipientId, Function<IdentityKey, Boolean> verifier, TrustLevel trustLevel
+    ) {
+        var identity = account.getIdentityKeyStore().getIdentity(recipientId);
+        if (identity == null) {
+            return false;
+        }
+
+        if (!verifier.apply(identity.getIdentityKey())) {
+            return false;
+        }
+
+        account.getIdentityKeyStore().setIdentityTrustLevel(recipientId, identity.getIdentityKey(), trustLevel);
+        try {
+            var address = addressResolver.resolveSignalServiceAddress(recipientId);
+            syncHelper.sendVerifiedMessage(address, identity.getIdentityKey(), trustLevel);
+        } catch (IOException e) {
+            logger.warn("Failed to send verification sync message: {}", e.getMessage());
+        }
+
+        return true;
+    }
+
+    public void handleIdentityFailure(
+            final RecipientId recipientId, final SendMessageResult.IdentityFailure identityFailure
+    ) {
+        final var identityKey = identityFailure.getIdentityKey();
+        if (identityKey != null) {
+            final var newIdentity = account.getIdentityKeyStore().saveIdentity(recipientId, identityKey, new Date());
+            if (newIdentity) {
+                account.getSessionStore().archiveSessions(recipientId);
+            }
+        } else {
+            // Retrieve profile to get the current identity key from the server
+            profileHelper.refreshRecipientProfile(recipientId);
+        }
+    }
+}
index 35790678cd379fb3c331cf121ae48da2cfc884c2..b1580b349b0088d99fdea712caf2a35aff447299 100644 (file)
@@ -6,7 +6,6 @@ import org.asamk.signal.manager.api.RecipientIdentifier;
 import org.asamk.signal.manager.groups.GroupId;
 import org.asamk.signal.manager.groups.GroupUtils;
 import org.asamk.signal.util.DateUtils;
 import org.asamk.signal.manager.groups.GroupId;
 import org.asamk.signal.manager.groups.GroupUtils;
 import org.asamk.signal.util.DateUtils;
-import org.asamk.signal.util.Util;
 import org.slf4j.helpers.MessageFormatter;
 import org.whispersystems.libsignal.protocol.DecryptionErrorMessage;
 import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
 import org.slf4j.helpers.MessageFormatter;
 import org.whispersystems.libsignal.protocol.DecryptionErrorMessage;
 import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
@@ -377,9 +376,6 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler {
             writer.println("Received sync message with verified identities:");
             final var verifiedMessage = syncMessage.getVerified().get();
             writer.println("- {}: {}", formatContact(verifiedMessage.getDestination()), verifiedMessage.getVerified());
             writer.println("Received sync message with verified identities:");
             final var verifiedMessage = syncMessage.getVerified().get();
             writer.println("- {}: {}", formatContact(verifiedMessage.getDestination()), verifiedMessage.getVerified());
-            var safetyNumber = Util.formatSafetyNumber(m.computeSafetyNumber(verifiedMessage.getDestination(),
-                    verifiedMessage.getIdentityKey()));
-            writer.indentedWriter().println(safetyNumber);
         }
         if (syncMessage.getConfiguration().isPresent()) {
             writer.println("Received sync message with configuration:");
         }
         if (syncMessage.getConfiguration().isPresent()) {
             writer.println("Received sync message with configuration:");
index 6e655bdc3ec8f2f3591983526d03b0e7e470eb63..59422e6922354ad01b454e2976dcbbb00ea6f11c 100644 (file)
@@ -30,7 +30,6 @@ import org.freedesktop.dbus.DBusPath;
 import org.freedesktop.dbus.connections.impl.DBusConnection;
 import org.freedesktop.dbus.exceptions.DBusException;
 import org.freedesktop.dbus.interfaces.DBusInterface;
 import org.freedesktop.dbus.connections.impl.DBusConnection;
 import org.freedesktop.dbus.exceptions.DBusException;
 import org.freedesktop.dbus.interfaces.DBusInterface;
-import org.whispersystems.libsignal.IdentityKey;
 import org.whispersystems.libsignal.InvalidKeyException;
 import org.whispersystems.libsignal.util.Pair;
 import org.whispersystems.libsignal.util.guava.Optional;
 import org.whispersystems.libsignal.InvalidKeyException;
 import org.whispersystems.libsignal.util.Pair;
 import org.whispersystems.libsignal.util.guava.Optional;
@@ -538,13 +537,6 @@ public class DbusManagerImpl implements Manager {
         throw new UnsupportedOperationException();
     }
 
         throw new UnsupportedOperationException();
     }
 
-    @Override
-    public String computeSafetyNumber(
-            final SignalServiceAddress theirAddress, final IdentityKey theirIdentityKey
-    ) {
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public SignalServiceAddress resolveSignalServiceAddress(final SignalServiceAddress address) {
         return address;
     @Override
     public SignalServiceAddress resolveSignalServiceAddress(final SignalServiceAddress address) {
         return address;