Search in sources :

Example 1 with OpenPgpV4Fingerprint

use of org.pgpainless.key.OpenPgpV4Fingerprint in project Smack by igniterealtime.

the class FileBasedOpenPgpMetadataStore method readFingerprintsAndDates.

static Map<OpenPgpV4Fingerprint, Date> readFingerprintsAndDates(File source) throws IOException {
    // TODO: Why do we not throw a FileNotFoundException here?
    if (!source.exists() || source.isDirectory()) {
        return new HashMap<>();
    }
    BufferedReader reader = null;
    try {
        InputStream inputStream = FileUtils.prepareFileInputStream(source);
        InputStreamReader isr = new InputStreamReader(inputStream, Util.UTF8);
        reader = new BufferedReader(isr);
        Map<OpenPgpV4Fingerprint, Date> fingerprintDateMap = new HashMap<>();
        String line;
        int lineNr = 0;
        while ((line = reader.readLine()) != null) {
            lineNr++;
            line = line.trim();
            String[] split = line.split(" ");
            if (split.length != 2) {
                LOGGER.log(Level.FINE, "Skipping invalid line " + lineNr + " in file " + source.getAbsolutePath());
                continue;
            }
            try {
                OpenPgpV4Fingerprint fingerprint = new OpenPgpV4Fingerprint(split[0]);
                Date date = XmppDateTime.parseXEP0082Date(split[1]);
                fingerprintDateMap.put(fingerprint, date);
            } catch (IllegalArgumentException | ParseException e) {
                LOGGER.log(Level.WARNING, "Error parsing fingerprint/date touple in line " + lineNr + " of file " + source.getAbsolutePath(), e);
            }
        }
        return fingerprintDateMap;
    } finally {
        CloseableUtil.maybeClose(reader, LOGGER);
    }
}
Also used : InputStreamReader(java.io.InputStreamReader) HashMap(java.util.HashMap) InputStream(java.io.InputStream) Date(java.util.Date) OpenPgpV4Fingerprint(org.pgpainless.key.OpenPgpV4Fingerprint) BufferedReader(java.io.BufferedReader) OpenPgpV4Fingerprint(org.pgpainless.key.OpenPgpV4Fingerprint) ParseException(java.text.ParseException)

Example 2 with OpenPgpV4Fingerprint

use of org.pgpainless.key.OpenPgpV4Fingerprint in project Smack by igniterealtime.

the class FileBasedOpenPgpTrustStore method readTrust.

@Override
protected Trust readTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException {
    File file = getTrustPath(owner, fingerprint);
    BufferedReader reader = null;
    try {
        InputStream inputStream = FileUtils.prepareFileInputStream(file);
        InputStreamReader isr = new InputStreamReader(inputStream, Util.UTF8);
        reader = new BufferedReader(isr);
        Trust trust = null;
        String line;
        int lineNr = 0;
        while ((line = reader.readLine()) != null) {
            lineNr++;
            try {
                trust = Trust.valueOf(line);
                break;
            } catch (IllegalArgumentException e) {
                LOGGER.log(Level.WARNING, "Skipping invalid trust record in line " + lineNr + " \"" + line + "\" of file " + file.getAbsolutePath());
            }
        }
        return trust != null ? trust : Trust.undecided;
    } catch (IOException e) {
        if (e instanceof FileNotFoundException) {
            return Trust.undecided;
        }
        throw e;
    } finally {
        CloseableUtil.maybeClose(reader, LOGGER);
    }
}
Also used : InputStreamReader(java.io.InputStreamReader) InputStream(java.io.InputStream) BufferedReader(java.io.BufferedReader) FileNotFoundException(java.io.FileNotFoundException) IOException(java.io.IOException) File(java.io.File) OpenPgpV4Fingerprint(org.pgpainless.key.OpenPgpV4Fingerprint)

Example 3 with OpenPgpV4Fingerprint

use of org.pgpainless.key.OpenPgpV4Fingerprint 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);
}
Also used : PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) HashMap(java.util.HashMap) IOException(java.io.IOException) Date(java.util.Date) PGPException(org.bouncycastle.openpgp.PGPException) PubkeyElement(org.jivesoftware.smackx.ox.element.PubkeyElement) BcKeyFingerprintCalculator(org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator) OpenPgpV4Fingerprint(org.pgpainless.key.OpenPgpV4Fingerprint) MissingUserIdOnKeyException(org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException)

Example 4 with OpenPgpV4Fingerprint

use of org.pgpainless.key.OpenPgpV4Fingerprint in project Smack by igniterealtime.

the class OpenPgpContact method getAnnouncedPublicKeys.

/**
 * Return any announced public keys. This is the set returned by {@link #getAnyPublicKeys()} with non-announced
 * keys and keys which lack a user-id with the contacts jid removed.
 *
 * @return announced keys of the contact
 *
 * @throws IOException IO is dangerous
 * @throws PGPException PGP is brittle
 */
public PGPPublicKeyRingCollection getAnnouncedPublicKeys() throws IOException, PGPException {
    PGPPublicKeyRingCollection anyKeys = getAnyPublicKeys();
    Map<OpenPgpV4Fingerprint, Date> announced = store.getAnnouncedFingerprintsOf(jid);
    PGPPublicKeyRingCollection announcedKeysCollection = null;
    for (OpenPgpV4Fingerprint announcedFingerprint : announced.keySet()) {
        PGPPublicKeyRing ring = anyKeys.getPublicKeyRing(announcedFingerprint.getKeyId());
        if (ring == null)
            continue;
        if (!new KeyRingInfo(ring).isUserIdValid("xmpp:" + getJid().toString())) {
            LOGGER.log(Level.WARNING, "Ignore key " + Long.toHexString(ring.getPublicKey().getKeyID()) + " as it lacks the user-id \"xmpp" + getJid().toString() + "\"");
            continue;
        }
        if (announcedKeysCollection == null) {
            announcedKeysCollection = new PGPPublicKeyRingCollection(Collections.singleton(ring));
        } else {
            announcedKeysCollection = PGPPublicKeyRingCollection.addPublicKeyRing(announcedKeysCollection, ring);
        }
    }
    return announcedKeysCollection;
}
Also used : PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) PGPPublicKeyRingCollection(org.bouncycastle.openpgp.PGPPublicKeyRingCollection) KeyRingInfo(org.pgpainless.key.info.KeyRingInfo) OpenPgpV4Fingerprint(org.pgpainless.key.OpenPgpV4Fingerprint) Date(java.util.Date)

Example 5 with OpenPgpV4Fingerprint

use of org.pgpainless.key.OpenPgpV4Fingerprint in project Smack by igniterealtime.

the class OpenPgpContact method getPublicKeysOfTrustState.

/**
 * Return a {@link PGPPublicKeyRingCollection}, which contains all keys from {@code keys}, which are marked with the
 * {@link OpenPgpTrustStore.Trust} state of {@code trust}.
 *
 * @param keys {@link PGPPublicKeyRingCollection}
 * @param trust {@link OpenPgpTrustStore.Trust}
 *
 * @return all keys from {@code keys} with trust state {@code trust}.
 *
 * @throws IOException IO error
 */
protected PGPPublicKeyRingCollection getPublicKeysOfTrustState(PGPPublicKeyRingCollection keys, OpenPgpTrustStore.Trust trust) throws IOException {
    if (keys == null) {
        return null;
    }
    Set<PGPPublicKeyRing> toRemove = new HashSet<>();
    Iterator<PGPPublicKeyRing> iterator = keys.iterator();
    while (iterator.hasNext()) {
        PGPPublicKeyRing ring = iterator.next();
        OpenPgpV4Fingerprint fingerprint = new OpenPgpV4Fingerprint(ring);
        if (store.getTrust(getJid(), fingerprint) != trust) {
            toRemove.add(ring);
        }
    }
    for (PGPPublicKeyRing ring : toRemove) {
        keys = PGPPublicKeyRingCollection.removePublicKeyRing(keys, ring);
    }
    if (!keys.iterator().hasNext()) {
        return null;
    }
    return keys;
}
Also used : PGPPublicKeyRing(org.bouncycastle.openpgp.PGPPublicKeyRing) OpenPgpV4Fingerprint(org.pgpainless.key.OpenPgpV4Fingerprint) HashSet(java.util.HashSet)

Aggregations

OpenPgpV4Fingerprint (org.pgpainless.key.OpenPgpV4Fingerprint)28 Date (java.util.Date)11 PGPSecretKeyRing (org.bouncycastle.openpgp.PGPSecretKeyRing)11 PGPPublicKeyRing (org.bouncycastle.openpgp.PGPPublicKeyRing)8 Test (org.junit.Test)7 Test (org.junit.jupiter.api.Test)5 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 PGPPublicKeyRingCollection (org.bouncycastle.openpgp.PGPPublicKeyRingCollection)3 PainlessOpenPgpProvider (org.jivesoftware.smackx.ox.crypto.PainlessOpenPgpProvider)3 PublicKeysListElement (org.jivesoftware.smackx.ox.element.PublicKeysListElement)3 SecretkeyElement (org.jivesoftware.smackx.ox.element.SecretkeyElement)3 MissingUserIdOnKeyException (org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException)3 OpenPgpStore (org.jivesoftware.smackx.ox.store.definition.OpenPgpStore)3 FileBasedOpenPgpStore (org.jivesoftware.smackx.ox.store.filebased.FileBasedOpenPgpStore)3 KeyRingInfo (org.pgpainless.key.info.KeyRingInfo)3 UnprotectedKeysProtector (org.pgpainless.key.protection.UnprotectedKeysProtector)3 BufferedReader (java.io.BufferedReader)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2