Skip to content

Commit

Permalink
Update libsignal-service
Browse files Browse the repository at this point in the history
  • Loading branch information
AsamK committed Sep 23, 2023
1 parent 73b4239 commit f1d735f
Show file tree
Hide file tree
Showing 22 changed files with 231 additions and 557 deletions.
354 changes: 29 additions & 325 deletions graalvm-config-dir/reflect-config.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion lib/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ dependencies {
implementation(files(libsignalClientPath))
}
implementation(libs.jackson.databind)
implementation(libs.protobuf)
implementation(libs.bouncycastle)
implementation(libs.slf4j.api)
implementation(libs.sqlite)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import org.signal.libsignal.protocol.message.DecryptionErrorMessage;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import org.whispersystems.signalservice.internal.push.Envelope;

import java.util.Optional;

Expand Down Expand Up @@ -62,10 +62,14 @@ public void execute(Context context) throws Throwable {
}

private static int envelopeTypeToCiphertextMessageType(int envelopeType) {
return switch (envelopeType) {
case SignalServiceProtos.Envelope.Type.PREKEY_BUNDLE_VALUE -> CiphertextMessage.PREKEY_TYPE;
case SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER_VALUE -> CiphertextMessage.SENDERKEY_TYPE;
case SignalServiceProtos.Envelope.Type.PLAINTEXT_CONTENT_VALUE -> CiphertextMessage.PLAINTEXT_CONTENT_TYPE;
final var type = Envelope.Type.fromValue(envelopeType);
if (type == null) {
return CiphertextMessage.WHISPER_TYPE;
}
return switch (type) {
case PREKEY_BUNDLE -> CiphertextMessage.PREKEY_TYPE;
case UNIDENTIFIED_SENDER -> CiphertextMessage.SENDERKEY_TYPE;
case PLAINTEXT_CONTENT -> CiphertextMessage.PLAINTEXT_CONTENT_TYPE;
default -> CiphertextMessage.WHISPER_TYPE;
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package org.asamk.signal.manager.api;

import com.google.protobuf.ByteString;

import org.asamk.signal.manager.groups.GroupLinkPassword;
import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
Expand All @@ -13,6 +11,8 @@
import java.net.URI;
import java.net.URISyntaxException;

import okio.ByteString;

public final class GroupInviteLinkUrl {

private static final String GROUP_URL_HOST = "signal.group";
Expand All @@ -24,7 +24,7 @@ public final class GroupInviteLinkUrl {

public static GroupInviteLinkUrl forGroup(GroupMasterKey groupMasterKey, DecryptedGroup group) {
return new GroupInviteLinkUrl(groupMasterKey,
GroupLinkPassword.fromBytes(group.getInviteLinkPassword().toByteArray()));
GroupLinkPassword.fromBytes(group.inviteLinkPassword.toByteArray()));
}

/**
Expand All @@ -50,19 +50,16 @@ public static GroupInviteLinkUrl fromUri(String urlString) throws InvalidGroupLi
}

var bytes = Base64UrlSafe.decodePaddingAgnostic(encoding);
var groupInviteLink = GroupInviteLink.parseFrom(bytes);

switch (groupInviteLink.getContentsCase()) {
case V1CONTENTS -> {
var groupInviteLinkContentsV1 = groupInviteLink.getV1Contents();
var groupMasterKey = new GroupMasterKey(groupInviteLinkContentsV1.getGroupMasterKey()
.toByteArray());
var password = GroupLinkPassword.fromBytes(groupInviteLinkContentsV1.getInviteLinkPassword()
.toByteArray());

return new GroupInviteLinkUrl(groupMasterKey, password);
}
default -> throw new UnknownGroupLinkVersionException("Url contains no known group link content");
GroupInviteLink groupInviteLink = GroupInviteLink.ADAPTER.decode(bytes);

if (groupInviteLink.v1Contents != null) {
var groupInviteLinkContentsV1 = groupInviteLink.v1Contents;
var groupMasterKey = new GroupMasterKey(groupInviteLinkContentsV1.groupMasterKey.toByteArray());
var password = GroupLinkPassword.fromBytes(groupInviteLinkContentsV1.inviteLinkPassword.toByteArray());

return new GroupInviteLinkUrl(groupMasterKey, password);
} else {
throw new UnknownGroupLinkVersionException("Url contains no known group link content");
}
} catch (InvalidInputException | IOException e) {
throw new InvalidGroupLinkException(e);
Expand Down Expand Up @@ -93,13 +90,12 @@ private GroupInviteLinkUrl(GroupMasterKey groupMasterKey, GroupLinkPassword pass
}

private static String createUrl(GroupMasterKey groupMasterKey, GroupLinkPassword password) {
var groupInviteLink = GroupInviteLink.newBuilder()
.setV1Contents(GroupInviteLink.GroupInviteLinkContentsV1.newBuilder()
.setGroupMasterKey(ByteString.copyFrom(groupMasterKey.serialize()))
.setInviteLinkPassword(ByteString.copyFrom(password.serialize())))
.build();
var groupInviteLink = new GroupInviteLink.Builder().v1Contents(new GroupInviteLink.GroupInviteLinkContentsV1.Builder().groupMasterKey(
ByteString.of(groupMasterKey.serialize()))
.inviteLinkPassword(ByteString.of(password.serialize()))
.build()).build();

var encoding = Base64UrlSafe.encodeBytesWithoutPadding(groupInviteLink.toByteArray());
var encoding = Base64UrlSafe.encodeBytesWithoutPadding(groupInviteLink.encode());

return GROUP_URL_PREFIX + encoding;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
import java.util.Set;
import java.util.stream.Collectors;

import static org.whispersystems.signalservice.internal.push.SignalServiceProtos.BodyRange;

public record MessageEnvelope(
Optional<RecipientAddress> sourceAddress,
int sourceDevice,
Expand Down Expand Up @@ -160,7 +158,7 @@ static Data from(
.map(a -> a.stream().map(preview -> Preview.from(preview, fileProvider)).toList())
.orElse(List.of()),
dataMessage.getBodyRanges()
.map(a -> a.stream().filter(BodyRange::hasStyle).map(TextStyle::from).toList())
.map(a -> a.stream().filter(r -> r.style != null).map(TextStyle::from).toList())
.orElse(List.of()));
}

Expand Down Expand Up @@ -250,7 +248,7 @@ static Quote from(
? List.of()
: quote.getBodyRanges()
.stream()
.filter(BodyRange::hasStyle)
.filter(r -> r.style != null)
.map(TextStyle::from)
.toList());
}
Expand Down Expand Up @@ -765,13 +763,12 @@ static Busy from(BusyMessage busyMessage) {
}
}

public record Hangup(long id, Type type, int deviceId, boolean isLegacy) {
public record Hangup(long id, Type type, int deviceId) {

static Hangup from(HangupMessage hangupMessage) {
return new Hangup(hangupMessage.getId(),
Type.from(hangupMessage.getType()),
hangupMessage.getDeviceId(),
hangupMessage.isLegacy());
hangupMessage.getDeviceId());
}

public enum Type {
Expand Down
36 changes: 19 additions & 17 deletions lib/src/main/java/org/asamk/signal/manager/api/TextStyle.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.asamk.signal.manager.api;

import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import org.whispersystems.signalservice.internal.push.BodyRange;

public record TextStyle(Style style, int start, int length) {
public record TextStyle(Style style, Integer start, Integer length) {

public enum Style {
NONE,
Expand All @@ -12,7 +12,10 @@ public enum Style {
STRIKETHROUGH,
MONOSPACE;

static Style fromInternal(SignalServiceProtos.BodyRange.Style style) {
static Style fromInternal(BodyRange.Style style) {
if (style == null) {
return NONE;
}
return switch (style) {
case NONE -> NONE;
case BOLD -> BOLD;
Expand All @@ -35,27 +38,26 @@ public static Style from(String style) {
};
}

SignalServiceProtos.BodyRange.Style toBodyRangeStyle() {
BodyRange.Style toBodyRangeStyle() {
return switch (this) {
case NONE -> SignalServiceProtos.BodyRange.Style.NONE;
case BOLD -> SignalServiceProtos.BodyRange.Style.BOLD;
case ITALIC -> SignalServiceProtos.BodyRange.Style.ITALIC;
case SPOILER -> SignalServiceProtos.BodyRange.Style.SPOILER;
case STRIKETHROUGH -> SignalServiceProtos.BodyRange.Style.STRIKETHROUGH;
case MONOSPACE -> SignalServiceProtos.BodyRange.Style.MONOSPACE;
case NONE -> BodyRange.Style.NONE;
case BOLD -> BodyRange.Style.BOLD;
case ITALIC -> BodyRange.Style.ITALIC;
case SPOILER -> BodyRange.Style.SPOILER;
case STRIKETHROUGH -> BodyRange.Style.STRIKETHROUGH;
case MONOSPACE -> BodyRange.Style.MONOSPACE;
};
}
}

static TextStyle from(SignalServiceProtos.BodyRange bodyRange) {
return new TextStyle(Style.fromInternal(bodyRange.getStyle()), bodyRange.getStart(), bodyRange.getLength());
static TextStyle from(BodyRange bodyRange) {
return new TextStyle(Style.fromInternal(bodyRange.style), bodyRange.start, bodyRange.length);
}

public SignalServiceProtos.BodyRange toBodyRange() {
return SignalServiceProtos.BodyRange.newBuilder()
.setStart(this.start())
.setLength(this.length())
.setStyle(this.style().toBodyRangeStyle())
public BodyRange toBodyRange() {
return new BodyRange.Builder().start(this.start())
.length(this.length())
.style(this.style().toBodyRangeStyle())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static void setGroupContext(
} else {
final var groupInfoV2 = (GroupInfoV2) groupInfo;
var group = SignalServiceGroupV2.newBuilder(groupInfoV2.getMasterKey())
.withRevision(groupInfoV2.getGroup() == null ? 0 : groupInfoV2.getGroup().getRevision())
.withRevision(groupInfoV2.getGroup() == null ? 0 : groupInfoV2.getGroup().revision)
.build();
messageBuilder.asGroupMessage(group);
}
Expand Down
32 changes: 16 additions & 16 deletions lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,11 @@ public GroupInfoV2 getOrMigrateGroup(
groupInfoV2 = new GroupInfoV2(groupId, groupMasterKey, account.getRecipientResolver());
}

if (groupInfoV2.getGroup() == null || groupInfoV2.getGroup().getRevision() < revision) {
if (groupInfoV2.getGroup() == null || groupInfoV2.getGroup().revision < revision) {
DecryptedGroup group = null;
if (signedGroupChange != null
&& groupInfoV2.getGroup() != null
&& groupInfoV2.getGroup().getRevision() + 1 == revision) {
&& groupInfoV2.getGroup().revision + 1 == revision) {
final var decryptedGroupChange = context.getGroupV2Helper()
.getDecryptedGroupChange(signedGroupChange, groupMasterKey);

Expand All @@ -151,8 +151,8 @@ public GroupInfoV2 getOrMigrateGroup(
}
if (group != null) {
storeProfileKeysFromMembers(group);
final var avatar = group.getAvatar();
if (avatar != null && !avatar.isEmpty()) {
final var avatar = group.avatar;
if (!avatar.isEmpty()) {
downloadGroupAvatar(groupId, groupSecretParams, avatar);
}
}
Expand Down Expand Up @@ -300,14 +300,14 @@ public Pair<GroupId, SendGroupMessageResults> joinGroup(
} catch (GroupLinkNotActiveException e) {
throw new InactiveGroupLinkException("Group link inactive (reason: " + e.getReason() + ")", e);
}
if (groupJoinInfo.getPendingAdminApproval()) {
if (groupJoinInfo.pendingAdminApproval) {
throw new PendingAdminApprovalException("You have already requested to join the group.");
}
final var groupChange = context.getGroupV2Helper()
.joinGroup(inviteLinkUrl.getGroupMasterKey(), inviteLinkUrl.getPassword(), groupJoinInfo);
final var group = getOrMigrateGroup(inviteLinkUrl.getGroupMasterKey(),
groupJoinInfo.getRevision() + 1,
groupChange.toByteArray());
groupJoinInfo.revision + 1,
groupChange.encode());

if (group.getGroup() == null) {
// Only requested member, can't send update to group members
Expand Down Expand Up @@ -400,8 +400,8 @@ private GroupInfo getGroup(GroupId groupId, boolean forceUpdate) {
} catch (NotAGroupMemberException ignored) {
}
storeProfileKeysFromMembers(decryptedGroup);
final var avatar = decryptedGroup.getAvatar();
if (avatar != null && !avatar.isEmpty()) {
final var avatar = decryptedGroup.avatar;
if (!avatar.isEmpty()) {
downloadGroupAvatar(groupInfoV2.getGroupId(), groupSecretParams, avatar);
}
}
Expand Down Expand Up @@ -446,16 +446,16 @@ private void retrieveGroupV2Avatar(
}

private void storeProfileKeysFromMembers(final DecryptedGroup group) {
for (var member : group.getMembersList()) {
final var serviceId = ServiceId.parseOrThrow(member.getAciBytes());
for (var member : group.members) {
final var serviceId = ServiceId.parseOrThrow(member.aciBytes);
final var recipientId = account.getRecipientResolver().resolveRecipient(serviceId);
final var profileStore = account.getProfileStore();
if (profileStore.getProfileKey(recipientId) != null) {
// We already have a profile key, not updating it from a non-authoritative source
continue;
}
try {
profileStore.storeProfileKey(recipientId, new ProfileKey(member.getProfileKey().toByteArray()));
profileStore.storeProfileKey(recipientId, new ProfileKey(member.profileKey.toByteArray()));
} catch (InvalidInputException ignored) {
}
}
Expand All @@ -479,7 +479,7 @@ private void storeProfileKeysFromHistory(
final DecryptedGroup newDecryptedGroup
) throws NotAGroupMemberException {
final var revisionWeWereAdded = context.getGroupV2Helper().findRevisionWeWereAdded(newDecryptedGroup);
final var localRevision = localGroup.getGroup() == null ? 0 : localGroup.getGroup().getRevision();
final var localRevision = localGroup.getGroup() == null ? 0 : localGroup.getGroup().revision;
var fromRevision = Math.max(revisionWeWereAdded, localRevision);
final var newProfileKeys = new HashMap<RecipientId, ProfileKey>();
while (true) {
Expand Down Expand Up @@ -753,7 +753,7 @@ private SendGroupMessageResults quitGroupV2(
groupInfoV2.setGroup(groupGroupChangePair.first());
account.getGroupStore().updateGroup(groupInfoV2);

var messageBuilder = getGroupUpdateMessageBuilder(groupInfoV2, groupGroupChangePair.second().toByteArray());
var messageBuilder = getGroupUpdateMessageBuilder(groupInfoV2, groupGroupChangePair.second().encode());
return sendGroupMessage(messageBuilder,
groupInfoV2.getMembersIncludingPendingWithout(account.getSelfRecipientId()),
groupInfoV2.getDistributionId());
Expand Down Expand Up @@ -782,7 +782,7 @@ private SignalServiceDataMessage.Builder getGroupUpdateMessageBuilder(GroupInfoV

private SignalServiceDataMessage.Builder getGroupUpdateMessageBuilder(GroupInfoV2 g, byte[] signedGroupChange) {
var group = SignalServiceGroupV2.newBuilder(g.getMasterKey())
.withRevision(g.getGroup().getRevision())
.withRevision(g.getGroup().revision)
.withSignedGroupChange(signedGroupChange);
return SignalServiceDataMessage.newBuilder()
.asGroupMessage(group.build())
Expand All @@ -798,7 +798,7 @@ private SendGroupMessageResults sendUpdateGroupV2Message(
members.addAll(group.getMembersIncludingPendingWithout(selfRecipientId));
account.getGroupStore().updateGroup(group);

final var messageBuilder = getGroupUpdateMessageBuilder(group, groupChange.toByteArray());
final var messageBuilder = getGroupUpdateMessageBuilder(group, groupChange.encode());
return sendGroupMessage(messageBuilder, members, group.getDistributionId());
}

Expand Down
Loading

0 comments on commit f1d735f

Please sign in to comment.