]> nmode's Git Repositories - signal-cli/blobdiff - lib/src/main/java/org/asamk/signal/manager/internal/RegistrationManagerImpl.java
Update libsignal-service-java
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / internal / RegistrationManagerImpl.java
index eb51b715faf2b55b848bca40e5e1cd197b168201..dca5f7ab7040e5bf4795a02a649d5e257de6a193 100644 (file)
@@ -29,16 +29,19 @@ import org.asamk.signal.manager.config.ServiceEnvironmentConfig;
 import org.asamk.signal.manager.helper.AccountFileUpdater;
 import org.asamk.signal.manager.helper.PinHelper;
 import org.asamk.signal.manager.storage.SignalAccount;
+import org.asamk.signal.manager.util.KeyUtils;
 import org.asamk.signal.manager.util.NumberVerificationUtils;
 import org.asamk.signal.manager.util.Utils;
 import org.signal.libsignal.usernames.BaseUsernameException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.whispersystems.signalservice.api.SignalServiceAccountManager;
+import org.whispersystems.signalservice.api.account.PreKeyCollection;
 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.ServiceIdType;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 import org.whispersystems.signalservice.api.push.exceptions.AlreadyVerifiedException;
 import org.whispersystems.signalservice.api.push.exceptions.DeprecatedVersionException;
@@ -48,6 +51,8 @@ import org.whispersystems.signalservice.internal.util.DynamicCredentialsProvider
 import java.io.IOException;
 import java.util.function.Consumer;
 
+import static org.asamk.signal.manager.config.ServiceConfig.PREKEY_MAXIMUM_ID;
+
 public class RegistrationManagerImpl implements RegistrationManager {
 
     private final static Logger logger = LoggerFactory.getLogger(RegistrationManagerImpl.class);
@@ -138,12 +143,21 @@ public class RegistrationManagerImpl implements RegistrationManager {
     public void verifyAccount(
             String verificationCode, String pin
     ) throws IOException, PinLockedException, IncorrectPinException {
-        var sessionId = account.getSessionId(account.getNumber());
-        final var result = NumberVerificationUtils.verifyNumber(sessionId,
+        if (account.getPniIdentityKeyPair() == null) {
+            account.setPniIdentityKeyPair(KeyUtils.generateIdentityKeyPair());
+        }
+
+        final var aciPreKeys = generatePreKeysForType(ServiceIdType.ACI);
+        final var pniPreKeys = generatePreKeysForType(ServiceIdType.PNI);
+        final var result = NumberVerificationUtils.verifyNumber(account.getSessionId(account.getNumber()),
                 verificationCode,
                 pin,
                 pinHelper,
-                this::verifyAccountWithCode);
+                (sessionId1, verificationCode1, registrationLock) -> verifyAccountWithCode(sessionId1,
+                        verificationCode1,
+                        registrationLock,
+                        aciPreKeys,
+                        pniPreKeys));
         final var response = result.first();
         final var masterKey = result.second();
         if (masterKey == null) {
@@ -153,7 +167,7 @@ public class RegistrationManagerImpl implements RegistrationManager {
         //accountManager.setGcmId(Optional.of(GoogleCloudMessaging.getInstance(this).register(REGISTRATION_ID)));
         final var aci = ACI.parseOrNull(response.getUuid());
         final var pni = PNI.parseOrNull(response.getPni());
-        account.finishRegistration(aci, pni, masterKey, pin);
+        account.finishRegistration(aci, pni, masterKey, pin, aciPreKeys, pniPreKeys);
         accountFileUpdater.updateAccountIdentifiers(account.getNumber(), aci);
 
         ManagerImpl m = null;
@@ -228,7 +242,11 @@ public class RegistrationManagerImpl implements RegistrationManager {
     }
 
     private VerifyAccountResponse verifyAccountWithCode(
-            final String sessionId, final String verificationCode, final String registrationLock
+            final String sessionId,
+            final String verificationCode,
+            final String registrationLock,
+            final PreKeyCollection aciPreKeys,
+            final PreKeyCollection pniPreKeys
     ) throws IOException {
         try {
             Utils.handleResponseException(accountManager.verifyAccount(verificationCode, sessionId));
@@ -238,9 +256,41 @@ public class RegistrationManagerImpl implements RegistrationManager {
         return Utils.handleResponseException(accountManager.registerAccount(sessionId,
                 null,
                 account.getAccountAttributes(registrationLock),
+                aciPreKeys,
+                pniPreKeys,
+                null,
                 true));
     }
 
+    private PreKeyCollection generatePreKeysForType(ServiceIdType serviceIdType) {
+        final var accountData = account.getAccountData(serviceIdType);
+        final var keyPair = accountData.getIdentityKeyPair();
+        final var preKeyMetadata = accountData.getPreKeyMetadata();
+
+        final var preKeyIdOffset = preKeyMetadata.getPreKeyIdOffset();
+        final var oneTimeEcPreKeys = KeyUtils.generatePreKeyRecords(preKeyIdOffset);
+        final var nextSignedPreKeyId = preKeyMetadata.getNextSignedPreKeyId();
+        final var signedPreKey = KeyUtils.generateSignedPreKeyRecord(nextSignedPreKeyId, keyPair);
+
+        final var privateKey = keyPair.getPrivateKey();
+        final var kyberPreKeyIdOffset = preKeyMetadata.getKyberPreKeyIdOffset();
+        final var oneTimeKyberPreKeys = KeyUtils.generateKyberPreKeyRecords(kyberPreKeyIdOffset, privateKey);
+        final var lastResortKyberPreKeyId = (kyberPreKeyIdOffset + oneTimeKyberPreKeys.size()) % PREKEY_MAXIMUM_ID;
+        final var lastResortKyberPreKey = KeyUtils.generateKyberPreKeyRecord(lastResortKyberPreKeyId, privateKey);
+
+        return new PreKeyCollection(keyPair,
+                nextSignedPreKeyId,
+                preKeyIdOffset,
+                lastResortKyberPreKeyId,
+                kyberPreKeyIdOffset,
+                serviceIdType,
+                keyPair.getPublicKey(),
+                signedPreKey,
+                oneTimeEcPreKeys,
+                lastResortKyberPreKey,
+                oneTimeKyberPreKeys);
+    }
+
     @Override
     public void close() {
         if (account != null) {