Mercury-IM/domain/src/main/java/org/mercury_im/messenger/core/crypto/MercuryOpenPgpManager.java

144 lines
6.9 KiB
Java
Raw Normal View History

2020-06-15 17:41:13 +02:00
package org.mercury_im.messenger.core.crypto;
import org.jivesoftware.smack.AbstractConnectionListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smackx.ox.OpenPgpManager;
2020-07-18 14:11:04 +02:00
import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase;
2020-11-09 15:23:22 +01:00
import org.jivesoftware.smackx.ox.callback.SecretKeyPassphraseCallback;
2020-06-15 17:41:13 +02:00
import org.jivesoftware.smackx.ox.crypto.OpenPgpProvider;
2020-06-18 21:52:06 +02:00
import org.jivesoftware.smackx.ox.crypto.PainlessOpenPgpProvider;
2020-06-15 17:41:13 +02:00
import org.jivesoftware.smackx.ox.exception.InvalidBackupCodeException;
import org.jivesoftware.smackx.ox.exception.NoBackupFoundException;
2020-06-18 21:52:06 +02:00
import org.jivesoftware.smackx.ox.store.definition.OpenPgpStore;
2020-06-15 17:41:13 +02:00
import org.jivesoftware.smackx.ox_im.OXInstantMessagingManager;
import org.jivesoftware.smackx.pubsub.PubSubException;
2020-06-18 21:52:06 +02:00
import org.mercury_im.messenger.core.SchedulersFacade;
2020-07-18 12:47:52 +02:00
import org.mercury_im.messenger.core.connection.MercuryConnection;
2020-07-18 14:11:04 +02:00
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
import org.mercury_im.messenger.core.data.repository.MessageRepository;
2020-06-18 21:52:06 +02:00
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
2020-07-18 14:11:04 +02:00
import org.mercury_im.messenger.core.data.repository.PeerRepository;
2020-06-18 21:52:06 +02:00
import org.mercury_im.messenger.core.store.crypto.MercuryOpenPgpStore;
2020-06-24 22:50:26 +02:00
import org.mercury_im.messenger.core.store.message.MercuryMessageStore;
2020-06-15 17:41:13 +02:00
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
public class MercuryOpenPgpManager {
private static final Logger LOGGER = Logger.getLogger(MercuryOpenPgpManager.class.getName());
2020-07-18 14:11:04 +02:00
private final PeerRepository peerRepository;
private final DirectChatRepository directChatRepository;
private final MessageRepository messageRepository;
2020-06-18 21:52:06 +02:00
private final OpenPgpRepository openPgpRepository;
private final SchedulersFacade schedulers;
2020-07-18 14:11:04 +02:00
private final OpenPgpSecretKeyBackupPassphraseGenerator passphraseGenerator;
2020-11-09 15:23:22 +01:00
private final LocalOxKeyGenerationStrategy keyGenerationStrategy;
2020-06-15 17:41:13 +02:00
@Inject
2020-07-18 14:11:04 +02:00
public MercuryOpenPgpManager(PeerRepository peerRepository,
DirectChatRepository directChatRepository,
MessageRepository messageRepository,
OpenPgpRepository openPgpRepository,
OpenPgpSecretKeyBackupPassphraseGenerator passphraseGenerator,
2020-11-09 15:23:22 +01:00
LocalOxKeyGenerationStrategy keyGenerationStrategy,
2020-07-18 14:11:04 +02:00
SchedulersFacade schedulers) {
this.peerRepository = peerRepository;
this.directChatRepository = directChatRepository;
this.messageRepository = messageRepository;
2020-06-18 21:52:06 +02:00
this.openPgpRepository = openPgpRepository;
this.schedulers = schedulers;
2020-11-09 15:23:22 +01:00
this.keyGenerationStrategy = keyGenerationStrategy;
2020-07-18 14:11:04 +02:00
this.passphraseGenerator = passphraseGenerator;
2020-06-15 17:41:13 +02:00
}
public void initialize(MercuryConnection connection) {
if (connection.getConnection().isAuthenticated()) {
setup(connection);
} else {
connection.getConnection().addConnectionListener(new AbstractConnectionListener() {
@Override
public void authenticated(XMPPConnection con, boolean resumed) {
if (!resumed) {
setup(connection);
}
}
});
}
}
private void setup(MercuryConnection connection) {
2020-06-18 21:52:06 +02:00
OpenPgpStore store = new MercuryOpenPgpStore(connection.getAccountId(), openPgpRepository, schedulers);
OpenPgpProvider provider = new PainlessOpenPgpProvider(store);
2020-06-24 22:50:26 +02:00
OpenPgpManager oxManager = OpenPgpManager.getInstanceFor(connection.getConnection());
oxManager.setOpenPgpProvider(provider);
2020-07-18 14:11:04 +02:00
OpenPgpSecretKeyBackupPassphrase passphrase = passphraseGenerator.generateBackupPassphrase();
generateAndPublish(connection, oxManager, passphrase);
}
private void generateAndPublish(MercuryConnection connection, OpenPgpManager oxManager, OpenPgpSecretKeyBackupPassphrase passphrase) {
boolean mustGenerate = false;
try {
if (!oxManager.hasSecretKeysAvailable()) {
oxManager.generateAndImportKeyPair(connection.getAccount().getJid());
//if (OpenPgpManager.serverSupportsSecretKeyBackups(connection.getConnection())) {
// oxManager.backupSecretKeyToServer(
// availableSecretKeys -> availableSecretKeys,
// passphrase);
//}
}
oxManager.announceSupportAndPublish();
OXInstantMessagingManager oximManager = OXInstantMessagingManager.getInstanceFor(connection.getConnection());
oximManager.addOxMessageListener(new MercuryMessageStore(connection.getAccount(),
peerRepository, directChatRepository, messageRepository, schedulers));
oximManager.announceSupportForOxInstantMessaging();
} catch (Exception e) {
e.printStackTrace();
}
}
private void tryRestoringAndPublish(MercuryConnection connection, OpenPgpManager oxManager, OpenPgpSecretKeyBackupPassphrase passphrase) {
2020-11-09 15:23:22 +01:00
boolean mustGenerate = false;
2020-06-15 17:41:13 +02:00
try {
if (!oxManager.hasSecretKeysAvailable()) {
2020-07-13 23:28:11 +02:00
mustGenerate = true;
if (OpenPgpManager.serverSupportsSecretKeyBackups(connection.getConnection())) {
try {
oxManager.restoreSecretKeyServerBackup(
2020-07-18 14:11:04 +02:00
() -> passphrase);
2020-07-13 23:28:11 +02:00
mustGenerate = false;
LOGGER.log(Level.INFO, "Successfully restored secret key backup!");
} catch (NoBackupFoundException | PubSubException.NotALeafNodeException | InvalidBackupCodeException e) {
LOGGER.log(Level.INFO, "Error restoring secret key backup.", e);
}
}
}
if (mustGenerate) {
oxManager.generateAndImportKeyPair(connection.getAccount().getJid());
if (OpenPgpManager.serverSupportsSecretKeyBackups(connection.getConnection())) {
2020-06-15 17:41:13 +02:00
oxManager.backupSecretKeyToServer(
2020-07-18 14:11:04 +02:00
availableSecretKeys -> availableSecretKeys,
passphrase);
2020-06-15 17:41:13 +02:00
}
}
oxManager.announceSupportAndPublish();
OXInstantMessagingManager oximManager = OXInstantMessagingManager.getInstanceFor(connection.getConnection());
2020-06-26 16:00:47 +02:00
oximManager.addOxMessageListener(new MercuryMessageStore(connection.getAccount(),
2020-07-18 14:11:04 +02:00
peerRepository, directChatRepository, messageRepository, schedulers));
2020-06-15 17:41:13 +02:00
oximManager.announceSupportForOxInstantMessaging();
} catch (Exception e) {
e.printStackTrace();
}
}
2020-11-09 15:23:22 +01:00
public boolean mustPromptForRestore() {
return keyGenerationStrategy.promptForBackupRestoreIfNoLocalKeyPresent();
}
2020-06-15 17:41:13 +02:00
}