Implement new OpenPgpProvider

This commit is contained in:
Paul Schaub 2018-07-08 18:23:08 +02:00
parent bf92cec618
commit 15eee8e65f
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
18 changed files with 301 additions and 188 deletions

View File

@ -1,129 +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;
import javax.xml.bind.DatatypeConverter;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.util.Arrays;
import org.jivesoftware.smack.util.Objects;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.util.encoders.Hex;
/**
* This class represents an hex encoded, uppercase OpenPGP v4 fingerprint.
*/
public class OpenPgpV4Fingerprint implements CharSequence, Comparable<OpenPgpV4Fingerprint> {
private final String fingerprint;
/**
* Create an {@link OpenPgpV4Fingerprint}.
* @see <a href="https://xmpp.org/extensions/xep-0373.html#annoucning-pubkey">
* XEP-0373 §4.1: The OpenPGP Public-Key Data Node about how to obtain the fingerprint</a>
* @param fingerprint hexadecimal representation of the fingerprint.
*/
public OpenPgpV4Fingerprint(String fingerprint) throws ParseException {
String fp = Objects.requireNonNull(fingerprint)
.trim()
.toUpperCase();
if (!isValid(fp)) {
throw new ParseException("Fingerprint " + fingerprint +
" does not appear to be a valid OpenPGP v4 fingerprint.", 0);
}
this.fingerprint = fp;
}
public OpenPgpV4Fingerprint(byte[] bytes) throws ParseException {
this(new String(bytes, Charset.forName("UTF-8")));
}
public OpenPgpV4Fingerprint(PGPPublicKey key) throws ParseException {
this(Hex.encode(key.getFingerprint()));
}
/**
* Check, whether the fingerprint consists of 40 valid hexadecimal characters.
* @param fp fingerprint to check.
* @return true if fingerprint is valid.
*/
private boolean isValid(String fp) {
return fp.matches("[0-9A-F]{40}");
}
/**
* Return the key id of the OpenPGP public key this {@link OpenPgpV4Fingerprint} belongs to.
*
* @see <a href="https://tools.ietf.org/html/rfc4880#section-12.2">
* RFC-4880 §12.2: Key IDs and Fingerprints</a>
* @return key id
*/
public long getKeyId() {
byte[] bytes = DatatypeConverter.parseHexBinary(this.toString());
byte[] lower8Bytes = Arrays.copyOfRange(bytes, 12, 20);
ByteBuffer byteBuffer = ByteBuffer.allocate(8);
byteBuffer.put(lower8Bytes);
byteBuffer.flip();
return byteBuffer.getLong();
}
@Override
public boolean equals(Object other) {
if (other == null) {
return false;
}
if (!(other instanceof CharSequence)) {
return false;
}
return this.toString().equals(other.toString());
}
@Override
public int hashCode() {
return fingerprint.hashCode();
}
@Override
public int length() {
return fingerprint.length();
}
@Override
public char charAt(int i) {
return fingerprint.charAt(i);
}
@Override
public CharSequence subSequence(int i, int i1) {
return fingerprint.subSequence(i, i1);
}
@Override
public String toString() {
return fingerprint;
}
@Override
public int compareTo(OpenPgpV4Fingerprint openPgpV4Fingerprint) {
return fingerprint.compareTo(openPgpV4Fingerprint.fingerprint);
}
}

View File

@ -16,8 +16,12 @@
*/
package org.jivesoftware.smackx.ox.element;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import org.jivesoftware.smack.packet.ExtensionElement;
import org.jivesoftware.smack.util.XmlStringBuilder;
import org.jivesoftware.smackx.ox.util.Util;
public class OpenPgpElement implements ExtensionElement {
@ -31,6 +35,10 @@ public class OpenPgpElement implements ExtensionElement {
this.base64EncodedOpenPgpMessage = base64EncodedOpenPgpMessage;
}
public InputStream toInputStream() {
return new ByteArrayInputStream(base64EncodedOpenPgpMessage.getBytes(Util.UTF8));
}
public String getEncryptedBase64MessageContent() {
return base64EncodedOpenPgpMessage;
}

View File

@ -0,0 +1,47 @@
package org.jivesoftware.smackx.ox.v2;
import java.io.IOException;
import java.util.Set;
import java.util.logging.Logger;
import org.jivesoftware.smackx.ox.v2.store.definition.OpenPgpStore;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.jxmpp.jid.BareJid;
public class OpenPgpContact {
private final Logger LOGGER;
protected final BareJid jid;
protected final OpenPgpStore store;
public OpenPgpContact(BareJid jid, OpenPgpStore store) {
this.jid = jid;
this.store = store;
LOGGER = Logger.getLogger(OpenPgpContact.class.getName() + ":" + jid.toString());
}
public PGPPublicKeyRingCollection getAnyPublicKeys() throws IOException, PGPException {
return store.getPublicKeysOf(jid);
}
public PGPPublicKeyRingCollection getAnnouncedPublicKeys() throws IOException, PGPException {
PGPPublicKeyRingCollection anyKeys = getAnyPublicKeys();
Set<OpenPgpV4Fingerprint> announced = store.getAnnouncedFingerprintsOf(jid).keySet();
PGPPublicKeyRingCollection announcedKeysCollection = anyKeys;
for (PGPPublicKeyRing ring : anyKeys) {
OpenPgpV4Fingerprint fingerprint = new OpenPgpV4Fingerprint(ring.getPublicKey());
if (!announced.contains(fingerprint)) {
announcedKeysCollection = PGPPublicKeyRingCollection.removePublicKeyRing(announcedKeysCollection, ring);
}
}
return announcedKeysCollection;
}
}

View File

@ -16,22 +16,24 @@
*/
package org.jivesoftware.smackx.ox.v2;
import java.io.IOException;
import java.util.Collection;
import org.jivesoftware.smackx.ox.OpenPgpContact;
import org.jivesoftware.smackx.ox.OpenPgpMessage;
import org.jivesoftware.smackx.ox.element.CryptElement;
import org.jivesoftware.smackx.ox.element.OpenPgpElement;
import org.jivesoftware.smackx.ox.element.SignElement;
import org.jivesoftware.smackx.ox.element.SigncryptElement;
import org.bouncycastle.openpgp.PGPException;
public interface OpenPgpProvider {
OpenPgpElement signAndEncrypt(SigncryptElement element, Collection<OpenPgpContact> recipients);
OpenPgpElement signAndEncrypt(SigncryptElement element, OpenPgpSelf self, Collection<OpenPgpContact> recipients) throws IOException, PGPException;
OpenPgpElement sign(SignElement element);
OpenPgpElement sign(SignElement element, OpenPgpSelf self) throws IOException, PGPException;
OpenPgpElement encrypt(CryptElement element, Collection<OpenPgpContact> recipients);
OpenPgpElement encrypt(CryptElement element, OpenPgpSelf self, Collection<OpenPgpContact> recipients) throws IOException, PGPException;
OpenPgpMessage decryptAndOrVerify(OpenPgpElement element);
OpenPgpMessage decryptAndOrVerify(OpenPgpElement element, OpenPgpSelf self, OpenPgpContact sender) throws IOException, PGPException;
}

View File

@ -0,0 +1,52 @@
package org.jivesoftware.smackx.ox.v2;
import java.io.IOException;
import org.jivesoftware.smackx.ox.v2.store.definition.OpenPgpStore;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.jxmpp.jid.BareJid;
public class OpenPgpSelf extends OpenPgpContact {
public OpenPgpSelf(BareJid jid, OpenPgpStore store) {
super(jid, store);
}
public boolean hasSecretKeyAvailable() throws IOException, PGPException {
return getSecretKeys() != null;
}
public PGPSecretKeyRingCollection getSecretKeys() throws IOException, PGPException {
return store.getSecretKeysOf(jid);
}
public PGPSecretKeyRing getSigningKeyRing() throws IOException, PGPException {
PGPSecretKeyRingCollection secretKeyRings = getSecretKeys();
if (secretKeyRings == null) {
return null;
}
PGPSecretKeyRing signingKeyRing = null;
for (PGPSecretKeyRing ring : secretKeyRings) {
if (signingKeyRing == null) {
signingKeyRing = ring;
continue;
}
if (ring.getPublicKey().getCreationTime().after(signingKeyRing.getPublicKey().getCreationTime())) {
signingKeyRing = ring;
}
}
return signingKeyRing;
}
public OpenPgpV4Fingerprint getSigningKeyFingerprint() throws IOException, PGPException {
PGPSecretKeyRing signingKeyRing = getSigningKeyRing();
return signingKeyRing != null ? new OpenPgpV4Fingerprint(signingKeyRing.getPublicKey()) : null;
}
}

View File

@ -0,0 +1,127 @@
package org.jivesoftware.smackx.ox.v2;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import org.jivesoftware.smack.util.stringencoder.Base64;
import org.jivesoftware.smackx.ox.OpenPgpMessage;
import org.jivesoftware.smackx.ox.element.CryptElement;
import org.jivesoftware.smackx.ox.element.OpenPgpElement;
import org.jivesoftware.smackx.ox.element.SignElement;
import org.jivesoftware.smackx.ox.element.SigncryptElement;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.util.io.Streams;
import org.pgpainless.pgpainless.PGPainless;
import org.pgpainless.pgpainless.decryption_verification.DecryptionStream;
import org.pgpainless.pgpainless.decryption_verification.PainlessResult;
import org.pgpainless.pgpainless.encryption_signing.EncryptionStream;
public class PainlessOpenPgpProvider implements OpenPgpProvider {
@Override
public OpenPgpElement signAndEncrypt(SigncryptElement element, OpenPgpSelf self, Collection<OpenPgpContact> recipients)
throws IOException, PGPException {
InputStream plainText = element.toInputStream();
ByteArrayOutputStream cipherText = new ByteArrayOutputStream();
ArrayList<PGPPublicKeyRingCollection> recipientKeys = new ArrayList<>();
for (OpenPgpContact contact : recipients) {
recipientKeys.add(contact.getAnnouncedPublicKeys());
}
EncryptionStream cipherStream = PGPainless.createEncryptor().onOutputStream(cipherText)
.toRecipients(recipientKeys.toArray(new PGPPublicKeyRingCollection[]{}))
.andToSelf(self.getAnnouncedPublicKeys())
.usingSecureAlgorithms()
.signWith(null, self.getSigningKeyRing())
.noArmor();
Streams.pipeAll(plainText, cipherStream);
plainText.close();
cipherStream.flush();
cipherStream.close();
cipherText.close();
String base64 = Base64.encodeToString(cipherText.toByteArray());
// TODO: Return feedback about encryption?
return new OpenPgpElement(base64);
}
@Override
public OpenPgpElement sign(SignElement element, OpenPgpSelf self)
throws IOException, PGPException {
InputStream plainText = element.toInputStream();
ByteArrayOutputStream cipherText = new ByteArrayOutputStream();
EncryptionStream cipherStream = PGPainless.createEncryptor().onOutputStream(cipherText)
.doNotEncrypt()
.signWith(null, self.getSigningKeyRing())
.noArmor();
Streams.pipeAll(plainText, cipherStream);
plainText.close();
cipherStream.flush();
cipherStream.close();
cipherText.close();
String base64 = Base64.encodeToString(cipherText.toByteArray());
return new OpenPgpElement(base64);
}
@Override
public OpenPgpElement encrypt(CryptElement element, OpenPgpSelf self, Collection<OpenPgpContact> recipients)
throws IOException, PGPException {
InputStream plainText = element.toInputStream();
ByteArrayOutputStream cipherText = new ByteArrayOutputStream();
ArrayList<PGPPublicKeyRingCollection> recipientKeys = new ArrayList<>();
for (OpenPgpContact contact : recipients) {
recipientKeys.add(contact.getAnnouncedPublicKeys());
}
EncryptionStream cipherStream = PGPainless.createEncryptor().onOutputStream(cipherText)
.toRecipients(recipientKeys.toArray(new PGPPublicKeyRingCollection[]{}))
.andToSelf(self.getAnnouncedPublicKeys())
.usingSecureAlgorithms()
.doNotSign()
.noArmor();
Streams.pipeAll(plainText, cipherStream);
plainText.close();
cipherStream.flush();
cipherStream.close();
cipherText.close();
String base64 = Base64.encodeToString(cipherText.toByteArray());
// TODO: Return feedback about encryption?
return new OpenPgpElement(base64);
}
@Override
public OpenPgpMessage decryptAndOrVerify(OpenPgpElement element, OpenPgpSelf self, OpenPgpContact sender) throws IOException, PGPException {
ByteArrayOutputStream plainText = new ByteArrayOutputStream();
InputStream cipherText = element.toInputStream();
DecryptionStream cipherStream = PGPainless.createDecryptor().onInputStream(cipherText)
.decryptWith(null, self.getSecretKeys())
.verifyWith(sender.getAnnouncedPublicKeys())
.ignoreMissingPublicKeys()
.build();
Streams.pipeAll(cipherStream, plainText);
cipherText.close();
cipherStream.close();
plainText.close();
PainlessResult info = cipherStream.getResult();
return new OpenPgpMessage(plainText.toByteArray(), new OpenPgpMessage.Metadata(
info.getDecryptionKeyId(), info.getVerifiedSignatureKeyIds()));
}
}

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.v2.store;
package org.jivesoftware.smackx.ox.v2.store.abstr;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
@ -24,6 +24,7 @@ import java.util.HashMap;
import java.util.Map;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jivesoftware.smackx.ox.v2.store.definition.OpenPgpKeyStore;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.v2.store;
package org.jivesoftware.smackx.ox.v2.store.abstr;
import java.io.IOException;
import java.util.Date;
@ -22,6 +22,7 @@ import java.util.HashMap;
import java.util.Map;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jivesoftware.smackx.ox.v2.store.definition.OpenPgpMetadataStore;
import org.jxmpp.jid.BareJid;

View File

@ -14,20 +14,25 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.v2.store;
package org.jivesoftware.smackx.ox.v2.store.abstr;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Observable;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smackx.ox.OpenPgpContact;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jivesoftware.smackx.ox.callback.SecretKeyPassphraseCallback;
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;
import org.jivesoftware.smackx.ox.v2.store.definition.OpenPgpKeyStore;
import org.jivesoftware.smackx.ox.v2.store.definition.OpenPgpMetadataStore;
import org.jivesoftware.smackx.ox.v2.store.definition.OpenPgpStore;
import org.jivesoftware.smackx.ox.v2.store.definition.OpenPgpTrustStore;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
@ -37,24 +42,26 @@ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.jxmpp.jid.BareJid;
import org.pgpainless.pgpainless.key.protection.SecretKeyRingProtector;
public abstract class OpenPgpStore implements OpenPgpKeyStore, OpenPgpMetadataStore, OpenPgpTrustStore {
public abstract class AbstractOpenPgpStore extends Observable implements OpenPgpStore {
protected final OpenPgpKeyStore keyStore;
protected final OpenPgpMetadataStore metadataStore;
protected final OpenPgpTrustStore trustStore;
protected SecretKeyPassphraseCallback secretKeyPassphraseCallback;
protected SecretKeyRingProtector unlocker;
protected final Map<BareJid, OpenPgpContact> contacts = new HashMap<>();
public OpenPgpStore(OpenPgpKeyStore keyStore,
OpenPgpMetadataStore metadataStore,
OpenPgpTrustStore trustStore) {
this.keyStore = keyStore;
this.metadataStore = metadataStore;
this.trustStore = trustStore;
protected AbstractOpenPgpStore(OpenPgpKeyStore keyStore,
OpenPgpMetadataStore metadataStore,
OpenPgpTrustStore trustStore) {
this.keyStore = Objects.requireNonNull(keyStore);
this.metadataStore = Objects.requireNonNull(metadataStore);
this.trustStore = Objects.requireNonNull(trustStore);
}
public OpenPgpContact getContact(BareJid jid) {
@Override
public OpenPgpContact getOpenPgpContact(BareJid jid) {
OpenPgpContact contact = contacts.get(jid);
if (contact != null) {
return contact;
@ -64,11 +71,13 @@ public abstract class OpenPgpStore implements OpenPgpKeyStore, OpenPgpMetadataSt
return null;
}
@Override
public void setKeyRingProtector(SecretKeyRingProtector protector) {
this.unlocker = protector;
}
public void setUnknownSecretKeyPassphraseCallback(SecretKeyPassphraseCallback callback) {
@Override
public void setSecretKeyPassphraseCallback(SecretKeyPassphraseCallback callback) {
this.secretKeyPassphraseCallback = callback;
}
@ -76,31 +85,11 @@ public abstract class OpenPgpStore implements OpenPgpKeyStore, OpenPgpMetadataSt
OpenPgpKeyStore
*/
@Override
public PGPPublicKeyRingCollection readPublicKeysOf(BareJid owner) throws IOException, PGPException {
return keyStore.readPublicKeysOf(owner);
}
@Override
public void writePublicKeysOf(BareJid owner, PGPPublicKeyRingCollection publicKeys) throws IOException {
keyStore.writePublicKeysOf(owner, publicKeys);
}
@Override
public PGPPublicKeyRingCollection getPublicKeysOf(BareJid owner) throws IOException, PGPException {
return keyStore.getPublicKeysOf(owner);
}
@Override
public PGPSecretKeyRingCollection readSecretKeysOf(BareJid owner) throws IOException, PGPException {
return keyStore.readSecretKeysOf(owner);
}
@Override
public void writeSecretKeysOf(BareJid owner, PGPSecretKeyRingCollection secretKeys) throws IOException {
keyStore.writeSecretKeysOf(owner, secretKeys);
}
@Override
public PGPSecretKeyRingCollection getSecretKeysOf(BareJid owner) throws IOException, PGPException {
return keyStore.getSecretKeysOf(owner);
@ -126,18 +115,13 @@ public abstract class OpenPgpStore implements OpenPgpKeyStore, OpenPgpMetadataSt
*/
@Override
public Set<OpenPgpV4Fingerprint> getAnnouncedFingerprintsOf(BareJid contact) throws IOException {
public Map<OpenPgpV4Fingerprint, Date> getAnnouncedFingerprintsOf(BareJid contact) throws IOException {
return metadataStore.getAnnouncedFingerprintsOf(contact);
}
@Override
public Set<OpenPgpV4Fingerprint> readAnnouncedFingerprintsOf(BareJid contact) throws IOException {
return metadataStore.readAnnouncedFingerprintsOf(contact);
}
@Override
public void writeAnnouncedFingerprintsOf(BareJid contact, PublicKeysListElement metadata) throws IOException {
metadataStore.writeAnnouncedFingerprintsOf(contact, metadata);
public void setAnnouncedFingerprintsOf(BareJid contact, Map<OpenPgpV4Fingerprint, Date> data) throws IOException {
metadataStore.setAnnouncedFingerprintsOf(contact, data);
}
/*
@ -145,12 +129,12 @@ public abstract class OpenPgpStore implements OpenPgpKeyStore, OpenPgpMetadataSt
*/
@Override
public Trust getTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint) {
public Trust getTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException {
return trustStore.getTrust(owner, fingerprint);
}
@Override
public void setTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint, Trust trust) {
public void setTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint, Trust trust) throws IOException {
trustStore.setTrust(owner, fingerprint, trust);
}
}

View File

@ -1,10 +1,11 @@
package org.jivesoftware.smackx.ox.v2.store;
package org.jivesoftware.smackx.ox.v2.store.abstr;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jivesoftware.smackx.ox.v2.store.definition.OpenPgpTrustStore;
import org.jxmpp.jid.BareJid;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.v2.store;
package org.jivesoftware.smackx.ox.v2.store.definition;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.v2.store;
package org.jivesoftware.smackx.ox.v2.store.definition;
import java.io.IOException;
import java.util.Date;

View File

@ -0,0 +1,19 @@
package org.jivesoftware.smackx.ox.v2.store.definition;
import org.jivesoftware.smackx.ox.OpenPgpContact;
import org.jivesoftware.smackx.ox.callback.SecretKeyPassphraseCallback;
import org.jxmpp.jid.BareJid;
import org.pgpainless.pgpainless.key.protection.SecretKeyRingProtector;
public interface OpenPgpStore extends OpenPgpKeyStore, OpenPgpMetadataStore, OpenPgpTrustStore {
OpenPgpContact getOpenPgpContact(BareJid contactsJid);
void setKeyRingProtector(SecretKeyRingProtector unlocker);
SecretKeyRingProtector getKeyRingProtector();
void setSecretKeyPassphraseCallback(SecretKeyPassphraseCallback callback);
}

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.ox.v2.store;
package org.jivesoftware.smackx.ox.v2.store.definition;
import java.io.IOException;

View File

@ -26,7 +26,7 @@ import java.io.IOException;
import java.io.OutputStream;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smackx.ox.v2.store.AbstractOpenPgpKeyStore;
import org.jivesoftware.smackx.ox.v2.store.abstr.AbstractOpenPgpKeyStore;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;

View File

@ -30,7 +30,7 @@ import java.util.logging.Logger;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jivesoftware.smackx.ox.util.Util;
import org.jivesoftware.smackx.ox.v2.store.AbstractOpenPgpMetadataStore;
import org.jivesoftware.smackx.ox.v2.store.abstr.AbstractOpenPgpMetadataStore;
import org.jxmpp.jid.BareJid;
import org.jxmpp.util.XmppDateTime;

View File

@ -19,11 +19,11 @@ package org.jivesoftware.smackx.ox.v2.store.filebased;
import java.io.File;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smackx.ox.v2.store.OpenPgpStore;
import org.jivesoftware.smackx.ox.v2.store.abstr.AbstractOpenPgpStore;
import org.jxmpp.jid.BareJid;
public class FileBasedOpenPgpStore extends OpenPgpStore {
public class FileBasedOpenPgpStore extends AbstractOpenPgpStore {
public FileBasedOpenPgpStore(File basePath) {
super(new FileBasedOpenPgpKeyStore(basePath),

View File

@ -27,7 +27,7 @@ import java.util.logging.Logger;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jivesoftware.smackx.ox.util.Util;
import org.jivesoftware.smackx.ox.v2.store.AbstractOpenPgpTrustStore;
import org.jivesoftware.smackx.ox.v2.store.abstr.AbstractOpenPgpTrustStore;
import org.jxmpp.jid.BareJid;