Update OpenPgp fingerprints of contacts

This commit is contained in:
Paul Schaub 2018-07-03 11:29:51 +02:00
parent 613c5d869a
commit 6c9e41c1b2
3 changed files with 62 additions and 21 deletions

View File

@ -26,6 +26,7 @@ import java.io.InputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@ -140,15 +141,6 @@ public final class OpenPgpManager extends Manager {
this.provider = provider;
}
/**
* Return the registered {@link OpenPgpProvider}.
*
* @return provider.
*/
OpenPgpProvider getOpenPgpProvider() {
return provider;
}
/**
* 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.
@ -231,12 +223,9 @@ public final class OpenPgpManager extends Manager {
* @throws SmackOpenPgpException if something happens while gathering fingerprints.
* @throws InterruptedException
* @throws XMPPException.XMPPErrorException
* @throws SmackException.NotConnectedException
* @throws SmackException.NoResponseException
*/
public OpenPgpContact getOpenPgpContact(EntityBareJid jid)
throws SmackOpenPgpException, InterruptedException, XMPPException.XMPPErrorException,
SmackException.NotConnectedException, SmackException.NoResponseException,
SmackException.NotLoggedInException {
throwIfNotAuthenticated();
@ -245,7 +234,7 @@ public final class OpenPgpManager extends Manager {
if (openPgpContact == null) {
OpenPgpFingerprints theirKeys = determineContactsKeys(jid);
OpenPgpFingerprints ourKeys = determineContactsKeys(connection().getUser().asBareJid());
openPgpContact = new OpenPgpContact(getOpenPgpProvider(), jid, ourKeys, theirKeys);
openPgpContact = new OpenPgpContact(provider, jid, ourKeys, theirKeys);
openPgpCapableContacts.put(jid, openPgpContact);
}
@ -434,20 +423,37 @@ public final class OpenPgpManager extends Manager {
provider.getStore().setAnnouncedKeysFingerprints(contact, announcedKeys);
Set<OpenPgpV4Fingerprint> missingKeys = listElement.getMetadata().keySet();
Set<OpenPgpV4Fingerprint> availableKeys = Collections.emptySet();
try {
missingKeys.removeAll(provider.getStore().getAvailableKeysFingerprints(contact).keySet());
availableKeys = new HashSet<>(provider.getStore().getAvailableKeysFingerprints(contact).keySet());
} catch (SmackOpenPgpException e) {
LOGGER.log(Level.WARNING, "Could not determine available keys", 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);
processPublicKey(pubkeyElement, contact);
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);
}
}
private final IncomingChatMessageListener incomingOpenPgpMessageListener =
@ -464,8 +470,7 @@ public final class OpenPgpManager extends Manager {
try {
contact = getOpenPgpContact(from);
} catch (SmackOpenPgpException | InterruptedException | XMPPException.XMPPErrorException |
SmackException.NotLoggedInException | SmackException.NotConnectedException |
SmackException.NoResponseException e) {
SmackException.NotLoggedInException e) {
LOGGER.log(Level.WARNING, "Could not begin encrypted chat with " + from, e);
return;
}

View File

@ -37,17 +37,18 @@ import org.jivesoftware.smackx.ox.element.SigncryptElement;
import org.jivesoftware.smackx.ox.exception.MissingOpenPgpKeyPairException;
import org.jivesoftware.smackx.ox.exception.MissingOpenPgpPublicKeyException;
import org.jivesoftware.smackx.ox.exception.SmackOpenPgpException;
import org.jivesoftware.smackx.ox.listener.internal.FingerprintsChangedListener;
import org.jivesoftware.smackx.ox.util.DecryptedBytesAndMetadata;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.Jid;
import org.xmlpull.v1.XmlPullParserException;
public class OpenPgpContact {
public class OpenPgpContact implements FingerprintsChangedListener {
private final BareJid jid;
private final OpenPgpFingerprints contactsFingerprints;
private final OpenPgpFingerprints ourFingerprints;
private OpenPgpFingerprints contactsFingerprints;
private OpenPgpFingerprints ourFingerprints;
private final OpenPgpProvider cryptoProvider;
private final OpenPgpV4Fingerprint singingKey;
@ -167,4 +168,13 @@ public class OpenPgpContact {
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;
}
}
}

View File

@ -0,0 +1,26 @@
/**
*
* 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);
}