mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-23 20:42:06 +01:00
Temp
This commit is contained in:
parent
c4848fffc9
commit
171cb07430
8 changed files with 223 additions and 205 deletions
|
@ -25,18 +25,19 @@ import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.DummyConnection;
|
||||||
|
import org.jivesoftware.smack.SmackException;
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
import org.jivesoftware.smack.util.FileUtils;
|
import org.jivesoftware.smack.util.FileUtils;
|
||||||
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
|
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
|
||||||
import org.jivesoftware.smackx.ox.TestKeys;
|
import org.jivesoftware.smackx.ox.TestKeys;
|
||||||
import org.jivesoftware.smackx.ox.chat.OpenPgpContact;
|
import org.jivesoftware.smackx.ox.chat.OpenPgpContact;
|
||||||
import org.jivesoftware.smackx.ox.chat.OpenPgpFingerprints;
|
|
||||||
import org.jivesoftware.smackx.ox.element.OpenPgpContentElement;
|
import org.jivesoftware.smackx.ox.element.OpenPgpContentElement;
|
||||||
import org.jivesoftware.smackx.ox.element.OpenPgpElement;
|
import org.jivesoftware.smackx.ox.element.OpenPgpElement;
|
||||||
import org.jivesoftware.smackx.ox.element.PubkeyElement;
|
import org.jivesoftware.smackx.ox.element.PubkeyElement;
|
||||||
|
@ -75,26 +76,29 @@ public class DryOxEncryptionTest extends OxTestSuite {
|
||||||
@Test
|
@Test
|
||||||
public void dryEncryptionTest()
|
public void dryEncryptionTest()
|
||||||
throws IOException, SmackOpenPgpException, MissingUserIdOnKeyException, MissingOpenPgpPublicKeyException,
|
throws IOException, SmackOpenPgpException, MissingUserIdOnKeyException, MissingOpenPgpPublicKeyException,
|
||||||
MissingOpenPgpKeyPairException, XmlPullParserException {
|
MissingOpenPgpKeyPairException, XmlPullParserException, SmackException.NotLoggedInException {
|
||||||
BareJid juliet = TestKeys.JULIET_JID;
|
BareJid julietJid = TestKeys.JULIET_JID;
|
||||||
BareJid romemo = TestKeys.ROMEO_JID;
|
BareJid romeoJid = TestKeys.ROMEO_JID;
|
||||||
|
|
||||||
|
XMPPConnection julietCon = new DummyConnection();
|
||||||
|
XMPPConnection romeoCon = new DummyConnection();
|
||||||
|
|
||||||
FileBasedPainlessOpenPgpStore julietStore = new FileBasedPainlessOpenPgpStore(julietPath, new UnprotectedKeysProtector());
|
FileBasedPainlessOpenPgpStore julietStore = new FileBasedPainlessOpenPgpStore(julietPath, new UnprotectedKeysProtector());
|
||||||
FileBasedPainlessOpenPgpStore romeoStore = new FileBasedPainlessOpenPgpStore(romeoPath, new UnprotectedKeysProtector());
|
FileBasedPainlessOpenPgpStore romeoStore = new FileBasedPainlessOpenPgpStore(romeoPath, new UnprotectedKeysProtector());
|
||||||
|
|
||||||
PainlessOpenPgpProvider julietProvider = new PainlessOpenPgpProvider(juliet, julietStore);
|
PainlessOpenPgpProvider julietProvider = new PainlessOpenPgpProvider(julietJid, julietStore);
|
||||||
PainlessOpenPgpProvider romeoProvider = new PainlessOpenPgpProvider(romemo, romeoStore);
|
PainlessOpenPgpProvider romeoProvider = new PainlessOpenPgpProvider(romeoJid, romeoStore);
|
||||||
|
|
||||||
OpenPgpV4Fingerprint julietFinger = julietProvider.importSecretKey(juliet,
|
OpenPgpV4Fingerprint julietFinger = julietProvider.importSecretKey(julietJid,
|
||||||
BCUtil.getDecodedBytes(TestKeys.JULIET_PRIV.getBytes(UTF8)));
|
BCUtil.getDecodedBytes(TestKeys.JULIET_PRIV.getBytes(UTF8)));
|
||||||
OpenPgpV4Fingerprint romeoFinger = romeoProvider.importSecretKey(romemo,
|
OpenPgpV4Fingerprint romeoFinger = romeoProvider.importSecretKey(romeoJid,
|
||||||
BCUtil.getDecodedBytes(TestKeys.ROMEO_PRIV.getBytes(UTF8)));
|
BCUtil.getDecodedBytes(TestKeys.ROMEO_PRIV.getBytes(UTF8)));
|
||||||
|
|
||||||
julietStore.setSigningKeyPairFingerprint(julietFinger);
|
julietStore.setSigningKeyPairFingerprint(julietFinger);
|
||||||
romeoStore.setSigningKeyPairFingerprint(romeoFinger);
|
romeoStore.setSigningKeyPairFingerprint(romeoFinger);
|
||||||
|
|
||||||
byte[] julietPubBytes = julietStore.getPublicKeyRingBytes(juliet, julietFinger);
|
byte[] julietPubBytes = julietStore.getPublicKeyRingBytes(julietJid, julietFinger);
|
||||||
byte[] romeoPubBytes = romeoStore.getPublicKeyRingBytes(romemo, romeoFinger);
|
byte[] romeoPubBytes = romeoStore.getPublicKeyRingBytes(romeoJid, romeoFinger);
|
||||||
|
|
||||||
assertNotNull(julietPubBytes);
|
assertNotNull(julietPubBytes);
|
||||||
assertNotNull(romeoPubBytes);
|
assertNotNull(romeoPubBytes);
|
||||||
|
@ -102,29 +106,20 @@ public class DryOxEncryptionTest extends OxTestSuite {
|
||||||
assertTrue(romeoPubBytes.length != 0);
|
assertTrue(romeoPubBytes.length != 0);
|
||||||
|
|
||||||
PubkeyElement julietPub = new PubkeyElement(new PubkeyElement.PubkeyDataElement(
|
PubkeyElement julietPub = new PubkeyElement(new PubkeyElement.PubkeyDataElement(
|
||||||
Base64.encode(julietStore.getPublicKeyRingBytes(juliet, julietFinger))),
|
Base64.encode(julietStore.getPublicKeyRingBytes(julietJid, julietFinger))),
|
||||||
new Date());
|
new Date());
|
||||||
PubkeyElement romeoPub = new PubkeyElement(new PubkeyElement.PubkeyDataElement(
|
PubkeyElement romeoPub = new PubkeyElement(new PubkeyElement.PubkeyDataElement(
|
||||||
Base64.encode(romeoStore.getPublicKeyRingBytes(romemo, romeoFinger))),
|
Base64.encode(romeoStore.getPublicKeyRingBytes(romeoJid, romeoFinger))),
|
||||||
new Date());
|
new Date());
|
||||||
|
|
||||||
julietProvider.importPublicKey(romemo, Base64.decode(romeoPub.getDataElement().getB64Data()));
|
julietProvider.importPublicKey(romeoJid, Base64.decode(romeoPub.getDataElement().getB64Data()));
|
||||||
romeoProvider.importPublicKey(juliet, Base64.decode(julietPub.getDataElement().getB64Data()));
|
romeoProvider.importPublicKey(julietJid, Base64.decode(julietPub.getDataElement().getB64Data()));
|
||||||
|
|
||||||
julietStore.setAnnouncedKeysFingerprints(romemo, Collections.singletonMap(romeoFinger, new Date()));
|
julietStore.setAnnouncedKeysFingerprints(romeoJid, Collections.singletonMap(romeoFinger, new Date()));
|
||||||
romeoStore.setAnnouncedKeysFingerprints(juliet, Collections.singletonMap(julietFinger, new Date()));
|
romeoStore.setAnnouncedKeysFingerprints(julietJid, Collections.singletonMap(julietFinger, new Date()));
|
||||||
|
|
||||||
OpenPgpFingerprints julietFingerprints = new OpenPgpFingerprints(juliet,
|
OpenPgpContact julietForRomeo = new OpenPgpContact(romeoProvider, julietJid, romeoCon);
|
||||||
Collections.singleton(julietFinger),
|
OpenPgpContact romeoForJuliet = new OpenPgpContact(julietProvider, romeoJid, julietCon);
|
||||||
Collections.singleton(julietFinger),
|
|
||||||
new HashMap<OpenPgpV4Fingerprint, Throwable>());
|
|
||||||
OpenPgpFingerprints romeoFingerprints = new OpenPgpFingerprints(romemo,
|
|
||||||
Collections.singleton(romeoFinger),
|
|
||||||
Collections.singleton(romeoFinger),
|
|
||||||
new HashMap<OpenPgpV4Fingerprint, Throwable>());
|
|
||||||
|
|
||||||
OpenPgpContact julietForRomeo = new OpenPgpContact(romeoProvider, juliet, romeoFingerprints, julietFingerprints);
|
|
||||||
OpenPgpContact romeoForJuliet = new OpenPgpContact(julietProvider, romemo, julietFingerprints, romeoFingerprints);
|
|
||||||
|
|
||||||
String bodyText = "Finden wir eine Kompromisslösung – machen wir es so, wie ich es sage.";
|
String bodyText = "Finden wir eine Kompromisslösung – machen wir es so, wie ich es sage.";
|
||||||
List<ExtensionElement> payload = Collections.<ExtensionElement>singletonList(new Message.Body("de",
|
List<ExtensionElement> payload = Collections.<ExtensionElement>singletonList(new Message.Body("de",
|
||||||
|
|
|
@ -127,7 +127,7 @@ public final class OXInstantMessagingManager extends Manager implements Signcryp
|
||||||
|
|
||||||
public void sendOxMessage(OpenPgpContact contact, CharSequence body)
|
public void sendOxMessage(OpenPgpContact contact, CharSequence body)
|
||||||
throws InterruptedException, MissingOpenPgpKeyPairException, IOException,
|
throws InterruptedException, MissingOpenPgpKeyPairException, IOException,
|
||||||
SmackException.NotConnectedException, SmackOpenPgpException {
|
SmackException.NotConnectedException, SmackOpenPgpException, SmackException.NotLoggedInException {
|
||||||
Message message = new Message(contact.getJid());
|
Message message = new Message(contact.getJid());
|
||||||
List<ExtensionElement> payload = new ArrayList<>();
|
List<ExtensionElement> payload = new ArrayList<>();
|
||||||
payload.add(new Message.Body(null, body.toString()));
|
payload.add(new Message.Body(null, body.toString()));
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.jivesoftware.smackx.ox;
|
||||||
|
|
||||||
import static org.jivesoftware.smackx.ox.util.PubSubDelegate.PEP_NODE_PUBLIC_KEYS;
|
import static org.jivesoftware.smackx.ox.util.PubSubDelegate.PEP_NODE_PUBLIC_KEYS;
|
||||||
import static org.jivesoftware.smackx.ox.util.PubSubDelegate.PEP_NODE_PUBLIC_KEYS_NOTIFY;
|
import static org.jivesoftware.smackx.ox.util.PubSubDelegate.PEP_NODE_PUBLIC_KEYS_NOTIFY;
|
||||||
import static org.jivesoftware.smackx.ox.util.PubSubDelegate.fetchPubkey;
|
|
||||||
import static org.jivesoftware.smackx.ox.util.PubSubDelegate.publishPublicKey;
|
import static org.jivesoftware.smackx.ox.util.PubSubDelegate.publishPublicKey;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -26,7 +25,6 @@ import java.io.InputStream;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.NoSuchProviderException;
|
import java.security.NoSuchProviderException;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -52,7 +50,7 @@ import org.jivesoftware.smackx.ox.callback.DisplayBackupCodeCallback;
|
||||||
import org.jivesoftware.smackx.ox.callback.SecretKeyBackupSelectionCallback;
|
import org.jivesoftware.smackx.ox.callback.SecretKeyBackupSelectionCallback;
|
||||||
import org.jivesoftware.smackx.ox.callback.SecretKeyRestoreSelectionCallback;
|
import org.jivesoftware.smackx.ox.callback.SecretKeyRestoreSelectionCallback;
|
||||||
import org.jivesoftware.smackx.ox.chat.OpenPgpContact;
|
import org.jivesoftware.smackx.ox.chat.OpenPgpContact;
|
||||||
import org.jivesoftware.smackx.ox.chat.OpenPgpFingerprints;
|
import org.jivesoftware.smackx.ox.chat.OpenPgpSelf;
|
||||||
import org.jivesoftware.smackx.ox.element.CryptElement;
|
import org.jivesoftware.smackx.ox.element.CryptElement;
|
||||||
import org.jivesoftware.smackx.ox.element.OpenPgpContentElement;
|
import org.jivesoftware.smackx.ox.element.OpenPgpContentElement;
|
||||||
import org.jivesoftware.smackx.ox.element.OpenPgpElement;
|
import org.jivesoftware.smackx.ox.element.OpenPgpElement;
|
||||||
|
@ -106,6 +104,8 @@ public final class OpenPgpManager extends Manager {
|
||||||
private final Set<SignElementReceivedListener> signElementReceivedListeners = new HashSet<>();
|
private final Set<SignElementReceivedListener> signElementReceivedListeners = new HashSet<>();
|
||||||
private final Set<CryptElementReceivedListener> cryptElementReceivedListeners = new HashSet<>();
|
private final Set<CryptElementReceivedListener> cryptElementReceivedListeners = new HashSet<>();
|
||||||
|
|
||||||
|
private OpenPgpSelf self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private constructor to avoid instantiation without putting the object into {@code INSTANCES}.
|
* Private constructor to avoid instantiation without putting the object into {@code INSTANCES}.
|
||||||
*
|
*
|
||||||
|
@ -141,6 +141,16 @@ public final class OpenPgpManager extends Manager {
|
||||||
this.provider = provider;
|
this.provider = provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OpenPgpSelf getOpenPgpSelf() throws SmackException.NotLoggedInException {
|
||||||
|
throwIfNotAuthenticated();
|
||||||
|
|
||||||
|
if (self == null) {
|
||||||
|
self = new OpenPgpSelf(provider, connection().getUser().asBareJid(), connection());
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a fresh OpenPGP key pair, given we don't have one already.
|
* Generate a fresh OpenPGP key pair, given we don't have one already.
|
||||||
* Publish the public key to the Public Key Node and update the Public Key Metadata Node with our keys fingerprint.
|
* Publish the public key to the Public Key Node and update the Public Key Metadata Node with our keys fingerprint.
|
||||||
|
@ -220,21 +230,13 @@ public final class OpenPgpManager extends Manager {
|
||||||
*
|
*
|
||||||
* @param jid {@link BareJid} of the contact.
|
* @param jid {@link BareJid} of the contact.
|
||||||
* @return {@link OpenPgpContact}.
|
* @return {@link OpenPgpContact}.
|
||||||
* @throws SmackOpenPgpException if something happens while gathering fingerprints.
|
|
||||||
* @throws InterruptedException
|
|
||||||
* @throws XMPPException.XMPPErrorException
|
|
||||||
*/
|
*/
|
||||||
public OpenPgpContact getOpenPgpContact(EntityBareJid jid)
|
public OpenPgpContact getOpenPgpContact(EntityBareJid jid) {
|
||||||
throws SmackOpenPgpException, InterruptedException, XMPPException.XMPPErrorException,
|
|
||||||
SmackException.NotLoggedInException {
|
|
||||||
throwIfNotAuthenticated();
|
|
||||||
|
|
||||||
OpenPgpContact openPgpContact = openPgpCapableContacts.get(jid);
|
OpenPgpContact openPgpContact = openPgpCapableContacts.get(jid);
|
||||||
|
|
||||||
if (openPgpContact == null) {
|
if (openPgpContact == null) {
|
||||||
OpenPgpFingerprints theirKeys = determineContactsKeys(jid);
|
openPgpContact = new OpenPgpContact(provider, jid, connection());
|
||||||
OpenPgpFingerprints ourKeys = determineContactsKeys(connection().getUser().asBareJid());
|
|
||||||
openPgpContact = new OpenPgpContact(provider, jid, ourKeys, theirKeys);
|
|
||||||
openPgpCapableContacts.put(jid, openPgpContact);
|
openPgpCapableContacts.put(jid, openPgpContact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,45 +345,6 @@ public final class OpenPgpManager extends Manager {
|
||||||
return fingerprint;
|
return fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine which keys belong to a user and fetch any missing keys.
|
|
||||||
*
|
|
||||||
* @param jid {@link BareJid} of the user in question.
|
|
||||||
* @return {@link OpenPgpFingerprints} object containing the announced, available and unfetchable keys of the user.
|
|
||||||
* @throws SmackOpenPgpException
|
|
||||||
* @throws InterruptedException
|
|
||||||
* @throws XMPPException.XMPPErrorException
|
|
||||||
*/
|
|
||||||
private OpenPgpFingerprints determineContactsKeys(BareJid jid)
|
|
||||||
throws SmackOpenPgpException, InterruptedException, XMPPException.XMPPErrorException {
|
|
||||||
Set<OpenPgpV4Fingerprint> announced = provider.getStore().getAnnouncedKeysFingerprints(jid).keySet();
|
|
||||||
Set<OpenPgpV4Fingerprint> available = provider.getStore().getAvailableKeysFingerprints(jid).keySet();
|
|
||||||
Map<OpenPgpV4Fingerprint, Throwable> unfetched = new HashMap<>();
|
|
||||||
for (OpenPgpV4Fingerprint f : announced) {
|
|
||||||
if (!available.contains(f)) {
|
|
||||||
try {
|
|
||||||
PubkeyElement pubkeyElement = PubSubDelegate.fetchPubkey(connection(), jid, f);
|
|
||||||
if (pubkeyElement == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
processPublicKey(pubkeyElement, jid);
|
|
||||||
available.add(f);
|
|
||||||
|
|
||||||
} catch (SmackException e) {
|
|
||||||
LOGGER.log(Level.WARNING, "Could not fetch public key " + f.toString() + " of user " + jid.toString(), e);
|
|
||||||
unfetched.put(f, e);
|
|
||||||
} catch (MissingUserIdOnKeyException e) {
|
|
||||||
LOGGER.log(Level.WARNING, "Key does not contain user-id of " + jid + ". Ignoring the key.", e);
|
|
||||||
unfetched.put(f, e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOGGER.log(Level.WARNING, "Could not import key " + f.toString() + " of user " + jid.toString(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new OpenPgpFingerprints(jid, announced, available, unfetched);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link PEPListener} that listens for changes to the OX public keys metadata node.
|
* {@link PEPListener} that listens for changes to the OX public keys metadata node.
|
||||||
*
|
*
|
||||||
|
@ -407,52 +370,13 @@ public final class OpenPgpManager extends Manager {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public void requestMetadataUpdate(BareJid contact)
|
|
||||||
throws InterruptedException, SmackException,
|
|
||||||
XMPPException.XMPPErrorException {
|
|
||||||
PublicKeysListElement metadata = PubSubDelegate.fetchPubkeysList(connection(), contact);
|
|
||||||
processPublicKeysListElement(contact, metadata);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processPublicKeysListElement(BareJid contact, PublicKeysListElement listElement) {
|
private void processPublicKeysListElement(BareJid contact, PublicKeysListElement listElement) {
|
||||||
Map<OpenPgpV4Fingerprint, Date> announcedKeys = new HashMap<>();
|
|
||||||
for (OpenPgpV4Fingerprint f : listElement.getMetadata().keySet()) {
|
|
||||||
PublicKeysListElement.PubkeyMetadataElement meta = listElement.getMetadata().get(f);
|
|
||||||
announcedKeys.put(meta.getV4Fingerprint(), meta.getDate());
|
|
||||||
}
|
|
||||||
|
|
||||||
provider.getStore().setAnnouncedKeysFingerprints(contact, announcedKeys);
|
OpenPgpContact openPgpContact = getOpenPgpContact(contact.asEntityBareJidIfPossible());
|
||||||
|
|
||||||
Set<OpenPgpV4Fingerprint> availableKeys = Collections.emptySet();
|
|
||||||
try {
|
try {
|
||||||
availableKeys = new HashSet<>(provider.getStore().getAvailableKeysFingerprints(contact).keySet());
|
openPgpContact.updateKeys(listElement);
|
||||||
} catch (SmackOpenPgpException e) {
|
} catch (SmackOpenPgpException e) {
|
||||||
LOGGER.log(Level.WARNING, "Could not determine available keys", e);
|
LOGGER.log(Level.WARNING, "Could not read key ring of contact " + contact, e);
|
||||||
}
|
|
||||||
|
|
||||||
Set<OpenPgpV4Fingerprint> missingKeys = listElement.getMetadata().keySet();
|
|
||||||
Map<OpenPgpV4Fingerprint, Throwable> unfetchable = new HashMap<>();
|
|
||||||
try {
|
|
||||||
missingKeys.removeAll(availableKeys);
|
|
||||||
for (OpenPgpV4Fingerprint missing : missingKeys) {
|
|
||||||
try {
|
|
||||||
PubkeyElement pubkeyElement = fetchPubkey(connection(), contact, missing);
|
|
||||||
if (pubkeyElement != null) {
|
|
||||||
processPublicKey(pubkeyElement, contact);
|
|
||||||
availableKeys.add(missing);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.log(Level.WARNING, "Error fetching missing OpenPGP key " + missing.toString(), e);
|
|
||||||
unfetchable.put(missing, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.log(Level.WARNING, "Error processing OpenPGP metadata update from " + contact + ".", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenPgpFingerprints fingerprints = new OpenPgpFingerprints(contact, announcedKeys.keySet(), availableKeys, unfetchable);
|
|
||||||
for (OpenPgpContact openPgpContact : openPgpCapableContacts.values()) {
|
|
||||||
openPgpContact.onFingerprintsChanged(contact, fingerprints);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,14 +390,7 @@ public final class OpenPgpManager extends Manager {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenPgpContact contact;
|
OpenPgpContact contact = getOpenPgpContact(from);
|
||||||
try {
|
|
||||||
contact = getOpenPgpContact(from);
|
|
||||||
} catch (SmackOpenPgpException | InterruptedException | XMPPException.XMPPErrorException |
|
|
||||||
SmackException.NotLoggedInException e) {
|
|
||||||
LOGGER.log(Level.WARNING, "Could not begin encrypted chat with " + from, e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenPgpContentElement contentElement = null;
|
OpenPgpContentElement contentElement = null;
|
||||||
try {
|
try {
|
||||||
|
@ -506,6 +423,10 @@ public final class OpenPgpManager extends Manager {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
throw new AssertionError("Invalid element received: " + contentElement.getClass().getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,15 @@ public interface OpenPgpProvider {
|
||||||
throws SmackOpenPgpException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,
|
throws SmackOpenPgpException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,
|
||||||
NoSuchProviderException, IOException;
|
NoSuchProviderException, IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import a public key. The bytes are expected to be decoded from base64.
|
||||||
|
* @param owner
|
||||||
|
* @param bytes
|
||||||
|
* @return
|
||||||
|
* @throws MissingUserIdOnKeyException
|
||||||
|
* @throws IOException
|
||||||
|
* @throws SmackOpenPgpException
|
||||||
|
*/
|
||||||
OpenPgpV4Fingerprint importPublicKey(BareJid owner, byte[] bytes)
|
OpenPgpV4Fingerprint importPublicKey(BareJid owner, byte[] bytes)
|
||||||
throws MissingUserIdOnKeyException, IOException, SmackOpenPgpException;
|
throws MissingUserIdOnKeyException, IOException, SmackOpenPgpException;
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,17 @@ package org.jivesoftware.smackx.ox.chat;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.jivesoftware.smack.SmackException;
|
import org.jivesoftware.smack.SmackException;
|
||||||
import org.jivesoftware.smack.XMPPConnection;
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smack.XMPPException;
|
||||||
import org.jivesoftware.smack.chat2.ChatManager;
|
import org.jivesoftware.smack.chat2.ChatManager;
|
||||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||||
import org.jivesoftware.smack.packet.Message;
|
import org.jivesoftware.smack.packet.Message;
|
||||||
|
@ -29,51 +36,168 @@ import org.jivesoftware.smack.util.MultiMap;
|
||||||
import org.jivesoftware.smack.util.stringencoder.Base64;
|
import org.jivesoftware.smack.util.stringencoder.Base64;
|
||||||
import org.jivesoftware.smackx.eme.element.ExplicitMessageEncryptionElement;
|
import org.jivesoftware.smackx.eme.element.ExplicitMessageEncryptionElement;
|
||||||
import org.jivesoftware.smackx.hints.element.StoreHint;
|
import org.jivesoftware.smackx.hints.element.StoreHint;
|
||||||
|
import org.jivesoftware.smackx.ox.OpenPgpManager;
|
||||||
import org.jivesoftware.smackx.ox.OpenPgpProvider;
|
import org.jivesoftware.smackx.ox.OpenPgpProvider;
|
||||||
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
|
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
|
||||||
import org.jivesoftware.smackx.ox.element.OpenPgpContentElement;
|
import org.jivesoftware.smackx.ox.element.OpenPgpContentElement;
|
||||||
import org.jivesoftware.smackx.ox.element.OpenPgpElement;
|
import org.jivesoftware.smackx.ox.element.OpenPgpElement;
|
||||||
|
import org.jivesoftware.smackx.ox.element.PubkeyElement;
|
||||||
|
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;
|
||||||
import org.jivesoftware.smackx.ox.element.SigncryptElement;
|
import org.jivesoftware.smackx.ox.element.SigncryptElement;
|
||||||
import org.jivesoftware.smackx.ox.exception.MissingOpenPgpKeyPairException;
|
import org.jivesoftware.smackx.ox.exception.MissingOpenPgpKeyPairException;
|
||||||
import org.jivesoftware.smackx.ox.exception.MissingOpenPgpPublicKeyException;
|
import org.jivesoftware.smackx.ox.exception.MissingOpenPgpPublicKeyException;
|
||||||
|
import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException;
|
||||||
import org.jivesoftware.smackx.ox.exception.SmackOpenPgpException;
|
import org.jivesoftware.smackx.ox.exception.SmackOpenPgpException;
|
||||||
import org.jivesoftware.smackx.ox.listener.internal.FingerprintsChangedListener;
|
|
||||||
import org.jivesoftware.smackx.ox.util.DecryptedBytesAndMetadata;
|
import org.jivesoftware.smackx.ox.util.DecryptedBytesAndMetadata;
|
||||||
|
import org.jivesoftware.smackx.ox.util.PubSubDelegate;
|
||||||
|
|
||||||
import org.jxmpp.jid.BareJid;
|
import org.jxmpp.jid.BareJid;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
public class OpenPgpContact implements FingerprintsChangedListener {
|
public class OpenPgpContact {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(OpenPgpContact.class.getName());
|
||||||
|
|
||||||
private final BareJid jid;
|
private final BareJid jid;
|
||||||
private OpenPgpFingerprints contactsFingerprints;
|
protected final OpenPgpProvider cryptoProvider;
|
||||||
private OpenPgpFingerprints ourFingerprints;
|
private final XMPPConnection connection;
|
||||||
private final OpenPgpProvider cryptoProvider;
|
|
||||||
private final OpenPgpV4Fingerprint singingKey;
|
private Map<OpenPgpV4Fingerprint, Date> announcedKeys = null;
|
||||||
|
private Map<OpenPgpV4Fingerprint, Date> availableKeys = null;
|
||||||
|
private final Map<OpenPgpV4Fingerprint, Throwable> unfetchableKeys = new HashMap<>();
|
||||||
|
|
||||||
public OpenPgpContact(OpenPgpProvider cryptoProvider,
|
public OpenPgpContact(OpenPgpProvider cryptoProvider,
|
||||||
BareJid jid,
|
BareJid jid,
|
||||||
OpenPgpFingerprints ourFingerprints,
|
XMPPConnection connection) {
|
||||||
OpenPgpFingerprints contactsFingerprints) {
|
|
||||||
this.cryptoProvider = cryptoProvider;
|
|
||||||
this.jid = jid;
|
this.jid = jid;
|
||||||
this.singingKey = cryptoProvider.getStore().getSigningKeyPairFingerprint();
|
this.cryptoProvider = cryptoProvider;
|
||||||
this.ourFingerprints = ourFingerprints;
|
this.connection = connection;
|
||||||
this.contactsFingerprints = contactsFingerprints;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BareJid getJid() {
|
public BareJid getJid() {
|
||||||
return jid;
|
return jid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenPgpFingerprints getFingerprints() {
|
public Map<OpenPgpV4Fingerprint, Date> getAnnouncedKeys() {
|
||||||
return contactsFingerprints;
|
if (announcedKeys == null) {
|
||||||
|
announcedKeys = cryptoProvider.getStore().getAnnouncedKeysFingerprints(getJid());
|
||||||
|
}
|
||||||
|
return announcedKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<OpenPgpV4Fingerprint, Date> getAvailableKeys() throws SmackOpenPgpException {
|
||||||
|
if (availableKeys == null) {
|
||||||
|
availableKeys = cryptoProvider.getStore().getAvailableKeysFingerprints(getJid());
|
||||||
|
}
|
||||||
|
return availableKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<OpenPgpV4Fingerprint, Throwable> getUnfetchableKeys() {
|
||||||
|
return unfetchableKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<OpenPgpV4Fingerprint> getActiveKeys() throws SmackOpenPgpException {
|
||||||
|
Set<OpenPgpV4Fingerprint> fingerprints = getAvailableKeys().keySet();
|
||||||
|
fingerprints.retainAll(getAnnouncedKeys().keySet());
|
||||||
|
return fingerprints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateKeys()
|
||||||
|
throws InterruptedException, XMPPException.XMPPErrorException, SmackException, SmackOpenPgpException {
|
||||||
|
updateKeys(PubSubDelegate.fetchPubkeysList(connection, getJid()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateKeys(PublicKeysListElement metadata)
|
||||||
|
throws SmackOpenPgpException {
|
||||||
|
storePublishedDevices(metadata);
|
||||||
|
this.availableKeys = getAvailableKeys();
|
||||||
|
|
||||||
|
for (OpenPgpV4Fingerprint fingerprint : announcedKeys.keySet()) {
|
||||||
|
Date announcedDate = announcedKeys.get(fingerprint);
|
||||||
|
Date availableDate = availableKeys.get(fingerprint);
|
||||||
|
|
||||||
|
if (availableDate == null || availableDate.before(announcedDate)) {
|
||||||
|
try {
|
||||||
|
updateKey(fingerprint);
|
||||||
|
unfetchableKeys.remove(fingerprint);
|
||||||
|
} catch (IOException | XMPPException.XMPPErrorException | SmackException | InterruptedException |
|
||||||
|
SmackOpenPgpException | MissingUserIdOnKeyException | NullPointerException e) {
|
||||||
|
LOGGER.log(Level.WARNING, "Could not update key " + fingerprint + " of " +getJid());
|
||||||
|
unfetchableKeys.put(fingerprint, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateKey(OpenPgpV4Fingerprint fingerprint)
|
||||||
|
throws InterruptedException, XMPPException.XMPPErrorException, SmackException, IOException,
|
||||||
|
MissingUserIdOnKeyException, SmackOpenPgpException {
|
||||||
|
PubkeyElement pubkeyElement = PubSubDelegate.fetchPubkey(connection, getJid(), fingerprint);
|
||||||
|
if (pubkeyElement == null) {
|
||||||
|
throw new NullPointerException("Fetched pubkeyElement for key " + fingerprint + " of " + getJid() + " is null.");
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] base64 = pubkeyElement.getDataElement().getB64Data();
|
||||||
|
OpenPgpV4Fingerprint imported = importPublicKey(Base64.decode(base64));
|
||||||
|
|
||||||
|
if (!fingerprint.equals(imported)) {
|
||||||
|
// Not sure, if this can/should happen. Lets be safe and throw, even if its too late at this point.
|
||||||
|
throw new AssertionError("Fingerprint of imported key differs from expected fingerprint. " +
|
||||||
|
"Expected: " + fingerprint + " Imported: " + imported);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OpenPgpV4Fingerprint importPublicKey(byte[] data)
|
||||||
|
throws SmackOpenPgpException, MissingUserIdOnKeyException, IOException {
|
||||||
|
OpenPgpV4Fingerprint fingerprint = cryptoProvider.importPublicKey(getJid(), data);
|
||||||
|
availableKeys.put(fingerprint, new Date());
|
||||||
|
return fingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<OpenPgpV4Fingerprint, Date> storePublishedDevices(PublicKeysListElement element) {
|
||||||
|
Map<OpenPgpV4Fingerprint, Date> announcedKeys = new HashMap<>();
|
||||||
|
|
||||||
|
for (OpenPgpV4Fingerprint f : element.getMetadata().keySet()) {
|
||||||
|
PublicKeysListElement.PubkeyMetadataElement meta = element.getMetadata().get(f);
|
||||||
|
announcedKeys.put(meta.getV4Fingerprint(), meta.getDate());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!announcedKeys.equals(this.announcedKeys)) {
|
||||||
|
cryptoProvider.getStore().setAnnouncedKeysFingerprints(getJid(), announcedKeys);
|
||||||
|
this.announcedKeys = announcedKeys;
|
||||||
|
}
|
||||||
|
return announcedKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
private MultiMap<BareJid, OpenPgpV4Fingerprint> getEncryptionKeys()
|
||||||
|
throws SmackOpenPgpException, SmackException.NotLoggedInException {
|
||||||
|
OpenPgpSelf self = getSelf();
|
||||||
|
|
||||||
|
Set<OpenPgpV4Fingerprint> contactsKeys = getActiveKeys();
|
||||||
|
Set<OpenPgpV4Fingerprint> ourKeys = self.getActiveKeys();
|
||||||
|
|
||||||
|
MultiMap<BareJid, OpenPgpV4Fingerprint> recipientsKeys = new MultiMap<>();
|
||||||
|
for (OpenPgpV4Fingerprint fingerprint : contactsKeys) {
|
||||||
|
recipientsKeys.put(getJid(), fingerprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (OpenPgpV4Fingerprint fingerprint : ourKeys) {
|
||||||
|
recipientsKeys.put(self.getJid(), fingerprint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return recipientsKeys;
|
||||||
|
}
|
||||||
|
|
||||||
|
private OpenPgpSelf getSelf() throws SmackException.NotLoggedInException {
|
||||||
|
return OpenPgpManager.getInstanceFor(connection).getOpenPgpSelf();
|
||||||
}
|
}
|
||||||
|
|
||||||
public OpenPgpElement encryptAndSign(List<ExtensionElement> payload)
|
public OpenPgpElement encryptAndSign(List<ExtensionElement> payload)
|
||||||
throws IOException, SmackOpenPgpException, MissingOpenPgpKeyPairException {
|
throws IOException, SmackOpenPgpException, MissingOpenPgpKeyPairException,
|
||||||
MultiMap<BareJid, OpenPgpV4Fingerprint> fingerprints = oursAndRecipientFingerprints();
|
SmackException.NotLoggedInException {
|
||||||
|
|
||||||
|
OpenPgpSelf self = OpenPgpManager.getInstanceFor(connection).getOpenPgpSelf();
|
||||||
|
|
||||||
SigncryptElement preparedPayload = new SigncryptElement(
|
SigncryptElement preparedPayload = new SigncryptElement(
|
||||||
Collections.<Jid>singleton(getJid()),
|
Collections.<Jid>singleton(getJid()),
|
||||||
|
@ -85,8 +209,8 @@ public class OpenPgpContact implements FingerprintsChangedListener {
|
||||||
try {
|
try {
|
||||||
encryptedBytes = cryptoProvider.signAndEncrypt(
|
encryptedBytes = cryptoProvider.signAndEncrypt(
|
||||||
preparedPayload,
|
preparedPayload,
|
||||||
singingKey,
|
self.getSigningKey(),
|
||||||
fingerprints);
|
getEncryptionKeys());
|
||||||
} catch (MissingOpenPgpPublicKeyException e) {
|
} catch (MissingOpenPgpPublicKeyException e) {
|
||||||
throw new AssertionError("Missing OpenPGP public key, even though this should not happen here.", e);
|
throw new AssertionError("Missing OpenPGP public key, even though this should not happen here.", e);
|
||||||
}
|
}
|
||||||
|
@ -95,7 +219,8 @@ public class OpenPgpContact implements FingerprintsChangedListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSignedEncryptedPayloadTo(Message message, List<ExtensionElement> payload)
|
public void addSignedEncryptedPayloadTo(Message message, List<ExtensionElement> payload)
|
||||||
throws IOException, SmackOpenPgpException, MissingOpenPgpKeyPairException {
|
throws IOException, SmackOpenPgpException, MissingOpenPgpKeyPairException,
|
||||||
|
SmackException.NotLoggedInException {
|
||||||
|
|
||||||
// Add encrypted payload to message
|
// Add encrypted payload to message
|
||||||
OpenPgpElement encryptedPayload = encryptAndSign(payload);
|
OpenPgpElement encryptedPayload = encryptAndSign(payload);
|
||||||
|
@ -114,8 +239,8 @@ public class OpenPgpContact implements FingerprintsChangedListener {
|
||||||
|
|
||||||
public void send(XMPPConnection connection, Message message, List<ExtensionElement> payload)
|
public void send(XMPPConnection connection, Message message, List<ExtensionElement> payload)
|
||||||
throws MissingOpenPgpKeyPairException, SmackException.NotConnectedException, InterruptedException,
|
throws MissingOpenPgpKeyPairException, SmackException.NotConnectedException, InterruptedException,
|
||||||
SmackOpenPgpException, IOException {
|
SmackOpenPgpException, IOException, SmackException.NotLoggedInException {
|
||||||
MultiMap<BareJid, OpenPgpV4Fingerprint> fingerprints = oursAndRecipientFingerprints();
|
MultiMap<BareJid, OpenPgpV4Fingerprint> fingerprints = getEncryptionKeys();
|
||||||
|
|
||||||
SigncryptElement preparedPayload = new SigncryptElement(
|
SigncryptElement preparedPayload = new SigncryptElement(
|
||||||
Collections.<Jid>singleton(getJid()),
|
Collections.<Jid>singleton(getJid()),
|
||||||
|
@ -128,7 +253,7 @@ public class OpenPgpContact implements FingerprintsChangedListener {
|
||||||
try {
|
try {
|
||||||
encryptedMessage = cryptoProvider.signAndEncrypt(
|
encryptedMessage = cryptoProvider.signAndEncrypt(
|
||||||
preparedPayload,
|
preparedPayload,
|
||||||
singingKey,
|
getSelf().getSigningKey(),
|
||||||
fingerprints);
|
fingerprints);
|
||||||
} catch (MissingOpenPgpPublicKeyException e) {
|
} catch (MissingOpenPgpPublicKeyException e) {
|
||||||
throw new AssertionError("Missing OpenPGP public key, even though this should not happen here.", e);
|
throw new AssertionError("Missing OpenPGP public key, even though this should not happen here.", e);
|
||||||
|
@ -154,28 +279,4 @@ public class OpenPgpContact implements FingerprintsChangedListener {
|
||||||
|
|
||||||
return openPgpMessage.getOpenPgpContentElement();
|
return openPgpMessage.getOpenPgpContentElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
private MultiMap<BareJid, OpenPgpV4Fingerprint> oursAndRecipientFingerprints() {
|
|
||||||
MultiMap<BareJid, OpenPgpV4Fingerprint> fingerprints = new MultiMap<>();
|
|
||||||
for (OpenPgpV4Fingerprint f : contactsFingerprints.getActiveKeys()) {
|
|
||||||
fingerprints.put(contactsFingerprints.getJid(), f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!contactsFingerprints.getJid().equals(ourFingerprints.getJid())) {
|
|
||||||
for (OpenPgpV4Fingerprint f : ourFingerprints.getActiveKeys()) {
|
|
||||||
fingerprints.put(ourFingerprints.getJid(), f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fingerprints;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFingerprintsChanged(BareJid contact, OpenPgpFingerprints newFingerprints) {
|
|
||||||
if (ourFingerprints.getJid().equals(contact)) {
|
|
||||||
this.ourFingerprints = newFingerprints;
|
|
||||||
} else if (contactsFingerprints.getJid().equals(contact)) {
|
|
||||||
this.contactsFingerprints = newFingerprints;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package org.jivesoftware.smackx.ox.chat;
|
||||||
|
|
||||||
|
import org.jivesoftware.smack.XMPPConnection;
|
||||||
|
import org.jivesoftware.smackx.ox.OpenPgpProvider;
|
||||||
|
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
|
import org.jxmpp.jid.BareJid;
|
||||||
|
|
||||||
|
public class OpenPgpSelf extends OpenPgpContact {
|
||||||
|
|
||||||
|
public OpenPgpSelf(OpenPgpProvider cryptoProvider, BareJid jid, XMPPConnection connection) {
|
||||||
|
super(cryptoProvider, jid, connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpenPgpV4Fingerprint getSigningKey() {
|
||||||
|
return cryptoProvider.getStore().getSigningKeyPairFingerprint();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,26 +0,0 @@
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Copyright 2018 Paul Schaub.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jivesoftware.smackx.ox.listener.internal;
|
|
||||||
|
|
||||||
import org.jivesoftware.smackx.ox.chat.OpenPgpFingerprints;
|
|
||||||
|
|
||||||
import org.jxmpp.jid.BareJid;
|
|
||||||
|
|
||||||
public interface FingerprintsChangedListener {
|
|
||||||
|
|
||||||
void onFingerprintsChanged(BareJid contact, OpenPgpFingerprints newFingerprints);
|
|
||||||
}
|
|
|
@ -212,7 +212,7 @@ public class PubSubDelegate {
|
||||||
try {
|
try {
|
||||||
pm.deleteNode(PEP_NODE_PUBLIC_KEYS);
|
pm.deleteNode(PEP_NODE_PUBLIC_KEYS);
|
||||||
} catch (XMPPException.XMPPErrorException e) {
|
} catch (XMPPException.XMPPErrorException e) {
|
||||||
if (e.getXMPPError().getCondition() == StanzaError.Condition.item_not_found) {
|
if (e.getStanzaError().getCondition() == StanzaError.Condition.item_not_found) {
|
||||||
LOGGER.log(Level.FINE, "Node does not exist. No need to delete it.");
|
LOGGER.log(Level.FINE, "Node does not exist. No need to delete it.");
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -237,7 +237,7 @@ public class PubSubDelegate {
|
||||||
try {
|
try {
|
||||||
pm.deleteNode(PEP_NODE_PUBLIC_KEY(fingerprint));
|
pm.deleteNode(PEP_NODE_PUBLIC_KEY(fingerprint));
|
||||||
} catch (XMPPException.XMPPErrorException e) {
|
} catch (XMPPException.XMPPErrorException e) {
|
||||||
if (e.getXMPPError().getCondition() == StanzaError.Condition.item_not_found) {
|
if (e.getStanzaError().getCondition() == StanzaError.Condition.item_not_found) {
|
||||||
LOGGER.log(Level.FINE, "Node does not exist. No need to delete it.");
|
LOGGER.log(Level.FINE, "Node does not exist. No need to delete it.");
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
|
|
Loading…
Reference in a new issue