]> nmode's Git Repositories - signal-cli/blobdiff - lib/src/main/java/org/asamk/signal/manager/internal/ProvisioningManagerImpl.java
Update libsignal-service
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / internal / ProvisioningManagerImpl.java
index d372a27ec468107bdfd0cbd13db50b0b81eb80c0..e5a381e102952830b1f257aa9b8121ea7b33110e 100644 (file)
@@ -19,6 +19,7 @@ package org.asamk.signal.manager.internal;
 import org.asamk.signal.manager.Manager;
 import org.asamk.signal.manager.ProvisioningManager;
 import org.asamk.signal.manager.Settings;
+import org.asamk.signal.manager.api.DeviceLinkUrl;
 import org.asamk.signal.manager.api.UserAlreadyExistsException;
 import org.asamk.signal.manager.config.ServiceConfig;
 import org.asamk.signal.manager.config.ServiceEnvironmentConfig;
@@ -26,16 +27,16 @@ import org.asamk.signal.manager.storage.SignalAccount;
 import org.asamk.signal.manager.storage.accounts.AccountsStore;
 import org.asamk.signal.manager.util.KeyUtils;
 import org.signal.libsignal.protocol.IdentityKeyPair;
-import org.signal.libsignal.protocol.util.KeyHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-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.ServiceIdType;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException;
+import org.whispersystems.signalservice.api.registration.ProvisioningApi;
 import org.whispersystems.signalservice.api.util.DeviceNameUtil;
-import org.whispersystems.signalservice.internal.push.ConfirmCodeMessage;
+import org.whispersystems.signalservice.internal.push.ProvisioningSocket;
+import org.whispersystems.signalservice.internal.push.PushServiceSocket;
 import org.whispersystems.signalservice.internal.util.DynamicCredentialsProvider;
 
 import java.io.IOException;
@@ -44,11 +45,11 @@ import java.nio.channels.OverlappingFileLockException;
 import java.util.concurrent.TimeoutException;
 import java.util.function.Consumer;
 
-import static org.asamk.signal.manager.config.ServiceConfig.getCapabilities;
+import static org.asamk.signal.manager.util.KeyUtils.generatePreKeysForType;
 
 public class ProvisioningManagerImpl implements ProvisioningManager {
 
-    private final static Logger logger = LoggerFactory.getLogger(ProvisioningManagerImpl.class);
+    private static final Logger logger = LoggerFactory.getLogger(ProvisioningManagerImpl.class);
 
     private final PathConfig pathConfig;
     private final ServiceEnvironmentConfig serviceEnvironmentConfig;
@@ -56,10 +57,8 @@ public class ProvisioningManagerImpl implements ProvisioningManager {
     private final Consumer<Manager> newManagerListener;
     private final AccountsStore accountsStore;
 
-    private final SignalServiceAccountManager accountManager;
+    private final ProvisioningApi provisioningApi;
     private final IdentityKeyPair tempIdentityKey;
-    private final int registrationId;
-    private final int pniRegistrationId;
     private final String password;
 
     public ProvisioningManagerImpl(
@@ -76,33 +75,33 @@ public class ProvisioningManagerImpl implements ProvisioningManager {
         this.accountsStore = accountsStore;
 
         tempIdentityKey = KeyUtils.generateIdentityKeyPair();
-        registrationId = KeyHelper.generateRegistrationId(false);
-        pniRegistrationId = KeyHelper.generateRegistrationId(false);
         password = KeyUtils.createPassword();
-        GroupsV2Operations groupsV2Operations;
-        try {
-            groupsV2Operations = new GroupsV2Operations(ClientZkOperations.create(serviceEnvironmentConfig.getSignalServiceConfiguration()),
-                    ServiceConfig.GROUP_MAX_SIZE);
-        } catch (Throwable ignored) {
-            groupsV2Operations = null;
-        }
-        accountManager = new SignalServiceAccountManager(serviceEnvironmentConfig.getSignalServiceConfiguration(),
-                new DynamicCredentialsProvider(null, null, null, password, SignalServiceAddress.DEFAULT_DEVICE_ID),
+        final var clientZkOperations = ClientZkOperations.create(serviceEnvironmentConfig.signalServiceConfiguration());
+        final var credentialsProvider = new DynamicCredentialsProvider(null,
+                null,
+                null,
+                password,
+                SignalServiceAddress.DEFAULT_DEVICE_ID);
+        final var pushServiceSocket = new PushServiceSocket(serviceEnvironmentConfig.signalServiceConfiguration(),
+                credentialsProvider,
                 userAgent,
-                groupsV2Operations,
+                clientZkOperations.getProfileOperations(),
                 ServiceConfig.AUTOMATIC_NETWORK_RETRY);
+        final var provisioningSocket = new ProvisioningSocket(serviceEnvironmentConfig.signalServiceConfiguration(),
+                userAgent);
+        this.provisioningApi = new ProvisioningApi(pushServiceSocket, provisioningSocket, credentialsProvider);
     }
 
     @Override
     public URI getDeviceLinkUri() throws TimeoutException, IOException {
-        var deviceUuid = accountManager.getNewDeviceUuid();
+        var deviceUuid = provisioningApi.getNewDeviceUuid();
 
-        return new DeviceLinkInfo(deviceUuid, tempIdentityKey.getPublicKey().getPublicKey()).createDeviceLinkUri();
+        return new DeviceLinkUrl(deviceUuid, tempIdentityKey.getPublicKey().getPublicKey()).createDeviceLinkUri();
     }
 
     @Override
     public String finishDeviceLink(String deviceName) throws IOException, TimeoutException, UserAlreadyExistsException {
-        var ret = accountManager.getNewDeviceRegistration(tempIdentityKey);
+        var ret = provisioningApi.getNewDeviceRegistration(tempIdentityKey);
         var number = ret.getNumber();
         var aci = ret.getAci();
         var pni = ret.getPni();
@@ -113,9 +112,9 @@ public class ProvisioningManagerImpl implements ProvisioningManager {
         if (accountPath == null) {
             accountPath = accountsStore.getPathByNumber(number);
         }
-        if (accountPath != null
-                && SignalAccount.accountFileExists(pathConfig.dataPath(), accountPath)
-                && !canRelinkExistingAccount(accountPath)) {
+        final var accountExists = accountPath != null && SignalAccount.accountFileExists(pathConfig.dataPath(),
+                accountPath);
+        if (accountExists && !canRelinkExistingAccount(accountPath)) {
             throw new UserAlreadyExistsException(number, SignalAccount.getFileName(pathConfig.dataPath(), accountPath));
         }
         if (accountPath == null) {
@@ -127,38 +126,45 @@ public class ProvisioningManagerImpl implements ProvisioningManager {
         var encryptedDeviceName = deviceName == null
                 ? null
                 : DeviceNameUtil.encryptDeviceName(deviceName, ret.getAciIdentity().getPrivateKey());
-
-        logger.debug("Finishing new device registration");
-        var deviceId = accountManager.finishNewDeviceRegistration(ret.getProvisioningCode(),
-                new ConfirmCodeMessage(false,
-                        true,
-                        registrationId,
-                        pniRegistrationId,
-                        encryptedDeviceName,
-                        getCapabilities(false)));
-
         // Create new account with the synced identity
         var profileKey = ret.getProfileKey() == null ? KeyUtils.createProfileKey() : ret.getProfileKey();
 
         SignalAccount account = null;
         try {
-            account = SignalAccount.createOrUpdateLinkedAccount(pathConfig.dataPath(),
-                    accountPath,
-                    number,
-                    serviceEnvironmentConfig.getType(),
+            if (!accountExists) {
+                account = SignalAccount.createLinkedAccount(pathConfig.dataPath(),
+                        accountPath,
+                        serviceEnvironmentConfig.type(),
+                        Settings.DEFAULT);
+            } else {
+                account = SignalAccount.load(pathConfig.dataPath(), accountPath, true, Settings.DEFAULT);
+            }
+
+            account.setProvisioningData(number,
                     aci,
                     pni,
                     password,
                     encryptedDeviceName,
-                    deviceId,
                     ret.getAciIdentity(),
                     ret.getPniIdentity(),
-                    registrationId,
-                    pniRegistrationId,
                     profileKey,
-                    Settings.DEFAULT);
+                    ret.getMasterKey(),
+                    ret.getAccountEntropyPool(),
+                    ret.getMediaRootBackupKey());
+
             account.getConfigurationStore().setReadReceipts(ret.isReadReceipts());
 
+            final var aciPreKeys = generatePreKeysForType(account.getAccountData(ServiceIdType.ACI));
+            final var pniPreKeys = generatePreKeysForType(account.getAccountData(ServiceIdType.PNI));
+
+            logger.debug("Finishing new device registration");
+            var deviceId = provisioningApi.finishNewDeviceRegistration(ret.getProvisioningCode(),
+                    account.getAccountAttributes(null),
+                    aciPreKeys,
+                    pniPreKeys);
+
+            account.finishLinking(deviceId, aciPreKeys, pniPreKeys);
+
             ManagerImpl m = null;
             try {
                 m = new ManagerImpl(account,
@@ -220,7 +226,7 @@ public class ProvisioningManagerImpl implements ProvisioningManager {
             }
             if (signalAccount.isRegistered()
                     && signalAccount.getServiceEnvironment() != null
-                    && signalAccount.getServiceEnvironment() != serviceEnvironmentConfig.getType()) {
+                    && signalAccount.getServiceEnvironment() != serviceEnvironmentConfig.type()) {
                 logger.debug("Account is registered in another environment: {}.",
                         signalAccount.getServiceEnvironment());
                 return false;