From: AsamK Date: Sat, 12 Dec 2020 10:51:38 +0000 (+0100) Subject: Apply decrypted group change when receiving signed change X-Git-Tag: v0.7.0~4 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/98dee97cc69b49c0c3b75bb8691ae7ccc266e4d2?ds=sidebyside Apply decrypted group change when receiving signed change --- diff --git a/src/main/java/org/asamk/signal/manager/Manager.java b/src/main/java/org/asamk/signal/manager/Manager.java index 90910085..000455ac 100644 --- a/src/main/java/org/asamk/signal/manager/Manager.java +++ b/src/main/java/org/asamk/signal/manager/Manager.java @@ -1534,8 +1534,18 @@ public class Manager implements Closeable { 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); } } diff --git a/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java b/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java index c1b6511a..334cacd8 100644 --- a/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java +++ b/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java @@ -1,11 +1,21 @@ 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.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.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.InvalidGroupStateException; +import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import java.util.Collection; @@ -80,4 +90,33 @@ public class GroupHelper { 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; + } }