]> nmode's Git Repositories - signal-cli/commitdiff
Apply decrypted group change when receiving signed change
authorAsamK <asamk@gmx.de>
Sat, 12 Dec 2020 10:51:38 +0000 (11:51 +0100)
committerAsamK <asamk@gmx.de>
Sat, 12 Dec 2020 10:51:38 +0000 (11:51 +0100)
src/main/java/org/asamk/signal/manager/Manager.java
src/main/java/org/asamk/signal/manager/helper/GroupHelper.java

index 909100855784f08e1a3c1d0f17e065db6c80eeaa..000455ac169740d0ec9ad6b9099030f3dc708b92 100644 (file)
@@ -1534,8 +1534,18 @@ public class Manager implements Closeable {
 
                     if (groupInfoV2.getGroup() == null
                             || groupInfoV2.getGroup().getRevision() < groupContext.getRevision()) {
 
                     if (groupInfoV2.getGroup() == null
                             || groupInfoV2.getGroup().getRevision() < groupContext.getRevision()) {
-                        // TODO check if revision is only 1 behind and a signedGroupChange is available
-                        groupInfoV2.setGroup(getDecryptedGroup(groupSecretParams));
+                        DecryptedGroup group = null;
+                        if (groupContext.hasSignedGroupChange()
+                                && groupInfoV2.getGroup() != null
+                                && groupInfoV2.getGroup().getRevision() + 1 == groupContext.getRevision()) {
+                            group = groupHelper.getUpdatedDecryptedGroup(groupInfoV2.getGroup(),
+                                    groupContext.getSignedGroupChange(),
+                                    groupMasterKey);
+                        }
+                        if (group == null) {
+                            group = getDecryptedGroup(groupSecretParams);
+                        }
+                        groupInfoV2.setGroup(group);
                         account.getGroupStore().updateGroup(groupInfoV2);
                     }
                 }
                         account.getGroupStore().updateGroup(groupInfoV2);
                     }
                 }
index c1b6511ae19b52622b1ef855be2a39d3bd54e849..334cacd8d88320df63a4cd32dd7ab04062777567 100644 (file)
@@ -1,11 +1,21 @@
 package org.asamk.signal.manager.helper;
 
 package org.asamk.signal.manager.helper;
 
+import com.google.protobuf.InvalidProtocolBufferException;
+
+import org.signal.storageservice.protos.groups.GroupChange;
 import org.signal.storageservice.protos.groups.Member;
 import org.signal.storageservice.protos.groups.Member;
+import org.signal.storageservice.protos.groups.local.DecryptedGroup;
+import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
+import org.signal.zkgroup.VerificationFailedException;
+import org.signal.zkgroup.groups.GroupMasterKey;
 import org.signal.zkgroup.groups.GroupSecretParams;
 import org.signal.zkgroup.profiles.ProfileKeyCredential;
 import org.whispersystems.libsignal.util.guava.Optional;
 import org.signal.zkgroup.groups.GroupSecretParams;
 import org.signal.zkgroup.profiles.ProfileKeyCredential;
 import org.whispersystems.libsignal.util.guava.Optional;
+import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
 import org.whispersystems.signalservice.api.groupsv2.GroupCandidate;
 import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
 import org.whispersystems.signalservice.api.groupsv2.GroupCandidate;
 import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
+import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException;
+import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 
 import java.util.Collection;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 
 import java.util.Collection;
@@ -80,4 +90,33 @@ public class GroupHelper {
                 0);
     }
 
                 0);
     }
 
+    public DecryptedGroup getUpdatedDecryptedGroup(
+            DecryptedGroup group, byte[] signedGroupChange, GroupMasterKey groupMasterKey
+    ) {
+        try {
+            final DecryptedGroupChange decryptedGroupChange = getDecryptedGroupChange(signedGroupChange,
+                    groupMasterKey);
+            if (decryptedGroupChange == null) {
+                return null;
+            }
+            return DecryptedGroupUtil.apply(group, decryptedGroupChange);
+        } catch (NotAbleToApplyGroupV2ChangeException e) {
+            return null;
+        }
+    }
+
+    private DecryptedGroupChange getDecryptedGroupChange(byte[] signedGroupChange, GroupMasterKey groupMasterKey) {
+        if (signedGroupChange != null) {
+            GroupsV2Operations.GroupOperations groupOperations = groupsV2Operations.forGroup(GroupSecretParams.deriveFromMasterKey(
+                    groupMasterKey));
+
+            try {
+                return groupOperations.decryptChange(GroupChange.parseFrom(signedGroupChange), true).orNull();
+            } catch (VerificationFailedException | InvalidGroupStateException | InvalidProtocolBufferException e) {
+                return null;
+            }
+        }
+
+        return null;
+    }
 }
 }