Includ pni signatures if necessary

This commit is contained in:
AsamK 2024-02-18 16:31:34 +01:00
parent bd792f5b7f
commit 91ed49e019
4 changed files with 83 additions and 19 deletions

View file

@ -299,6 +299,12 @@ public final class IncomingMessageHandler {
final var senderDeviceId = senderDeviceAddress.deviceId(); final var senderDeviceId = senderDeviceAddress.deviceId();
final var destination = getDestination(envelope); final var destination = getDestination(envelope);
if (account.getPni().equals(destination.serviceId)) {
account.getRecipientStore().markNeedsPniSignature(destination.recipientId, true);
} else if (account.getAci().equals(destination.serviceId)) {
account.getRecipientStore().markNeedsPniSignature(destination.recipientId, false);
}
if (content.getReceiptMessage().isPresent()) { if (content.getReceiptMessage().isPresent()) {
final var message = content.getReceiptMessage().get(); final var message = content.getReceiptMessage().get();
if (message.isDeliveryReceipt()) { if (message.isDeliveryReceipt()) {

View file

@ -127,10 +127,10 @@ public class SendHelper {
) { ) {
final var messageSendLogStore = account.getMessageSendLogStore(); final var messageSendLogStore = account.getMessageSendLogStore();
final var result = handleSendMessage(recipientId, final var result = handleSendMessage(recipientId,
(messageSender, address, unidentifiedAccess) -> messageSender.sendReceipt(address, (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendReceipt(address,
unidentifiedAccess, unidentifiedAccess,
receiptMessage, receiptMessage,
false)); includePniSignature));
messageSendLogStore.insertIfPossible(receiptMessage.getWhen(), result, ContentHint.IMPLICIT, false); messageSendLogStore.insertIfPossible(receiptMessage.getWhen(), result, ContentHint.IMPLICIT, false);
handleSendMessageResult(result); handleSendMessageResult(result);
return result; return result;
@ -144,13 +144,14 @@ public class SendHelper {
.withProfileKey(profileKey) .withProfileKey(profileKey)
.build(); .build();
return handleSendMessage(recipientId, return handleSendMessage(recipientId,
(messageSender, address, unidentifiedAccess) -> messageSender.sendDataMessage(address, (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendDataMessage(
address,
unidentifiedAccess, unidentifiedAccess,
ContentHint.IMPLICIT, ContentHint.IMPLICIT,
message, message,
SignalServiceMessageSender.IndividualSendEvents.EMPTY, SignalServiceMessageSender.IndividualSendEvents.EMPTY,
false, false,
false)); includePniSignature));
} }
public SendMessageResult sendRetryReceipt( public SendMessageResult sendRetryReceipt(
@ -161,7 +162,8 @@ public class SendHelper {
recipientId, recipientId,
errorMessage.getDeviceId()); errorMessage.getDeviceId());
final var result = handleSendMessage(recipientId, final var result = handleSendMessage(recipientId,
(messageSender, address, unidentifiedAccess) -> messageSender.sendRetryReceipt(address, (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendRetryReceipt(
address,
unidentifiedAccess, unidentifiedAccess,
groupId.map(GroupId::serialize), groupId.map(GroupId::serialize),
errorMessage)); errorMessage));
@ -170,7 +172,10 @@ public class SendHelper {
} }
public SendMessageResult sendNullMessage(RecipientId recipientId) { public SendMessageResult sendNullMessage(RecipientId recipientId) {
final var result = handleSendMessage(recipientId, SignalServiceMessageSender::sendNullMessage); final var result = handleSendMessage(recipientId,
(messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendNullMessage(
address,
unidentifiedAccess));
handleSendMessageResult(result); handleSendMessageResult(result);
return result; return result;
} }
@ -220,10 +225,8 @@ public class SendHelper {
SignalServiceTypingMessage message, RecipientId recipientId SignalServiceTypingMessage message, RecipientId recipientId
) { ) {
final var result = handleSendMessage(recipientId, final var result = handleSendMessage(recipientId,
(messageSender, address, unidentifiedAccess) -> messageSender.sendTyping(List.of(address), (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendTyping(List.of(
List.of(unidentifiedAccess), address), List.of(unidentifiedAccess), message, null).getFirst());
message,
null).getFirst());
handleSendMessageResult(result); handleSendMessageResult(result);
return result; return result;
} }
@ -247,7 +250,8 @@ public class SendHelper {
logger.trace("Resending message {} to {}", timestamp, recipientId); logger.trace("Resending message {} to {}", timestamp, recipientId);
if (messageSendLogEntry.groupId().isEmpty()) { if (messageSendLogEntry.groupId().isEmpty()) {
return handleSendMessage(recipientId, return handleSendMessage(recipientId,
(messageSender, address, unidentifiedAccess) -> messageSender.resendContent(address, (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.resendContent(
address,
unidentifiedAccess, unidentifiedAccess,
timestamp, timestamp,
messageSendLogEntry.content(), messageSendLogEntry.content(),
@ -277,7 +281,7 @@ public class SendHelper {
.build(); .build();
final var result = handleSendMessage(recipientId, final var result = handleSendMessage(recipientId,
(messageSender, address, unidentifiedAccess) -> messageSender.resendContent(address, (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.resendContent(address,
unidentifiedAccess, unidentifiedAccess,
timestamp, timestamp,
contentToSend, contentToSend,
@ -660,17 +664,18 @@ public class SendHelper {
) { ) {
final var messageSendLogStore = account.getMessageSendLogStore(); final var messageSendLogStore = account.getMessageSendLogStore();
final var urgent = true; final var urgent = true;
final var includePniSignature = false;
final var result = handleSendMessage(recipientId, final var result = handleSendMessage(recipientId,
editTargetTimestamp.isEmpty() editTargetTimestamp.isEmpty()
? (messageSender, address, unidentifiedAccess) -> messageSender.sendDataMessage(address, ? (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendDataMessage(
address,
unidentifiedAccess, unidentifiedAccess,
ContentHint.RESENDABLE, ContentHint.RESENDABLE,
message, message,
SignalServiceMessageSender.IndividualSendEvents.EMPTY, SignalServiceMessageSender.IndividualSendEvents.EMPTY,
urgent, urgent,
includePniSignature) includePniSignature)
: (messageSender, address, unidentifiedAccess) -> messageSender.sendEditMessage(address, : (messageSender, address, unidentifiedAccess, includePniSignature) -> messageSender.sendEditMessage(
address,
unidentifiedAccess, unidentifiedAccess,
ContentHint.RESENDABLE, ContentHint.RESENDABLE,
message, message,
@ -687,8 +692,12 @@ public class SendHelper {
var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId); var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId);
try { try {
final boolean includePniSignature = account.getRecipientStore().needsPniSignature(recipientId);
try { try {
return s.send(messageSender, address, context.getUnidentifiedAccessHelper().getAccessFor(recipientId)); return s.send(messageSender,
address,
context.getUnidentifiedAccessHelper().getAccessFor(recipientId),
includePniSignature);
} catch (UnregisteredUserException e) { } catch (UnregisteredUserException e) {
final RecipientId newRecipientId; final RecipientId newRecipientId;
try { try {
@ -699,7 +708,8 @@ public class SendHelper {
address = context.getRecipientHelper().resolveSignalServiceAddress(newRecipientId); address = context.getRecipientHelper().resolveSignalServiceAddress(newRecipientId);
return s.send(messageSender, return s.send(messageSender,
address, address,
context.getUnidentifiedAccessHelper().getAccessFor(newRecipientId)); context.getUnidentifiedAccessHelper().getAccessFor(newRecipientId),
includePniSignature);
} }
} catch (UnregisteredUserException e) { } catch (UnregisteredUserException e) {
return SendMessageResult.unregisteredFailure(address); return SendMessageResult.unregisteredFailure(address);
@ -774,7 +784,8 @@ public class SendHelper {
SendMessageResult send( SendMessageResult send(
SignalServiceMessageSender messageSender, SignalServiceMessageSender messageSender,
SignalServiceAddress address, SignalServiceAddress address,
Optional<UnidentifiedAccessPair> unidentifiedAccess Optional<UnidentifiedAccessPair> unidentifiedAccess,
boolean includePniSignature
) throws IOException, UnregisteredUserException, ProofRequiredException, RateLimitException, org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; ) throws IOException, UnregisteredUserException, ProofRequiredException, RateLimitException, org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
} }

View file

@ -33,7 +33,7 @@ import java.util.UUID;
public class AccountDatabase extends Database { public class AccountDatabase extends Database {
private static final Logger logger = LoggerFactory.getLogger(AccountDatabase.class); private static final Logger logger = LoggerFactory.getLogger(AccountDatabase.class);
private static final long DATABASE_VERSION = 23; private static final long DATABASE_VERSION = 24;
private AccountDatabase(final HikariDataSource dataSource) { private AccountDatabase(final HikariDataSource dataSource) {
super(logger, DATABASE_VERSION, dataSource); super(logger, DATABASE_VERSION, dataSource);
@ -573,6 +573,14 @@ public class AccountDatabase extends Database {
"""); """);
} }
} }
if (oldVersion < 24) {
logger.debug("Updating database: Create needs_pni_signature column");
try (final var statement = connection.createStatement()) {
statement.executeUpdate("""
ALTER TABLE recipient ADD needs_pni_signature INTEGER NOT NULL DEFAULT FALSE;
""");
}
}
} }
private static void createUuidMappingTable( private static void createUuidMappingTable(

View file

@ -66,6 +66,7 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
unregistered_timestamp INTEGER, unregistered_timestamp INTEGER,
profile_key BLOB, profile_key BLOB,
profile_key_credential BLOB, profile_key_credential BLOB,
needs_pni_signature INTEGER NOT NULL DEFAULT FALSE,
given_name TEXT, given_name TEXT,
family_name TEXT, family_name TEXT,
@ -856,6 +857,44 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
return count; return count;
} }
public void markNeedsPniSignature(final RecipientId recipientId, final boolean value) {
logger.debug("Marking {} numbers as need pni signature = {}", recipientId, value);
try (final var connection = database.getConnection()) {
final var sql = (
"""
UPDATE %s
SET needs_pni_signature = ?
WHERE _id = ?
"""
).formatted(TABLE_RECIPIENT);
try (final var statement = connection.prepareStatement(sql)) {
statement.setBoolean(1, value);
statement.setLong(2, recipientId.id());
statement.executeUpdate();
}
} catch (SQLException e) {
throw new RuntimeException("Failed update recipient store", e);
}
}
public boolean needsPniSignature(final RecipientId recipientId) {
try (final var connection = database.getConnection()) {
final var sql = (
"""
SELECT needs_pni_signature
FROM %s
WHERE _id = ?
"""
).formatted(TABLE_RECIPIENT);
try (final var statement = connection.prepareStatement(sql)) {
statement.setLong(1, recipientId.id());
return Utils.executeQuerySingleRow(statement, resultSet -> resultSet.getBoolean("needs_pni_signature"));
}
} catch (SQLException e) {
throw new RuntimeException("Failed read recipient store", e);
}
}
public void markUnregistered(final Set<String> unregisteredUsers) { public void markUnregistered(final Set<String> unregisteredUsers) {
logger.debug("Marking {} numbers as unregistered", unregisteredUsers.size()); logger.debug("Marking {} numbers as unregistered", unregisteredUsers.size());
try (final var connection = database.getConnection()) { try (final var connection = database.getConnection()) {