]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/groups/GroupUtils.java
b73be0ab0ada04eaa3cc5d5a6b398d7cf957e3e6
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / groups / GroupUtils.java
1 package org.asamk.signal.manager.groups;
2
3 import org.asamk.signal.manager.api.GroupId;
4 import org.asamk.signal.manager.api.GroupIdV1;
5 import org.asamk.signal.manager.api.GroupIdV2;
6 import org.asamk.signal.manager.storage.groups.GroupInfo;
7 import org.asamk.signal.manager.storage.groups.GroupInfoV1;
8 import org.asamk.signal.manager.storage.groups.GroupInfoV2;
9 import org.signal.libsignal.protocol.kdf.HKDF;
10 import org.signal.libsignal.zkgroup.InvalidInputException;
11 import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
12 import org.signal.libsignal.zkgroup.groups.GroupSecretParams;
13 import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
14 import org.whispersystems.signalservice.api.messages.SignalServiceGroup;
15 import org.whispersystems.signalservice.api.messages.SignalServiceGroupContext;
16 import org.whispersystems.signalservice.api.messages.SignalServiceGroupV2;
17
18 public class GroupUtils {
19
20 public static void setGroupContext(
21 final SignalServiceDataMessage.Builder messageBuilder, final GroupInfo groupInfo
22 ) {
23 if (groupInfo instanceof GroupInfoV1) {
24 var group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.DELIVER)
25 .withId(groupInfo.getGroupId().serialize())
26 .build();
27 messageBuilder.asGroupMessage(group);
28 } else {
29 final var groupInfoV2 = (GroupInfoV2) groupInfo;
30 var group = SignalServiceGroupV2.newBuilder(groupInfoV2.getMasterKey())
31 .withRevision(groupInfoV2.getGroup() == null ? 0 : groupInfoV2.getGroup().getRevision())
32 .build();
33 messageBuilder.asGroupMessage(group);
34 }
35 }
36
37 public static GroupId getGroupId(SignalServiceGroupContext context) {
38 if (context.getGroupV1().isPresent()) {
39 return GroupId.v1(context.getGroupV1().get().getGroupId());
40 } else if (context.getGroupV2().isPresent()) {
41 return getGroupIdV2(context.getGroupV2().get().getMasterKey());
42 } else {
43 return null;
44 }
45 }
46
47 public static GroupIdV2 getGroupIdV2(GroupSecretParams groupSecretParams) {
48 return GroupId.v2(groupSecretParams.getPublicParams().getGroupIdentifier().serialize());
49 }
50
51 public static GroupIdV2 getGroupIdV2(GroupMasterKey groupMasterKey) {
52 final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupMasterKey);
53 return getGroupIdV2(groupSecretParams);
54 }
55
56 public static GroupIdV2 getGroupIdV2(GroupIdV1 groupIdV1) {
57 final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(deriveV2MigrationMasterKey(groupIdV1));
58 return getGroupIdV2(groupSecretParams);
59 }
60
61 private static GroupMasterKey deriveV2MigrationMasterKey(GroupIdV1 groupIdV1) {
62 try {
63 return new GroupMasterKey(HKDF.deriveSecrets(groupIdV1.serialize(),
64 "GV2 Migration".getBytes(),
65 GroupMasterKey.SIZE));
66 } catch (InvalidInputException e) {
67 throw new AssertionError(e);
68 }
69 }
70 }