From: AsamK Date: Thu, 13 May 2021 15:15:14 +0000 (+0200) Subject: Update libsignal-service-java X-Git-Tag: v0.8.4~43 X-Git-Url: https://git.nmode.ca/signal-cli/commitdiff_plain/06e9f8ba6403ea83ab3535a3b1eb900f252d8b9d?ds=inline Update libsignal-service-java --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 17044042..7515a984 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## [Unreleased] ## [0.8.3] - 2021-05-13 +**Attention**: Now requires native libsignal-client version 0.5.1 + ### Fixed - Upgrading from account files with older profiles - Building native image with graalvm diff --git a/graalvm-config-dir/jni-config.json b/graalvm-config-dir/jni-config.json index aeebbec8..bb19e040 100644 --- a/graalvm-config-dir/jni-config.json +++ b/graalvm-config-dir/jni-config.json @@ -56,13 +56,23 @@ "name":"org.whispersystems.libsignal.UntrustedIdentityException", "methods":[{"name":"","parameterTypes":["java.lang.String"] }] }, +{ + "name":"org.whispersystems.libsignal.logging.Log", + "methods":[{"name":"log","parameterTypes":["int","java.lang.String","java.lang.String"] }] +}, { "name":"org.whispersystems.libsignal.protocol.PreKeySignalMessage", - "methods":[{"name":"","parameterTypes":["long"] }] + "methods":[ + {"name":"","parameterTypes":["long"] }, + {"name":"nativeHandle","parameterTypes":[] } + ] }, { "name":"org.whispersystems.libsignal.protocol.SignalMessage", - "methods":[{"name":"","parameterTypes":["long"] }] + "methods":[ + {"name":"","parameterTypes":["long"] }, + {"name":"nativeHandle","parameterTypes":[] } + ] }, { "name":"org.whispersystems.libsignal.state.IdentityKeyStore" diff --git a/graalvm-config-dir/reflect-config.json b/graalvm-config-dir/reflect-config.json index 2c1aaf60..db7e24f6 100644 --- a/graalvm-config-dir/reflect-config.json +++ b/graalvm-config-dir/reflect-config.json @@ -1013,6 +1013,7 @@ "fields":[ {"name":"accessControl_", "allowUnsafeAccess":true}, {"name":"avatar_", "allowUnsafeAccess":true}, + {"name":"description_", "allowUnsafeAccess":true}, {"name":"disappearingMessagesTimer_", "allowUnsafeAccess":true}, {"name":"inviteLinkPassword_", "allowUnsafeAccess":true}, {"name":"members_", "allowUnsafeAccess":true}, @@ -1050,6 +1051,7 @@ {"name":"modifyAddFromInviteLinkAccess_", "allowUnsafeAccess":true}, {"name":"modifyAttributesAccess_", "allowUnsafeAccess":true}, {"name":"modifyAvatar_", "allowUnsafeAccess":true}, + {"name":"modifyDescription_", "allowUnsafeAccess":true}, {"name":"modifyDisappearingMessagesTimer_", "allowUnsafeAccess":true}, {"name":"modifyInviteLinkPassword_", "allowUnsafeAccess":true}, {"name":"modifyMemberAccess_", "allowUnsafeAccess":true}, @@ -1147,6 +1149,7 @@ "fields":[ {"name":"accessControl_", "allowUnsafeAccess":true}, {"name":"avatar_", "allowUnsafeAccess":true}, + {"name":"description_", "allowUnsafeAccess":true}, {"name":"disappearingMessagesTimer_", "allowUnsafeAccess":true}, {"name":"inviteLinkPassword_", "allowUnsafeAccess":true}, {"name":"members_", "allowUnsafeAccess":true}, @@ -1167,6 +1170,7 @@ {"name":"modifyMemberRoles_", "allowUnsafeAccess":true}, {"name":"newAttributeAccess_", "allowUnsafeAccess":true}, {"name":"newAvatar_", "allowUnsafeAccess":true}, + {"name":"newDescription_", "allowUnsafeAccess":true}, {"name":"newInviteLinkAccess_", "allowUnsafeAccess":true}, {"name":"newInviteLinkPassword_", "allowUnsafeAccess":true}, {"name":"newMemberAccess_", "allowUnsafeAccess":true}, @@ -1759,6 +1763,7 @@ {"name":"groupV2_", "allowUnsafeAccess":true}, {"name":"group_", "allowUnsafeAccess":true}, {"name":"isViewOnce_", "allowUnsafeAccess":true}, + {"name":"payment_", "allowUnsafeAccess":true}, {"name":"preview_", "allowUnsafeAccess":true}, {"name":"profileKey_", "allowUnsafeAccess":true}, {"name":"quote_", "allowUnsafeAccess":true}, @@ -1952,13 +1957,15 @@ {"name":"groups_", "allowUnsafeAccess":true}, {"name":"keys_", "allowUnsafeAccess":true}, {"name":"messageRequestResponse_", "allowUnsafeAccess":true}, + {"name":"outgoingPayment_", "allowUnsafeAccess":true}, {"name":"padding_", "allowUnsafeAccess":true}, {"name":"read_", "allowUnsafeAccess":true}, {"name":"request_", "allowUnsafeAccess":true}, {"name":"sent_", "allowUnsafeAccess":true}, {"name":"stickerPackOperation_", "allowUnsafeAccess":true}, {"name":"verified_", "allowUnsafeAccess":true}, - {"name":"viewOnceOpen_", "allowUnsafeAccess":true} + {"name":"viewOnceOpen_", "allowUnsafeAccess":true}, + {"name":"viewed_", "allowUnsafeAccess":true} ] }, { @@ -2038,6 +2045,15 @@ {"name":"type_", "allowUnsafeAccess":true} ] }, +{ + "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$SyncMessage$Viewed", + "fields":[ + {"name":"bitField0_", "allowUnsafeAccess":true}, + {"name":"senderE164_", "allowUnsafeAccess":true}, + {"name":"senderUuid_", "allowUnsafeAccess":true}, + {"name":"timestamp_", "allowUnsafeAccess":true} + ] +}, { "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$TypingMessage", "fields":[ diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index a9b5a95f..de3e9382 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -14,7 +14,7 @@ repositories { } dependencies { - api("com.github.turasa:signal-service-java:2.15.3_unofficial_21") + api("com.github.turasa:signal-service-java:2.15.3_unofficial_22") implementation("com.google.protobuf:protobuf-javalite:3.10.0") implementation("org.bouncycastle:bcprov-jdk15on:1.68") implementation("org.slf4j:slf4j-api:1.7.30") diff --git a/lib/src/main/java/org/asamk/signal/manager/Manager.java b/lib/src/main/java/org/asamk/signal/manager/Manager.java index 4d519c51..096f1c07 100644 --- a/lib/src/main/java/org/asamk/signal/manager/Manager.java +++ b/lib/src/main/java/org/asamk/signal/manager/Manager.java @@ -83,6 +83,7 @@ import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceMessagePipe; import org.whispersystems.signalservice.api.SignalServiceMessageReceiver; import org.whispersystems.signalservice.api.SignalServiceMessageSender; +import org.whispersystems.signalservice.api.SignalSessionLock; import org.whispersystems.signalservice.api.crypto.SignalServiceCipher; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations; @@ -161,6 +162,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; import java.util.stream.Collectors; @@ -193,6 +195,15 @@ public class Manager implements Closeable { private final PinHelper pinHelper; private final AvatarStore avatarStore; private final AttachmentStore attachmentStore; + private final SignalSessionLock sessionLock = new SignalSessionLock() { + private final ReentrantLock LEGACY_LOCK = new ReentrantLock(); + + @Override + public Lock acquire() { + LEGACY_LOCK.lock(); + return LEGACY_LOCK::unlock; + } + }; Manager( SignalAccount account, @@ -389,6 +400,7 @@ public class Manager implements Closeable { newProfile.getInternalServiceName(), newProfile.getAbout() == null ? "" : newProfile.getAbout(), newProfile.getAboutEmoji() == null ? "" : newProfile.getAboutEmoji(), + Optional.absent(), streamDetails); } @@ -534,6 +546,7 @@ public class Manager implements Closeable { account.getPassword(), account.getDeviceId(), account.getSignalProtocolStore(), + sessionLock, userAgent, account.isMultiDevice(), Optional.fromNullable(messagePipe), @@ -1511,18 +1524,12 @@ public class Manager implements Closeable { } } - private SignalServiceContent decryptMessage(SignalServiceEnvelope envelope) throws InvalidMetadataMessageException, ProtocolInvalidMessageException, ProtocolDuplicateMessageException, ProtocolLegacyMessageException, ProtocolInvalidKeyIdException, InvalidMetadataVersionException, ProtocolInvalidVersionException, ProtocolNoSessionException, ProtocolInvalidKeyException, SelfSendException, UnsupportedDataMessageException, org.whispersystems.libsignal.UntrustedIdentityException { + private SignalServiceContent decryptMessage(SignalServiceEnvelope envelope) throws InvalidMetadataMessageException, ProtocolInvalidMessageException, ProtocolDuplicateMessageException, ProtocolLegacyMessageException, ProtocolInvalidKeyIdException, InvalidMetadataVersionException, ProtocolInvalidVersionException, ProtocolNoSessionException, ProtocolInvalidKeyException, SelfSendException, UnsupportedDataMessageException, ProtocolUntrustedIdentityException { var cipher = new SignalServiceCipher(account.getSelfAddress(), account.getSignalProtocolStore(), + sessionLock, certificateValidator); - try { - return cipher.decrypt(envelope); - } catch (ProtocolUntrustedIdentityException e) { - if (e.getCause() instanceof org.whispersystems.libsignal.UntrustedIdentityException) { - throw (org.whispersystems.libsignal.UntrustedIdentityException) e.getCause(); - } - throw new AssertionError(e); - } + return cipher.decrypt(envelope); } private void handleEndSession(RecipientId recipientId) { @@ -1766,9 +1773,9 @@ public class Manager implements Closeable { if (!envelope.isReceipt()) { try { content = decryptMessage(envelope); - } catch (org.whispersystems.libsignal.UntrustedIdentityException e) { + } catch (ProtocolUntrustedIdentityException e) { if (!envelope.hasSource()) { - final var identifier = ((org.whispersystems.libsignal.UntrustedIdentityException) e).getName(); + final var identifier = e.getSender(); final var recipientId = resolveRecipient(identifier); try { account.getMessageCache().replaceSender(cachedMessage, recipientId); @@ -1889,8 +1896,8 @@ public class Manager implements Closeable { handler.handleMessage(envelope, content, exception); } if (cachedMessage[0] != null) { - if (exception instanceof org.whispersystems.libsignal.UntrustedIdentityException) { - final var identifier = ((org.whispersystems.libsignal.UntrustedIdentityException) exception).getName(); + if (exception instanceof ProtocolUntrustedIdentityException) { + final var identifier = ((ProtocolUntrustedIdentityException) exception).getSender(); final var recipientId = resolveRecipient(identifier); queuedActions.add(new RetrieveProfileAction(recipientId)); if (!envelope.hasSource()) { 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 4cf86537..c3314f75 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 @@ -51,7 +51,7 @@ public class ServiceConfig { public static boolean isSignalClientAvailable() { try { - org.signal.client.internal.Native.DisplayableFingerprint_Format(new byte[30], new byte[30]); + org.signal.client.internal.Native.DeviceTransfer_GeneratePrivateKey(); return true; } catch (UnsatisfiedLinkError ignored) { return false; diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/protocol/SignalProtocolStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/protocol/SignalProtocolStore.java index 1872e356..e308bb66 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/protocol/SignalProtocolStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/protocol/SignalProtocolStore.java @@ -4,6 +4,7 @@ import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKeyPair; import org.whispersystems.libsignal.InvalidKeyIdException; import org.whispersystems.libsignal.SignalProtocolAddress; +import org.whispersystems.libsignal.groups.state.SenderKeyRecord; import org.whispersystems.libsignal.state.IdentityKeyStore; import org.whispersystems.libsignal.state.PreKeyRecord; import org.whispersystems.libsignal.state.PreKeyStore; @@ -14,6 +15,7 @@ import org.whispersystems.signalservice.api.SignalServiceProtocolStore; import org.whispersystems.signalservice.api.SignalServiceSessionStore; import java.util.List; +import java.util.UUID; public class SignalProtocolStore implements SignalServiceProtocolStore { @@ -138,4 +140,15 @@ public class SignalProtocolStore implements SignalServiceProtocolStore { public void removeSignedPreKey(int signedPreKeyId) { signedPreKeyStore.removeSignedPreKey(signedPreKeyId); } + + @Override + public void storeSenderKey( + final SignalProtocolAddress sender, final UUID distributionId, final SenderKeyRecord record + ) { + } + + @Override + public SenderKeyRecord loadSenderKey(final SignalProtocolAddress sender, final UUID distributionId) { + return null; + } } diff --git a/lib/src/main/java/org/asamk/signal/manager/util/AttachmentUtils.java b/lib/src/main/java/org/asamk/signal/manager/util/AttachmentUtils.java index 1909711d..aadadf95 100644 --- a/lib/src/main/java/org/asamk/signal/manager/util/AttachmentUtils.java +++ b/lib/src/main/java/org/asamk/signal/manager/util/AttachmentUtils.java @@ -49,6 +49,7 @@ public class AttachmentUtils { name, false, false, + false, preview, 0, 0, diff --git a/lib/src/main/java/org/asamk/signal/manager/util/ProfileUtils.java b/lib/src/main/java/org/asamk/signal/manager/util/ProfileUtils.java index f865ab21..c2ab7a5e 100644 --- a/lib/src/main/java/org/asamk/signal/manager/util/ProfileUtils.java +++ b/lib/src/main/java/org/asamk/signal/manager/util/ProfileUtils.java @@ -18,9 +18,9 @@ public class ProfileUtils { ) { var profileCipher = new ProfileCipher(profileKey); try { - var name = decryptName(encryptedProfile.getName(), profileCipher); - var about = decryptName(encryptedProfile.getAbout(), profileCipher); - var aboutEmoji = decryptName(encryptedProfile.getAboutEmoji(), profileCipher); + var name = decrypt(encryptedProfile.getName(), profileCipher); + var about = decrypt(encryptedProfile.getAbout(), profileCipher); + var aboutEmoji = decrypt(encryptedProfile.getAboutEmoji(), profileCipher); final var nameParts = splitName(name); return new Profile(new Date().getTime(), @@ -66,13 +66,13 @@ public class ProfileUtils { return capabilities; } - private static String decryptName( + private static String decrypt( final String encryptedName, final ProfileCipher profileCipher ) throws InvalidCiphertextException { try { return encryptedName == null ? null - : new String(profileCipher.decryptName(Base64.getDecoder().decode(encryptedName))); + : new String(profileCipher.decrypt(Base64.getDecoder().decode(encryptedName))); } catch (IllegalArgumentException e) { return null; } diff --git a/src/main/java/org/asamk/signal/ReceiveMessageHandler.java b/src/main/java/org/asamk/signal/ReceiveMessageHandler.java index ce4f1068..e63ce548 100644 --- a/src/main/java/org/asamk/signal/ReceiveMessageHandler.java +++ b/src/main/java/org/asamk/signal/ReceiveMessageHandler.java @@ -5,8 +5,8 @@ import org.asamk.signal.manager.groups.GroupId; import org.asamk.signal.manager.groups.GroupUtils; import org.asamk.signal.util.DateUtils; import org.asamk.signal.util.Util; +import org.signal.libsignal.metadata.ProtocolUntrustedIdentityException; import org.slf4j.helpers.MessageFormatter; -import org.whispersystems.libsignal.UntrustedIdentityException; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; import org.whispersystems.signalservice.api.messages.SignalServiceContent; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; @@ -20,7 +20,6 @@ import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.InvalidNumberException; -import java.io.IOException; import java.util.Base64; import java.util.stream.Collectors; @@ -34,16 +33,6 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { @Override public void handleMessage(SignalServiceEnvelope envelope, SignalServiceContent content, Throwable exception) { - try { - printMessage(envelope, content, exception); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void printMessage( - SignalServiceEnvelope envelope, SignalServiceContent content, Throwable exception - ) throws IOException { PlainTextWriter writer = new PlainTextWriterImpl(System.out); if (envelope.hasSource()) { @@ -64,11 +53,11 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { writer.println("Got receipt."); } else if (envelope.isSignalMessage() || envelope.isPreKeySignalMessage() || envelope.isUnidentifiedSender()) { if (exception != null) { - if (exception instanceof UntrustedIdentityException) { - var e = (UntrustedIdentityException) exception; + if (exception instanceof ProtocolUntrustedIdentityException) { + var e = (ProtocolUntrustedIdentityException) exception; writer.println( "The user’s key is untrusted, either the user has reinstalled Signal or a third party sent this message."); - final var recipientName = m.resolveSignalServiceAddress(e.getName()).getLegacyIdentifier(); + final var recipientName = m.resolveSignalServiceAddress(e.getSender()).getLegacyIdentifier(); writer.println( "Use 'signal-cli -u {} listIdentities -n {}', verify the key and run 'signal-cli -u {} trust -v \"FINGER_PRINT\" {}' to mark it as trusted", m.getUsername(), @@ -127,7 +116,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { private void printDataMessage( PlainTextWriter writer, SignalServiceDataMessage message - ) throws IOException { + ) { writer.println("Message timestamp: {}", DateUtils.formatTimestamp(message.getTimestamp())); if (message.isViewOnce()) { writer.println("=VIEW ONCE="); @@ -210,7 +199,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { private void printTypingMessage( final PlainTextWriter writer, final SignalServiceTypingMessage typingMessage - ) throws IOException { + ) { writer.println("Action: {}", typingMessage.getAction()); writer.println("Timestamp: {}", DateUtils.formatTimestamp(typingMessage.getTimestamp())); if (typingMessage.getGroupId().isPresent()) { @@ -222,7 +211,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { private void printReceiptMessage( final PlainTextWriter writer, final SignalServiceReceiptMessage receiptMessage - ) throws IOException { + ) { writer.println("When: {}", DateUtils.formatTimestamp(receiptMessage.getWhen())); if (receiptMessage.isDeliveryReceipt()) { writer.println("Is delivery receipt"); @@ -241,7 +230,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { private void printCallMessage( final PlainTextWriter writer, final SignalServiceCallMessage callMessage - ) throws IOException { + ) { if (callMessage.getDestinationDeviceId().isPresent()) { final var deviceId = callMessage.getDestinationDeviceId().get(); writer.println("Destination device id: {}", deviceId); @@ -277,7 +266,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { private void printSyncMessage( final PlainTextWriter writer, final SignalServiceSyncMessage syncMessage - ) throws IOException { + ) { if (syncMessage.getContacts().isPresent()) { final var contactsMessage = syncMessage.getContacts().get(); var type = contactsMessage.isComplete() ? "complete" : "partial"; @@ -425,7 +414,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { private void printPreview( final PlainTextWriter writer, final SignalServiceDataMessage.Preview preview - ) throws IOException { + ) { writer.println("Title: {}", preview.getTitle()); writer.println("Description: {}", preview.getDescription()); writer.println("Date: {}", DateUtils.formatTimestamp(preview.getDate())); @@ -438,7 +427,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { private void printSticker( final PlainTextWriter writer, final SignalServiceDataMessage.Sticker sticker - ) throws IOException { + ) { writer.println("Pack id: {}", Base64.getEncoder().encodeToString(sticker.getPackId())); writer.println("Pack key: {}", Base64.getEncoder().encodeToString(sticker.getPackKey())); writer.println("Sticker id: {}", sticker.getStickerId()); @@ -448,7 +437,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { private void printReaction( final PlainTextWriter writer, final SignalServiceDataMessage.Reaction reaction - ) throws IOException { + ) { writer.println("Emoji: {}", reaction.getEmoji()); writer.println("Target author: {}", formatContact(m.resolveSignalServiceAddress(reaction.getTargetAuthor()))); writer.println("Target timestamp: {}", DateUtils.formatTimestamp(reaction.getTargetSentTimestamp())); @@ -457,7 +446,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { private void printQuote( final PlainTextWriter writer, final SignalServiceDataMessage.Quote quote - ) throws IOException { + ) { writer.println("Id: {}", quote.getId()); writer.println("Author: {}", m.resolveSignalServiceAddress(quote.getAuthor()).getLegacyIdentifier()); writer.println("Text: {}", quote.getText()); @@ -482,7 +471,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { } } - private void printSharedContact(final PlainTextWriter writer, final SharedContact contact) throws IOException { + private void printSharedContact(final PlainTextWriter writer, final SharedContact contact) { writer.println("Name:"); var name = contact.getName(); writer.indent(w -> { @@ -591,7 +580,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { private void printGroupContext( final PlainTextWriter writer, final SignalServiceGroupContext groupContext - ) throws IOException { + ) { final var groupId = GroupUtils.getGroupId(groupContext); if (groupContext.getGroupV1().isPresent()) { var groupInfo = groupContext.getGroupV1().get(); @@ -616,7 +605,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { } } - private void printGroupInfo(final PlainTextWriter writer, final GroupId groupId) throws IOException { + private void printGroupInfo(final PlainTextWriter writer, final GroupId groupId) { writer.println("Id: {}", groupId.toBase64()); var group = m.getGroup(groupId); @@ -629,7 +618,7 @@ public class ReceiveMessageHandler implements Manager.ReceiveMessageHandler { private void printMention( PlainTextWriter writer, SignalServiceDataMessage.Mention mention - ) throws IOException { + ) { final var address = m.resolveSignalServiceAddress(new SignalServiceAddress(mention.getUuid(), null)); writer.println("- {}: {} (length: {})", formatContact(address), mention.getStart(), mention.getLength()); }