diff --git a/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java b/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java index 4e9f1a7..6f2fa69 100644 --- a/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java +++ b/app/src/main/java/org/mercury_im/messenger/android/di/component/AppComponent.java @@ -5,6 +5,7 @@ import org.mercury_im.messenger.android.di.module.AndroidDatabaseModule; import org.mercury_im.messenger.android.di.module.AndroidSchedulersModule; import org.mercury_im.messenger.android.ui.account.detail.AndroidAccountDetailsViewModel; import org.mercury_im.messenger.android.ui.roster.contacts.AndroidContactListViewModel; +import org.mercury_im.messenger.core.di.module.OpenPgpModule; import org.mercury_im.messenger.core.di.module.RxMercuryMessageStoreFactoryModule; import org.mercury_im.messenger.core.di.module.RxMercuryRosterStoreFactoryModule; import org.mercury_im.messenger.core.di.module.XmppTcpConnectionFactoryModule; @@ -46,6 +47,7 @@ import dagger.Component; ViewModelModule.class, XmppTcpConnectionFactoryModule.class, RxMercuryMessageStoreFactoryModule.class, + OpenPgpModule.class, RxMercuryRosterStoreFactoryModule.class }) public interface AppComponent { diff --git a/data/src/main/java/org/mercury_im/messenger/data/di/RepositoryModule.java b/data/src/main/java/org/mercury_im/messenger/data/di/RepositoryModule.java index 6000969..a657f8c 100644 --- a/data/src/main/java/org/mercury_im/messenger/data/di/RepositoryModule.java +++ b/data/src/main/java/org/mercury_im/messenger/data/di/RepositoryModule.java @@ -7,7 +7,6 @@ import org.mercury_im.messenger.core.data.repository.GroupChatRepository; import org.mercury_im.messenger.core.data.repository.MessageRepository; import org.mercury_im.messenger.core.data.repository.OpenPgpRepository; import org.mercury_im.messenger.core.data.repository.PeerRepository; -import org.mercury_im.messenger.core.data.repository.Repositories; import org.mercury_im.messenger.data.mapping.AccountMapping; import org.mercury_im.messenger.data.mapping.DirectChatMapping; import org.mercury_im.messenger.data.mapping.EntityCapsMapping; @@ -92,18 +91,4 @@ public class RepositoryModule { ReactiveEntityStore data, AccountRepository accountRepository) { return new RxOpenPgpRepository(data, accountRepository); } - - @Provides - @Singleton - static Repositories provideRepositories( - AccountRepository accountRepository, - DirectChatRepository directChatRepository, - GroupChatRepository groupChatRepository, - MessageRepository messageRepository, - PeerRepository peerRepository, - EntityCapsRepository entityCapsRepository, - OpenPgpRepository openPgpRepository) { - return new Repositories(accountRepository, directChatRepository, groupChatRepository, - messageRepository, peerRepository, entityCapsRepository, openPgpRepository); - } } diff --git a/domain/src/main/java/org/mercury_im/messenger/core/Messenger.java b/domain/src/main/java/org/mercury_im/messenger/core/Messenger.java index cdc425c..f19b3bd 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/Messenger.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/Messenger.java @@ -13,7 +13,6 @@ import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.stringprep.XmppStringprepException; import org.mercury_im.messenger.core.connection.MercuryConnection; import org.mercury_im.messenger.core.connection.MercuryConnectionManager; -import org.mercury_im.messenger.core.data.repository.Repositories; import org.mercury_im.messenger.core.exception.ConnectionNotFoundException; import org.mercury_im.messenger.core.exception.ContactAlreadyAddedException; import org.mercury_im.messenger.entity.contact.Peer; @@ -35,14 +34,11 @@ public class Messenger { private static final Logger LOGGER = Logger.getLogger(Messenger.class.getName()); private final MercuryConnectionManager connectionManager; - private final Repositories repositories; private final SchedulersFacade schedulers; @Inject - public Messenger(Repositories repositories, - MercuryConnectionManager connectionManager, + public Messenger(MercuryConnectionManager connectionManager, SchedulersFacade schedulers) { - this.repositories = repositories; this.connectionManager = connectionManager; this.schedulers = schedulers; } diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnectionManager.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnectionManager.java index 45e981b..9043a55 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnectionManager.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/connection/MercuryConnectionManager.java @@ -7,7 +7,6 @@ import org.mercury_im.messenger.core.connection.state.ConnectionPoolState; import org.mercury_im.messenger.core.connection.state.ConnectionState; import org.mercury_im.messenger.core.crypto.MercuryOpenPgpManager; import org.mercury_im.messenger.core.data.repository.AccountRepository; -import org.mercury_im.messenger.core.data.repository.Repositories; import org.mercury_im.messenger.core.store.caps.MercuryEntityCapsStore; import org.mercury_im.messenger.core.store.message.MercuryMessageStore; import org.mercury_im.messenger.core.store.message.MercuryMessageStoreFactory; @@ -58,14 +57,14 @@ public class MercuryConnectionManager { } @Inject - public MercuryConnectionManager(Repositories repositories, + public MercuryConnectionManager(AccountRepository accountRepository, RosterStoreBinder rosterStoreBinder, MercuryEntityCapsStore entityCapsStore, MercuryMessageStoreFactory messageStoreFactory, XmppConnectionFactory connectionFactory, MercuryOpenPgpManager cryptoManager, SchedulersFacade schedulers) { - this.accountRepository = repositories.getAccountRepository(); + this.accountRepository = accountRepository; this.rosterStoreBinder = rosterStoreBinder; this.connectionFactory = connectionFactory; this.messageStoreFactory = messageStoreFactory; @@ -131,8 +130,8 @@ public class MercuryConnectionManager { private BiPredicate, Optional> accountNotToggledNorRemoved = (first, second) -> // Account not removed first.isPresent() == second.isPresent() - // If account is not removed check if not toggled - && (!first.isPresent() || first.getItem().isEnabled() == second.getItem().isEnabled()); + // If account is not removed check if not toggled + && (!first.isPresent() || first.getItem().isEnabled() == second.getItem().isEnabled()); private synchronized void putConnection(MercuryConnection connection) { connectionsMap.put(connection.getAccountId(), connection); diff --git a/domain/src/main/java/org/mercury_im/messenger/core/connection/XmppDirectMessageCenter.java b/domain/src/main/java/org/mercury_im/messenger/core/connection/XmppDirectMessageCenter.java index 319d28f..ad70bd6 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/connection/XmppDirectMessageCenter.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/connection/XmppDirectMessageCenter.java @@ -14,7 +14,6 @@ import org.mercury_im.messenger.core.data.repository.AccountRepository; import org.mercury_im.messenger.core.data.repository.DirectChatRepository; import org.mercury_im.messenger.core.data.repository.MessageRepository; import org.mercury_im.messenger.core.data.repository.PeerRepository; -import org.mercury_im.messenger.core.data.repository.Repositories; import org.mercury_im.messenger.core.listener.IncomingDirectMessageListener; import org.mercury_im.messenger.entity.Account; import org.mercury_im.messenger.entity.chat.DirectChat; @@ -44,13 +43,15 @@ public class XmppDirectMessageCenter private Set messageListeners = new LinkedHashSet<>(); @Inject - public XmppDirectMessageCenter(Account account, Messenger messenger, Repositories repositories) { + public XmppDirectMessageCenter(Account account, Messenger messenger, PeerRepository peerRepository, + AccountRepository accountRepository, DirectChatRepository directChatRepository, + MessageRepository messageRepository) { this.messenger = messenger; this.account = account; - this.peerRepository = repositories.getPeerRepository(); - this.accountRepository = repositories.getAccountRepository(); - this.directChatRepository = repositories.getDirectChatRepository(); - this.messageRepository = repositories.getMessageRepository(); + this.peerRepository = peerRepository; + this.accountRepository = accountRepository; + this.directChatRepository = directChatRepository; + this.messageRepository = messageRepository; XMPPConnection connection = getMessenger().getConnectionManager().getConnection(account).getConnection(); diff --git a/domain/src/main/java/org/mercury_im/messenger/core/crypto/InsecureStaticSecretKeyBackupPassphraseGenerator.java b/domain/src/main/java/org/mercury_im/messenger/core/crypto/InsecureStaticSecretKeyBackupPassphraseGenerator.java new file mode 100644 index 0000000..a267be6 --- /dev/null +++ b/domain/src/main/java/org/mercury_im/messenger/core/crypto/InsecureStaticSecretKeyBackupPassphraseGenerator.java @@ -0,0 +1,16 @@ +package org.mercury_im.messenger.core.crypto; + +import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase; + +/** + * For testing purposes we always use the same static passphrase for secret key backups. + * This obviously MUST NOT make it to production! + */ +public class InsecureStaticSecretKeyBackupPassphraseGenerator implements OpenPgpSecretKeyBackupPassphraseGenerator { + + @Override + public OpenPgpSecretKeyBackupPassphrase generateBackupPassphrase() { + return new OpenPgpSecretKeyBackupPassphrase("71ZA-Y416-UA7A-7NCE-3SNM-88EF"); + } + +} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/crypto/MercuryOpenPgpManager.java b/domain/src/main/java/org/mercury_im/messenger/core/crypto/MercuryOpenPgpManager.java index 4fa7d15..970bb73 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/crypto/MercuryOpenPgpManager.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/crypto/MercuryOpenPgpManager.java @@ -3,18 +3,20 @@ package org.mercury_im.messenger.core.crypto; import org.jivesoftware.smack.AbstractConnectionListener; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smackx.ox.OpenPgpManager; +import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase; import org.jivesoftware.smackx.ox.crypto.OpenPgpProvider; import org.jivesoftware.smackx.ox.crypto.PainlessOpenPgpProvider; import org.jivesoftware.smackx.ox.exception.InvalidBackupCodeException; import org.jivesoftware.smackx.ox.exception.NoBackupFoundException; import org.jivesoftware.smackx.ox.store.definition.OpenPgpStore; -import org.jivesoftware.smackx.ox.util.SecretKeyBackupHelper; import org.jivesoftware.smackx.ox_im.OXInstantMessagingManager; import org.jivesoftware.smackx.pubsub.PubSubException; import org.mercury_im.messenger.core.SchedulersFacade; import org.mercury_im.messenger.core.connection.MercuryConnection; +import org.mercury_im.messenger.core.data.repository.DirectChatRepository; +import org.mercury_im.messenger.core.data.repository.MessageRepository; import org.mercury_im.messenger.core.data.repository.OpenPgpRepository; -import org.mercury_im.messenger.core.data.repository.Repositories; +import org.mercury_im.messenger.core.data.repository.PeerRepository; import org.mercury_im.messenger.core.store.crypto.MercuryOpenPgpStore; import org.mercury_im.messenger.core.store.message.MercuryMessageStore; @@ -27,17 +29,26 @@ public class MercuryOpenPgpManager { private static final Logger LOGGER = Logger.getLogger(MercuryOpenPgpManager.class.getName()); - private final Repositories repositories; + private final PeerRepository peerRepository; + private final DirectChatRepository directChatRepository; + private final MessageRepository messageRepository; private final OpenPgpRepository openPgpRepository; private final SchedulersFacade schedulers; + private final OpenPgpSecretKeyBackupPassphraseGenerator passphraseGenerator; @Inject - public MercuryOpenPgpManager(OpenPgpRepository openPgpRepository, - SchedulersFacade schedulers, - Repositories repositories) { + public MercuryOpenPgpManager(PeerRepository peerRepository, + DirectChatRepository directChatRepository, + MessageRepository messageRepository, + OpenPgpRepository openPgpRepository, + OpenPgpSecretKeyBackupPassphraseGenerator passphraseGenerator, + SchedulersFacade schedulers) { + this.peerRepository = peerRepository; + this.directChatRepository = directChatRepository; + this.messageRepository = messageRepository; this.openPgpRepository = openPgpRepository; this.schedulers = schedulers; - this.repositories = repositories; + this.passphraseGenerator = passphraseGenerator; } public void initialize(MercuryConnection connection) { @@ -56,14 +67,11 @@ public class MercuryOpenPgpManager { } private void setup(MercuryConnection connection) { - final String temporaryFixedTestingPassword = "71ZA-Y416-UA7A-7NCE-3SNM-88EF"; OpenPgpStore store = new MercuryOpenPgpStore(connection.getAccountId(), openPgpRepository, schedulers); OpenPgpProvider provider = new PainlessOpenPgpProvider(store); OpenPgpManager oxManager = OpenPgpManager.getInstanceFor(connection.getConnection()); oxManager.setOpenPgpProvider(provider); - SecretKeyBackupHelper.setBackupCodeGenerator( - // TODO: REMOVE IN PRODUCTION!!! - () -> temporaryFixedTestingPassword); + OpenPgpSecretKeyBackupPassphrase passphrase = passphraseGenerator.generateBackupPassphrase(); try { boolean mustGenerate = false; if (!oxManager.hasSecretKeysAvailable()) { @@ -71,7 +79,7 @@ public class MercuryOpenPgpManager { if (OpenPgpManager.serverSupportsSecretKeyBackups(connection.getConnection())) { try { oxManager.restoreSecretKeyServerBackup( - () -> temporaryFixedTestingPassword); + () -> passphrase); mustGenerate = false; LOGGER.log(Level.INFO, "Successfully restored secret key backup!"); } catch (NoBackupFoundException | PubSubException.NotALeafNodeException | InvalidBackupCodeException e) { @@ -84,15 +92,14 @@ public class MercuryOpenPgpManager { oxManager.generateAndImportKeyPair(connection.getAccount().getJid()); if (OpenPgpManager.serverSupportsSecretKeyBackups(connection.getConnection())) { oxManager.backupSecretKeyToServer( - backupCode -> LOGGER.log(Level.INFO, "OpenPGP Backup Code: " + backupCode), - availableSecretKeys -> availableSecretKeys); + availableSecretKeys -> availableSecretKeys, + passphrase); } } oxManager.announceSupportAndPublish(); OXInstantMessagingManager oximManager = OXInstantMessagingManager.getInstanceFor(connection.getConnection()); oximManager.addOxMessageListener(new MercuryMessageStore(connection.getAccount(), - repositories.getPeerRepository(), repositories.getDirectChatRepository(), - repositories.getMessageRepository(), schedulers)); + peerRepository, directChatRepository, messageRepository, schedulers)); oximManager.announceSupportForOxInstantMessaging(); } catch (Exception e) { e.printStackTrace(); diff --git a/domain/src/main/java/org/mercury_im/messenger/core/crypto/OpenPgpSecretKeyBackupPassphraseGenerator.java b/domain/src/main/java/org/mercury_im/messenger/core/crypto/OpenPgpSecretKeyBackupPassphraseGenerator.java new file mode 100644 index 0000000..2947878 --- /dev/null +++ b/domain/src/main/java/org/mercury_im/messenger/core/crypto/OpenPgpSecretKeyBackupPassphraseGenerator.java @@ -0,0 +1,8 @@ +package org.mercury_im.messenger.core.crypto; + +import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase; + +public interface OpenPgpSecretKeyBackupPassphraseGenerator { + + OpenPgpSecretKeyBackupPassphrase generateBackupPassphrase(); +} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/crypto/SecureRandomSecretKeyBackupPassphraseGenerator.java b/domain/src/main/java/org/mercury_im/messenger/core/crypto/SecureRandomSecretKeyBackupPassphraseGenerator.java new file mode 100644 index 0000000..e2c2940 --- /dev/null +++ b/domain/src/main/java/org/mercury_im/messenger/core/crypto/SecureRandomSecretKeyBackupPassphraseGenerator.java @@ -0,0 +1,13 @@ +package org.mercury_im.messenger.core.crypto; + +import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase; +import org.jivesoftware.smackx.ox.util.SecretKeyBackupHelper; + +public class SecureRandomSecretKeyBackupPassphraseGenerator implements OpenPgpSecretKeyBackupPassphraseGenerator { + + @Override + public OpenPgpSecretKeyBackupPassphrase generateBackupPassphrase() { + return SecretKeyBackupHelper.generateBackupPassword(); + } + +} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/data/repository/Repositories.java b/domain/src/main/java/org/mercury_im/messenger/core/data/repository/Repositories.java deleted file mode 100644 index 6179ba5..0000000 --- a/domain/src/main/java/org/mercury_im/messenger/core/data/repository/Repositories.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.mercury_im.messenger.core.data.repository; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import lombok.Value; - -@Singleton -@Value -public class Repositories { - - AccountRepository accountRepository; - DirectChatRepository directChatRepository; - GroupChatRepository groupChatRepository; - MessageRepository messageRepository; - PeerRepository peerRepository; - EntityCapsRepository entityCapsRepository; - OpenPgpRepository openPgpRepository; - - @Inject - public Repositories(AccountRepository accountRepository, - DirectChatRepository directChatRepository, - GroupChatRepository groupChatRepository, - MessageRepository messageRepository, - PeerRepository peerRepository, - EntityCapsRepository entityCapsRepository, - OpenPgpRepository openPgpRepository) { - this.accountRepository = accountRepository; - this.directChatRepository = directChatRepository; - this.groupChatRepository = groupChatRepository; - this.messageRepository = messageRepository; - this.peerRepository = peerRepository; - this.entityCapsRepository = entityCapsRepository; - this.openPgpRepository = openPgpRepository; - } -} diff --git a/domain/src/main/java/org/mercury_im/messenger/core/di/module/OpenPgpModule.java b/domain/src/main/java/org/mercury_im/messenger/core/di/module/OpenPgpModule.java index c1b699f..dde4619 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/di/module/OpenPgpModule.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/di/module/OpenPgpModule.java @@ -1,8 +1,21 @@ package org.mercury_im.messenger.core.di.module; +import org.mercury_im.messenger.core.crypto.InsecureStaticSecretKeyBackupPassphraseGenerator; +import org.mercury_im.messenger.core.crypto.OpenPgpSecretKeyBackupPassphraseGenerator; + +import javax.inject.Singleton; + import dagger.Module; +import dagger.Provides; @Module public class OpenPgpModule { + @Singleton + @Provides + static OpenPgpSecretKeyBackupPassphraseGenerator provideSecretKeyBackupPassphraseGenerator() { + // TODO: THIS MUST NEVER MAKE IT TO PRODUCTION!!! + return new InsecureStaticSecretKeyBackupPassphraseGenerator(); + } + } diff --git a/domain/src/main/java/org/mercury_im/messenger/core/di/module/RxMercuryMessageStoreFactoryModule.java b/domain/src/main/java/org/mercury_im/messenger/core/di/module/RxMercuryMessageStoreFactoryModule.java index 4a28e6e..7372b40 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/di/module/RxMercuryMessageStoreFactoryModule.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/di/module/RxMercuryMessageStoreFactoryModule.java @@ -1,7 +1,9 @@ package org.mercury_im.messenger.core.di.module; import org.mercury_im.messenger.core.SchedulersFacade; -import org.mercury_im.messenger.core.data.repository.Repositories; +import org.mercury_im.messenger.core.data.repository.DirectChatRepository; +import org.mercury_im.messenger.core.data.repository.MessageRepository; +import org.mercury_im.messenger.core.data.repository.PeerRepository; import org.mercury_im.messenger.core.store.message.MercuryMessageStore; import org.mercury_im.messenger.core.store.message.MercuryMessageStoreFactory; @@ -15,12 +17,12 @@ public class RxMercuryMessageStoreFactoryModule { @Provides @Singleton - static MercuryMessageStoreFactory provideMessageStoreFactory(Repositories repositories, SchedulersFacade schedulers) { + static MercuryMessageStoreFactory provideMessageStoreFactory(PeerRepository peerRepository, + DirectChatRepository directChatRepository, + MessageRepository messageRepository, + SchedulersFacade schedulers) { - return account -> new MercuryMessageStore(account, - repositories.getPeerRepository(), - repositories.getDirectChatRepository(), - repositories.getMessageRepository(), - schedulers); + return account -> new MercuryMessageStore(account, peerRepository, directChatRepository, + messageRepository, schedulers); } } diff --git a/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/openpgp/OxSecretKeyBackupRestoreViewModel.java b/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/openpgp/OxSecretKeyBackupRestoreViewModel.java index b3197bf..69e2590 100644 --- a/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/openpgp/OxSecretKeyBackupRestoreViewModel.java +++ b/domain/src/main/java/org/mercury_im/messenger/core/viewmodel/openpgp/OxSecretKeyBackupRestoreViewModel.java @@ -4,6 +4,7 @@ import org.bouncycastle.openpgp.PGPException; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.ox.OpenPgpManager; +import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase; import org.jivesoftware.smackx.ox.exception.InvalidBackupCodeException; import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException; import org.jivesoftware.smackx.ox.exception.NoBackupFoundException; @@ -41,7 +42,8 @@ public class OxSecretKeyBackupRestoreViewModel implements MercuryViewModel { public void onRestoreCodeEntered(String code) { try { - OpenPgpV4Fingerprint fingerprint = openPgpManager.restoreSecretKeyServerBackup(() -> code); + OpenPgpSecretKeyBackupPassphrase passphrase = new OpenPgpSecretKeyBackupPassphrase(code); + OpenPgpV4Fingerprint fingerprint = openPgpManager.restoreSecretKeyServerBackup(() -> passphrase); LOGGER.log(Level.INFO, "Successfully restored OX secret key " + fingerprint + " for " + openPgpManager.getOpenPgpSelf().getJid()); finished.onNext(true); } catch (InvalidBackupCodeException e) { diff --git a/libs/Smack b/libs/Smack index f1f0a3d..1267729 160000 --- a/libs/Smack +++ b/libs/Smack @@ -1 +1 @@ -Subproject commit f1f0a3d61ac9698bfbc627db4b6fdde5e478c4d8 +Subproject commit 1267729430f2c53f966b98febf16ef7f262b94d7