package org.jivesoftware.smackx.ikey_ox; import org.bouncycastle.openpgp.PGPException; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smackx.ikey.IkeyManager; import org.jivesoftware.smackx.ikey.element.IkeyElement; import org.jivesoftware.smackx.ikey.element.SubordinateElement; import org.jivesoftware.smackx.ikey.element.SubordinateListElement; import org.jivesoftware.smackx.ikey.element.SuperordinateElement; import org.jivesoftware.smackx.ikey.mechanism.IkeySignatureCreationMechanism; import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase; import org.jivesoftware.smackx.ox.element.SecretkeyElement; import org.jivesoftware.smackx.ox.util.OpenPgpPubSubUtil; import org.jivesoftware.smackx.ox.util.SecretKeyBackupHelper; import org.jivesoftware.smackx.pep.PepManager; import org.jivesoftware.smackx.pubsub.PubSubException; import org.mercury_im.messenger.core.crypto.OpenPgpSecretKeyBackupPassphraseGenerator; import org.mercury_im.messenger.core.crypto.SecureRandomSecretKeyBackupPassphraseGenerator; import org.pgpainless.key.protection.SecretKeyRingProtector; import java.io.IOException; import java.util.Arrays; import java.util.Date; import java.util.Map; import java.util.WeakHashMap; import static org.jivesoftware.smackx.ikey.util.IkeyConstants.SUPERORDINATE_NODE; public final class OxIkeyManager extends Manager { private static final Map INSTANCES = new WeakHashMap<>(); private final IkeyManager ikeyManager; private OxIkeyManager(XMPPConnection connection) { super(connection); this.ikeyManager = IkeyManager.getInstanceFor(connection); } public static OxIkeyManager getInstanceFor(XMPPConnection connection) { OxIkeyManager manager = INSTANCES.get(connection); if (manager == null) { manager = new OxIkeyManager(connection); INSTANCES.put(connection, manager); } return manager; } public SecretkeyElement fetchSecretIdentityKey() throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException { return OpenPgpPubSubUtil.fetchSecretKey(PepManager.getInstanceFor(connection()), SUPERORDINATE_NODE); } public OpenPgpSecretKeyBackupPassphrase depositSecretIdentityKey(PGPSecretKeyRing secretKey) throws PGPException, InterruptedException, SmackException.NoResponseException, SmackException.NotConnectedException, SmackException.FeatureNotSupportedException, XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, IOException { OpenPgpSecretKeyBackupPassphraseGenerator passphraseGenerator = new SecureRandomSecretKeyBackupPassphraseGenerator(); OpenPgpSecretKeyBackupPassphrase passphrase = passphraseGenerator.generateBackupPassphrase(); depositSecretIdentityKey(secretKey, passphrase); return passphrase; } public void depositSecretIdentityKey(PGPSecretKeyRing secretKey, OpenPgpSecretKeyBackupPassphrase passphrase) throws InterruptedException, SmackException.NoResponseException, SmackException.NotConnectedException, SmackException.FeatureNotSupportedException, XMPPException.XMPPErrorException, PubSubException.NotALeafNodeException, IOException, PGPException { SecretkeyElement secretkeyElement = SecretKeyBackupHelper.createSecretkeyElement(secretKey.getEncoded(), passphrase); OpenPgpPubSubUtil.depositSecretKey(connection(), secretkeyElement, SUPERORDINATE_NODE); } public IkeyElement createOxIkeyElement(PGPSecretKeyRing secretKeys, SecretKeyRingProtector keyRingProtector, SubordinateElement... subordinateElements) throws IOException { IkeySignatureCreationMechanism mechanism = new OxIkeySignatureCreationMechanism(secretKeys, keyRingProtector); SuperordinateElement superordinateElement = new SuperordinateElement(secretKeys.getPublicKey().getEncoded()); SubordinateListElement subordinateListElement = new SubordinateListElement(connection().getUser().asEntityBareJid(), new Date(), Arrays.asList(subordinateElements)); return ikeyManager.createIkeyElement(mechanism, superordinateElement, subordinateListElement); } public boolean deleteSecretIdentityKeyNode() throws XMPPException.XMPPErrorException, SmackException.NotConnectedException, InterruptedException, SmackException.NoResponseException { return OpenPgpPubSubUtil.deleteSecretKeyNode(PepManager.getInstanceFor(connection()), SUPERORDINATE_NODE); } }