mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 02:20:39 +00:00
Update libsignal-service-java
This commit is contained in:
parent
2c44b65e9f
commit
f3b2df62da
21 changed files with 273 additions and 120 deletions
|
@ -12,6 +12,10 @@
|
|||
"name":"java.lang.Boolean",
|
||||
"methods":[{"name":"getBoolean","parameterTypes":["java.lang.String"] }]
|
||||
},
|
||||
{
|
||||
"name":"java.lang.Class",
|
||||
"methods":[{"name":"getCanonicalName","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
"name":"java.lang.ClassLoader",
|
||||
"methods":[
|
||||
|
@ -30,6 +34,10 @@
|
|||
{
|
||||
"name":"java.lang.NoSuchMethodError"
|
||||
},
|
||||
{
|
||||
"name":"java.lang.Throwable",
|
||||
"methods":[{"name":"getMessage","parameterTypes":[] }]
|
||||
},
|
||||
{
|
||||
"name":"java.lang.UnsatisfiedLinkError",
|
||||
"methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
|
||||
|
@ -115,6 +123,9 @@
|
|||
"name":"org.whispersystems.libsignal.InvalidKeyException",
|
||||
"methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
|
||||
},
|
||||
{
|
||||
"name":"org.whispersystems.libsignal.InvalidKeyIdException"
|
||||
},
|
||||
{
|
||||
"name":"org.whispersystems.libsignal.InvalidMessageException",
|
||||
"methods":[{"name":"<init>","parameterTypes":["java.lang.String"] }]
|
||||
|
|
|
@ -2023,11 +2023,6 @@
|
|||
"queryAllDeclaredMethods":true,
|
||||
"queryAllDeclaredConstructors":true
|
||||
},
|
||||
{
|
||||
"name":"org.whispersystems.signalservice.api.push.AccountIdentifier",
|
||||
"allDeclaredFields":true,
|
||||
"queryAllDeclaredMethods":true
|
||||
},
|
||||
{
|
||||
"name":"org.whispersystems.signalservice.api.push.SignedPreKeyEntity",
|
||||
"allDeclaredFields":true,
|
||||
|
@ -2314,16 +2309,19 @@
|
|||
{
|
||||
"name":"org.whispersystems.signalservice.internal.push.ProvisioningProtos$ProvisionMessage",
|
||||
"fields":[
|
||||
{"name":"aciIdentityKeyPrivate_"},
|
||||
{"name":"aciIdentityKeyPublic_"},
|
||||
{"name":"aci_"},
|
||||
{"name":"bitField0_"},
|
||||
{"name":"identityKeyPrivate_"},
|
||||
{"name":"identityKeyPublic_"},
|
||||
{"name":"number_"},
|
||||
{"name":"pniIdentityKeyPrivate_"},
|
||||
{"name":"pniIdentityKeyPublic_"},
|
||||
{"name":"pni_"},
|
||||
{"name":"profileKey_"},
|
||||
{"name":"provisioningCode_"},
|
||||
{"name":"provisioningVersion_"},
|
||||
{"name":"readReceipts_"},
|
||||
{"name":"userAgent_"},
|
||||
{"name":"uuid_"}
|
||||
{"name":"userAgent_"}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -2686,6 +2684,7 @@
|
|||
"fields":[
|
||||
{"name":"bitField0_"},
|
||||
{"name":"content_"},
|
||||
{"name":"destinationUuid_"},
|
||||
{"name":"legacyMessage_"},
|
||||
{"name":"relay_"},
|
||||
{"name":"serverGuid_"},
|
||||
|
@ -2852,6 +2851,14 @@
|
|||
{"name":"type_"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$SyncMessage$PniIdentity",
|
||||
"fields":[
|
||||
{"name":"bitField0_"},
|
||||
{"name":"privateKey_"},
|
||||
{"name":"publicKey_"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$SyncMessage$Read",
|
||||
"fields":[
|
||||
|
|
|
@ -14,7 +14,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation("com.github.turasa", "signal-service-java", "2.15.3_unofficial_41")
|
||||
implementation("com.github.turasa", "signal-service-java", "2.15.3_unofficial_42")
|
||||
implementation("com.fasterxml.jackson.core", "jackson-databind", "2.13.1")
|
||||
implementation("com.google.protobuf", "protobuf-javalite", "3.11.4")
|
||||
implementation("org.bouncycastle", "bcprov-jdk15on", "1.70")
|
||||
|
|
|
@ -278,7 +278,7 @@ class ManagerImpl implements Manager {
|
|||
public List<Device> getLinkedDevices() throws IOException {
|
||||
var devices = dependencies.getAccountManager().getDevices();
|
||||
account.setMultiDevice(devices.size() > 1);
|
||||
var identityKey = account.getIdentityKeyPair().getPrivateKey();
|
||||
var identityKey = account.getAciIdentityKeyPair().getPrivateKey();
|
||||
return devices.stream().map(d -> {
|
||||
String deviceName = d.getName();
|
||||
if (deviceName != null) {
|
||||
|
@ -568,7 +568,7 @@ class ManagerImpl implements Manager {
|
|||
final var recipientId = context.getRecipientHelper().resolveRecipient(m.recipient());
|
||||
mentions.add(new SignalServiceDataMessage.Mention(context.getRecipientHelper()
|
||||
.resolveSignalServiceAddress(recipientId)
|
||||
.getAci(), m.start(), m.length()));
|
||||
.getServiceId(), m.start(), m.length()));
|
||||
}
|
||||
return mentions;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ class ProvisioningManagerImpl implements ProvisioningManager {
|
|||
groupsV2Operations = null;
|
||||
}
|
||||
accountManager = new SignalServiceAccountManager(serviceEnvironmentConfig.getSignalServiceConfiguration(),
|
||||
new DynamicCredentialsProvider(null, null, password, SignalServiceAddress.DEFAULT_DEVICE_ID),
|
||||
new DynamicCredentialsProvider(null, null, null, password, SignalServiceAddress.DEFAULT_DEVICE_ID),
|
||||
userAgent,
|
||||
groupsV2Operations,
|
||||
ServiceConfig.AUTOMATIC_NETWORK_RETRY);
|
||||
|
@ -97,6 +97,7 @@ class ProvisioningManagerImpl implements ProvisioningManager {
|
|||
var ret = accountManager.getNewDeviceRegistration(tempIdentityKey);
|
||||
var number = ret.getNumber();
|
||||
var aci = ret.getAci();
|
||||
var pni = ret.getPni();
|
||||
|
||||
logger.info("Received link information from {}, linking in progress ...", number);
|
||||
|
||||
|
@ -117,7 +118,7 @@ class ProvisioningManagerImpl implements ProvisioningManager {
|
|||
|
||||
var encryptedDeviceName = deviceName == null
|
||||
? null
|
||||
: DeviceNameUtil.encryptDeviceName(deviceName, ret.getIdentity().getPrivateKey());
|
||||
: DeviceNameUtil.encryptDeviceName(deviceName, ret.getAciIdentity().getPrivateKey());
|
||||
|
||||
logger.debug("Finishing new device registration");
|
||||
var deviceId = accountManager.finishNewDeviceRegistration(ret.getProvisioningCode(),
|
||||
|
@ -135,10 +136,12 @@ class ProvisioningManagerImpl implements ProvisioningManager {
|
|||
accountPath,
|
||||
number,
|
||||
aci,
|
||||
pni,
|
||||
password,
|
||||
encryptedDeviceName,
|
||||
deviceId,
|
||||
ret.getIdentity(),
|
||||
ret.getAciIdentity(),
|
||||
ret.getPniIdentity(),
|
||||
registrationId,
|
||||
profileKey,
|
||||
TrustNewIdentity.ON_FIRST_USE);
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.whispersystems.signalservice.api.SignalServiceAccountManager;
|
|||
import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations;
|
||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.PNI;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse;
|
||||
|
@ -79,7 +80,7 @@ class RegistrationManagerImpl implements RegistrationManager {
|
|||
this.accountManager = new SignalServiceAccountManager(serviceEnvironmentConfig.getSignalServiceConfiguration(),
|
||||
new DynamicCredentialsProvider(
|
||||
// Using empty UUID, because registering doesn't work otherwise
|
||||
null, account.getNumber(), account.getPassword(), SignalServiceAddress.DEFAULT_DEVICE_ID),
|
||||
null, null, account.getNumber(), account.getPassword(), SignalServiceAddress.DEFAULT_DEVICE_ID),
|
||||
userAgent,
|
||||
groupsV2Operations,
|
||||
ServiceConfig.AUTOMATIC_NETWORK_RETRY);
|
||||
|
@ -116,7 +117,8 @@ class RegistrationManagerImpl implements RegistrationManager {
|
|||
|
||||
//accountManager.setGcmId(Optional.of(GoogleCloudMessaging.getInstance(this).register(REGISTRATION_ID)));
|
||||
final var aci = ACI.parseOrNull(response.getUuid());
|
||||
account.finishRegistration(aci, masterKey, pin);
|
||||
final var pni = PNI.parseOrNull(response.getPni());
|
||||
account.finishRegistration(aci, pni, masterKey, pin);
|
||||
accountFileUpdater.updateAccountIdentifiers(account.getNumber(), aci);
|
||||
|
||||
ManagerImpl m = null;
|
||||
|
|
|
@ -125,14 +125,16 @@ public class SignalAccountFiles {
|
|||
final var accountPath = accountsStore.getPathByNumber(number);
|
||||
if (accountPath == null || !SignalAccount.accountFileExists(pathConfig.dataPath(), accountPath)) {
|
||||
final var newAccountPath = accountPath == null ? accountsStore.addAccount(number, null) : accountPath;
|
||||
var identityKey = KeyUtils.generateIdentityKeyPair();
|
||||
var aciIdentityKey = KeyUtils.generateIdentityKeyPair();
|
||||
var pniIdentityKey = KeyUtils.generateIdentityKeyPair();
|
||||
var registrationId = KeyHelper.generateRegistrationId(false);
|
||||
|
||||
var profileKey = KeyUtils.createProfileKey();
|
||||
var account = SignalAccount.create(pathConfig.dataPath(),
|
||||
newAccountPath,
|
||||
number,
|
||||
identityKey,
|
||||
aciIdentityKey,
|
||||
pniIdentityKey,
|
||||
registrationId,
|
||||
profileKey,
|
||||
trustNewIdentity);
|
||||
|
|
|
@ -88,6 +88,7 @@ public class SignalDependencies {
|
|||
|
||||
public SignalServiceAccountManager createUnauthenticatedAccountManager(String number, String password) {
|
||||
return new SignalServiceAccountManager(getServiceEnvironmentConfig().getSignalServiceConfiguration(),
|
||||
null,
|
||||
null,
|
||||
number,
|
||||
SignalServiceAddress.DEFAULT_DEVICE_ID,
|
||||
|
|
|
@ -17,10 +17,8 @@ public class RetrieveStorageDataAction implements HandleAction {
|
|||
public void execute(Context context) throws Throwable {
|
||||
if (context.getAccount().getStorageKey() != null) {
|
||||
context.getStorageHelper().readDataFromStorage();
|
||||
} else {
|
||||
if (!context.getAccount().isMasterDevice()) {
|
||||
context.getSyncHelper().requestAllSyncData();
|
||||
}
|
||||
} else if (!context.getAccount().isMasterDevice()) {
|
||||
context.getSyncHelper().requestSyncKeys();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package org.asamk.signal.manager.actions;
|
||||
|
||||
import org.asamk.signal.manager.helper.Context;
|
||||
|
||||
public class SendPniIdentityKeyAction implements HandleAction {
|
||||
|
||||
private static final SendPniIdentityKeyAction INSTANCE = new SendPniIdentityKeyAction();
|
||||
|
||||
private SendPniIdentityKeyAction() {
|
||||
}
|
||||
|
||||
public static SendPniIdentityKeyAction create() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Context context) throws Throwable {
|
||||
context.getSyncHelper().sendPniIdentity();
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ import org.slf4j.LoggerFactory;
|
|||
import org.whispersystems.libsignal.InvalidKeyException;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.PNI;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException;
|
||||
import org.whispersystems.signalservice.api.util.DeviceNameUtil;
|
||||
|
||||
|
@ -55,9 +56,12 @@ public class AccountHelper {
|
|||
}
|
||||
try {
|
||||
context.getPreKeyHelper().refreshPreKeysIfNecessary();
|
||||
if (account.getAci() == null) {
|
||||
if (account.getAci() == null || account.getPni() == null) {
|
||||
checkWhoAmiI();
|
||||
}
|
||||
if (!account.isMasterDevice() && account.getPniIdentityKeyPair() == null) {
|
||||
context.getSyncHelper().requestSyncPniIdentity();
|
||||
}
|
||||
updateAccountAttributes();
|
||||
} catch (AuthorizationFailedException e) {
|
||||
account.setRegistered(false);
|
||||
|
@ -69,16 +73,18 @@ public class AccountHelper {
|
|||
final var whoAmI = dependencies.getAccountManager().getWhoAmI();
|
||||
final var number = whoAmI.getNumber();
|
||||
final var aci = ACI.parseOrNull(whoAmI.getAci());
|
||||
if (number.equals(account.getNumber()) && aci.equals(account.getAci())) {
|
||||
final var pni = PNI.parseOrNull(whoAmI.getPni());
|
||||
if (number.equals(account.getNumber()) && aci.equals(account.getAci()) && pni.equals(account.getPni())) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateSelfIdentifiers(number, aci);
|
||||
updateSelfIdentifiers(number, aci, pni);
|
||||
}
|
||||
|
||||
private void updateSelfIdentifiers(final String number, final ACI aci) {
|
||||
private void updateSelfIdentifiers(final String number, final ACI aci, final PNI pni) {
|
||||
account.setNumber(number);
|
||||
account.setAci(aci);
|
||||
account.setPni(pni);
|
||||
account.getRecipientStore().resolveSelfRecipientTrusted(account.getSelfRecipientAddress());
|
||||
// TODO check and update remote storage
|
||||
context.getUnidentifiedAccessHelper().rotateSenderCertificates();
|
||||
|
@ -103,11 +109,11 @@ public class AccountHelper {
|
|||
(verificationCode1, registrationLock) -> dependencies.getAccountManager()
|
||||
.changeNumber(verificationCode1, newNumber, registrationLock));
|
||||
// TODO handle response
|
||||
updateSelfIdentifiers(newNumber, account.getAci());
|
||||
updateSelfIdentifiers(newNumber, account.getAci(), PNI.parseOrThrow(result.first().getPni()));
|
||||
}
|
||||
|
||||
public void setDeviceName(String deviceName) {
|
||||
final var privateKey = account.getIdentityKeyPair().getPrivateKey();
|
||||
final var privateKey = account.getAciIdentityKeyPair().getPrivateKey();
|
||||
final var encryptedDeviceName = DeviceNameUtil.encryptDeviceName(deviceName, privateKey);
|
||||
account.setEncryptedDeviceName(encryptedDeviceName);
|
||||
}
|
||||
|
@ -127,15 +133,15 @@ public class AccountHelper {
|
|||
}
|
||||
|
||||
public void addDevice(DeviceLinkInfo deviceLinkInfo) throws IOException, InvalidDeviceLinkException {
|
||||
var identityKeyPair = account.getIdentityKeyPair();
|
||||
var verificationCode = dependencies.getAccountManager().getNewDeviceVerificationCode();
|
||||
|
||||
try {
|
||||
dependencies.getAccountManager()
|
||||
.addDevice(deviceLinkInfo.deviceIdentifier(),
|
||||
deviceLinkInfo.deviceKey(),
|
||||
identityKeyPair,
|
||||
Optional.of(account.getProfileKey().serialize()),
|
||||
account.getAciIdentityKeyPair(),
|
||||
account.getPniIdentityKeyPair(),
|
||||
account.getProfileKey(),
|
||||
verificationCode);
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new InvalidDeviceLinkException("Invalid device link", e);
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
|||
import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException;
|
||||
import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
|
||||
|
||||
|
@ -150,7 +151,7 @@ class GroupV2Helper {
|
|||
final var memberList = new ArrayList<>(members);
|
||||
final var credentials = context.getProfileHelper().getRecipientProfileKeyCredential(memberList).stream();
|
||||
final var uuids = memberList.stream()
|
||||
.map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getAci().uuid());
|
||||
.map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid());
|
||||
var candidates = Utils.zip(uuids,
|
||||
credentials,
|
||||
(uuid, credential) -> new GroupCandidate(uuid, Optional.fromNullable(credential)))
|
||||
|
@ -218,7 +219,7 @@ class GroupV2Helper {
|
|||
final var memberList = new ArrayList<>(newMembers);
|
||||
final var credentials = context.getProfileHelper().getRecipientProfileKeyCredential(memberList).stream();
|
||||
final var uuids = memberList.stream()
|
||||
.map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getAci().uuid());
|
||||
.map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid());
|
||||
var candidates = Utils.zip(uuids,
|
||||
credentials,
|
||||
(uuid, credential) -> new GroupCandidate(uuid, Optional.fromNullable(credential)))
|
||||
|
@ -245,8 +246,8 @@ class GroupV2Helper {
|
|||
|
||||
final var adminUuids = membersToMakeAdmin.stream()
|
||||
.map(context.getRecipientHelper()::resolveSignalServiceAddress)
|
||||
.map(SignalServiceAddress::getAci)
|
||||
.map(ACI::uuid)
|
||||
.map(SignalServiceAddress::getServiceId)
|
||||
.map(ServiceId::uuid)
|
||||
.toList();
|
||||
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
|
||||
return commitChange(groupInfoV2,
|
||||
|
@ -258,8 +259,8 @@ class GroupV2Helper {
|
|||
) throws IOException {
|
||||
final var memberUuids = members.stream()
|
||||
.map(context.getRecipientHelper()::resolveSignalServiceAddress)
|
||||
.map(SignalServiceAddress::getAci)
|
||||
.map(ACI::uuid)
|
||||
.map(SignalServiceAddress::getServiceId)
|
||||
.map(ServiceId::uuid)
|
||||
.collect(Collectors.toSet());
|
||||
return ejectMembers(groupInfoV2, memberUuids);
|
||||
}
|
||||
|
@ -270,8 +271,8 @@ class GroupV2Helper {
|
|||
var pendingMembersList = groupInfoV2.getGroup().getPendingMembersList();
|
||||
final var memberUuids = members.stream()
|
||||
.map(context.getRecipientHelper()::resolveSignalServiceAddress)
|
||||
.map(SignalServiceAddress::getAci)
|
||||
.map(ACI::uuid)
|
||||
.map(SignalServiceAddress::getServiceId)
|
||||
.map(ServiceId::uuid)
|
||||
.map(uuid -> DecryptedGroupUtil.findPendingByUuid(pendingMembersList, uuid))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
|
@ -343,7 +344,7 @@ class GroupV2Helper {
|
|||
|
||||
change.setSourceUuid(context.getRecipientHelper()
|
||||
.resolveSignalServiceAddress(selfRecipientId)
|
||||
.getAci()
|
||||
.getServiceId()
|
||||
.toByteString());
|
||||
|
||||
return commitChange(groupSecretParams, decryptedGroupJoinInfo.getRevision(), change, groupLinkPassword);
|
||||
|
@ -360,7 +361,7 @@ class GroupV2Helper {
|
|||
|
||||
final var change = groupOperations.createAcceptInviteChange(profileKeyCredential);
|
||||
|
||||
final var aci = context.getRecipientHelper().resolveSignalServiceAddress(selfRecipientId).getAci();
|
||||
final var aci = context.getRecipientHelper().resolveSignalServiceAddress(selfRecipientId).getServiceId();
|
||||
change.setSourceUuid(aci.toByteString());
|
||||
|
||||
return commitChange(groupInfoV2, change);
|
||||
|
@ -372,7 +373,7 @@ class GroupV2Helper {
|
|||
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
|
||||
final var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId);
|
||||
final var newRole = admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT;
|
||||
final var change = groupOperations.createChangeMemberRole(address.getAci().uuid(), newRole);
|
||||
final var change = groupOperations.createChangeMemberRole(address.getServiceId().uuid(), newRole);
|
||||
return commitChange(groupInfoV2, change);
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ public class IdentityHelper {
|
|||
) {
|
||||
return Utils.computeSafetyNumber(capabilities.isUuid(),
|
||||
account.getSelfAddress(),
|
||||
account.getIdentityKeyPair().getPublicKey(),
|
||||
account.getAciIdentityKeyPair().getPublicKey(),
|
||||
theirAddress,
|
||||
theirIdentityKey);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.asamk.signal.manager.actions.RetrieveProfileAction;
|
|||
import org.asamk.signal.manager.actions.RetrieveStorageDataAction;
|
||||
import org.asamk.signal.manager.actions.SendGroupInfoAction;
|
||||
import org.asamk.signal.manager.actions.SendGroupInfoRequestAction;
|
||||
import org.asamk.signal.manager.actions.SendPniIdentityKeyAction;
|
||||
import org.asamk.signal.manager.actions.SendReceiptAction;
|
||||
import org.asamk.signal.manager.actions.SendRetryMessageRequestAction;
|
||||
import org.asamk.signal.manager.actions.SendSyncBlockedListAction;
|
||||
|
@ -31,6 +32,7 @@ import org.asamk.signal.manager.storage.groups.GroupInfoV1;
|
|||
import org.asamk.signal.manager.storage.recipients.Profile;
|
||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||
import org.asamk.signal.manager.storage.stickers.Sticker;
|
||||
import org.asamk.signal.manager.util.KeyUtils;
|
||||
import org.signal.libsignal.metadata.ProtocolInvalidKeyException;
|
||||
import org.signal.libsignal.metadata.ProtocolInvalidKeyIdException;
|
||||
import org.signal.libsignal.metadata.ProtocolInvalidMessageException;
|
||||
|
@ -340,6 +342,9 @@ public final class IncomingMessageHandler {
|
|||
if (rm.isConfigurationRequest()) {
|
||||
actions.add(SendSyncConfigurationAction.create());
|
||||
}
|
||||
if (rm.isPniIdentityRequest()) {
|
||||
actions.add(SendPniIdentityKeyAction.create());
|
||||
}
|
||||
}
|
||||
if (syncMessage.getGroups().isPresent()) {
|
||||
logger.warn("Received a group v1 sync message, that can't be handled anymore, ignoring.");
|
||||
|
@ -440,6 +445,11 @@ public final class IncomingMessageHandler {
|
|||
.get());
|
||||
}
|
||||
}
|
||||
if (syncMessage.getPniIdentity().isPresent()) {
|
||||
final var pniIdentity = syncMessage.getPniIdentity().get();
|
||||
account.setPniIdentityKeyPair(KeyUtils.getIdentityKeyPair(pniIdentity.getPublicKey().toByteArray(),
|
||||
pniIdentity.getPrivateKey().toByteArray()));
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.slf4j.LoggerFactory;
|
|||
import org.whispersystems.libsignal.IdentityKeyPair;
|
||||
import org.whispersystems.libsignal.state.PreKeyRecord;
|
||||
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
|
||||
import org.whispersystems.signalservice.api.push.ServiceIdType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
@ -28,17 +29,32 @@ public class PreKeyHelper {
|
|||
}
|
||||
|
||||
public void refreshPreKeysIfNecessary() throws IOException {
|
||||
if (dependencies.getAccountManager().getPreKeysCount() < ServiceConfig.PREKEY_MINIMUM_COUNT) {
|
||||
refreshPreKeys();
|
||||
refreshPreKeysIfNecessary(ServiceIdType.ACI);
|
||||
refreshPreKeysIfNecessary(ServiceIdType.PNI);
|
||||
}
|
||||
|
||||
public void refreshPreKeysIfNecessary(ServiceIdType serviceIdType) throws IOException {
|
||||
if (dependencies.getAccountManager().getPreKeysCount(serviceIdType) < ServiceConfig.PREKEY_MINIMUM_COUNT) {
|
||||
refreshPreKeys(serviceIdType);
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshPreKeys() throws IOException {
|
||||
refreshPreKeys(ServiceIdType.ACI);
|
||||
refreshPreKeys(ServiceIdType.PNI);
|
||||
}
|
||||
|
||||
public void refreshPreKeys(ServiceIdType serviceIdType) throws IOException {
|
||||
if (serviceIdType != ServiceIdType.ACI) {
|
||||
// TODO implement
|
||||
return;
|
||||
}
|
||||
var oneTimePreKeys = generatePreKeys();
|
||||
final var identityKeyPair = account.getIdentityKeyPair();
|
||||
final var identityKeyPair = account.getAciIdentityKeyPair();
|
||||
var signedPreKeyRecord = generateSignedPreKey(identityKeyPair);
|
||||
|
||||
dependencies.getAccountManager().setPreKeys(identityKeyPair.getPublicKey(), signedPreKeyRecord, oneTimePreKeys);
|
||||
dependencies.getAccountManager()
|
||||
.setPreKeys(serviceIdType, identityKeyPair.getPublicKey(), signedPreKeyRecord, oneTimePreKeys);
|
||||
}
|
||||
|
||||
private List<PreKeyRecord> generatePreKeys() {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package org.asamk.signal.manager.helper;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
import org.asamk.signal.manager.api.TrustLevel;
|
||||
import org.asamk.signal.manager.storage.SignalAccount;
|
||||
import org.asamk.signal.manager.storage.groups.GroupInfoV1;
|
||||
|
@ -49,11 +51,20 @@ public class SyncHelper {
|
|||
}
|
||||
|
||||
public void requestAllSyncData() {
|
||||
requestSyncGroups();
|
||||
requestSyncContacts();
|
||||
requestSyncBlocked();
|
||||
requestSyncConfiguration();
|
||||
requestSyncData(SignalServiceProtos.SyncMessage.Request.Type.GROUPS);
|
||||
requestSyncData(SignalServiceProtos.SyncMessage.Request.Type.CONTACTS);
|
||||
requestSyncData(SignalServiceProtos.SyncMessage.Request.Type.BLOCKED);
|
||||
requestSyncData(SignalServiceProtos.SyncMessage.Request.Type.CONFIGURATION);
|
||||
requestSyncKeys();
|
||||
requestSyncPniIdentity();
|
||||
}
|
||||
|
||||
public void requestSyncKeys() {
|
||||
requestSyncData(SignalServiceProtos.SyncMessage.Request.Type.KEYS);
|
||||
}
|
||||
|
||||
public void requestSyncPniIdentity() {
|
||||
requestSyncData(SignalServiceProtos.SyncMessage.Request.Type.PNI_IDENTITY);
|
||||
}
|
||||
|
||||
public void sendSyncFetchProfileMessage() {
|
||||
|
@ -217,6 +228,15 @@ public class SyncHelper {
|
|||
context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forConfiguration(configurationMessage));
|
||||
}
|
||||
|
||||
public void sendPniIdentity() {
|
||||
final var pniIdentityKeyPair = account.getPniIdentityKeyPair();
|
||||
var pniIdentity = SignalServiceProtos.SyncMessage.PniIdentity.newBuilder()
|
||||
.setPrivateKey(ByteString.copyFrom(pniIdentityKeyPair.getPrivateKey().serialize()))
|
||||
.setPublicKey(ByteString.copyFrom(pniIdentityKeyPair.getPublicKey().serialize()))
|
||||
.build();
|
||||
context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forPniIdentity(pniIdentity));
|
||||
}
|
||||
|
||||
public void handleSyncDeviceContacts(final InputStream input) throws IOException {
|
||||
final var s = new DeviceContactsInputStream(input);
|
||||
DeviceContact c;
|
||||
|
@ -270,42 +290,8 @@ public class SyncHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private void requestSyncGroups() {
|
||||
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
||||
.setType(SignalServiceProtos.SyncMessage.Request.Type.GROUPS)
|
||||
.build();
|
||||
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||
context.getSendHelper().sendSyncMessage(message);
|
||||
}
|
||||
|
||||
private void requestSyncContacts() {
|
||||
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
||||
.setType(SignalServiceProtos.SyncMessage.Request.Type.CONTACTS)
|
||||
.build();
|
||||
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||
context.getSendHelper().sendSyncMessage(message);
|
||||
}
|
||||
|
||||
private void requestSyncBlocked() {
|
||||
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
||||
.setType(SignalServiceProtos.SyncMessage.Request.Type.BLOCKED)
|
||||
.build();
|
||||
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||
context.getSendHelper().sendSyncMessage(message);
|
||||
}
|
||||
|
||||
private void requestSyncConfiguration() {
|
||||
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
||||
.setType(SignalServiceProtos.SyncMessage.Request.Type.CONFIGURATION)
|
||||
.build();
|
||||
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||
context.getSendHelper().sendSyncMessage(message);
|
||||
}
|
||||
|
||||
private void requestSyncKeys() {
|
||||
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
||||
.setType(SignalServiceProtos.SyncMessage.Request.Type.KEYS)
|
||||
.build();
|
||||
private void requestSyncData(final SignalServiceProtos.SyncMessage.Request.Type type) {
|
||||
var r = SignalServiceProtos.SyncMessage.Request.newBuilder().setType(type).build();
|
||||
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||
context.getSendHelper().sendSyncMessage(message);
|
||||
}
|
||||
|
|
|
@ -49,8 +49,9 @@ import org.whispersystems.signalservice.api.SignalServiceDataStore;
|
|||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
|
||||
import org.whispersystems.signalservice.api.kbs.MasterKey;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.AccountIdentifier;
|
||||
import org.whispersystems.signalservice.api.push.DistributionId;
|
||||
import org.whispersystems.signalservice.api.push.PNI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.storage.StorageKey;
|
||||
import org.whispersystems.signalservice.api.util.CredentialsProvider;
|
||||
|
@ -94,6 +95,7 @@ public class SignalAccount implements Closeable {
|
|||
private String accountPath;
|
||||
private String number;
|
||||
private ACI aci;
|
||||
private PNI pni;
|
||||
private String encryptedDeviceName;
|
||||
private int deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID;
|
||||
private boolean isMultiDevice = false;
|
||||
|
@ -105,7 +107,8 @@ public class SignalAccount implements Closeable {
|
|||
private ProfileKey profileKey;
|
||||
private int preKeyIdOffset = 1;
|
||||
private int nextSignedPreKeyId = 1;
|
||||
private IdentityKeyPair identityKeyPair;
|
||||
private IdentityKeyPair aciIdentityKeyPair;
|
||||
private IdentityKeyPair pniIdentityKeyPair;
|
||||
private int localRegistrationId;
|
||||
private TrustNewIdentity trustNewIdentity;
|
||||
private long lastReceiveTimestamp = 0;
|
||||
|
@ -161,7 +164,8 @@ public class SignalAccount implements Closeable {
|
|||
File dataPath,
|
||||
String accountPath,
|
||||
String number,
|
||||
IdentityKeyPair identityKey,
|
||||
IdentityKeyPair aciIdentityKey,
|
||||
IdentityKeyPair pniIdentityKey,
|
||||
int registrationId,
|
||||
ProfileKey profileKey,
|
||||
final TrustNewIdentity trustNewIdentity
|
||||
|
@ -180,7 +184,8 @@ public class SignalAccount implements Closeable {
|
|||
signalAccount.profileKey = profileKey;
|
||||
|
||||
signalAccount.dataPath = dataPath;
|
||||
signalAccount.identityKeyPair = identityKey;
|
||||
signalAccount.aciIdentityKeyPair = aciIdentityKey;
|
||||
signalAccount.pniIdentityKeyPair = pniIdentityKey;
|
||||
signalAccount.localRegistrationId = registrationId;
|
||||
signalAccount.trustNewIdentity = trustNewIdentity;
|
||||
signalAccount.groupStore = new GroupStore(getGroupCachePath(dataPath, accountPath),
|
||||
|
@ -203,10 +208,12 @@ public class SignalAccount implements Closeable {
|
|||
String accountPath,
|
||||
String number,
|
||||
ACI aci,
|
||||
PNI pni,
|
||||
String password,
|
||||
String encryptedDeviceName,
|
||||
int deviceId,
|
||||
IdentityKeyPair identityKey,
|
||||
IdentityKeyPair aciIdentityKey,
|
||||
IdentityKeyPair pniIdentityKey,
|
||||
int registrationId,
|
||||
ProfileKey profileKey,
|
||||
final TrustNewIdentity trustNewIdentity
|
||||
|
@ -218,17 +225,27 @@ public class SignalAccount implements Closeable {
|
|||
accountPath,
|
||||
number,
|
||||
aci,
|
||||
pni,
|
||||
password,
|
||||
encryptedDeviceName,
|
||||
deviceId,
|
||||
identityKey,
|
||||
aciIdentityKey,
|
||||
pniIdentityKey,
|
||||
registrationId,
|
||||
profileKey,
|
||||
trustNewIdentity);
|
||||
}
|
||||
|
||||
final var signalAccount = load(dataPath, accountPath, true, trustNewIdentity);
|
||||
signalAccount.setProvisioningData(number, aci, password, encryptedDeviceName, deviceId, profileKey);
|
||||
signalAccount.setProvisioningData(number,
|
||||
aci,
|
||||
pni,
|
||||
password,
|
||||
encryptedDeviceName,
|
||||
deviceId,
|
||||
aciIdentityKey,
|
||||
pniIdentityKey,
|
||||
profileKey);
|
||||
signalAccount.getRecipientStore().resolveSelfRecipientTrusted(signalAccount.getSelfRecipientAddress());
|
||||
signalAccount.getSessionStore().archiveAllSessions();
|
||||
signalAccount.getSenderKeyStore().deleteAll();
|
||||
|
@ -253,10 +270,12 @@ public class SignalAccount implements Closeable {
|
|||
String accountPath,
|
||||
String number,
|
||||
ACI aci,
|
||||
PNI pni,
|
||||
String password,
|
||||
String encryptedDeviceName,
|
||||
int deviceId,
|
||||
IdentityKeyPair identityKey,
|
||||
IdentityKeyPair aciIdentityKey,
|
||||
IdentityKeyPair pniIdentityKey,
|
||||
int registrationId,
|
||||
ProfileKey profileKey,
|
||||
final TrustNewIdentity trustNewIdentity
|
||||
|
@ -267,11 +286,18 @@ public class SignalAccount implements Closeable {
|
|||
final var pair = openFileChannel(fileName, true);
|
||||
var signalAccount = new SignalAccount(pair.first(), pair.second());
|
||||
|
||||
signalAccount.setProvisioningData(number, aci, password, encryptedDeviceName, deviceId, profileKey);
|
||||
signalAccount.setProvisioningData(number,
|
||||
aci,
|
||||
pni,
|
||||
password,
|
||||
encryptedDeviceName,
|
||||
deviceId,
|
||||
aciIdentityKey,
|
||||
pniIdentityKey,
|
||||
profileKey);
|
||||
|
||||
signalAccount.dataPath = dataPath;
|
||||
signalAccount.accountPath = accountPath;
|
||||
signalAccount.identityKeyPair = identityKey;
|
||||
signalAccount.localRegistrationId = registrationId;
|
||||
signalAccount.trustNewIdentity = trustNewIdentity;
|
||||
signalAccount.groupStore = new GroupStore(getGroupCachePath(dataPath, accountPath),
|
||||
|
@ -283,6 +309,7 @@ public class SignalAccount implements Closeable {
|
|||
signalAccount.getRecipientStore().resolveSelfRecipientTrusted(signalAccount.getSelfRecipientAddress());
|
||||
signalAccount.previousStorageVersion = CURRENT_STORAGE_VERSION;
|
||||
signalAccount.migrateLegacyConfigs();
|
||||
signalAccount.clearAllPreKeys();
|
||||
signalAccount.save();
|
||||
|
||||
return signalAccount;
|
||||
|
@ -291,17 +318,23 @@ public class SignalAccount implements Closeable {
|
|||
private void setProvisioningData(
|
||||
final String number,
|
||||
final ACI aci,
|
||||
final PNI pni,
|
||||
final String password,
|
||||
final String encryptedDeviceName,
|
||||
final int deviceId,
|
||||
final IdentityKeyPair aciIdentity,
|
||||
final IdentityKeyPair pniIdentity,
|
||||
final ProfileKey profileKey
|
||||
) {
|
||||
this.number = number;
|
||||
this.aci = aci;
|
||||
this.pni = pni;
|
||||
this.password = password;
|
||||
this.profileKey = profileKey;
|
||||
this.encryptedDeviceName = encryptedDeviceName;
|
||||
this.deviceId = deviceId;
|
||||
this.aciIdentityKeyPair = aciIdentity;
|
||||
this.pniIdentityKeyPair = pniIdentity;
|
||||
this.registered = true;
|
||||
this.isMultiDevice = true;
|
||||
this.lastReceiveTimestamp = 0;
|
||||
|
@ -330,6 +363,9 @@ public class SignalAccount implements Closeable {
|
|||
}
|
||||
save();
|
||||
}
|
||||
if (isMasterDevice() && getPniIdentityKeyPair() == null) {
|
||||
setPniIdentityKeyPair(KeyUtils.generateIdentityKeyPair());
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeRecipients(RecipientId recipientId, RecipientId toBeMergedRecipientId) {
|
||||
|
@ -440,7 +476,14 @@ public class SignalAccount implements Closeable {
|
|||
try {
|
||||
aci = ACI.parseOrThrow(rootNode.get("uuid").asText());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IOException("Config file contains an invalid uuid, needs to be a valid UUID", e);
|
||||
throw new IOException("Config file contains an invalid aci/uuid, needs to be a valid UUID", e);
|
||||
}
|
||||
}
|
||||
if (rootNode.hasNonNull("pni")) {
|
||||
try {
|
||||
pni = PNI.parseOrThrow(rootNode.get("pni").asText());
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new IOException("Config file contains an invalid pni, needs to be a valid UUID", e);
|
||||
}
|
||||
}
|
||||
if (rootNode.hasNonNull("deviceName")) {
|
||||
|
@ -459,11 +502,16 @@ public class SignalAccount implements Closeable {
|
|||
if (rootNode.hasNonNull("registrationId")) {
|
||||
registrationId = rootNode.get("registrationId").asInt();
|
||||
}
|
||||
IdentityKeyPair identityKeyPair = null;
|
||||
IdentityKeyPair aciIdentityKeyPair = null;
|
||||
if (rootNode.hasNonNull("identityPrivateKey") && rootNode.hasNonNull("identityKey")) {
|
||||
final var publicKeyBytes = Base64.getDecoder().decode(rootNode.get("identityKey").asText());
|
||||
final var privateKeyBytes = Base64.getDecoder().decode(rootNode.get("identityPrivateKey").asText());
|
||||
identityKeyPair = KeyUtils.getIdentityKeyPair(publicKeyBytes, privateKeyBytes);
|
||||
aciIdentityKeyPair = KeyUtils.getIdentityKeyPair(publicKeyBytes, privateKeyBytes);
|
||||
}
|
||||
if (rootNode.hasNonNull("pniIdentityPrivateKey") && rootNode.hasNonNull("pniIdentityKey")) {
|
||||
final var publicKeyBytes = Base64.getDecoder().decode(rootNode.get("pniIdentityKey").asText());
|
||||
final var privateKeyBytes = Base64.getDecoder().decode(rootNode.get("pniIdentityPrivateKey").asText());
|
||||
pniIdentityKeyPair = KeyUtils.getIdentityKeyPair(publicKeyBytes, privateKeyBytes);
|
||||
}
|
||||
|
||||
if (rootNode.hasNonNull("registrationLockPin")) {
|
||||
|
@ -504,12 +552,12 @@ public class SignalAccount implements Closeable {
|
|||
LegacyJsonSignalProtocolStore.class)
|
||||
: null;
|
||||
if (legacySignalProtocolStore != null && legacySignalProtocolStore.getLegacyIdentityKeyStore() != null) {
|
||||
identityKeyPair = legacySignalProtocolStore.getLegacyIdentityKeyStore().getIdentityKeyPair();
|
||||
aciIdentityKeyPair = legacySignalProtocolStore.getLegacyIdentityKeyStore().getIdentityKeyPair();
|
||||
registrationId = legacySignalProtocolStore.getLegacyIdentityKeyStore().getLocalRegistrationId();
|
||||
migratedLegacyConfig = true;
|
||||
}
|
||||
|
||||
this.identityKeyPair = identityKeyPair;
|
||||
this.aciIdentityKeyPair = aciIdentityKeyPair;
|
||||
this.localRegistrationId = registrationId;
|
||||
this.trustNewIdentity = trustNewIdentity;
|
||||
|
||||
|
@ -741,6 +789,7 @@ public class SignalAccount implements Closeable {
|
|||
rootNode.put("version", CURRENT_STORAGE_VERSION)
|
||||
.put("username", number)
|
||||
.put("uuid", aci == null ? null : aci.toString())
|
||||
.put("pni", pni == null ? null : pni.toString())
|
||||
.put("deviceName", encryptedDeviceName)
|
||||
.put("deviceId", deviceId)
|
||||
.put("isMultiDevice", isMultiDevice)
|
||||
|
@ -748,8 +797,18 @@ public class SignalAccount implements Closeable {
|
|||
.put("password", password)
|
||||
.put("registrationId", localRegistrationId)
|
||||
.put("identityPrivateKey",
|
||||
Base64.getEncoder().encodeToString(identityKeyPair.getPrivateKey().serialize()))
|
||||
.put("identityKey", Base64.getEncoder().encodeToString(identityKeyPair.getPublicKey().serialize()))
|
||||
Base64.getEncoder().encodeToString(aciIdentityKeyPair.getPrivateKey().serialize()))
|
||||
.put("identityKey",
|
||||
Base64.getEncoder().encodeToString(aciIdentityKeyPair.getPublicKey().serialize()))
|
||||
.put("pniIdentityPrivateKey",
|
||||
pniIdentityKeyPair == null
|
||||
? null
|
||||
: Base64.getEncoder()
|
||||
.encodeToString(pniIdentityKeyPair.getPrivateKey().serialize()))
|
||||
.put("pniIdentityKey",
|
||||
pniIdentityKeyPair == null
|
||||
? null
|
||||
: Base64.getEncoder().encodeToString(pniIdentityKeyPair.getPublicKey().serialize()))
|
||||
.put("registrationLockPin", registrationLockPin)
|
||||
.put("pinMasterKey",
|
||||
pinMasterKey == null ? null : Base64.getEncoder().encodeToString(pinMasterKey.serialize()))
|
||||
|
@ -820,8 +879,14 @@ public class SignalAccount implements Closeable {
|
|||
public SignalServiceDataStore getSignalServiceDataStore() {
|
||||
return new SignalServiceDataStore() {
|
||||
@Override
|
||||
public SignalServiceAccountDataStore get(final AccountIdentifier accountIdentifier) {
|
||||
return getSignalServiceAccountDataStore();
|
||||
public SignalServiceAccountDataStore get(final ServiceId accountIdentifier) {
|
||||
if (accountIdentifier.equals(aci)) {
|
||||
return getSignalServiceAccountDataStore();
|
||||
} else if (accountIdentifier.equals(pni)) {
|
||||
throw new AssertionError("PNI not to be used yet!");
|
||||
} else {
|
||||
throw new IllegalArgumentException("No matching store found for " + accountIdentifier);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -831,7 +896,7 @@ public class SignalAccount implements Closeable {
|
|||
|
||||
@Override
|
||||
public SignalServiceAccountDataStore pni() {
|
||||
return getSignalServiceAccountDataStore();
|
||||
throw new AssertionError("PNI not to be used yet!");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -870,7 +935,7 @@ public class SignalAccount implements Closeable {
|
|||
return getOrCreate(() -> identityKeyStore,
|
||||
() -> identityKeyStore = new IdentityKeyStore(getIdentitiesPath(dataPath, accountPath),
|
||||
getRecipientStore(),
|
||||
identityKeyPair,
|
||||
aciIdentityKeyPair,
|
||||
localRegistrationId,
|
||||
trustNewIdentity));
|
||||
}
|
||||
|
@ -937,6 +1002,11 @@ public class SignalAccount implements Closeable {
|
|||
return aci;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PNI getPni() {
|
||||
return pni;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getE164() {
|
||||
return number;
|
||||
|
@ -972,6 +1042,15 @@ public class SignalAccount implements Closeable {
|
|||
save();
|
||||
}
|
||||
|
||||
public PNI getPni() {
|
||||
return pni;
|
||||
}
|
||||
|
||||
public void setPni(final PNI pni) {
|
||||
this.pni = pni;
|
||||
save();
|
||||
}
|
||||
|
||||
public SignalServiceAddress getSelfAddress() {
|
||||
return new SignalServiceAddress(aci, number);
|
||||
}
|
||||
|
@ -1001,8 +1080,17 @@ public class SignalAccount implements Closeable {
|
|||
return deviceId == SignalServiceAddress.DEFAULT_DEVICE_ID;
|
||||
}
|
||||
|
||||
public IdentityKeyPair getIdentityKeyPair() {
|
||||
return identityKeyPair;
|
||||
public IdentityKeyPair getAciIdentityKeyPair() {
|
||||
return aciIdentityKeyPair;
|
||||
}
|
||||
|
||||
public IdentityKeyPair getPniIdentityKeyPair() {
|
||||
return pniIdentityKeyPair;
|
||||
}
|
||||
|
||||
public void setPniIdentityKeyPair(final IdentityKeyPair identityKeyPair) {
|
||||
pniIdentityKeyPair = identityKeyPair;
|
||||
save();
|
||||
}
|
||||
|
||||
public int getLocalRegistrationId() {
|
||||
|
@ -1118,7 +1206,7 @@ public class SignalAccount implements Closeable {
|
|||
return configurationStore.getPhoneNumberUnlisted() == null || !configurationStore.getPhoneNumberUnlisted();
|
||||
}
|
||||
|
||||
public void finishRegistration(final ACI aci, final MasterKey masterKey, final String pin) {
|
||||
public void finishRegistration(final ACI aci, final PNI pni, final MasterKey masterKey, final String pin) {
|
||||
this.pinMasterKey = masterKey;
|
||||
this.storageManifestVersion = -1;
|
||||
this.storageKey = null;
|
||||
|
@ -1127,6 +1215,7 @@ public class SignalAccount implements Closeable {
|
|||
this.isMultiDevice = false;
|
||||
this.registered = true;
|
||||
this.aci = aci;
|
||||
this.pni = pni;
|
||||
this.registrationLockPin = pin;
|
||||
this.lastReceiveTimestamp = 0;
|
||||
save();
|
||||
|
@ -1135,7 +1224,7 @@ public class SignalAccount implements Closeable {
|
|||
getSessionStore().archiveAllSessions();
|
||||
getSenderKeyStore().deleteAll();
|
||||
final var recipientId = getRecipientStore().resolveSelfRecipientTrusted(getSelfRecipientAddress());
|
||||
final var publicKey = getIdentityKeyPair().getPublicKey();
|
||||
final var publicKey = getAciIdentityKeyPair().getPublicKey();
|
||||
getIdentityKeyStore().saveIdentity(recipientId, publicKey, new Date());
|
||||
getIdentityKeyStore().setIdentityTrustLevel(recipientId, publicKey, TrustLevel.TRUSTED_VERIFIED);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ public record RecipientAddress(Optional<UUID> uuid, Optional<String> number) {
|
|||
}
|
||||
|
||||
public RecipientAddress(SignalServiceAddress address) {
|
||||
this(Optional.of(address.getAci().uuid()), Optional.ofNullable(address.getNumber().orNull()));
|
||||
this(Optional.of(address.getServiceId().uuid()), Optional.ofNullable(address.getNumber().orNull()));
|
||||
}
|
||||
|
||||
public RecipientAddress(UUID uuid) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package org.asamk.signal.manager.storage.recipients;
|
||||
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
|
||||
public interface RecipientResolver {
|
||||
|
@ -11,7 +11,7 @@ public interface RecipientResolver {
|
|||
|
||||
RecipientId resolveRecipient(SignalServiceAddress address);
|
||||
|
||||
RecipientId resolveRecipient(ACI aci);
|
||||
RecipientId resolveRecipient(ServiceId aci);
|
||||
|
||||
RecipientId resolveRecipient(long recipientId);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.signal.zkgroup.profiles.ProfileKeyCredential;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.signalservice.api.push.ACI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
|
||||
|
@ -171,8 +172,8 @@ public class RecipientStore implements RecipientResolver, ContactsStore, Profile
|
|||
}
|
||||
|
||||
@Override
|
||||
public RecipientId resolveRecipient(ACI aci) {
|
||||
return resolveRecipient(new RecipientAddress(aci.uuid()), false, false);
|
||||
public RecipientId resolveRecipient(ServiceId serviceId) {
|
||||
return resolveRecipient(new RecipientAddress(serviceId.uuid()), false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -65,8 +65,8 @@ public class Utils {
|
|||
if (isUuidCapable) {
|
||||
// Version 2: UUID user
|
||||
version = 2;
|
||||
ownId = ownAddress.getAci().toByteArray();
|
||||
theirId = theirAddress.getAci().toByteArray();
|
||||
ownId = ownAddress.getServiceId().toByteArray();
|
||||
theirId = theirAddress.getServiceId().toByteArray();
|
||||
} else {
|
||||
// Version 1: E164 user
|
||||
version = 1;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue