mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-27 22:42:06 +01:00
Implement restoring secret key
This commit is contained in:
parent
878ac56ed0
commit
653f318d37
3 changed files with 61 additions and 2 deletions
|
@ -42,6 +42,7 @@ import org.jivesoftware.smackx.ox.element.SigncryptElement;
|
||||||
import org.jivesoftware.smackx.ox.exception.CorruptedOpenPgpKeyException;
|
import org.jivesoftware.smackx.ox.exception.CorruptedOpenPgpKeyException;
|
||||||
|
|
||||||
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.BouncyGPG;
|
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.BouncyGPG;
|
||||||
|
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.algorithms.PGPHashAlgorithms;
|
||||||
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.algorithms.PGPSymmetricEncryptionAlgorithms;
|
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.algorithms.PGPSymmetricEncryptionAlgorithms;
|
||||||
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.algorithms.PublicKeySize;
|
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.algorithms.PublicKeySize;
|
||||||
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.keys.callbacks.KeyringConfigCallbacks;
|
import name.neuhalfen.projects.crypto.bouncycastle.openpgp.keys.callbacks.KeyringConfigCallbacks;
|
||||||
|
@ -52,13 +53,16 @@ import name.neuhalfen.projects.crypto.bouncycastle.openpgp.keys.keyrings.Keyring
|
||||||
import org.bouncycastle.bcpg.HashAlgorithmTags;
|
import org.bouncycastle.bcpg.HashAlgorithmTags;
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPKeyRingGenerator;
|
import org.bouncycastle.openpgp.PGPKeyRingGenerator;
|
||||||
|
import org.bouncycastle.openpgp.PGPPrivateKey;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKey;
|
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKey;
|
import org.bouncycastle.openpgp.PGPSecretKey;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
|
import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor;
|
||||||
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
|
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
|
||||||
|
import org.bouncycastle.openpgp.operator.PGPDigestCalculatorProvider;
|
||||||
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
|
||||||
|
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyDecryptorBuilder;
|
||||||
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
import org.bouncycastle.openpgp.operator.jcajce.JcePBESecretKeyEncryptorBuilder;
|
||||||
import org.bouncycastle.util.encoders.Hex;
|
import org.bouncycastle.util.encoders.Hex;
|
||||||
import org.bouncycastle.util.io.Streams;
|
import org.bouncycastle.util.io.Streams;
|
||||||
|
@ -67,8 +71,8 @@ import org.jxmpp.jid.BareJid;
|
||||||
public class BouncyCastleOpenPgpProvider implements OpenPgpProvider {
|
public class BouncyCastleOpenPgpProvider implements OpenPgpProvider {
|
||||||
|
|
||||||
private final BareJid ourJid;
|
private final BareJid ourJid;
|
||||||
private final InMemoryKeyring ourKeys;
|
private InMemoryKeyring ourKeys;
|
||||||
private final Long ourKeyId;
|
private Long ourKeyId;
|
||||||
private final Map<BareJid, InMemoryKeyring> theirKeys = new HashMap<>();
|
private final Map<BareJid, InMemoryKeyring> theirKeys = new HashMap<>();
|
||||||
|
|
||||||
public BouncyCastleOpenPgpProvider(BareJid ourJid) throws IOException, PGPException, NoSuchAlgorithmException {
|
public BouncyCastleOpenPgpProvider(BareJid ourJid) throws IOException, PGPException, NoSuchAlgorithmException {
|
||||||
|
@ -146,6 +150,44 @@ public class BouncyCastleOpenPgpProvider implements OpenPgpProvider {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void restoreSecretKeyElement(SecretkeyElement secretkeyElement, String password)
|
||||||
|
throws CorruptedOpenPgpKeyException {
|
||||||
|
byte[] encoded = Base64.decode(secretkeyElement.getB64Data());
|
||||||
|
|
||||||
|
try {
|
||||||
|
PGPDigestCalculatorProvider calculatorProvider = new JcaPGPDigestCalculatorProviderBuilder()
|
||||||
|
.setProvider(BouncyGPG.getProvider())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
InMemoryKeyring keyring = KeyringConfigs.forGpgExportedKeys(
|
||||||
|
KeyringConfigCallbacks.withPassword(password));
|
||||||
|
keyring.addSecretKey(encoded);
|
||||||
|
for (PGPSecretKeyRing r : keyring.getSecretKeyRings()) {
|
||||||
|
PGPSecretKey s = r.getSecretKey();
|
||||||
|
PGPPrivateKey privateKey = s.extractPrivateKey(new JcePBESecretKeyDecryptorBuilder(calculatorProvider).build(password.toCharArray()));
|
||||||
|
PGPPublicKey publicKey = s.getPublicKey();
|
||||||
|
PGPSecretKey secretKey = new PGPSecretKey(
|
||||||
|
privateKey,
|
||||||
|
publicKey,
|
||||||
|
calculatorProvider.get(PGPHashAlgorithms.SHA1.getAlgorithmId()),
|
||||||
|
true,
|
||||||
|
null);
|
||||||
|
|
||||||
|
InMemoryKeyring newKeyring = KeyringConfigs.forGpgExportedKeys(
|
||||||
|
KeyringConfigCallbacks.withUnprotectedKeys());
|
||||||
|
|
||||||
|
newKeyring.addSecretKey(secretKey.getEncoded());
|
||||||
|
newKeyring.addPublicKey(secretKey.getPublicKey().getEncoded());
|
||||||
|
|
||||||
|
ourKeys = newKeyring;
|
||||||
|
ourKeyId = secretKey.getKeyID();
|
||||||
|
}
|
||||||
|
} catch (PGPException | IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OpenPgpElement signAndEncrypt(SigncryptElement element, Set<BareJid> recipients)
|
public OpenPgpElement signAndEncrypt(SigncryptElement element, Set<BareJid> recipients)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.util.Async;
|
import org.jivesoftware.smack.util.Async;
|
||||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
|
import org.jivesoftware.smackx.ox.callback.AskForBackupCodeCallback;
|
||||||
import org.jivesoftware.smackx.ox.callback.DisplayBackupCodeCallback;
|
import org.jivesoftware.smackx.ox.callback.DisplayBackupCodeCallback;
|
||||||
import org.jivesoftware.smackx.ox.element.PubkeyElement;
|
import org.jivesoftware.smackx.ox.element.PubkeyElement;
|
||||||
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;
|
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;
|
||||||
|
@ -296,6 +297,20 @@ public final class OpenPgpManager extends Manager {
|
||||||
callback.displayBackupCode(password);
|
callback.displayBackupCode(password);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void fetchSecretKey(AskForBackupCodeCallback callback)
|
||||||
|
throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException,
|
||||||
|
SmackException.NotConnectedException, SmackException.NoResponseException, CorruptedOpenPgpKeyException {
|
||||||
|
PubSubManager pm = PubSubManager.getInstance(connection());
|
||||||
|
LeafNode secretKeyNode = pm.getOrCreateLeafNode(PEP_NODE_SECRET_KEY);
|
||||||
|
List<PayloadItem<SecretkeyElement>> list = secretKeyNode.getItems(1);
|
||||||
|
if (list.size() == 0) {
|
||||||
|
LOGGER.log(Level.INFO, "No secret key published!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SecretkeyElement secretkeyElement = list.get(0).getPayload();
|
||||||
|
provider.restoreSecretKeyElement(secretkeyElement, callback.askForBackupCode());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the upper-case hex encoded OpenPGP v4 fingerprint of our key pair.
|
* Return the upper-case hex encoded OpenPGP v4 fingerprint of our key pair.
|
||||||
*
|
*
|
||||||
|
|
|
@ -154,4 +154,6 @@ public interface OpenPgpProvider {
|
||||||
String getFingerprint() throws CorruptedOpenPgpKeyException;
|
String getFingerprint() throws CorruptedOpenPgpKeyException;
|
||||||
|
|
||||||
SecretkeyElement createSecretkeyElement(String password) throws CorruptedOpenPgpKeyException;
|
SecretkeyElement createSecretkeyElement(String password) throws CorruptedOpenPgpKeyException;
|
||||||
|
|
||||||
|
void restoreSecretKeyElement(SecretkeyElement secretkeyElement, String password) throws CorruptedOpenPgpKeyException;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue