mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 10:30:38 +00:00
Reduce use of unknown serviceIds
This commit is contained in:
parent
22c948166a
commit
780c69d804
11 changed files with 110 additions and 83 deletions
|
@ -676,14 +676,17 @@ class ManagerImpl implements Manager {
|
||||||
var delete = new SignalServiceDataMessage.RemoteDelete(targetSentTimestamp);
|
var delete = new SignalServiceDataMessage.RemoteDelete(targetSentTimestamp);
|
||||||
final var messageBuilder = SignalServiceDataMessage.newBuilder().withRemoteDelete(delete);
|
final var messageBuilder = SignalServiceDataMessage.newBuilder().withRemoteDelete(delete);
|
||||||
for (final var recipient : recipients) {
|
for (final var recipient : recipients) {
|
||||||
if (recipient instanceof RecipientIdentifier.Single r) {
|
if (recipient instanceof RecipientIdentifier.Uuid u) {
|
||||||
|
account.getMessageSendLogStore()
|
||||||
|
.deleteEntryForRecipientNonGroup(targetSentTimestamp, ServiceId.from(u.uuid()));
|
||||||
|
} else if (recipient instanceof RecipientIdentifier.Single r) {
|
||||||
try {
|
try {
|
||||||
final var recipientId = context.getRecipientHelper().resolveRecipient(r);
|
final var recipientId = context.getRecipientHelper().resolveRecipient(r);
|
||||||
account.getMessageSendLogStore()
|
final var address = account.getRecipientAddressResolver().resolveRecipientAddress(recipientId);
|
||||||
.deleteEntryForRecipientNonGroup(targetSentTimestamp,
|
if (address.serviceId().isPresent()) {
|
||||||
account.getRecipientAddressResolver()
|
account.getMessageSendLogStore()
|
||||||
.resolveRecipientAddress(recipientId)
|
.deleteEntryForRecipientNonGroup(targetSentTimestamp, address.serviceId().get());
|
||||||
.getServiceId());
|
}
|
||||||
} catch (UnregisteredRecipientException ignored) {
|
} catch (UnregisteredRecipientException ignored) {
|
||||||
}
|
}
|
||||||
} else if (recipient instanceof RecipientIdentifier.Group r) {
|
} else if (recipient instanceof RecipientIdentifier.Group r) {
|
||||||
|
@ -749,8 +752,10 @@ class ManagerImpl implements Manager {
|
||||||
final var serviceId = context.getAccount()
|
final var serviceId = context.getAccount()
|
||||||
.getRecipientAddressResolver()
|
.getRecipientAddressResolver()
|
||||||
.resolveRecipientAddress(recipientId)
|
.resolveRecipientAddress(recipientId)
|
||||||
.getServiceId();
|
.serviceId();
|
||||||
account.getAciSessionStore().deleteAllSessions(serviceId);
|
if (serviceId.isPresent()) {
|
||||||
|
account.getAciSessionStore().deleteAllSessions(serviceId.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1131,9 +1136,12 @@ class ManagerImpl implements Manager {
|
||||||
public List<Identity> getIdentities(RecipientIdentifier.Single recipient) {
|
public List<Identity> getIdentities(RecipientIdentifier.Single recipient) {
|
||||||
ServiceId serviceId;
|
ServiceId serviceId;
|
||||||
try {
|
try {
|
||||||
serviceId = account.getRecipientAddressResolver()
|
final var address = account.getRecipientAddressResolver()
|
||||||
.resolveRecipientAddress(context.getRecipientHelper().resolveRecipient(recipient))
|
.resolveRecipientAddress(context.getRecipientHelper().resolveRecipient(recipient));
|
||||||
.getServiceId();
|
if (address.serviceId().isEmpty()) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
serviceId = address.serviceId().get();
|
||||||
} catch (UnregisteredRecipientException e) {
|
} catch (UnregisteredRecipientException e) {
|
||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,10 +39,6 @@ public record RecipientAddress(Optional<UUID> uuid, Optional<String> number, Opt
|
||||||
this(Optional.of(uuid), Optional.empty(), Optional.empty());
|
this(Optional.of(uuid), Optional.empty(), Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceId getServiceId() {
|
|
||||||
return ServiceId.from(uuid.orElse(UNKNOWN_UUID));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIdentifier() {
|
public String getIdentifier() {
|
||||||
if (uuid.isPresent()) {
|
if (uuid.isPresent()) {
|
||||||
return uuid.get().toString();
|
return uuid.get().toString();
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.asamk.signal.manager.helper;
|
||||||
|
|
||||||
import org.asamk.signal.manager.api.TrustLevel;
|
import org.asamk.signal.manager.api.TrustLevel;
|
||||||
import org.asamk.signal.manager.storage.SignalAccount;
|
import org.asamk.signal.manager.storage.SignalAccount;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||||
import org.asamk.signal.manager.util.Utils;
|
import org.asamk.signal.manager.util.Utils;
|
||||||
import org.signal.libsignal.protocol.IdentityKey;
|
import org.signal.libsignal.protocol.IdentityKey;
|
||||||
|
@ -17,7 +16,7 @@ import org.whispersystems.signalservice.api.push.ServiceId;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.function.Function;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import static org.asamk.signal.manager.config.ServiceConfig.capabilities;
|
import static org.asamk.signal.manager.config.ServiceConfig.capabilities;
|
||||||
|
|
||||||
|
@ -34,22 +33,19 @@ public class IdentityHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean trustIdentityVerified(RecipientId recipientId, byte[] fingerprint) {
|
public boolean trustIdentityVerified(RecipientId recipientId, byte[] fingerprint) {
|
||||||
final var serviceId = account.getRecipientAddressResolver().resolveRecipientAddress(recipientId).getServiceId();
|
return trustIdentity(recipientId,
|
||||||
return trustIdentity(serviceId,
|
(serviceId, identityKey) -> Arrays.equals(identityKey.serialize(), fingerprint),
|
||||||
identityKey -> Arrays.equals(identityKey.serialize(), fingerprint),
|
|
||||||
TrustLevel.TRUSTED_VERIFIED);
|
TrustLevel.TRUSTED_VERIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean trustIdentityVerifiedSafetyNumber(RecipientId recipientId, String safetyNumber) {
|
public boolean trustIdentityVerifiedSafetyNumber(RecipientId recipientId, String safetyNumber) {
|
||||||
final var serviceId = account.getRecipientAddressResolver().resolveRecipientAddress(recipientId).getServiceId();
|
return trustIdentity(recipientId,
|
||||||
return trustIdentity(serviceId,
|
(serviceId, identityKey) -> safetyNumber.equals(computeSafetyNumber(serviceId, identityKey)),
|
||||||
identityKey -> safetyNumber.equals(computeSafetyNumber(serviceId, identityKey)),
|
|
||||||
TrustLevel.TRUSTED_VERIFIED);
|
TrustLevel.TRUSTED_VERIFIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean trustIdentityVerifiedSafetyNumber(RecipientId recipientId, byte[] safetyNumber) {
|
public boolean trustIdentityVerifiedSafetyNumber(RecipientId recipientId, byte[] safetyNumber) {
|
||||||
final var serviceId = account.getRecipientAddressResolver().resolveRecipientAddress(recipientId).getServiceId();
|
return trustIdentity(recipientId, (serviceId, identityKey) -> {
|
||||||
return trustIdentity(serviceId, identityKey -> {
|
|
||||||
final var fingerprint = computeSafetyNumberForScanning(serviceId, identityKey);
|
final var fingerprint = computeSafetyNumberForScanning(serviceId, identityKey);
|
||||||
try {
|
try {
|
||||||
return fingerprint != null && fingerprint.compareTo(safetyNumber);
|
return fingerprint != null && fingerprint.compareTo(safetyNumber);
|
||||||
|
@ -60,8 +56,7 @@ public class IdentityHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean trustIdentityAllKeys(RecipientId recipientId) {
|
public boolean trustIdentityAllKeys(RecipientId recipientId) {
|
||||||
final var serviceId = account.getRecipientAddressResolver().resolveRecipientAddress(recipientId).getServiceId();
|
return trustIdentity(recipientId, (serviceId, identityKey) -> true, TrustLevel.TRUSTED_UNVERIFIED);
|
||||||
return trustIdentity(serviceId, identityKey -> true, TrustLevel.TRUSTED_UNVERIFIED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String computeSafetyNumber(ServiceId serviceId, IdentityKey theirIdentityKey) {
|
public String computeSafetyNumber(ServiceId serviceId, IdentityKey theirIdentityKey) {
|
||||||
|
@ -77,35 +72,50 @@ public class IdentityHelper {
|
||||||
private Fingerprint computeSafetyNumberFingerprint(
|
private Fingerprint computeSafetyNumberFingerprint(
|
||||||
final ServiceId serviceId, final IdentityKey theirIdentityKey
|
final ServiceId serviceId, final IdentityKey theirIdentityKey
|
||||||
) {
|
) {
|
||||||
final var address = account.getRecipientAddressResolver()
|
final var recipientId = account.getRecipientResolver().resolveRecipient(serviceId);
|
||||||
.resolveRecipientAddress(account.getRecipientResolver().resolveRecipient(serviceId));
|
final var address = account.getRecipientAddressResolver().resolveRecipientAddress(recipientId);
|
||||||
|
|
||||||
return Utils.computeSafetyNumber(capabilities.getUuid(),
|
if (capabilities.getUuid()) {
|
||||||
account.getSelfRecipientAddress(),
|
if (serviceId.isUnknown()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Utils.computeSafetyNumberForUuid(account.getAci(),
|
||||||
|
account.getAciIdentityKeyPair().getPublicKey(),
|
||||||
|
serviceId,
|
||||||
|
theirIdentityKey);
|
||||||
|
}
|
||||||
|
if (address.number().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Utils.computeSafetyNumberForNumber(account.getNumber(),
|
||||||
account.getAciIdentityKeyPair().getPublicKey(),
|
account.getAciIdentityKeyPair().getPublicKey(),
|
||||||
address.getServiceId().equals(serviceId)
|
address.number().get(),
|
||||||
? address
|
|
||||||
: new RecipientAddress(serviceId, address.number().orElse(null)),
|
|
||||||
theirIdentityKey);
|
theirIdentityKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean trustIdentity(
|
private boolean trustIdentity(
|
||||||
ServiceId serviceId, Function<IdentityKey, Boolean> verifier, TrustLevel trustLevel
|
RecipientId recipientId, BiFunction<ServiceId, IdentityKey, Boolean> verifier, TrustLevel trustLevel
|
||||||
) {
|
) {
|
||||||
|
final var serviceId = account.getRecipientAddressResolver()
|
||||||
|
.resolveRecipientAddress(recipientId)
|
||||||
|
.serviceId()
|
||||||
|
.orElse(null);
|
||||||
|
if (serviceId == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
var identity = account.getIdentityKeyStore().getIdentityInfo(serviceId);
|
var identity = account.getIdentityKeyStore().getIdentityInfo(serviceId);
|
||||||
if (identity == null) {
|
if (identity == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!verifier.apply(identity.getIdentityKey())) {
|
if (!verifier.apply(serviceId, identity.getIdentityKey())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
account.getIdentityKeyStore().setIdentityTrustLevel(serviceId, identity.getIdentityKey(), trustLevel);
|
account.getIdentityKeyStore().setIdentityTrustLevel(serviceId, identity.getIdentityKey(), trustLevel);
|
||||||
try {
|
try {
|
||||||
final var address = account.getRecipientAddressResolver()
|
final var address = context.getRecipientHelper()
|
||||||
.resolveRecipientAddress(account.getRecipientResolver().resolveRecipient(serviceId))
|
.resolveSignalServiceAddress(account.getRecipientResolver().resolveRecipient(serviceId));
|
||||||
.toSignalServiceAddress();
|
|
||||||
context.getSyncHelper().sendVerifiedMessage(address, identity.getIdentityKey(), trustLevel);
|
context.getSyncHelper().sendVerifiedMessage(address, identity.getIdentityKey(), trustLevel);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to send verification sync message: {}", e.getMessage());
|
logger.warn("Failed to send verification sync message: {}", e.getMessage());
|
||||||
|
|
|
@ -12,6 +12,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.whispersystems.signalservice.api.SignalWebSocket;
|
import org.whispersystems.signalservice.api.SignalWebSocket;
|
||||||
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
|
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
|
||||||
|
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||||
import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState;
|
import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState;
|
||||||
import org.whispersystems.signalservice.api.websocket.WebSocketUnavailableException;
|
import org.whispersystems.signalservice.api.websocket.WebSocketUnavailableException;
|
||||||
|
|
||||||
|
@ -225,8 +226,9 @@ public class ReceiveHelper {
|
||||||
if (exception instanceof UntrustedIdentityException) {
|
if (exception instanceof UntrustedIdentityException) {
|
||||||
logger.debug("Keeping message with untrusted identity in message cache");
|
logger.debug("Keeping message with untrusted identity in message cache");
|
||||||
final var address = ((UntrustedIdentityException) exception).getSender();
|
final var address = ((UntrustedIdentityException) exception).getSender();
|
||||||
final var recipientId = account.getRecipientResolver().resolveRecipient(address.getServiceId());
|
if (!envelope.hasSourceUuid() && address.uuid().isPresent()) {
|
||||||
if (!envelope.hasSourceUuid()) {
|
final var recipientId = account.getRecipientResolver()
|
||||||
|
.resolveRecipient(ServiceId.from(address.uuid().get()));
|
||||||
try {
|
try {
|
||||||
cachedMessage[0] = account.getMessageCache().replaceSender(cachedMessage[0], recipientId);
|
cachedMessage[0] = account.getMessageCache().replaceSender(cachedMessage[0], recipientId);
|
||||||
} catch (IOException ioException) {
|
} catch (IOException ioException) {
|
||||||
|
|
|
@ -182,8 +182,8 @@ public class RecipientHelper {
|
||||||
public record RegisteredUser(Optional<ACI> aci, Optional<PNI> pni) {
|
public record RegisteredUser(Optional<ACI> aci, Optional<PNI> pni) {
|
||||||
|
|
||||||
public RegisteredUser {
|
public RegisteredUser {
|
||||||
aci = aci.isPresent() && aci.get().equals(ServiceId.UNKNOWN) ? Optional.empty() : aci;
|
aci = aci.isPresent() && aci.get().isUnknown() ? Optional.empty() : aci;
|
||||||
pni = pni.isPresent() && pni.get().equals(ServiceId.UNKNOWN) ? Optional.empty() : pni;
|
pni = pni.isPresent() && pni.get().isUnknown() ? Optional.empty() : pni;
|
||||||
if (aci.isEmpty() && pni.isEmpty()) {
|
if (aci.isEmpty() && pni.isEmpty()) {
|
||||||
throw new AssertionError("Must have either a ACI or PNI!");
|
throw new AssertionError("Must have either a ACI or PNI!");
|
||||||
}
|
}
|
||||||
|
|
|
@ -492,7 +492,11 @@ public class SendHelper {
|
||||||
|
|
||||||
final var serviceId = account.getRecipientAddressResolver()
|
final var serviceId = account.getRecipientAddressResolver()
|
||||||
.resolveRecipientAddress(recipientId)
|
.resolveRecipientAddress(recipientId)
|
||||||
.getServiceId();
|
.serviceId()
|
||||||
|
.orElse(null);
|
||||||
|
if (serviceId == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
final var identity = account.getIdentityKeyStore().getIdentityInfo(serviceId);
|
final var identity = account.getIdentityKeyStore().getIdentityInfo(serviceId);
|
||||||
if (identity == null || !identity.getTrustLevel().isTrusted()) {
|
if (identity == null || !identity.getTrustLevel().isTrusted()) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -101,11 +101,15 @@ public class StorageHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
final var contactRecord = record.getContact().get();
|
final var contactRecord = record.getContact().get();
|
||||||
final var address = new RecipientAddress(contactRecord.getServiceId(), contactRecord.getNumber().orElse(null));
|
final var serviceId = contactRecord.getServiceId();
|
||||||
|
if (contactRecord.getNumber().isEmpty() && serviceId.isUnknown()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final var address = new RecipientAddress(serviceId, contactRecord.getNumber().orElse(null));
|
||||||
var recipientId = account.getRecipientResolver().resolveRecipient(address);
|
var recipientId = account.getRecipientResolver().resolveRecipient(address);
|
||||||
if (contactRecord.getUsername().isPresent()) {
|
if (serviceId.isValid() && contactRecord.getUsername().isPresent()) {
|
||||||
recipientId = account.getRecipientTrustedResolver()
|
recipientId = account.getRecipientTrustedResolver()
|
||||||
.resolveRecipientTrusted(contactRecord.getServiceId(), contactRecord.getUsername().get());
|
.resolveRecipientTrusted(serviceId, contactRecord.getUsername().get());
|
||||||
}
|
}
|
||||||
|
|
||||||
final var contact = account.getContactStore().getContact(recipientId);
|
final var contact = account.getContactStore().getContact(recipientId);
|
||||||
|
@ -166,16 +170,15 @@ public class StorageHelper {
|
||||||
logger.warn("Received invalid contact profile key from storage");
|
logger.warn("Received invalid contact profile key from storage");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (contactRecord.getIdentityKey().isPresent()) {
|
if (contactRecord.getIdentityKey().isPresent() && serviceId.isValid()) {
|
||||||
try {
|
try {
|
||||||
logger.trace("Storing identity key {}", recipientId);
|
logger.trace("Storing identity key {}", recipientId);
|
||||||
final var identityKey = new IdentityKey(contactRecord.getIdentityKey().get());
|
final var identityKey = new IdentityKey(contactRecord.getIdentityKey().get());
|
||||||
account.getIdentityKeyStore().saveIdentity(address.getServiceId(), identityKey);
|
account.getIdentityKeyStore().saveIdentity(serviceId, identityKey);
|
||||||
|
|
||||||
final var trustLevel = TrustLevel.fromIdentityState(contactRecord.getIdentityState());
|
final var trustLevel = TrustLevel.fromIdentityState(contactRecord.getIdentityState());
|
||||||
if (trustLevel != null) {
|
if (trustLevel != null) {
|
||||||
account.getIdentityKeyStore()
|
account.getIdentityKeyStore().setIdentityTrustLevel(serviceId, identityKey, trustLevel);
|
||||||
.setIdentityTrustLevel(address.getServiceId(), identityKey, trustLevel);
|
|
||||||
}
|
}
|
||||||
} catch (InvalidKeyException e) {
|
} catch (InvalidKeyException e) {
|
||||||
logger.warn("Received invalid contact identity key from storage");
|
logger.warn("Received invalid contact identity key from storage");
|
||||||
|
|
|
@ -813,7 +813,7 @@ public class SignalAccount implements Closeable {
|
||||||
if (identity.getAddress().serviceId().isEmpty()) {
|
if (identity.getAddress().serviceId().isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final var serviceId = identity.getAddress().getServiceId();
|
final var serviceId = identity.getAddress().serviceId().get();
|
||||||
getIdentityKeyStore().saveIdentity(serviceId, identity.getIdentityKey());
|
getIdentityKeyStore().saveIdentity(serviceId, identity.getIdentityKey());
|
||||||
getIdentityKeyStore().setIdentityTrustLevel(serviceId,
|
getIdentityKeyStore().setIdentityTrustLevel(serviceId,
|
||||||
identity.getIdentityKey(),
|
identity.getIdentityKey(),
|
||||||
|
|
|
@ -72,6 +72,10 @@ public class LegacyIdentityKeyStore {
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
final var address = addressResolver.resolveRecipientAddress(recipientId);
|
||||||
|
if (address.serviceId().isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
try (var inputStream = new FileInputStream(file)) {
|
try (var inputStream = new FileInputStream(file)) {
|
||||||
var storage = objectMapper.readValue(inputStream, IdentityStorage.class);
|
var storage = objectMapper.readValue(inputStream, IdentityStorage.class);
|
||||||
|
|
||||||
|
@ -79,7 +83,7 @@ public class LegacyIdentityKeyStore {
|
||||||
var trustLevel = TrustLevel.fromInt(storage.trustLevel());
|
var trustLevel = TrustLevel.fromInt(storage.trustLevel());
|
||||||
var added = storage.addedTimestamp();
|
var added = storage.addedTimestamp();
|
||||||
|
|
||||||
final var serviceId = addressResolver.resolveRecipientAddress(recipientId).getServiceId();
|
final var serviceId = address.serviceId().get();
|
||||||
return new IdentityInfo(serviceId, id, trustLevel, added);
|
return new IdentityInfo(serviceId, id, trustLevel, added);
|
||||||
} catch (IOException | InvalidKeyException e) {
|
} catch (IOException | InvalidKeyException e) {
|
||||||
logger.warn("Failed to load identity key: {}", e.getMessage());
|
logger.warn("Failed to load identity key: {}", e.getMessage());
|
||||||
|
|
|
@ -17,10 +17,10 @@ public record RecipientAddress(
|
||||||
* @param number The phone number of the user, if available.
|
* @param number The phone number of the user, if available.
|
||||||
*/
|
*/
|
||||||
public RecipientAddress {
|
public RecipientAddress {
|
||||||
if (serviceId.isPresent() && serviceId.get().equals(ServiceId.UNKNOWN)) {
|
if (serviceId.isPresent() && serviceId.get().isUnknown()) {
|
||||||
serviceId = Optional.empty();
|
serviceId = Optional.empty();
|
||||||
}
|
}
|
||||||
if (pni.isPresent() && pni.get().equals(ServiceId.UNKNOWN)) {
|
if (pni.isPresent() && pni.get().isUnknown()) {
|
||||||
pni = Optional.empty();
|
pni = Optional.empty();
|
||||||
}
|
}
|
||||||
if (serviceId.isEmpty() && pni.isPresent()) {
|
if (serviceId.isEmpty() && pni.isPresent()) {
|
||||||
|
@ -88,10 +88,6 @@ public record RecipientAddress(
|
||||||
address.username.equals(this.username) ? Optional.empty() : this.username);
|
address.username.equals(this.username) ? Optional.empty() : this.username);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServiceId getServiceId() {
|
|
||||||
return serviceId.orElse(ServiceId.UNKNOWN);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIdentifier() {
|
public String getIdentifier() {
|
||||||
if (serviceId.isPresent()) {
|
if (serviceId.isPresent()) {
|
||||||
return serviceId.get().toString();
|
return serviceId.get().toString();
|
||||||
|
@ -173,7 +169,7 @@ public record RecipientAddress(
|
||||||
}
|
}
|
||||||
|
|
||||||
public SignalServiceAddress toSignalServiceAddress() {
|
public SignalServiceAddress toSignalServiceAddress() {
|
||||||
return new SignalServiceAddress(getServiceId(), number);
|
return new SignalServiceAddress(serviceId.orElse(ServiceId.UNKNOWN), number);
|
||||||
}
|
}
|
||||||
|
|
||||||
public org.asamk.signal.manager.api.RecipientAddress toApiRecipientAddress() {
|
public org.asamk.signal.manager.api.RecipientAddress toApiRecipientAddress() {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package org.asamk.signal.manager.util;
|
package org.asamk.signal.manager.util;
|
||||||
|
|
||||||
import org.asamk.signal.manager.api.Pair;
|
import org.asamk.signal.manager.api.Pair;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
|
|
||||||
import org.signal.libsignal.protocol.IdentityKey;
|
import org.signal.libsignal.protocol.IdentityKey;
|
||||||
import org.signal.libsignal.protocol.fingerprint.Fingerprint;
|
import org.signal.libsignal.protocol.fingerprint.Fingerprint;
|
||||||
import org.signal.libsignal.protocol.fingerprint.NumericFingerprintGenerator;
|
import org.signal.libsignal.protocol.fingerprint.NumericFingerprintGenerator;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||||
import org.whispersystems.signalservice.api.util.StreamDetails;
|
import org.whispersystems.signalservice.api.util.StreamDetails;
|
||||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||||
|
|
||||||
|
@ -56,31 +56,35 @@ public class Utils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Fingerprint computeSafetyNumber(
|
public static Fingerprint computeSafetyNumberForNumber(
|
||||||
boolean isUuidCapable,
|
String ownNumber, IdentityKey ownIdentityKey, String theirNumber, IdentityKey theirIdentityKey
|
||||||
RecipientAddress ownAddress,
|
|
||||||
IdentityKey ownIdentityKey,
|
|
||||||
RecipientAddress theirAddress,
|
|
||||||
IdentityKey theirIdentityKey
|
|
||||||
) {
|
) {
|
||||||
int version;
|
// Version 1: E164 user
|
||||||
byte[] ownId;
|
final var version = 1;
|
||||||
byte[] theirId;
|
final var ownId = ownNumber.getBytes(StandardCharsets.UTF_8);
|
||||||
|
final var theirId = theirNumber.getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
if (!isUuidCapable && ownAddress.number().isPresent() && theirAddress.number().isPresent()) {
|
return getFingerprint(version, ownId, ownIdentityKey, theirId, theirIdentityKey);
|
||||||
// Version 1: E164 user
|
}
|
||||||
version = 1;
|
|
||||||
ownId = ownAddress.number().get().getBytes();
|
|
||||||
theirId = theirAddress.number().get().getBytes();
|
|
||||||
} else if (isUuidCapable && theirAddress.serviceId().isPresent()) {
|
|
||||||
// Version 2: UUID user
|
|
||||||
version = 2;
|
|
||||||
ownId = ownAddress.getServiceId().toByteArray();
|
|
||||||
theirId = theirAddress.getServiceId().toByteArray();
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public static Fingerprint computeSafetyNumberForUuid(
|
||||||
|
ServiceId ownServiceId, IdentityKey ownIdentityKey, ServiceId theirServiceId, IdentityKey theirIdentityKey
|
||||||
|
) {
|
||||||
|
// Version 2: UUID user
|
||||||
|
final var version = 2;
|
||||||
|
final var ownId = ownServiceId.toByteArray();
|
||||||
|
final var theirId = theirServiceId.toByteArray();
|
||||||
|
|
||||||
|
return getFingerprint(version, ownId, ownIdentityKey, theirId, theirIdentityKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Fingerprint getFingerprint(
|
||||||
|
final int version,
|
||||||
|
final byte[] ownId,
|
||||||
|
final IdentityKey ownIdentityKey,
|
||||||
|
final byte[] theirId,
|
||||||
|
final IdentityKey theirIdentityKey
|
||||||
|
) {
|
||||||
return new NumericFingerprintGenerator(5200).createFor(version,
|
return new NumericFingerprintGenerator(5200).createFor(version,
|
||||||
ownId,
|
ownId,
|
||||||
ownIdentityKey,
|
ownIdentityKey,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue