From 41726d339f570ed89f5aa0aefd8466d793ab1909 Mon Sep 17 00:00:00 2001 From: AsamK Date: Sun, 8 Sep 2024 10:13:59 +0200 Subject: [PATCH] Update libsignal-service-java --- CHANGELOG.md | 2 +- graalvm-config-dir/reflect-config.json | 2 +- graalvm-config-dir/resource-config.json | 2 ++ .../signal/manager/config/ServiceConfig.java | 3 +- .../signal/manager/helper/AccountHelper.java | 34 +++++++++++------- .../signal/manager/helper/SyncHelper.java | 35 +++++++++++++------ .../storage/prekeys/SignedPreKeyStore.java | 20 +++++++---- settings.gradle.kts | 2 +- .../java/org/asamk/signal/BaseConfig.java | 2 +- 9 files changed, 69 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b534de6..bcceabd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## [Unreleased] -Requires libsignal-client version 0.52.5 +Requires libsignal-client version 0.56.0 ### Fixed diff --git a/graalvm-config-dir/reflect-config.json b/graalvm-config-dir/reflect-config.json index 0a65c68b..d38c8ed2 100644 --- a/graalvm-config-dir/reflect-config.json +++ b/graalvm-config-dir/reflect-config.json @@ -2143,7 +2143,7 @@ "allDeclaredFields":true, "allDeclaredMethods":true, "allDeclaredConstructors":true, - "methods":[{"name":"getAnnouncementGroup","parameterTypes":[] }, {"name":"getChangeNumber","parameterTypes":[] }, {"name":"getDeleteSync","parameterTypes":[] }, {"name":"getGiftBadges","parameterTypes":[] }, {"name":"getPaymentActivation","parameterTypes":[] }, {"name":"getPni","parameterTypes":[] }, {"name":"getSenderKey","parameterTypes":[] }, {"name":"getStorage","parameterTypes":[] }, {"name":"getStories","parameterTypes":[] }] + "methods":[{"name":"getAnnouncementGroup","parameterTypes":[] }, {"name":"getChangeNumber","parameterTypes":[] }, {"name":"getDeleteSync","parameterTypes":[] }, {"name":"getGiftBadges","parameterTypes":[] }, {"name":"getPaymentActivation","parameterTypes":[] }, {"name":"getPni","parameterTypes":[] }, {"name":"getSenderKey","parameterTypes":[] }, {"name":"getStorage","parameterTypes":[] }, {"name":"getStories","parameterTypes":[] }, {"name":"getVersionedExpirationTimer","parameterTypes":[] }] }, { "name":"org.whispersystems.signalservice.api.account.ChangePhoneNumberRequest", diff --git a/graalvm-config-dir/resource-config.json b/graalvm-config-dir/resource-config.json index 2c5463f7..eb97bf2f 100644 --- a/graalvm-config-dir/resource-config.json +++ b/graalvm-config-dir/resource-config.json @@ -184,6 +184,8 @@ "pattern":"\\Qlibsignal_jni.dylib\\E" }, { "pattern":"\\Qlibsignal_jni.so\\E" + }, { + "pattern":"\\Qlibsignal_jni_amd64.so\\E" }, { "pattern":"\\Qorg/asamk/signal/manager/config/ias.store\\E" }, { diff --git a/lib/src/main/java/org/asamk/signal/manager/config/ServiceConfig.java b/lib/src/main/java/org/asamk/signal/manager/config/ServiceConfig.java index 62aedaf6..2de70a53 100644 --- a/lib/src/main/java/org/asamk/signal/manager/config/ServiceConfig.java +++ b/lib/src/main/java/org/asamk/signal/manager/config/ServiceConfig.java @@ -28,7 +28,8 @@ public class ServiceConfig { public static AccountAttributes.Capabilities getCapabilities(boolean isPrimaryDevice) { final var deleteSync = !isPrimaryDevice; - return new AccountAttributes.Capabilities(true, deleteSync); + final var versionedExpirationTimer = !isPrimaryDevice; + return new AccountAttributes.Capabilities(true, deleteSync, versionedExpirationTimer); } public static ServiceEnvironmentConfig getServiceEnvironmentConfig( diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java index 0ec45cb9..5163c8fc 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java @@ -220,20 +220,30 @@ public class AccountHelper { final var messageSender = dependencies.getMessageSender(); for (final var deviceId : deviceIds) { // Signed Prekey - final var signedPreKeyRecord = KeyUtils.generateSignedPreKeyRecord(KeyUtils.getRandomInt(PREKEY_MAXIMUM_ID), - pniIdentity.getPrivateKey()); - final var signedPreKeyEntity = new SignedPreKeyEntity(signedPreKeyRecord.getId(), - signedPreKeyRecord.getKeyPair().getPublicKey(), - signedPreKeyRecord.getSignature()); - devicePniSignedPreKeys.put(deviceId, signedPreKeyEntity); + final SignedPreKeyRecord signedPreKeyRecord; + try { + signedPreKeyRecord = KeyUtils.generateSignedPreKeyRecord(KeyUtils.getRandomInt(PREKEY_MAXIMUM_ID), + pniIdentity.getPrivateKey()); + final var signedPreKeyEntity = new SignedPreKeyEntity(signedPreKeyRecord.getId(), + signedPreKeyRecord.getKeyPair().getPublicKey(), + signedPreKeyRecord.getSignature()); + devicePniSignedPreKeys.put(deviceId, signedPreKeyEntity); + } catch (InvalidKeyException e) { + throw new AssertionError("unexpected invalid key", e); + } // Last-resort kyber prekey - final var lastResortKyberPreKeyRecord = KeyUtils.generateKyberPreKeyRecord(KeyUtils.getRandomInt( - PREKEY_MAXIMUM_ID), pniIdentity.getPrivateKey()); - final var kyberPreKeyEntity = new KyberPreKeyEntity(lastResortKyberPreKeyRecord.getId(), - lastResortKyberPreKeyRecord.getKeyPair().getPublicKey(), - lastResortKyberPreKeyRecord.getSignature()); - devicePniLastResortKyberPreKeys.put(deviceId, kyberPreKeyEntity); + final KyberPreKeyRecord lastResortKyberPreKeyRecord; + try { + lastResortKyberPreKeyRecord = KeyUtils.generateKyberPreKeyRecord(KeyUtils.getRandomInt(PREKEY_MAXIMUM_ID), + pniIdentity.getPrivateKey()); + final var kyberPreKeyEntity = new KyberPreKeyEntity(lastResortKyberPreKeyRecord.getId(), + lastResortKyberPreKeyRecord.getKeyPair().getPublicKey(), + lastResortKyberPreKeyRecord.getSignature()); + devicePniLastResortKyberPreKeys.put(deviceId, kyberPreKeyEntity); + } catch (InvalidKeyException e) { + throw new AssertionError("unexpected invalid key", e); + } // Registration Id var pniRegistrationId = -1; diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/SyncHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/SyncHelper.java index 9af1f01f..efb48623 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/SyncHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/SyncHelper.java @@ -9,7 +9,6 @@ import org.asamk.signal.manager.storage.groups.GroupInfoV1; import org.asamk.signal.manager.storage.recipients.RecipientAddress; import org.asamk.signal.manager.storage.recipients.RecipientId; import org.asamk.signal.manager.storage.stickers.StickerPack; -import org.asamk.signal.manager.util.AttachmentUtils; import org.asamk.signal.manager.util.IOUtils; import org.asamk.signal.manager.util.MimeUtils; import org.jetbrains.annotations.NotNull; @@ -18,12 +17,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.signalservice.api.messages.SendMessageResult; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; -import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream; import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage; import org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage; import org.whispersystems.signalservice.api.messages.multidevice.ConfigurationMessage; import org.whispersystems.signalservice.api.messages.multidevice.ContactsMessage; import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact; +import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactAvatar; import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsInputStream; import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsOutputStream; import org.whispersystems.signalservice.api.messages.multidevice.DeviceGroup; @@ -170,7 +169,14 @@ public class SyncHelper { final var contact = contactPair.second(); final var address = account.getRecipientAddressResolver().resolveRecipientAddress(recipientId); - out.write(getDeviceContact(address, recipientId, contact)); + final var deviceContact = getDeviceContact(address, recipientId, contact); + out.write(deviceContact); + deviceContact.getAvatar().ifPresent(a -> { + try { + a.getInputStream().close(); + } catch (IOException ignored) { + } + }); } if (account.getProfileKey() != null) { @@ -178,7 +184,14 @@ public class SyncHelper { final var address = account.getSelfRecipientAddress(); final var recipientId = account.getSelfRecipientId(); final var contact = account.getContactStore().getContact(recipientId); - out.write(getDeviceContact(address, recipientId, contact)); + final var deviceContact = getDeviceContact(address, recipientId, contact); + out.write(deviceContact); + deviceContact.getAvatar().ifPresent(a -> { + try { + a.getInputStream().close(); + } catch (IOException ignored) { + } + }); } } @@ -234,6 +247,7 @@ public class SyncHelper { Optional.ofNullable(profileKey), Optional.ofNullable(contact == null ? null : contact.messageExpirationTime()), Optional.empty(), + Optional.empty(), contact != null && contact.isArchived()); } @@ -391,7 +405,7 @@ public class SyncHelper { account.getContactStore().storeContact(recipientId, builder.build()); if (c.getAvatar().isPresent()) { - downloadContactAvatar(c.getAvatar().get(), address); + storeContactAvatar(c.getAvatar().get(), address); } } } @@ -425,21 +439,22 @@ public class SyncHelper { return context.getSendHelper().sendSyncMessage(message); } - private Optional createContactAvatarAttachment(RecipientAddress address) throws IOException { + private Optional createContactAvatarAttachment(RecipientAddress address) throws IOException { final var streamDetails = context.getAvatarStore().retrieveContactAvatar(address); if (streamDetails == null) { return Optional.empty(); } - final var uploadSpec = context.getDependencies().getMessageSender().getResumableUploadSpec().toProto(); - return Optional.of(AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty(), uploadSpec)); + return Optional.of(new DeviceContactAvatar(streamDetails.getStream(), + streamDetails.getLength(), + streamDetails.getContentType())); } - private void downloadContactAvatar(SignalServiceAttachment avatar, RecipientAddress address) { + private void storeContactAvatar(DeviceContactAvatar avatar, RecipientAddress address) { try { context.getAvatarStore() .storeContactAvatar(address, - outputStream -> context.getAttachmentHelper().retrieveAttachment(avatar, outputStream)); + outputStream -> IOUtils.copyStream(avatar.getInputStream(), outputStream)); } catch (IOException e) { logger.warn("Failed to download avatar for contact {}, ignoring: {}", address, e.getMessage()); } diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/prekeys/SignedPreKeyStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/prekeys/SignedPreKeyStore.java index 0de10b13..d62e939d 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/prekeys/SignedPreKeyStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/prekeys/SignedPreKeyStore.java @@ -93,9 +93,13 @@ public class SignedPreKeyStore implements org.signal.libsignal.protocol.state.Si try (final var statement = connection.prepareStatement(sql)) { statement.setInt(1, accountIdType); statement.setInt(2, signedPreKeyId); - final var keyPair = record.getKeyPair(); - statement.setBytes(3, keyPair.getPublicKey().serialize()); - statement.setBytes(4, keyPair.getPrivateKey().serialize()); + try { + final var keyPair = record.getKeyPair(); + statement.setBytes(3, keyPair.getPublicKey().serialize()); + statement.setBytes(4, keyPair.getPrivateKey().serialize()); + } catch (InvalidKeyException e) { + throw new AssertionError("unexpected invalid key", e); + } statement.setBytes(5, record.getSignature()); statement.setLong(6, record.getTimestamp()); statement.executeUpdate(); @@ -193,9 +197,13 @@ public class SignedPreKeyStore implements org.signal.libsignal.protocol.state.Si for (final var record : signedPreKeys) { statement.setInt(1, accountIdType); statement.setInt(2, record.getId()); - final var keyPair = record.getKeyPair(); - statement.setBytes(3, keyPair.getPublicKey().serialize()); - statement.setBytes(4, keyPair.getPrivateKey().serialize()); + try { + final var keyPair = record.getKeyPair(); + statement.setBytes(3, keyPair.getPublicKey().serialize()); + statement.setBytes(4, keyPair.getPrivateKey().serialize()); + } catch (InvalidKeyException e) { + throw new AssertionError("unexpected invalid key", e); + } statement.setBytes(5, record.getSignature()); statement.setLong(6, record.getTimestamp()); statement.executeUpdate(); diff --git a/settings.gradle.kts b/settings.gradle.kts index e03e3059..95d5a87d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -15,7 +15,7 @@ dependencyResolutionManagement { library("slf4j.jul", "org.slf4j", "jul-to-slf4j").versionRef("slf4j") library("logback", "ch.qos.logback", "logback-classic").version("1.5.6") - library("signalservice", "com.github.turasa", "signal-service-java").version("2.15.3_unofficial_106") + library("signalservice", "com.github.turasa", "signal-service-java").version("2.15.3_unofficial_107") library("sqlite", "org.xerial", "sqlite-jdbc").version("3.46.0.0") library("hikari", "com.zaxxer", "HikariCP").version("5.1.0") library("junit.jupiter", "org.junit.jupiter", "junit-jupiter").version("5.10.2") diff --git a/src/main/java/org/asamk/signal/BaseConfig.java b/src/main/java/org/asamk/signal/BaseConfig.java index 6fd1b21e..ef4c4d7e 100644 --- a/src/main/java/org/asamk/signal/BaseConfig.java +++ b/src/main/java/org/asamk/signal/BaseConfig.java @@ -8,7 +8,7 @@ public class BaseConfig { public static final String PROJECT_VERSION = BaseConfig.class.getPackage().getImplementationVersion(); static final String USER_AGENT_SIGNAL_ANDROID = Optional.ofNullable(System.getenv("SIGNAL_CLI_USER_AGENT")) - .orElse("Signal-Android/7.14.1"); + .orElse("Signal-Android/7.16.2"); static final String USER_AGENT_SIGNAL_CLI = PROJECT_NAME == null ? "signal-cli" : PROJECT_NAME + "/" + PROJECT_VERSION; -- 2.50.1