1 package org
.asamk
.signal
.manager
.groups
;
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
;
18 public class GroupUtils
{
20 public static void setGroupContext(
21 final SignalServiceDataMessage
.Builder messageBuilder
, final GroupInfo groupInfo
23 if (groupInfo
instanceof GroupInfoV1
) {
24 var group
= SignalServiceGroup
.newBuilder(SignalServiceGroup
.Type
.DELIVER
)
25 .withId(groupInfo
.getGroupId().serialize())
27 messageBuilder
.asGroupMessage(group
);
29 final var groupInfoV2
= (GroupInfoV2
) groupInfo
;
30 var group
= SignalServiceGroupV2
.newBuilder(groupInfoV2
.getMasterKey())
31 .withRevision(groupInfoV2
.getGroup() == null ?
0 : groupInfoV2
.getGroup().revision
)
33 messageBuilder
.asGroupMessage(group
);
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());
47 public static GroupIdV2
getGroupIdV2(GroupSecretParams groupSecretParams
) {
48 return GroupId
.v2(groupSecretParams
.getPublicParams().getGroupIdentifier().serialize());
51 public static GroupIdV2
getGroupIdV2(GroupMasterKey groupMasterKey
) {
52 final var groupSecretParams
= GroupSecretParams
.deriveFromMasterKey(groupMasterKey
);
53 return getGroupIdV2(groupSecretParams
);
56 public static GroupIdV2
getGroupIdV2(GroupIdV1 groupIdV1
) {
57 final var groupSecretParams
= GroupSecretParams
.deriveFromMasterKey(deriveV2MigrationMasterKey(groupIdV1
));
58 return getGroupIdV2(groupSecretParams
);
61 private static GroupMasterKey
deriveV2MigrationMasterKey(GroupIdV1 groupIdV1
) {
63 return new GroupMasterKey(HKDF
.deriveSecrets(groupIdV1
.serialize(),
64 "GV2 Migration".getBytes(),
65 GroupMasterKey
.SIZE
));
66 } catch (InvalidInputException e
) {
67 throw new AssertionError(e
);