From 7f83bfefd6531cd9d9390dcf4a7673c2f368d57d Mon Sep 17 00:00:00 2001 From: AsamK Date: Mon, 2 Oct 2023 12:09:41 +0200 Subject: [PATCH] Reorganize SignalAccount --- .../signal/manager/helper/PreKeyHelper.java | 12 +- .../signal/manager/storage/SignalAccount.java | 260 ++++++++---------- 2 files changed, 127 insertions(+), 145 deletions(-) diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/PreKeyHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/PreKeyHelper.java index 34d11171..e06ebbc1 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/PreKeyHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/PreKeyHelper.java @@ -120,7 +120,8 @@ public class PreKeyHelper { } private List generatePreKeys(ServiceIdType serviceIdType) { - final var offset = account.getPreKeyIdOffset(serviceIdType); + final var accountData = account.getAccountData(serviceIdType); + final var offset = accountData.getPreKeyMetadata().getPreKeyIdOffset(); var records = KeyUtils.generatePreKeyRecords(offset); account.addPreKeys(serviceIdType, records); @@ -144,7 +145,8 @@ public class PreKeyHelper { } private SignedPreKeyRecord generateSignedPreKey(ServiceIdType serviceIdType, IdentityKeyPair identityKeyPair) { - final var signedPreKeyId = account.getNextSignedPreKeyId(serviceIdType); + final var accountData = account.getAccountData(serviceIdType); + final var signedPreKeyId = accountData.getPreKeyMetadata().getNextSignedPreKeyId(); var record = KeyUtils.generateSignedPreKeyRecord(signedPreKeyId, identityKeyPair); account.addSignedPreKey(serviceIdType, record); @@ -155,7 +157,8 @@ public class PreKeyHelper { private List generateKyberPreKeys( ServiceIdType serviceIdType, final IdentityKeyPair identityKeyPair ) { - final var offset = account.getKyberPreKeyIdOffset(serviceIdType); + final var accountData = account.getAccountData(serviceIdType); + final var offset = accountData.getPreKeyMetadata().getKyberPreKeyIdOffset(); var records = KeyUtils.generateKyberPreKeyRecords(offset, identityKeyPair.getPrivateKey()); account.addKyberPreKeys(serviceIdType, records); @@ -182,7 +185,8 @@ public class PreKeyHelper { private KyberPreKeyRecord generateLastResortKyberPreKey( ServiceIdType serviceIdType, IdentityKeyPair identityKeyPair ) { - final var signedPreKeyId = account.getKyberPreKeyIdOffset(serviceIdType); + final var accountData = account.getAccountData(serviceIdType); + final var signedPreKeyId = accountData.getPreKeyMetadata().getKyberPreKeyIdOffset(); var record = KeyUtils.generateKyberPreKeyRecord(signedPreKeyId, identityKeyPair.getPrivateKey()); account.addLastResortKyberPreKey(serviceIdType, record); diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java b/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java index 18a195e6..aef1d1c9 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java @@ -120,25 +120,27 @@ public class SignalAccount implements Closeable { private File dataPath; private String accountPath; + private ServiceEnvironment serviceEnvironment; private String number; private String username; private ACI aci; private PNI pni; - private String sessionId; - private String sessionNumber; private String encryptedDeviceName; private int deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID; - private boolean isMultiDevice = false; private String password; private String registrationLockPin; private MasterKey pinMasterKey; private StorageKey storageKey; - private long storageManifestVersion = -1; private ProfileKey profileKey; + private Settings settings; - private long lastReceiveTimestamp = 0; + private String sessionId; + private String sessionNumber; + private long lastReceiveTimestamp = 0; + private long storageManifestVersion = -1; + private boolean isMultiDevice = false; private boolean registered = false; private final AccountData aciAccountData = new AccountData(ServiceIdType.ACI); @@ -225,7 +227,7 @@ public class SignalAccount implements Closeable { return signalAccount; } - public static SignalAccount createOrUpdateLinkedAccount( + private static SignalAccount createLinkedAccount( File dataPath, String accountPath, String number, @@ -242,27 +244,18 @@ public class SignalAccount implements Closeable { ProfileKey profileKey, final Settings settings ) throws IOException { - IOUtils.createPrivateDirectories(dataPath); var fileName = getFileName(dataPath, accountPath); - if (!fileName.exists()) { - return createLinkedAccount(dataPath, - accountPath, - number, - serviceEnvironment, - aci, - pni, - password, - encryptedDeviceName, - deviceId, - aciIdentityKey, - pniIdentityKey, - registrationId, - pniRegistrationId, - profileKey, - settings); - } + IOUtils.createPrivateFile(fileName); - final var signalAccount = load(dataPath, accountPath, true, settings); + final var pair = openFileChannel(fileName, true); + var signalAccount = new SignalAccount(pair.first(), pair.second()); + + signalAccount.dataPath = dataPath; + signalAccount.accountPath = accountPath; + signalAccount.serviceEnvironment = serviceEnvironment; + signalAccount.aciAccountData.setLocalRegistrationId(registrationId); + signalAccount.pniAccountData.setLocalRegistrationId(pniRegistrationId); + signalAccount.settings = settings; signalAccount.setProvisioningData(number, aci, pni, @@ -272,51 +265,20 @@ public class SignalAccount implements Closeable { aciIdentityKey, pniIdentityKey, profileKey); + + signalAccount.configurationStore = new ConfigurationStore(signalAccount::saveConfigurationStore); + signalAccount.getRecipientTrustedResolver() .resolveSelfRecipientTrusted(signalAccount.getSelfRecipientAddress()); - signalAccount.aciAccountData.getSessionStore().archiveAllSessions(); - signalAccount.pniAccountData.getSessionStore().archiveAllSessions(); - signalAccount.getSenderKeyStore().deleteAll(); + signalAccount.previousStorageVersion = CURRENT_STORAGE_VERSION; + signalAccount.migrateLegacyConfigs(); signalAccount.clearAllPreKeys(); - return signalAccount; - } - - public void initDatabase() { - getAccountDatabase(); - } - - private void clearAllPreKeys() { - clearAllPreKeys(ServiceIdType.ACI); - clearAllPreKeys(ServiceIdType.PNI); - } - - private void clearAllPreKeys(ServiceIdType serviceIdType) { - final var accountData = getAccountData(serviceIdType); - resetPreKeyOffsets(serviceIdType); - resetKyberPreKeyOffsets(serviceIdType); - accountData.getPreKeyStore().removeAllPreKeys(); - accountData.getSignedPreKeyStore().removeAllSignedPreKeys(); - accountData.getKyberPreKeyStore().removeAllKyberPreKeys(); - save(); - } - - private void setPreKeys(ServiceIdType serviceIdType, PreKeyCollection preKeyCollection) { - final var accountData = getAccountData(serviceIdType); - final var preKeyMetadata = accountData.getPreKeyMetadata(); - preKeyMetadata.nextSignedPreKeyId = preKeyCollection.getSignedPreKey().getId(); - preKeyMetadata.kyberPreKeyIdOffset = preKeyCollection.getLastResortKyberPreKey().getId(); - - accountData.getPreKeyStore().removeAllPreKeys(); - accountData.getSignedPreKeyStore().removeAllSignedPreKeys(); - accountData.getKyberPreKeyStore().removeAllKyberPreKeys(); - - addSignedPreKey(serviceIdType, preKeyCollection.getSignedPreKey()); - addLastResortKyberPreKey(serviceIdType, preKeyCollection.getLastResortKyberPreKey()); + signalAccount.save(); - save(); + return signalAccount; } - private static SignalAccount createLinkedAccount( + public static SignalAccount createOrUpdateLinkedAccount( File dataPath, String accountPath, String number, @@ -333,18 +295,27 @@ public class SignalAccount implements Closeable { ProfileKey profileKey, final Settings settings ) throws IOException { + IOUtils.createPrivateDirectories(dataPath); var fileName = getFileName(dataPath, accountPath); - IOUtils.createPrivateFile(fileName); - - final var pair = openFileChannel(fileName, true); - var signalAccount = new SignalAccount(pair.first(), pair.second()); + if (!fileName.exists()) { + return createLinkedAccount(dataPath, + accountPath, + number, + serviceEnvironment, + aci, + pni, + password, + encryptedDeviceName, + deviceId, + aciIdentityKey, + pniIdentityKey, + registrationId, + pniRegistrationId, + profileKey, + settings); + } - signalAccount.dataPath = dataPath; - signalAccount.accountPath = accountPath; - signalAccount.serviceEnvironment = serviceEnvironment; - signalAccount.aciAccountData.setLocalRegistrationId(registrationId); - signalAccount.pniAccountData.setLocalRegistrationId(pniRegistrationId); - signalAccount.settings = settings; + final var signalAccount = load(dataPath, accountPath, true, settings); signalAccount.setProvisioningData(number, aci, pni, @@ -354,16 +325,12 @@ public class SignalAccount implements Closeable { aciIdentityKey, pniIdentityKey, profileKey); - - signalAccount.configurationStore = new ConfigurationStore(signalAccount::saveConfigurationStore); - signalAccount.getRecipientTrustedResolver() .resolveSelfRecipientTrusted(signalAccount.getSelfRecipientAddress()); - signalAccount.previousStorageVersion = CURRENT_STORAGE_VERSION; - signalAccount.migrateLegacyConfigs(); + signalAccount.aciAccountData.getSessionStore().archiveAllSessions(); + signalAccount.pniAccountData.getSessionStore().archiveAllSessions(); + signalAccount.getSenderKeyStore().deleteAll(); signalAccount.clearAllPreKeys(); - signalAccount.save(); - return signalAccount; } @@ -399,6 +366,42 @@ public class SignalAccount implements Closeable { trustSelfIdentity(ServiceIdType.PNI); } + public void finishRegistration( + final ACI aci, + final PNI pni, + final MasterKey masterKey, + final String pin, + final PreKeyCollection aciPreKeys, + final PreKeyCollection pniPreKeys + ) { + this.pinMasterKey = masterKey; + this.storageManifestVersion = -1; + this.setStorageManifest(null); + this.storageKey = null; + this.encryptedDeviceName = null; + this.deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID; + this.isMultiDevice = false; + this.registered = true; + this.aci = aci; + this.pni = pni; + this.registrationLockPin = pin; + this.lastReceiveTimestamp = 0; + save(); + + setPreKeys(ServiceIdType.ACI, aciPreKeys); + setPreKeys(ServiceIdType.PNI, pniPreKeys); + aciAccountData.getSessionStore().archiveAllSessions(); + pniAccountData.getSessionStore().archiveAllSessions(); + getSenderKeyStore().deleteAll(); + getRecipientTrustedResolver().resolveSelfRecipientTrusted(getSelfRecipientAddress()); + trustSelfIdentity(ServiceIdType.ACI); + trustSelfIdentity(ServiceIdType.PNI); + } + + public void initDatabase() { + getAccountDatabase(); + } + private void migrateLegacyConfigs() { if (getPassword() == null) { setPassword(KeyUtils.createPassword()); @@ -1066,6 +1069,37 @@ public class SignalAccount implements Closeable { } } + private void clearAllPreKeys() { + clearAllPreKeys(ServiceIdType.ACI); + clearAllPreKeys(ServiceIdType.PNI); + } + + private void clearAllPreKeys(ServiceIdType serviceIdType) { + final var accountData = getAccountData(serviceIdType); + resetPreKeyOffsets(serviceIdType); + resetKyberPreKeyOffsets(serviceIdType); + accountData.getPreKeyStore().removeAllPreKeys(); + accountData.getSignedPreKeyStore().removeAllSignedPreKeys(); + accountData.getKyberPreKeyStore().removeAllKyberPreKeys(); + save(); + } + + private void setPreKeys(ServiceIdType serviceIdType, PreKeyCollection preKeyCollection) { + final var accountData = getAccountData(serviceIdType); + final var preKeyMetadata = accountData.getPreKeyMetadata(); + preKeyMetadata.nextSignedPreKeyId = preKeyCollection.getSignedPreKey().getId(); + preKeyMetadata.kyberPreKeyIdOffset = preKeyCollection.getLastResortKyberPreKey().getId(); + + accountData.getPreKeyStore().removeAllPreKeys(); + accountData.getSignedPreKeyStore().removeAllSignedPreKeys(); + accountData.getKyberPreKeyStore().removeAllKyberPreKeys(); + + addSignedPreKey(serviceIdType, preKeyCollection.getSignedPreKey()); + addLastResortKyberPreKey(serviceIdType, preKeyCollection.getLastResortKyberPreKey()); + + save(); + } + public void resetPreKeyOffsets(final ServiceIdType serviceIdType) { final var preKeyMetadata = getAccountData(serviceIdType).getPreKeyMetadata(); preKeyMetadata.preKeyIdOffset = getRandomPreKeyIdOffset(); @@ -1344,7 +1378,7 @@ public class SignalAccount implements Closeable { public AccountAttributes getAccountAttributes(String registrationLock) { return new AccountAttributes(null, - getLocalRegistrationId(), + aciAccountData.getLocalRegistrationId(), false, false, true, @@ -1354,7 +1388,7 @@ public class SignalAccount implements Closeable { isDiscoverableByPhoneNumber(), getAccountCapabilities(), encryptedDeviceName, - getLocalPniRegistrationId(), + pniAccountData.getLocalRegistrationId(), null); // TODO recoveryPassword? } @@ -1398,7 +1432,7 @@ public class SignalAccount implements Closeable { final int localPniRegistrationId ) { setPniIdentityKeyPair(pniIdentityKeyPair); - setLocalPniRegistrationId(localPniRegistrationId); + pniAccountData.setLocalRegistrationId(localPniRegistrationId); final var preKeyMetadata = getAccountData(ServiceIdType.PNI).getPreKeyMetadata(); preKeyMetadata.nextSignedPreKeyId = pniSignedPreKey.getId(); @@ -1407,6 +1441,7 @@ public class SignalAccount implements Closeable { preKeyMetadata.kyberPreKeyIdOffset = lastResortKyberPreKey.getId(); addLastResortKyberPreKey(ServiceIdType.PNI, lastResortKyberPreKey); } + save(); } public SignalServiceAddress getSelfAddress() { @@ -1465,19 +1500,6 @@ public class SignalAccount implements Closeable { save(); } - public int getLocalRegistrationId() { - return aciAccountData.getLocalRegistrationId(); - } - - public int getLocalPniRegistrationId() { - return pniAccountData.getLocalRegistrationId(); - } - - public void setLocalPniRegistrationId(final int localPniRegistrationId) { - pniAccountData.setLocalRegistrationId(localPniRegistrationId); - save(); - } - public String getPassword() { return password; } @@ -1604,18 +1626,6 @@ public class SignalAccount implements Closeable { return UnidentifiedAccess.deriveAccessKeyFrom(getProfileKey()); } - public int getPreKeyIdOffset(ServiceIdType serviceIdType) { - return getAccountData(serviceIdType).getPreKeyMetadata().preKeyIdOffset; - } - - public int getNextSignedPreKeyId(ServiceIdType serviceIdType) { - return getAccountData(serviceIdType).getPreKeyMetadata().nextSignedPreKeyId; - } - - public int getKyberPreKeyIdOffset(ServiceIdType serviceIdType) { - return getAccountData(serviceIdType).getPreKeyMetadata().kyberPreKeyIdOffset; - } - public boolean isRegistered() { return registered; } @@ -1656,38 +1666,6 @@ public class SignalAccount implements Closeable { return phoneNumberUnlisted == null || !phoneNumberUnlisted; } - public void finishRegistration( - final ACI aci, - final PNI pni, - final MasterKey masterKey, - final String pin, - final PreKeyCollection aciPreKeys, - final PreKeyCollection pniPreKeys - ) { - this.pinMasterKey = masterKey; - this.storageManifestVersion = -1; - this.setStorageManifest(null); - this.storageKey = null; - this.encryptedDeviceName = null; - this.deviceId = SignalServiceAddress.DEFAULT_DEVICE_ID; - this.isMultiDevice = false; - this.registered = true; - this.aci = aci; - this.pni = pni; - this.registrationLockPin = pin; - this.lastReceiveTimestamp = 0; - save(); - - setPreKeys(ServiceIdType.ACI, aciPreKeys); - setPreKeys(ServiceIdType.PNI, pniPreKeys); - aciAccountData.getSessionStore().archiveAllSessions(); - pniAccountData.getSessionStore().archiveAllSessions(); - getSenderKeyStore().deleteAll(); - getRecipientTrustedResolver().resolveSelfRecipientTrusted(getSelfRecipientAddress()); - trustSelfIdentity(ServiceIdType.ACI); - trustSelfIdentity(ServiceIdType.PNI); - } - private void trustSelfIdentity(ServiceIdType serviceIdType) { final var accountData = getAccountData(serviceIdType); final var serviceId = accountData.getServiceId(); -- 2.50.1