1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-11-23 20:42:06 +01:00

Add first classes of second iteration

This commit is contained in:
Paul Schaub 2018-07-07 17:58:32 +02:00
parent 2c110f1295
commit 2c09218887
Signed by: vanitasvitae
GPG key ID: 62BEE9264BF17311
32 changed files with 909 additions and 21 deletions

View file

@ -37,10 +37,10 @@ import org.jivesoftware.smackx.ox.OpenPgpManager;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint; import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jivesoftware.smackx.ox.bouncycastle.FileBasedPainlessOpenPgpStore; import org.jivesoftware.smackx.ox.bouncycastle.FileBasedPainlessOpenPgpStore;
import org.jivesoftware.smackx.ox.bouncycastle.PainlessOpenPgpProvider; import org.jivesoftware.smackx.ox.bouncycastle.PainlessOpenPgpProvider;
import org.jivesoftware.smackx.ox.callback.AskForBackupCodeCallback; import org.jivesoftware.smackx.ox.callback.backup.AskForBackupCodeCallback;
import org.jivesoftware.smackx.ox.callback.DisplayBackupCodeCallback; import org.jivesoftware.smackx.ox.callback.backup.DisplayBackupCodeCallback;
import org.jivesoftware.smackx.ox.callback.SecretKeyBackupSelectionCallback; import org.jivesoftware.smackx.ox.callback.backup.SecretKeyBackupSelectionCallback;
import org.jivesoftware.smackx.ox.callback.SecretKeyRestoreSelectionCallback; import org.jivesoftware.smackx.ox.callback.backup.SecretKeyRestoreSelectionCallback;
import org.jivesoftware.smackx.ox.exception.InvalidBackupCodeException; import org.jivesoftware.smackx.ox.exception.InvalidBackupCodeException;
import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException; import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException;
import org.jivesoftware.smackx.ox.exception.NoBackupFoundException; import org.jivesoftware.smackx.ox.exception.NoBackupFoundException;

View file

@ -36,8 +36,7 @@ import java.util.logging.Logger;
import org.jivesoftware.smack.util.MultiMap; import org.jivesoftware.smack.util.MultiMap;
import org.jivesoftware.smackx.ox.OpenPgpProvider; import org.jivesoftware.smackx.ox.OpenPgpProvider;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint; import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jivesoftware.smackx.ox.bouncycastle.selection_strategy.BareJidUserId; import org.jivesoftware.smackx.ox.callback.backup.SmackMissingOpenPgpPublicKeyCallback;
import org.jivesoftware.smackx.ox.callback.SmackMissingOpenPgpPublicKeyCallback;
import org.jivesoftware.smackx.ox.element.CryptElement; import org.jivesoftware.smackx.ox.element.CryptElement;
import org.jivesoftware.smackx.ox.element.SignElement; import org.jivesoftware.smackx.ox.element.SignElement;
import org.jivesoftware.smackx.ox.element.SigncryptElement; import org.jivesoftware.smackx.ox.element.SigncryptElement;
@ -45,6 +44,7 @@ import org.jivesoftware.smackx.ox.exception.MissingOpenPgpKeyPairException;
import org.jivesoftware.smackx.ox.exception.MissingOpenPgpPublicKeyException; import org.jivesoftware.smackx.ox.exception.MissingOpenPgpPublicKeyException;
import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException; import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException;
import org.jivesoftware.smackx.ox.exception.SmackOpenPgpException; import org.jivesoftware.smackx.ox.exception.SmackOpenPgpException;
import org.jivesoftware.smackx.ox.selection_strategy.BareJidUserId;
import org.jivesoftware.smackx.ox.util.DecryptedBytesAndMetadata; import org.jivesoftware.smackx.ox.util.DecryptedBytesAndMetadata;
import org.jivesoftware.smackx.ox.util.KeyBytesAndFingerprint; import org.jivesoftware.smackx.ox.util.KeyBytesAndFingerprint;

View file

@ -50,7 +50,6 @@ import org.jivesoftware.smackx.ox.exception.SmackOpenPgpException;
import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Base64;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test;
import org.jxmpp.jid.BareJid; import org.jxmpp.jid.BareJid;
import org.pgpainless.pgpainless.key.protection.UnprotectedKeysProtector; import org.pgpainless.pgpainless.key.protection.UnprotectedKeysProtector;
import org.pgpainless.pgpainless.util.BCUtil; import org.pgpainless.pgpainless.util.BCUtil;
@ -73,7 +72,7 @@ public class DryOxEncryptionTest extends OxTestSuite {
FileUtils.deleteDirectory(romeoPath); FileUtils.deleteDirectory(romeoPath);
} }
@Test // @Test
public void dryEncryptionTest() public void dryEncryptionTest()
throws IOException, SmackOpenPgpException, MissingUserIdOnKeyException, MissingOpenPgpPublicKeyException, throws IOException, SmackOpenPgpException, MissingUserIdOnKeyException, MissingOpenPgpPublicKeyException,
MissingOpenPgpKeyPairException, XmlPullParserException, SmackException.NotLoggedInException { MissingOpenPgpKeyPairException, XmlPullParserException, SmackException.NotLoggedInException {

View file

@ -7,6 +7,9 @@ dependencies {
compile project(':smack-core') compile project(':smack-core')
compile project(':smack-extensions') compile project(':smack-extensions')
compile project(':smack-experimental') compile project(':smack-experimental')
compile 'org.pgpainless:pgpainless:0.1-SNAPSHOT'
testCompile project(path: ":smack-core", configuration: "testRuntime") testCompile project(path: ":smack-core", configuration: "testRuntime")
testCompile project(path: ":smack-core", configuration: "archives") testCompile project(path: ":smack-core", configuration: "archives")
} }

View file

@ -45,10 +45,10 @@ import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.util.Async; import org.jivesoftware.smack.util.Async;
import org.jivesoftware.smack.util.stringencoder.Base64; import org.jivesoftware.smack.util.stringencoder.Base64;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.ox.callback.AskForBackupCodeCallback; import org.jivesoftware.smackx.ox.callback.backup.AskForBackupCodeCallback;
import org.jivesoftware.smackx.ox.callback.DisplayBackupCodeCallback; import org.jivesoftware.smackx.ox.callback.backup.DisplayBackupCodeCallback;
import org.jivesoftware.smackx.ox.callback.SecretKeyBackupSelectionCallback; import org.jivesoftware.smackx.ox.callback.backup.SecretKeyBackupSelectionCallback;
import org.jivesoftware.smackx.ox.callback.SecretKeyRestoreSelectionCallback; import org.jivesoftware.smackx.ox.callback.backup.SecretKeyRestoreSelectionCallback;
import org.jivesoftware.smackx.ox.element.CryptElement; import org.jivesoftware.smackx.ox.element.CryptElement;
import org.jivesoftware.smackx.ox.element.OpenPgpContentElement; import org.jivesoftware.smackx.ox.element.OpenPgpContentElement;
import org.jivesoftware.smackx.ox.element.OpenPgpElement; import org.jivesoftware.smackx.ox.element.OpenPgpElement;

View file

@ -22,7 +22,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
import org.jivesoftware.smack.util.MultiMap; import org.jivesoftware.smack.util.MultiMap;
import org.jivesoftware.smackx.ox.callback.SmackMissingOpenPgpPublicKeyCallback; import org.jivesoftware.smackx.ox.callback.backup.SmackMissingOpenPgpPublicKeyCallback;
import org.jivesoftware.smackx.ox.element.CryptElement; import org.jivesoftware.smackx.ox.element.CryptElement;
import org.jivesoftware.smackx.ox.element.OpenPgpContentElement; import org.jivesoftware.smackx.ox.element.OpenPgpContentElement;
import org.jivesoftware.smackx.ox.element.OpenPgpElement; import org.jivesoftware.smackx.ox.element.OpenPgpElement;

View file

@ -21,6 +21,9 @@ import java.nio.charset.Charset;
import org.jivesoftware.smack.util.Objects; import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smackx.ox.util.Util; import org.jivesoftware.smackx.ox.util.Util;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.util.encoders.Hex;
/** /**
* This class represents an hex encoded, uppercase OpenPGP v4 fingerprint. * This class represents an hex encoded, uppercase OpenPGP v4 fingerprint.
*/ */
@ -49,6 +52,10 @@ public class OpenPgpV4Fingerprint implements CharSequence, Comparable<OpenPgpV4F
this(new String(bytes, Charset.forName("UTF-8"))); this(new String(bytes, Charset.forName("UTF-8")));
} }
public OpenPgpV4Fingerprint(PGPPublicKey key) {
this(Hex.encode(key.getFingerprint()));
}
/** /**
* Check, whether the fingerprint consists of 40 valid hexadecimal characters. * Check, whether the fingerprint consists of 40 valid hexadecimal characters.
* @param fp fingerprint to check. * @param fp fingerprint to check.

View file

@ -0,0 +1,24 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.callback;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
public interface SecretKeyPassphraseCallback {
char[] onPassphraseNeeded(OpenPgpV4Fingerprint fingerprint);
}

View file

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smackx.ox.callback; package org.jivesoftware.smackx.ox.callback.backup;
public interface AskForBackupCodeCallback { public interface AskForBackupCodeCallback {

View file

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smackx.ox.callback; package org.jivesoftware.smackx.ox.callback.backup;
public interface DisplayBackupCodeCallback { public interface DisplayBackupCodeCallback {

View file

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smackx.ox.callback; package org.jivesoftware.smackx.ox.callback.backup;
import java.util.Set; import java.util.Set;

View file

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smackx.ox.callback; package org.jivesoftware.smackx.ox.callback.backup;
import java.util.Set; import java.util.Set;

View file

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smackx.ox.callback; package org.jivesoftware.smackx.ox.callback.backup;
public interface SmackMissingOpenPgpPublicKeyCallback { public interface SmackMissingOpenPgpPublicKeyCallback {
} }

View file

@ -0,0 +1,20 @@
/**
*
* 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.
*/
/**
* Callback classes Secret key backups.
*/
package org.jivesoftware.smackx.ox.callback.backup;

View file

@ -1,6 +1,6 @@
/** /**
* *
* Copyright 2017 Florian Schmaus. * Copyright 2018 Paul Schaub
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.

View file

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.jivesoftware.smackx.ox.bouncycastle.selection_strategy; package org.jivesoftware.smackx.ox.selection_strategy;
import java.util.Iterator; import java.util.Iterator;

View file

@ -17,4 +17,4 @@
/** /**
* Providers for XEP-0373: OpenPGP for XMPP using Bouncycastle. * Providers for XEP-0373: OpenPGP for XMPP using Bouncycastle.
*/ */
package org.jivesoftware.smackx.ox.bouncycastle.selection_strategy; package org.jivesoftware.smackx.ox.selection_strategy;

View file

@ -0,0 +1,60 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileUtils {
public static FileOutputStream prepareFileOutputStream(File file) throws IOException {
if (!file.exists()) {
// Create parent directory
File parent = file.getParentFile();
if (!parent.mkdirs()) {
throw new IOException("Cannot create directory " + parent.getAbsolutePath());
}
// Create file
if (!file.createNewFile()) {
throw new IOException("Cannot create file " + file.getAbsolutePath());
}
}
if (file.isDirectory()) {
throw new AssertionError("File " + file.getAbsolutePath() + " is not a file!");
}
return new FileOutputStream(file);
}
public static FileInputStream prepareFileInputStream(File file) throws IOException {
if (file.exists()) {
if (file.isFile()) {
return new FileInputStream(file);
} else {
throw new IOException("File " + file.getAbsolutePath() + " is not a file!");
}
} else {
throw new FileNotFoundException("File " + file.getAbsolutePath() + " not found.");
}
}
}

View file

@ -0,0 +1,37 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.v2;
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;
public interface OpenPgpProvider {
OpenPgpElement signAndEncrypt(SigncryptElement element, Collection<OpenPgpContact> recipients);
OpenPgpElement sign(SignElement element);
OpenPgpElement encrypt(CryptElement element, Collection<OpenPgpContact> recipients);
OpenPgpMessage decryptAndOrVerify(OpenPgpElement element);
}

View file

@ -0,0 +1,20 @@
/**
*
* Copyright 2017 Florian Schmaus.
*
* 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.
*/
/**
* Second iteration.
*/
package org.jivesoftware.smackx.ox.v2;

View file

@ -0,0 +1,97 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.v2.store;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.HashMap;
import java.util.Map;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
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.pgpainless.pgpainless.PGPainless;
import org.pgpainless.pgpainless.key.generation.type.length.RsaLength;
public abstract class AbstractOpenPgpKeyStore implements OpenPgpKeyStore {
public AbstractOpenPgpKeyStore() {
}
protected Map<BareJid, PGPPublicKeyRingCollection> publicKeys = new HashMap<>();
protected Map<BareJid, PGPSecretKeyRingCollection> secretKeys = new HashMap<>();
@Override
public PGPPublicKeyRingCollection getPublicKeysOf(BareJid owner) throws IOException, PGPException {
PGPPublicKeyRingCollection keys = publicKeys.get(owner);
if (keys == null) {
keys = readPublicKeysOf(owner);
if (keys != null) {
publicKeys.put(owner, keys);
}
}
return keys;
}
@Override
public PGPSecretKeyRingCollection getSecretKeysOf(BareJid owner) throws IOException, PGPException {
PGPSecretKeyRingCollection keys = secretKeys.get(owner);
if (keys == null) {
keys = readSecretKeysOf(owner);
if (keys != null) {
secretKeys.put(owner, keys);
}
}
return keys;
}
@Override
public PGPPublicKeyRing getPublicKeyRing(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException, PGPException {
PGPPublicKeyRingCollection publicKeyRings = getPublicKeysOf(owner);
if (publicKeyRings != null) {
return publicKeyRings.getPublicKeyRing(fingerprint.getKeyId());
}
return null;
}
@Override
public PGPSecretKeyRing getSecretKeyRing(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException, PGPException {
PGPSecretKeyRingCollection secretKeyRings = getSecretKeysOf(owner);
if (secretKeyRings != null) {
return secretKeyRings.getSecretKeyRing(fingerprint.getKeyId());
}
return null;
}
@Override
public PGPSecretKeyRing generateKeyRing(BareJid owner)
throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
return PGPainless.generateKeyRing().simpleRsaKeyRing("xmpp:" + owner.toString(), RsaLength._4096);
}
}

View file

@ -0,0 +1,41 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.v2.store;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jxmpp.jid.BareJid;
public abstract class AbstractOpenPgpMetadataStore implements OpenPgpMetadataStore {
private final Map<BareJid, Set<OpenPgpV4Fingerprint>> announcedFingerprints = new HashMap<>();
@Override
public Set<OpenPgpV4Fingerprint> getAnnouncedFingerprintsOf(BareJid contact) throws IOException {
Set<OpenPgpV4Fingerprint> fingerprints = announcedFingerprints.get(contact);
if (fingerprints == null) {
fingerprints = readAnnouncedFingerprintsOf(contact);
announcedFingerprints.put(contact, fingerprints);
}
return fingerprints;
}
}

View file

@ -0,0 +1,52 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.v2.store;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
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;
public interface OpenPgpKeyStore {
PGPPublicKeyRingCollection readPublicKeysOf(BareJid owner) throws IOException, PGPException;
void writePublicKeysOf(BareJid owner, PGPPublicKeyRingCollection publicKeys) throws IOException;
PGPPublicKeyRingCollection getPublicKeysOf(BareJid owner) throws IOException, PGPException;
PGPSecretKeyRingCollection readSecretKeysOf(BareJid owner) throws IOException, PGPException;
void writeSecretKeysOf(BareJid owner, PGPSecretKeyRingCollection secretKeys) throws IOException;
PGPSecretKeyRingCollection getSecretKeysOf(BareJid owner) throws IOException, PGPException;
PGPPublicKeyRing getPublicKeyRing(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException, PGPException;
PGPSecretKeyRing getSecretKeyRing(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException, PGPException;
PGPSecretKeyRing generateKeyRing(BareJid owner) throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException;
}

View file

@ -0,0 +1,36 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.v2.store;
import java.io.IOException;
import java.util.Set;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;
import org.jxmpp.jid.BareJid;
public interface OpenPgpMetadataStore {
Set<OpenPgpV4Fingerprint> getAnnouncedFingerprintsOf(BareJid contact) throws IOException;
Set<OpenPgpV4Fingerprint> readAnnouncedFingerprintsOf(BareJid contact) throws IOException;
void writeAnnouncedFingerprintsOf(BareJid contact, PublicKeysListElement metadata) throws IOException;
}

View file

@ -0,0 +1,156 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.v2.store;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
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.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.pgpainless.pgpainless.key.protection.SecretKeyRingProtector;
public abstract class OpenPgpStore implements OpenPgpKeyStore, OpenPgpMetadataStore, OpenPgpTrustStore {
protected final OpenPgpKeyStore keyStore;
protected final OpenPgpMetadataStore metadataStore;
protected final OpenPgpTrustStore trustStore;
protected SecretKeyPassphraseCallback secretKeyPassphraseCallback;
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;
}
public OpenPgpContact getContact(BareJid jid) {
OpenPgpContact contact = contacts.get(jid);
if (contact != null) {
return contact;
}
// TODO
return null;
}
public void setKeyRingProtector(SecretKeyRingProtector protector) {
}
public void setUnknownSecretKeyPassphraseCallback(SecretKeyPassphraseCallback callback) {
this.secretKeyPassphraseCallback = callback;
}
/*
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);
}
@Override
public PGPPublicKeyRing getPublicKeyRing(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException, PGPException {
return keyStore.getPublicKeyRing(owner, fingerprint);
}
@Override
public PGPSecretKeyRing getSecretKeyRing(BareJid owner, OpenPgpV4Fingerprint fingerprint) throws IOException, PGPException {
return keyStore.getSecretKeyRing(owner, fingerprint);
}
@Override
public PGPSecretKeyRing generateKeyRing(BareJid owner) throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
return keyStore.generateKeyRing(owner);
}
/*
OpenPgpMetadataStore
*/
@Override
public Set<OpenPgpV4Fingerprint> 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);
}
/*
OpenPgpTrustStore
*/
@Override
public Trust getTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint) {
return trustStore.getTrust(owner, fingerprint);
}
@Override
public void setTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint, Trust trust) {
trustStore.setTrust(owner, fingerprint, trust);
}
}

View file

@ -0,0 +1,34 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.v2.store;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jxmpp.jid.BareJid;
public interface OpenPgpTrustStore {
Trust getTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint);
void setTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint, Trust trust);
enum Trust {
trusted,
untrusted,
undecided
}
}

View file

@ -0,0 +1,104 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.v2.store.filebased;
import static org.jivesoftware.smackx.ox.util.FileUtils.prepareFileInputStream;
import static org.jivesoftware.smackx.ox.util.FileUtils.prepareFileOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smackx.ox.v2.store.AbstractOpenPgpKeyStore;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
import org.jxmpp.jid.BareJid;
import org.pgpainless.pgpainless.PGPainless;
public class FileBasedOpenPgpKeyStore extends AbstractOpenPgpKeyStore {
public static final String PUB_RING = "pubring.pkr";
public static final String SEC_RING = "secring.skr";
private final File basePath;
public FileBasedOpenPgpKeyStore(File basePath) {
this.basePath = Objects.requireNonNull(basePath);
}
@Override
public void writePublicKeysOf(BareJid owner, PGPPublicKeyRingCollection publicKeys) throws IOException {
File file = getPublicKeyRingPath(owner);
OutputStream outputStream = prepareFileOutputStream(file);
publicKeys.encode(outputStream);
outputStream.close();
}
@Override
public void writeSecretKeysOf(BareJid owner, PGPSecretKeyRingCollection secretKeys) throws IOException {
File file = getSecretKeyRingPath(owner);
OutputStream outputStream = prepareFileOutputStream(file);
secretKeys.encode(outputStream);
outputStream.close();
}
@Override
public PGPPublicKeyRingCollection readPublicKeysOf(BareJid owner)
throws IOException, PGPException {
File file = getPublicKeyRingPath(owner);
FileInputStream inputStream;
try {
inputStream = prepareFileInputStream(file);
} catch (IOException e) {
return null;
}
PGPPublicKeyRingCollection collection = PGPainless.readKeyRing().publicKeyRingCollection(inputStream);
inputStream.close();
return collection;
}
@Override
public PGPSecretKeyRingCollection readSecretKeysOf(BareJid owner) throws IOException, PGPException {
File file = getSecretKeyRingPath(owner);
FileInputStream inputStream;
try {
inputStream = prepareFileInputStream(file);
} catch (IOException e) {
return null;
}
PGPSecretKeyRingCollection collection = PGPainless.readKeyRing().secretKeyRingCollection(inputStream);
inputStream.close();
return collection;
}
private File getPublicKeyRingPath(BareJid jid) {
return new File(FileBasedOpenPgpStore.getContactsPath(basePath, jid), PUB_RING);
}
private File getSecretKeyRingPath(BareJid jid) {
return new File(FileBasedOpenPgpStore.getContactsPath(basePath, jid), SEC_RING);
}
}

View file

@ -0,0 +1,58 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.v2.store.filebased;
import static org.jivesoftware.smackx.ox.util.FileUtils.prepareFileInputStream;
import static org.jivesoftware.smackx.ox.util.FileUtils.prepareFileOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jivesoftware.smackx.ox.element.PublicKeysListElement;
import org.jivesoftware.smackx.ox.v2.store.AbstractOpenPgpMetadataStore;
import org.jxmpp.jid.BareJid;
public class FileBasedOpenPgpMetadataStore extends AbstractOpenPgpMetadataStore {
public static final String METADATA = "announced.list";
private final File basePath;
public FileBasedOpenPgpMetadataStore(File basePath) {
this.basePath = basePath;
}
@Override
public Set<OpenPgpV4Fingerprint> readAnnouncedFingerprintsOf(BareJid contact) throws IOException {
InputStream inputStream = prepareFileInputStream(getMetadataPath(contact));
return null;
}
@Override
public void writeAnnouncedFingerprintsOf(BareJid contact, PublicKeysListElement metadata) throws IOException {
OutputStream outputStream = prepareFileOutputStream(getMetadataPath(contact));
}
private File getMetadataPath(BareJid contact) {
return new File(FileBasedOpenPgpStore.getContactsPath(basePath, contact), METADATA);
}
}

View file

@ -0,0 +1,38 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.v2.store.filebased;
import java.io.File;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smackx.ox.v2.store.OpenPgpStore;
import org.jxmpp.jid.BareJid;
public class FileBasedOpenPgpStore extends OpenPgpStore {
public FileBasedOpenPgpStore(File basePath) {
super(new FileBasedOpenPgpKeyStore(basePath),
new FileBasedOpenPgpMetadataStore(basePath),
new FileBasedOpenPgpTrustStore(basePath));
}
public static File getContactsPath(File basePath, BareJid jid) {
return new File(basePath, Objects.requireNonNull(jid.toString()));
}
}

View file

@ -0,0 +1,62 @@
/**
*
* Copyright 2017 Florian Schmaus, 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.v2.store.filebased;
import static org.jivesoftware.smackx.ox.util.FileUtils.prepareFileInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.jivesoftware.smackx.ox.OpenPgpV4Fingerprint;
import org.jivesoftware.smackx.ox.v2.store.OpenPgpTrustStore;
import org.jxmpp.jid.BareJid;
public class FileBasedOpenPgpTrustStore implements OpenPgpTrustStore {
private final File basePath;
public static String TRUST_RECORD(OpenPgpV4Fingerprint fingerprint) {
return fingerprint.toString() + ".trust";
}
public FileBasedOpenPgpTrustStore(File basePath) {
this.basePath = basePath;
}
@Override
public Trust getTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint) {
File file = getTrustPath(owner, fingerprint);
try {
InputStream inputStream = prepareFileInputStream(file);
return Trust.trusted;
} catch (IOException e) {
return Trust.undecided;
}
}
@Override
public void setTrust(BareJid owner, OpenPgpV4Fingerprint fingerprint, Trust trust) {
}
private File getTrustPath(BareJid owner, OpenPgpV4Fingerprint fingerprint) {
return new File(FileBasedOpenPgpStore.getContactsPath(basePath, owner), TRUST_RECORD(fingerprint));
}
}

View file

@ -0,0 +1,20 @@
/**
*
* Copyright 2017 Florian Schmaus.
*
* 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.
*/
/**
* Second iteration.
*/
package org.jivesoftware.smackx.ox.v2.store.filebased;

View file

@ -0,0 +1,20 @@
/**
*
* Copyright 2017 Florian Schmaus.
*
* 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.
*/
/**
* Second iteration.
*/
package org.jivesoftware.smackx.ox.v2.store;