mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-27 06:22:07 +01:00
Improve key selection
This commit is contained in:
parent
cc44b623a3
commit
a470af0b73
3 changed files with 53 additions and 46 deletions
|
@ -31,7 +31,6 @@ import org.jivesoftware.smack.util.stringencoder.Base64;
|
|||
import org.jivesoftware.smackx.ox.element.PubkeyElement;
|
||||
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;
|
||||
import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException;
|
||||
import org.jivesoftware.smackx.ox.selection_strategy.AnnouncedKeys;
|
||||
import org.jivesoftware.smackx.ox.selection_strategy.BareJidUserId;
|
||||
import org.jivesoftware.smackx.ox.store.definition.OpenPgpStore;
|
||||
import org.jivesoftware.smackx.ox.util.PubSubDelegate;
|
||||
|
@ -43,6 +42,7 @@ import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
|||
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.pgpainless.pgpainless.key.OpenPgpV4Fingerprint;
|
||||
import org.pgpainless.pgpainless.util.BCUtil;
|
||||
|
||||
public class OpenPgpContact {
|
||||
|
||||
|
@ -69,26 +69,29 @@ public class OpenPgpContact {
|
|||
PGPPublicKeyRingCollection anyKeys = getAnyPublicKeys();
|
||||
Map<OpenPgpV4Fingerprint, Date> announced = store.getAnnouncedFingerprintsOf(jid);
|
||||
|
||||
PGPPublicKeyRingCollection announcedKeysCollection = anyKeys;
|
||||
|
||||
BareJidUserId.PubRingSelectionStrategy userIdFilter = new BareJidUserId.PubRingSelectionStrategy();
|
||||
AnnouncedKeys.PubKeyRingSelectionStrategy announcedFilter = new AnnouncedKeys.PubKeyRingSelectionStrategy();
|
||||
|
||||
for (PGPPublicKeyRing ring : (anyKeys != null ? anyKeys : Collections.<PGPPublicKeyRing>emptyList())) {
|
||||
PGPPublicKeyRingCollection announcedKeysCollection = null;
|
||||
for (OpenPgpV4Fingerprint announcedFingerprint : announced.keySet()) {
|
||||
PGPPublicKeyRing ring = anyKeys.getPublicKeyRing(announcedFingerprint.getKeyId());
|
||||
|
||||
if (ring == null) continue;
|
||||
|
||||
ring = BCUtil.removeUnassociatedKeysFromKeyRing(ring, ring.getPublicKey(announcedFingerprint.getKeyId()));
|
||||
|
||||
if (!userIdFilter.accept(getJid(), ring)) {
|
||||
LOGGER.log(Level.WARNING, "Ignore key " + Long.toHexString(ring.getPublicKey().getKeyID()) +
|
||||
" as it lacks the user-id \"xmpp" + getJid().toString() + "\"");
|
||||
announcedKeysCollection = PGPPublicKeyRingCollection.removePublicKeyRing(announcedKeysCollection, ring);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!announcedFilter.accept(announced, ring)) {
|
||||
LOGGER.log(Level.WARNING, "Ignore key " + Long.toHexString(ring.getPublicKey().getKeyID()) +
|
||||
" as it is not announced by " + getJid().toString());
|
||||
announcedKeysCollection = PGPPublicKeyRingCollection.removePublicKeyRing(announcedKeysCollection, ring);
|
||||
if (announcedKeysCollection == null) {
|
||||
announcedKeysCollection = new PGPPublicKeyRingCollection(Collections.singleton(ring));
|
||||
} else {
|
||||
announcedKeysCollection = PGPPublicKeyRingCollection.addPublicKeyRing(announcedKeysCollection, ring);
|
||||
}
|
||||
}
|
||||
|
||||
return announcedKeysCollection;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ import static org.jivesoftware.smackx.ox.util.PubSubDelegate.PEP_NODE_PUBLIC_KEY
|
|||
import static org.jivesoftware.smackx.ox.util.PubSubDelegate.publishPublicKey;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
|
@ -79,12 +78,10 @@ import org.jivesoftware.smackx.pubsub.PubSubFeature;
|
|||
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
import org.pgpainless.pgpainless.PGPainless;
|
||||
import org.pgpainless.pgpainless.key.OpenPgpV4Fingerprint;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
|
@ -412,18 +409,41 @@ public final class OpenPgpManager extends Manager {
|
|||
};
|
||||
|
||||
private void processPublicKeysListElement(BareJid contact, PublicKeysListElement listElement) {
|
||||
|
||||
OpenPgpContact openPgpContact = getOpenPgpContact(contact.asEntityBareJidIfPossible());
|
||||
// TODO: Quick and dirty. Do it properly!!!
|
||||
try {
|
||||
PGPPublicKeyRingCollection contactsKeys = provider.getStore().getPublicKeysOf(contact);
|
||||
openPgpContact.updateKeys(connection());
|
||||
} catch (Exception e) {
|
||||
LOGGER.log(Level.WARNING, "Could not update contacts keys", e);
|
||||
}
|
||||
/*
|
||||
try {
|
||||
PGPPublicKeyRingCollection contactsKeys = openPgpContact.getAnyPublicKeys();
|
||||
for (OpenPgpV4Fingerprint fingerprint : listElement.getMetadata().keySet()) {
|
||||
PGPPublicKeyRing key = contactsKeys.getPublicKeyRing(fingerprint.getKeyId());
|
||||
if (key == null) {
|
||||
try {
|
||||
PubkeyElement pubkeyElement = PubSubDelegate.fetchPubkey(connection(), contact, fingerprint);
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (XMPPException.XMPPErrorException e) {
|
||||
e.printStackTrace();
|
||||
} catch (PubSubException.NotAPubSubNodeException e) {
|
||||
e.printStackTrace();
|
||||
} catch (PubSubException.NotALeafNodeException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SmackException.NotConnectedException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SmackException.NoResponseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (PGPException | IOException e) {
|
||||
LOGGER.log(Level.WARNING, "Could not read public keys of " + contact, e);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private final IncomingChatMessageListener incomingOpenPgpMessageListener =
|
||||
|
@ -478,22 +498,6 @@ public final class OpenPgpManager extends Manager {
|
|||
Private stuff.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Process a {@link PubkeyElement}. This includes unpacking the key from the element and importing it.
|
||||
*
|
||||
* @param pubkeyElement {@link PubkeyElement} containing the key
|
||||
* @param owner owner of the key
|
||||
* @throws MissingUserIdOnKeyException if the key does not have an OpenPGP user-id of the form
|
||||
* "xmpp:juliet@capulet.lit" with the owners {@link BareJid}
|
||||
* @throws IOException row, row, row your byte gently down the {@link InputStream}
|
||||
*/
|
||||
private void processPublicKey(PubkeyElement pubkeyElement, BareJid owner)
|
||||
throws MissingUserIdOnKeyException, IOException, PGPException {
|
||||
byte[] base64 = pubkeyElement.getDataElement().getB64Data();
|
||||
PGPPublicKeyRing keyRing = PGPainless.readKeyRing().publicKeyRing(Base64.decode(base64));
|
||||
provider.getStore().importPublicKey(owner, keyRing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link PubkeyElement} which contains the OpenPGP public key of {@code owner} which belongs to
|
||||
* the {@link OpenPgpV4Fingerprint} {@code fingerprint}.
|
||||
|
@ -509,14 +513,11 @@ public final class OpenPgpManager extends Manager {
|
|||
OpenPgpV4Fingerprint fingerprint,
|
||||
Date date)
|
||||
throws MissingOpenPgpPublicKeyException, IOException, PGPException {
|
||||
PGPPublicKeyRingCollection publicKeyRingCollection = provider.getStore().getPublicKeysOf(owner);
|
||||
if (publicKeyRingCollection != null) {
|
||||
PGPPublicKeyRing keys = publicKeyRingCollection.getPublicKeyRing(fingerprint.getKeyId());
|
||||
if (keys != null) {
|
||||
byte[] keyBytes = keys.getEncoded(true);
|
||||
PGPPublicKeyRing ring = provider.getStore().getPublicKeyRing(owner, fingerprint);
|
||||
if (ring != null) {
|
||||
byte[] keyBytes = ring.getEncoded(true);
|
||||
return createPubkeyElement(keyBytes, date);
|
||||
}
|
||||
}
|
||||
throw new MissingOpenPgpPublicKeyException(owner, fingerprint);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
|||
import org.jxmpp.jid.BareJid;
|
||||
import org.pgpainless.pgpainless.PGPainless;
|
||||
import org.pgpainless.pgpainless.key.OpenPgpV4Fingerprint;
|
||||
import org.pgpainless.pgpainless.key.generation.type.length.RsaLength;
|
||||
import org.pgpainless.pgpainless.util.BCUtil;
|
||||
|
||||
public abstract class AbstractOpenPgpKeyStore implements OpenPgpKeyStore {
|
||||
|
@ -87,15 +86,17 @@ public abstract class AbstractOpenPgpKeyStore implements OpenPgpKeyStore {
|
|||
throw new MissingUserIdOnKeyException(owner, secretKeys.getPublicKey().getKeyID());
|
||||
}
|
||||
|
||||
PGPSecretKeyRing importKeys = BCUtil.removeUnassociatedKeysFromKeyRing(secretKeys, secretKeys.getPublicKey());
|
||||
|
||||
PGPSecretKeyRingCollection secretKeyRings = getSecretKeysOf(owner);
|
||||
try {
|
||||
if (secretKeyRings != null) {
|
||||
secretKeyRings = PGPSecretKeyRingCollection.addSecretKeyRing(secretKeyRings, secretKeys);
|
||||
secretKeyRings = PGPSecretKeyRingCollection.addSecretKeyRing(secretKeyRings, importKeys);
|
||||
} else {
|
||||
secretKeyRings = BCUtil.keyRingsToKeyRingCollection(secretKeys);
|
||||
secretKeyRings = BCUtil.keyRingsToKeyRingCollection(importKeys);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOGGER.log(Level.INFO, "Skipping secret key ring " + Long.toHexString(secretKeys.getPublicKey().getKeyID()) +
|
||||
LOGGER.log(Level.INFO, "Skipping secret key ring " + Long.toHexString(importKeys.getPublicKey().getKeyID()) +
|
||||
" as it is already in the key ring of " + owner.toString());
|
||||
}
|
||||
this.secretKeyRingCollections.put(owner, secretKeyRings);
|
||||
|
@ -110,15 +111,17 @@ public abstract class AbstractOpenPgpKeyStore implements OpenPgpKeyStore {
|
|||
throw new MissingUserIdOnKeyException(owner, publicKeys.getPublicKey().getKeyID());
|
||||
}
|
||||
|
||||
PGPPublicKeyRing importKeys = BCUtil.removeUnassociatedKeysFromKeyRing(publicKeys, publicKeys.getPublicKey());
|
||||
|
||||
PGPPublicKeyRingCollection publicKeyRings = getPublicKeysOf(owner);
|
||||
try {
|
||||
if (publicKeyRings != null) {
|
||||
publicKeyRings = PGPPublicKeyRingCollection.addPublicKeyRing(publicKeyRings, publicKeys);
|
||||
publicKeyRings = PGPPublicKeyRingCollection.addPublicKeyRing(publicKeyRings, importKeys);
|
||||
} else {
|
||||
publicKeyRings = BCUtil.keyRingsToKeyRingCollection(publicKeys);
|
||||
publicKeyRings = BCUtil.keyRingsToKeyRingCollection(importKeys);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
LOGGER.log(Level.INFO, "Skipping public key ring " + Long.toHexString(publicKeys.getPublicKey().getKeyID()) +
|
||||
LOGGER.log(Level.INFO, "Skipping public key ring " + Long.toHexString(importKeys.getPublicKey().getKeyID()) +
|
||||
" as it is already in the key ring of " + owner.toString());
|
||||
}
|
||||
this.publicKeyRingCollections.put(owner, publicKeyRings);
|
||||
|
@ -176,6 +179,6 @@ public abstract class AbstractOpenPgpKeyStore implements OpenPgpKeyStore {
|
|||
@Override
|
||||
public PGPSecretKeyRing generateKeyRing(BareJid owner)
|
||||
throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
|
||||
return PGPainless.generateKeyRing().simpleRsaKeyRing("xmpp:" + owner.toString(), RsaLength._4096);
|
||||
return PGPainless.generateKeyRing().simpleEcKeyRing("xmpp:" + owner.toString());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue