use of org.jivesoftware.smackx.ox.element.PubkeyElement in project Smack by igniterealtime.
the class OpenPgpContact method updateKeys.
/**
* Update the contacts keys using a prefetched {@link PublicKeysListElement}.
*
* @param connection our {@link XMPPConnection}.
* @param metadata pre-fetched OX metadata node of the contact.
*
* @throws InterruptedException in case the thread gets interrupted.
* @throws SmackException.NotConnectedException in case the connection is not connected.
* @throws SmackException.NoResponseException in case the server doesn't respond.
* @throws IOException IO is dangerous.
*/
public void updateKeys(XMPPConnection connection, PublicKeysListElement metadata) throws InterruptedException, SmackException.NotConnectedException, SmackException.NoResponseException, IOException {
Map<OpenPgpV4Fingerprint, Date> fingerprintsAndDates = new HashMap<>();
for (OpenPgpV4Fingerprint fingerprint : metadata.getMetadata().keySet()) {
fingerprintsAndDates.put(fingerprint, metadata.getMetadata().get(fingerprint).getDate());
}
store.setAnnouncedFingerprintsOf(getJid(), fingerprintsAndDates);
Map<OpenPgpV4Fingerprint, Date> fetchDates = store.getPublicKeyFetchDates(getJid());
for (OpenPgpV4Fingerprint fingerprint : metadata.getMetadata().keySet()) {
Date fetchDate = fetchDates.get(fingerprint);
if (fetchDate != null && fingerprintsAndDates.get(fingerprint) != null && fetchDate.after(fingerprintsAndDates.get(fingerprint))) {
LOGGER.log(Level.FINE, "Skip key " + Long.toHexString(fingerprint.getKeyId()) + " as we already have the most recent version. " + "Last announced: " + fingerprintsAndDates.get(fingerprint).toString() + " Last fetched: " + fetchDate.toString());
continue;
}
try {
PubkeyElement key = OpenPgpPubSubUtil.fetchPubkey(connection, getJid(), fingerprint);
unfetchableKeys.remove(fingerprint);
fetchDates.put(fingerprint, new Date());
if (key == null) {
LOGGER.log(Level.WARNING, "Public key " + Long.toHexString(fingerprint.getKeyId()) + " can not be imported: Is null");
unfetchableKeys.put(fingerprint, new NullPointerException("Public key is null."));
continue;
}
PGPPublicKeyRing keyRing = new PGPPublicKeyRing(Base64.decode(key.getDataElement().getB64Data()), new BcKeyFingerprintCalculator());
store.importPublicKey(getJid(), keyRing);
} catch (PubSubException.NotAPubSubNodeException | PubSubException.NotALeafNodeException | XMPPException.XMPPErrorException e) {
LOGGER.log(Level.WARNING, "Error fetching public key " + Long.toHexString(fingerprint.getKeyId()), e);
unfetchableKeys.put(fingerprint, e);
} catch (PGPException | IOException e) {
LOGGER.log(Level.WARNING, "Public key " + Long.toHexString(fingerprint.getKeyId()) + " can not be imported.", e);
unfetchableKeys.put(fingerprint, e);
} catch (MissingUserIdOnKeyException e) {
LOGGER.log(Level.WARNING, "Public key " + Long.toHexString(fingerprint.getKeyId()) + " is missing the user-id \"xmpp:" + getJid() + "\". Refuse to import it.", e);
unfetchableKeys.put(fingerprint, e);
}
}
store.setPublicKeyFetchDates(getJid(), fetchDates);
}
use of org.jivesoftware.smackx.ox.element.PubkeyElement in project Smack by igniterealtime.
the class PubkeyElementTest method providerTest.
@SuppressWarnings("UndefinedEquals")
@ParameterizedTest
@EnumSource(SmackTestUtil.XmlPullParserKind.class)
public void providerTest(SmackTestUtil.XmlPullParserKind parserKind) throws ParseException, XmlPullParserException, IOException, SmackParsingException {
String base64EncodedOpenPgpPublicKey = "VGhpcyBpcyBqdXN0IGEgdGVzdA==";
String pubkeyElement = "<pubkey xmlns='urn:xmpp:openpgp:0' date='2018-01-21T10:46:21.000+00:00'>" + "<data>" + base64EncodedOpenPgpPublicKey + "</data>" + "</pubkey>";
Date date = XmppDateTime.parseXEP0082Date("2018-01-21T10:46:21.000+00:00");
PubkeyElement element = new PubkeyElement(new PubkeyElement.PubkeyDataElement(base64EncodedOpenPgpPublicKey), date);
assertXmlSimilar(pubkeyElement, element.toXML().toString());
XmlPullParser parser = SmackTestUtil.getParserFor(pubkeyElement, parserKind);
PubkeyElement parsed = PubkeyElementProvider.INSTANCE.parse(parser);
assertEquals(element.getDate(), parsed.getDate());
assertEquals(element.getDataElement().getB64Data(), parsed.getDataElement().getB64Data());
}
use of org.jivesoftware.smackx.ox.element.PubkeyElement in project Smack by igniterealtime.
the class OpenPgpManager method announceSupportAndPublish.
/**
* 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.
* Lastly register a {@link PepListener} which listens for updates to Public Key Metadata Nodes.
*
* @throws NoSuchAlgorithmException if we are missing an algorithm to generate a fresh key pair.
* @throws NoSuchProviderException if we are missing a suitable {@link java.security.Provider}.
* @throws InterruptedException if the thread gets interrupted.
* @throws PubSubException.NotALeafNodeException if one of the PubSub nodes is not a {@link LeafNode}.
* @throws XMPPException.XMPPErrorException in case of an XMPP protocol error.
* @throws SmackException.NotConnectedException if we are not connected.
* @throws SmackException.NoResponseException if the server doesn't respond.
* @throws IOException IO is dangerous.
* @throws InvalidAlgorithmParameterException if illegal algorithm parameters are used for key generation.
* @throws SmackException.NotLoggedInException if we are not logged in.
* @throws PGPException if something goes wrong during key loading/generating
*/
public void announceSupportAndPublish() throws NoSuchAlgorithmException, NoSuchProviderException, InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, SmackException.NotConnectedException, SmackException.NoResponseException, IOException, InvalidAlgorithmParameterException, SmackException.NotLoggedInException, PGPException {
throwIfNoProviderSet();
throwIfNotAuthenticated();
OpenPgpV4Fingerprint primaryFingerprint = getOurFingerprint();
if (primaryFingerprint == null) {
primaryFingerprint = generateAndImportKeyPair(getJidOrThrow());
}
// Create <pubkey/> element
PubkeyElement pubkeyElement;
try {
pubkeyElement = createPubkeyElement(getJidOrThrow(), primaryFingerprint, new Date());
} catch (MissingOpenPgpKeyException e) {
throw new AssertionError("Cannot publish our public key, since it is missing (MUST NOT happen!)");
}
// publish it
publishPublicKey(pepManager, pubkeyElement, primaryFingerprint);
// Subscribe to public key changes
pepManager.addPepEventListener(PEP_NODE_PUBLIC_KEYS, PublicKeysListElement.class, pepPublicKeyListElementListener);
ServiceDiscoveryManager.getInstanceFor(connection()).addFeature(PEP_NODE_PUBLIC_KEYS_NOTIFY);
}
use of org.jivesoftware.smackx.ox.element.PubkeyElement in project Smack by igniterealtime.
the class PubkeyElementProvider method parse.
@Override
public PubkeyElement parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, ParseException {
String dateString = parser.getAttributeValue(null, PubkeyElement.ATTR_DATE);
Date date = ParserUtils.getDateFromOptionalXep82String(dateString);
while (true) {
XmlPullParser.Event tag = parser.next();
if (tag == XmlPullParser.Event.START_ELEMENT) {
String name = parser.getName();
switch(name) {
case PubkeyElement.PubkeyDataElement.ELEMENT:
String base64EncodedOpenPgpPubKey = parser.nextText();
PubkeyElement.PubkeyDataElement pubkeyDataElement = new PubkeyElement.PubkeyDataElement(base64EncodedOpenPgpPubKey);
return new PubkeyElement(pubkeyDataElement, date);
}
}
}
}
Aggregations