mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-11-29 15:52:08 +01:00
Rework tests
This commit is contained in:
parent
061e1c9292
commit
8647fde896
7 changed files with 354 additions and 98 deletions
|
@ -6,6 +6,8 @@ import java.util.Set;
|
||||||
|
|
||||||
import de.vanitasvitae.crypto.pgpainless.algorithm.CompressionAlgorithm;
|
import de.vanitasvitae.crypto.pgpainless.algorithm.CompressionAlgorithm;
|
||||||
import de.vanitasvitae.crypto.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
import de.vanitasvitae.crypto.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
|
||||||
public class PainlessResult {
|
public class PainlessResult {
|
||||||
|
|
||||||
|
@ -38,6 +40,10 @@ public class PainlessResult {
|
||||||
return recipientKeyIds;
|
return recipientKeyIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEncrypted() {
|
||||||
|
return !getRecipientKeyIds().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
public Long getDecryptionKeyId() {
|
public Long getDecryptionKeyId() {
|
||||||
return decryptionKeyId;
|
return decryptionKeyId;
|
||||||
}
|
}
|
||||||
|
@ -54,14 +60,32 @@ public class PainlessResult {
|
||||||
return integrityProtected;
|
return integrityProtected;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<Long> getSignatureKeyIds() {
|
public Set<Long> getAllSignatureKeyIds() {
|
||||||
return signatureKeyIds;
|
return signatureKeyIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSigned() {
|
||||||
|
return !signatureKeyIds.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
public Set<Long> getVerifiedSignatureKeyIds() {
|
public Set<Long> getVerifiedSignatureKeyIds() {
|
||||||
return verifiedSignatureKeyIds;
|
return verifiedSignatureKeyIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isVerified() {
|
||||||
|
return !verifiedSignatureKeyIds.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsVerifiedSignatureFrom(PGPPublicKeyRing publicKeys) {
|
||||||
|
for (PGPPublicKey key : publicKeys) {
|
||||||
|
long id = key.getKeyID();
|
||||||
|
if (verifiedSignatureKeyIds.contains(id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static Builder getBuilder() {
|
public static Builder getBuilder() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import java.io.InputStream;
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import de.vanitasvitae.crypto.pgpainless.PainlessResult;
|
import de.vanitasvitae.crypto.pgpainless.PainlessResult;
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
@ -16,6 +18,8 @@ import org.bouncycastle.openpgp.PGPSignatureList;
|
||||||
|
|
||||||
public class SignatureVerifyingInputStream extends FilterInputStream {
|
public class SignatureVerifyingInputStream extends FilterInputStream {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(SignatureVerifyingInputStream.class.getName());
|
||||||
|
|
||||||
private final PGPObjectFactory objectFactory;
|
private final PGPObjectFactory objectFactory;
|
||||||
private final Map<Long, PGPOnePassSignature> onePassSignatures;
|
private final Map<Long, PGPOnePassSignature> onePassSignatures;
|
||||||
private final PainlessResult.Builder resultBuilder;
|
private final PainlessResult.Builder resultBuilder;
|
||||||
|
@ -44,6 +48,7 @@ public class SignatureVerifyingInputStream extends FilterInputStream {
|
||||||
|
|
||||||
private void validateOnePassSignatures() throws IOException {
|
private void validateOnePassSignatures() throws IOException {
|
||||||
if (onePassSignatures.isEmpty()) {
|
if (onePassSignatures.isEmpty()) {
|
||||||
|
LOGGER.log(Level.FINE, "No One-Pass-Signatures found -> No validation.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package de.vanitasvitae.crypto.pgpainless.util;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKey;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||||
|
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
|
||||||
|
|
||||||
|
public class BCUtil {
|
||||||
|
|
||||||
|
public static PGPPublicKeyRingCollection keyRingsToKeyRingCollection(PGPPublicKeyRing... rings)
|
||||||
|
throws IOException, PGPException {
|
||||||
|
return new PGPPublicKeyRingCollection(Arrays.asList(rings));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPSecretKeyRingCollection keyRingsToKeyRingCollection(PGPSecretKeyRing... rings)
|
||||||
|
throws IOException, PGPException {
|
||||||
|
return new PGPSecretKeyRingCollection(Arrays.asList(rings));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPPublicKeyRing publicKeyRingFromSecretKeyRing(PGPSecretKeyRing ring) throws IOException {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
for (Iterator<PGPPublicKey> i = ring.getPublicKeys(); i.hasNext(); ) {
|
||||||
|
PGPPublicKey k = i.next();
|
||||||
|
k.encode(buffer);
|
||||||
|
}
|
||||||
|
buffer.close();
|
||||||
|
ByteArrayInputStream in = new ByteArrayInputStream(buffer.toByteArray());
|
||||||
|
return new PGPPublicKeyRing(in, new BcKeyFingerprintCalculator());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package de.vanitasvitae.crypto.pgpainless;
|
||||||
|
|
||||||
|
import java.security.Security;
|
||||||
|
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
|
public abstract class AbstractPGPainlessTest {
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void registerProvider() {
|
||||||
|
Security.addProvider(new BouncyCastleProvider());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package de.vanitasvitae.crypto.pgpainless;
|
package de.vanitasvitae.crypto.pgpainless;
|
||||||
|
|
||||||
import static junit.framework.TestCase.assertEquals;
|
|
||||||
import static junit.framework.TestCase.assertTrue;
|
import static junit.framework.TestCase.assertTrue;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
@ -9,133 +8,120 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.Security;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.NoSuchProviderException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import de.vanitasvitae.crypto.pgpainless.key.SecretKeyRingProtector;
|
||||||
import de.vanitasvitae.crypto.pgpainless.key.UnprotectedKeysProtector;
|
import de.vanitasvitae.crypto.pgpainless.key.UnprotectedKeysProtector;
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import de.vanitasvitae.crypto.pgpainless.key.generation.type.length.RsaLength;
|
||||||
|
import de.vanitasvitae.crypto.pgpainless.util.BCUtil;
|
||||||
import org.bouncycastle.openpgp.PGPException;
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
|
||||||
import org.bouncycastle.openpgp.PGPUtil;
|
|
||||||
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
|
|
||||||
import org.bouncycastle.util.io.Streams;
|
import org.bouncycastle.util.io.Streams;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class EncryptDecryptTest {
|
public class EncryptDecryptTest extends AbstractPGPainlessTest {
|
||||||
PGPSecretKeyRing juliet = new PGPSecretKeyRing(PGPUtil.getDecoderStream(new ByteArrayInputStream(TestKeys.JULIET_PRIV.getBytes())), new BcKeyFingerprintCalculator());
|
|
||||||
PGPSecretKeyRing romeo = new PGPSecretKeyRing(PGPUtil.getDecoderStream(new ByteArrayInputStream(TestKeys.ROMEO_PRIV.getBytes())), new BcKeyFingerprintCalculator());
|
|
||||||
|
|
||||||
public EncryptDecryptTest() throws IOException, PGPException {
|
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void freshRsaTest()
|
||||||
|
throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException,
|
||||||
|
IOException {
|
||||||
|
PGPSecretKeyRing aliceSec = PGPainless.generateKeyRing().simpleRsaKeyRing("alice@wonderland.lit", RsaLength._4096);
|
||||||
|
PGPSecretKeyRing hatterSec = PGPainless.generateKeyRing().simpleRsaKeyRing("hatter@wonderland.lit", RsaLength._4096);
|
||||||
|
|
||||||
|
encryptDecryptForSecretKeyRings(aliceSec, hatterSec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void keyIdTest() {
|
public void freshEcTest() throws IOException, PGPException, NoSuchAlgorithmException, NoSuchProviderException,
|
||||||
assertEquals("b4b509cb5936e03e", Long.toHexString(juliet.getSecretKey().getKeyID()));
|
InvalidAlgorithmParameterException {
|
||||||
|
PGPSecretKeyRing aliceSec = PGPainless.generateKeyRing().simpleEcKeyRing("alice@wonderland.lit");
|
||||||
|
PGPSecretKeyRing hatterSec = PGPainless.generateKeyRing().simpleEcKeyRing("hatter@wonderland.lit");
|
||||||
|
|
||||||
|
encryptDecryptForSecretKeyRings(aliceSec, hatterSec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() throws Exception {
|
public void freshRsaEcTest()
|
||||||
Security.addProvider(new BouncyCastleProvider());
|
throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException,
|
||||||
PGPPublicKeyRing jPub = new PGPPublicKeyRing(PGPUtil.getDecoderStream(new ByteArrayInputStream(TestKeys.JULIET_PUB.getBytes())), new BcKeyFingerprintCalculator());
|
IOException {
|
||||||
|
PGPSecretKeyRing aliceSec = PGPainless.generateKeyRing().simpleRsaKeyRing("alice@wonderland.lit", RsaLength._4096);
|
||||||
|
PGPSecretKeyRing hatterSec = PGPainless.generateKeyRing().simpleEcKeyRing("hatter@wonderland.lit");
|
||||||
|
|
||||||
ByteArrayOutputStream toEncrypted = new ByteArrayOutputStream();
|
encryptDecryptForSecretKeyRings(aliceSec, hatterSec);
|
||||||
|
}
|
||||||
|
|
||||||
OutputStream encryptor = PGPainless.createEncryptor().onOutputStream(toEncrypted)
|
@Test
|
||||||
.toRecipient(jPub.getPublicKey())
|
public void freshEcRsaTest()
|
||||||
|
throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException,
|
||||||
|
IOException {
|
||||||
|
PGPSecretKeyRing aliceSec = PGPainless.generateKeyRing().simpleEcKeyRing("alice@wonderland.lit");
|
||||||
|
PGPSecretKeyRing hatterSec = PGPainless.generateKeyRing().simpleRsaKeyRing("hatter@wonderland.lit", RsaLength._4096);
|
||||||
|
|
||||||
|
|
||||||
|
encryptDecryptForSecretKeyRings(aliceSec, hatterSec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
|
private void encryptDecryptForSecretKeyRings(PGPSecretKeyRing aliceSec, PGPSecretKeyRing hatterSec)
|
||||||
|
throws PGPException,
|
||||||
|
IOException {
|
||||||
|
PGPPublicKeyRing alicePub = BCUtil.publicKeyRingFromSecretKeyRing(aliceSec);
|
||||||
|
PGPPublicKeyRing hatterPub = BCUtil.publicKeyRingFromSecretKeyRing(hatterSec);
|
||||||
|
|
||||||
|
SecretKeyRingProtector keyDecryptor = new UnprotectedKeysProtector();
|
||||||
|
|
||||||
|
byte[] secretMessage = ("Ah, Juliet, if the measure of thy joy\n" +
|
||||||
|
"Be heaped like mine, and that thy skill be more\n" +
|
||||||
|
"To blazon it, then sweeten with thy breath\n" +
|
||||||
|
"This neighbor air, and let rich music’s tongue\n" +
|
||||||
|
"Unfold the imagined happiness that both\n" +
|
||||||
|
"Receive in either by this dear encounter.").getBytes(UTF8);
|
||||||
|
|
||||||
|
Logger.getLogger(EncryptDecryptTest.class.getName())
|
||||||
|
.log(Level.INFO, " " + secretMessage.length);
|
||||||
|
|
||||||
|
ByteArrayOutputStream envelope = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
OutputStream encryptor = PGPainless.createEncryptor()
|
||||||
|
.onOutputStream(envelope)
|
||||||
|
.toRecipients(Collections.singleton(alicePub))
|
||||||
.usingSecureAlgorithms()
|
.usingSecureAlgorithms()
|
||||||
.signWith(new PGPSecretKeyRing(PGPUtil.getDecoderStream(new ByteArrayInputStream(TestKeys.JULIET_PRIV.getBytes())), new BcKeyFingerprintCalculator()), new UnprotectedKeysProtector())
|
.signWith(hatterSec, keyDecryptor)
|
||||||
.asciiArmor();
|
.noArmor();
|
||||||
|
|
||||||
String message = "This message is encrypted using OpenPGP";
|
Streams.pipeAll(new ByteArrayInputStream(secretMessage), encryptor);
|
||||||
ByteArrayInputStream fromPlain = new ByteArrayInputStream(message.getBytes());
|
|
||||||
|
|
||||||
Streams.pipeAll(fromPlain, encryptor);
|
|
||||||
fromPlain.close();
|
|
||||||
encryptor.close();
|
encryptor.close();
|
||||||
|
byte[] encryptedSecretMessage = envelope.toByteArray();
|
||||||
|
|
||||||
System.out.println(new String(toEncrypted.toByteArray()));
|
// Juliet trieth to comprehend Romeos words
|
||||||
|
|
||||||
|
|
||||||
ByteArrayInputStream fromEncrypted = new ByteArrayInputStream(toEncrypted.toByteArray());
|
|
||||||
ByteArrayOutputStream toPlain = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
|
ByteArrayInputStream envelopeIn = new ByteArrayInputStream(encryptedSecretMessage);
|
||||||
PainlessResult.ResultAndInputStream resultAndInputStream = PGPainless.createDecryptor()
|
PainlessResult.ResultAndInputStream resultAndInputStream = PGPainless.createDecryptor()
|
||||||
.onInputStream(fromEncrypted)
|
.onInputStream(envelopeIn)
|
||||||
.decryptWith(new PGPSecretKeyRingCollection(Collections.singleton(juliet)),
|
.decryptWith(BCUtil.keyRingsToKeyRingCollection(aliceSec), keyDecryptor)
|
||||||
new UnprotectedKeysProtector())
|
.verifyWith(Collections.singleton(TestKeys.ROMEO_KEY_ID), BCUtil.keyRingsToKeyRingCollection(hatterPub))
|
||||||
.verifyWith(Collections.singleton(jPub.getPublicKey().getKeyID()), Collections.singleton(jPub))
|
|
||||||
.ignoreMissingPublicKeys()
|
.ignoreMissingPublicKeys()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
InputStream decryptor = resultAndInputStream.getInputStream();
|
InputStream decryptor = resultAndInputStream.getInputStream();
|
||||||
|
OutputStream decryptedSecretMessage = new ByteArrayOutputStream();
|
||||||
|
|
||||||
Streams.pipeAll(decryptor, toPlain);
|
Streams.pipeAll(decryptor, decryptedSecretMessage);
|
||||||
|
|
||||||
fromEncrypted.close();
|
|
||||||
decryptor.close();
|
decryptor.close();
|
||||||
|
|
||||||
assertTrue(Arrays.equals(message.getBytes(), toPlain.toByteArray()));
|
assertTrue(Arrays.equals(secretMessage, ((ByteArrayOutputStream) decryptedSecretMessage).toByteArray()));
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
PainlessResult result = resultAndInputStream.getResult();
|
||||||
public void decryptVerifyTest() throws Exception {
|
assertTrue(result.containsVerifiedSignatureFrom(hatterPub));
|
||||||
String encryptedMessage = "-----BEGIN PGP MESSAGE-----\n" +
|
|
||||||
"\n" +
|
|
||||||
"hQGMAwAAAAAAAAAAAQwAoJtfpcBPCwhUzzHuVIcBzBLyfIWT/EJ527neb46lN56S\n" +
|
|
||||||
"B05BTIRudIeCsPYz81jwiFi/k0MBecRfozZ1xCPByo8ohSvRgzEHEkCNgObQ1bz0\n" +
|
|
||||||
"iB+Xb76OEzFOCPUebTaVscLNf8ak/GSzaW7jDc+5vnvDf7cV0x26pe4odpS/U5Tr\n" +
|
|
||||||
"cO3wb/47K+sJ1cxJmPtcD41O02xu3QisQKPrimM0Kue6ziGeKyw1RkSowv9U47TK\n" +
|
|
||||||
"wppPCHOTli2Nf+gZizF1oyQZzPGst4fjujygcIoajplfW9nZvxsbmYRSLSdmV9m6\n" +
|
|
||||||
"k1jQbPDUhVs0gstH92C6hPpoBWxoxkHcwz8gy36nCyB6cYGyq3oN1UnGU4afPyD5\n" +
|
|
||||||
"SmmEjELBd2i2Ll/DYk2x06SnKZMQuWrSCZzWgl/9HsPo5ydVb97OjuEpWtW9xDMA\n" +
|
|
||||||
"KlYPNWEq+b+akOEstNraC3pfVKvypz6ZzaMAS1gWWNYg8dlwBJOUVMSo7iLaUQkK\n" +
|
|
||||||
"yp4uH1DlsyVu1atCUc8thQIMAwAAAAAAAAAAAQ/5AdiZ/sG859Y/rGR7U/8MzGg0\n" +
|
|
||||||
"j3f2vrgDF/0NRRk5aqd1lb4CaZvrztcYqW3cEK7iF9rKwImZZiWIptjJ9Mz6f1Zl\n" +
|
|
||||||
"FbODObSVRZAcZqYGswEEfsQvpQFlwG6Qx48OaQaDPr147raFI3C3kEU9Nb2VBg8+\n" +
|
|
||||||
"MevJaXJft5PXwUTG2Qvfxqr/3hfGAwB4/zHwA8vFd1np3spryfrC9Dq8UXUoRXIS\n" +
|
|
||||||
"xaFPiLEYt8rLef8f11OypEpmknIibu9jjJtuVZo+SjP6jgLHDwM7rqCZFITM2Qra\n" +
|
|
||||||
"2iBCt8YVcIiTK137t+EfsdVN/KHiRbc++e9zUbGMEextbtNbdoFOU4dnKBm6Su8l\n" +
|
|
||||||
"Z5UerNbR8D7+xJKfAEabdi0qI7QFmhTZ/4H/22yrvoD9jMFSBXUTE9ENIX9Hfqom\n" +
|
|
||||||
"UdsHfuE+5PC0JjkZkhchDO1M7XBX++lBCFsq2abfdpmaX+roVX0iTGboxr5Ag1Cf\n" +
|
|
||||||
"T2zWyRX/XKnvmdeGICV5qjy/ThuSWvAclazyFxWLamMztJq5BRpfAzKNQRDqlmKw\n" +
|
|
||||||
"eePtKW2EWUIjFQ5/UAM6Edu/K34ksFxb0w6YGLzQSskGr7gGAipLmpek6vcUSUA1\n" +
|
|
||||||
"oc9XJGdpx93GDRcqDjKDt/ej06VxG33/pW65ntf5QM/+LScGqaLhAHyEOsBzVIXY\n" +
|
|
||||||
"BONcadSgzkTrlbSMGAmFAQwDtLUJy1k24D4BB/0brqR0UN1LtO+Lc/vN6X/Um2CZ\n" +
|
|
||||||
"CM6MRhPnXP63Q9HHkGJ2S8zGWvQLwWL9Y14CFCgm6rACLBSIyPbihhC2OC8afhSy\n" +
|
|
||||||
"apGkdHtdghS2egs2U8qlJ2Y32IAG9CcUtNkRjxp+/RWSrmZeuL4l7DXCyH5lUadx\n" +
|
|
||||||
"5bPZhAHqW9408q2rQd9dBg2o7ciGXTJSKVahjuiB/O0gchOnbqnlYJbKbCkntXUo\n" +
|
|
||||||
"c7h4w1e8MutisSJorh7kbxgxUJSboZzEkiUfnoacPTz6bL+re9tmnpvlee70sIyM\n" +
|
|
||||||
"BiYRCyPw7Ice4R3XyWtsMTjT/wjZ//whMpWdy2drcJSyhh+GQMbekTVsNWod0lQB\n" +
|
|
||||||
"JTPUfti2VU7PMB3LjJA+l/T9iWPPx8lirnLhXOOerWKH9I5Wo4Kqv/47aJhfMO6+\n" +
|
|
||||||
"jmLekAOylq+9DizrslW/EUgQyjIbcWfmyMiV6E2RwbI93tE=\n" +
|
|
||||||
"=GAhR\n" +
|
|
||||||
"-----END PGP MESSAGE-----";
|
|
||||||
|
|
||||||
PainlessResult.ResultAndInputStream resultAndInputStream = PGPainless.createDecryptor()
|
|
||||||
.onInputStream(new ByteArrayInputStream(encryptedMessage.getBytes()))
|
|
||||||
.decryptWith(new PGPSecretKeyRingCollection(Collections.singleton(juliet)), new UnprotectedKeysProtector())
|
|
||||||
.verifyWith(
|
|
||||||
Collections.singleton(juliet.getPublicKey().getKeyID()),
|
|
||||||
Collections.singleton(
|
|
||||||
new PGPPublicKeyRing(
|
|
||||||
PGPUtil.getDecoderStream(new ByteArrayInputStream(TestKeys.JULIET_PUB.getBytes())),
|
|
||||||
new BcKeyFingerprintCalculator())))
|
|
||||||
.ignoreMissingPublicKeys()
|
|
||||||
.build();
|
|
||||||
|
|
||||||
InputStream decryptor = resultAndInputStream.getInputStream();
|
|
||||||
ByteArrayOutputStream toPlain = new ByteArrayOutputStream();
|
|
||||||
Streams.pipeAll(decryptor, toPlain);
|
|
||||||
decryptor.close();
|
|
||||||
toPlain.close();
|
|
||||||
|
|
||||||
byte[] expected = "This message is encrypted\n".getBytes(Charset.forName("UTF-8"));
|
|
||||||
byte[] actual = toPlain.toByteArray();
|
|
||||||
|
|
||||||
assertTrue(Arrays.equals(expected, actual));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,33 @@
|
||||||
*/
|
*/
|
||||||
package de.vanitasvitae.crypto.pgpainless;
|
package de.vanitasvitae.crypto.pgpainless;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
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.bouncycastle.openpgp.PGPUtil;
|
||||||
|
import org.bouncycastle.openpgp.operator.KeyFingerPrintCalculator;
|
||||||
|
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
|
||||||
|
|
||||||
public class TestKeys {
|
public class TestKeys {
|
||||||
|
|
||||||
|
private static final KeyFingerPrintCalculator calc = new BcKeyFingerprintCalculator();
|
||||||
|
private static PGPSecretKeyRing julietSecretKeyRing = null;
|
||||||
|
private static PGPPublicKeyRing julietPublicKeyRing = null;
|
||||||
|
private static PGPSecretKeyRing romeoSecretKeyRing = null;
|
||||||
|
private static PGPPublicKeyRing romeoPublicKeyRing = null;
|
||||||
|
|
||||||
|
private static PGPSecretKeyRingCollection julietSecretKeyRingCollection = null;
|
||||||
|
private static PGPPublicKeyRingCollection julietPublicKeyRingCollection = null;
|
||||||
|
private static PGPSecretKeyRingCollection romeoSecretKeyRingCollection = null;
|
||||||
|
private static PGPPublicKeyRingCollection romeoPublicKeyRingCollection = null;
|
||||||
|
|
||||||
public static final String JULIET_UID = "xmpp:juliet@capulet.lit";
|
public static final String JULIET_UID = "xmpp:juliet@capulet.lit";
|
||||||
|
public static final long JULIET_KEY_ID = -5425419407118114754L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public key of xmpp:juliet@capulet.lit.
|
* Public key of xmpp:juliet@capulet.lit.
|
||||||
|
@ -46,7 +70,7 @@ public class TestKeys {
|
||||||
/**
|
/**
|
||||||
* Private key of xmpp:juliet@capulet.lit.
|
* Private key of xmpp:juliet@capulet.lit.
|
||||||
*/
|
*/
|
||||||
public static final String JULIET_PRIV = "" +
|
public static final String JULIET_SEC = "" +
|
||||||
"-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
"-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"lQOYBFrxov4BCAChZwPrBxxIlwzpieR5T2pnaOZLWH0WqSON6rVjvfbJHWdDi3Th\n" +
|
"lQOYBFrxov4BCAChZwPrBxxIlwzpieR5T2pnaOZLWH0WqSON6rVjvfbJHWdDi3Th\n" +
|
||||||
|
@ -80,6 +104,7 @@ public class TestKeys {
|
||||||
"-----END PGP PRIVATE KEY BLOCK-----";
|
"-----END PGP PRIVATE KEY BLOCK-----";
|
||||||
|
|
||||||
public static final String ROMEO_UID = "xmpp:romeo@montague.lit";
|
public static final String ROMEO_UID = "xmpp:romeo@montague.lit";
|
||||||
|
public static final long ROMEO_KEY_ID = 334147643349279223L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public key of xmpp:romeo@montague.lit.
|
* Public key of xmpp:romeo@montague.lit.
|
||||||
|
@ -107,7 +132,7 @@ public class TestKeys {
|
||||||
/**
|
/**
|
||||||
* Private key of xmpp:romeo@montague.lit.
|
* Private key of xmpp:romeo@montague.lit.
|
||||||
*/
|
*/
|
||||||
public static final String ROMEO_PRIV = "" +
|
public static final String ROMEO_SEC = "" +
|
||||||
"-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
"-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
||||||
"\n" +
|
"\n" +
|
||||||
"lQOYBFrxopkBCADiYg/+mEObXgxuMW6/LFKpEyaJK9pBMgutuxnYZ9PXWZmOhDIT\n" +
|
"lQOYBFrxopkBCADiYg/+mEObXgxuMW6/LFKpEyaJK9pBMgutuxnYZ9PXWZmOhDIT\n" +
|
||||||
|
@ -139,4 +164,105 @@ public class TestKeys {
|
||||||
"qFTwYFYxAf/RA6tuhIQEoCnpCytFMvrRKMb3Bx5vYRDVmE3jeg==\n" +
|
"qFTwYFYxAf/RA6tuhIQEoCnpCytFMvrRKMb3Bx5vYRDVmE3jeg==\n" +
|
||||||
"=LZ1b\n" +
|
"=LZ1b\n" +
|
||||||
"-----END PGP PRIVATE KEY BLOCK-----";
|
"-----END PGP PRIVATE KEY BLOCK-----";
|
||||||
|
|
||||||
|
public static PGPSecretKeyRing getJulietSecretKeyRing() throws IOException, PGPException {
|
||||||
|
if (julietSecretKeyRing == null) {
|
||||||
|
julietSecretKeyRing = new PGPSecretKeyRing(
|
||||||
|
PGPUtil.getDecoderStream(new ByteArrayInputStream(JULIET_SEC.getBytes())), calc);
|
||||||
|
}
|
||||||
|
return julietSecretKeyRing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPSecretKeyRingCollection getJulietSecretKeyRingCollection() throws IOException, PGPException {
|
||||||
|
if (julietSecretKeyRingCollection == null) {
|
||||||
|
julietSecretKeyRingCollection = new PGPSecretKeyRingCollection(
|
||||||
|
PGPUtil.getDecoderStream(new ByteArrayInputStream(JULIET_SEC.getBytes())), calc);
|
||||||
|
}
|
||||||
|
return julietSecretKeyRingCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPPublicKeyRing getJulietPublicKeyRing() throws IOException {
|
||||||
|
if (julietPublicKeyRing == null) {
|
||||||
|
julietPublicKeyRing = new PGPPublicKeyRing(
|
||||||
|
PGPUtil.getDecoderStream(new ByteArrayInputStream(JULIET_PUB.getBytes())), calc);
|
||||||
|
}
|
||||||
|
return julietPublicKeyRing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPPublicKeyRingCollection getJulietPublicKeyRingCollection() throws IOException, PGPException {
|
||||||
|
if (julietPublicKeyRingCollection == null) {
|
||||||
|
julietPublicKeyRingCollection = new PGPPublicKeyRingCollection(
|
||||||
|
PGPUtil.getDecoderStream(new ByteArrayInputStream(JULIET_PUB.getBytes())), calc);
|
||||||
|
}
|
||||||
|
return julietPublicKeyRingCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPSecretKeyRing getRomeoSecretKeyRing() throws IOException, PGPException {
|
||||||
|
if (romeoSecretKeyRing == null) {
|
||||||
|
romeoSecretKeyRing = new PGPSecretKeyRing(
|
||||||
|
PGPUtil.getDecoderStream(new ByteArrayInputStream(ROMEO_SEC.getBytes())), calc);
|
||||||
|
}
|
||||||
|
return romeoSecretKeyRing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPSecretKeyRingCollection getRomeoSecretKeyRingCollection() throws IOException, PGPException {
|
||||||
|
if (romeoSecretKeyRingCollection == null) {
|
||||||
|
romeoSecretKeyRingCollection = new PGPSecretKeyRingCollection(
|
||||||
|
PGPUtil.getDecoderStream(new ByteArrayInputStream(ROMEO_SEC.getBytes())), calc);
|
||||||
|
}
|
||||||
|
return romeoSecretKeyRingCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPPublicKeyRing getRomeoPublicKeyRing() throws IOException {
|
||||||
|
if (romeoPublicKeyRing == null) {
|
||||||
|
romeoPublicKeyRing = new PGPPublicKeyRing(
|
||||||
|
PGPUtil.getDecoderStream(new ByteArrayInputStream(ROMEO_PUB.getBytes())), calc);
|
||||||
|
}
|
||||||
|
return romeoPublicKeyRing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PGPPublicKeyRingCollection getRomeoPublicKeyRingCollection() throws IOException, PGPException {
|
||||||
|
if (romeoPublicKeyRingCollection == null) {
|
||||||
|
romeoPublicKeyRingCollection = new PGPPublicKeyRingCollection(
|
||||||
|
PGPUtil.getDecoderStream(new ByteArrayInputStream(ROMEO_PUB.getBytes())), calc);
|
||||||
|
}
|
||||||
|
return romeoPublicKeyRingCollection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String TEST_MESSAGE_01_PLAIN = "This message is encrypted\n";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Message signed with {@link #JULIET_SEC} and encrypted for {@link #JULIET_PUB}.
|
||||||
|
*/
|
||||||
|
public static final String TEST_MESSAGE_01 = "-----BEGIN PGP MESSAGE-----\n" +
|
||||||
|
"\n" +
|
||||||
|
"hQGMAwAAAAAAAAAAAQwAoJtfpcBPCwhUzzHuVIcBzBLyfIWT/EJ527neb46lN56S\n" +
|
||||||
|
"B05BTIRudIeCsPYz81jwiFi/k0MBecRfozZ1xCPByo8ohSvRgzEHEkCNgObQ1bz0\n" +
|
||||||
|
"iB+Xb76OEzFOCPUebTaVscLNf8ak/GSzaW7jDc+5vnvDf7cV0x26pe4odpS/U5Tr\n" +
|
||||||
|
"cO3wb/47K+sJ1cxJmPtcD41O02xu3QisQKPrimM0Kue6ziGeKyw1RkSowv9U47TK\n" +
|
||||||
|
"wppPCHOTli2Nf+gZizF1oyQZzPGst4fjujygcIoajplfW9nZvxsbmYRSLSdmV9m6\n" +
|
||||||
|
"k1jQbPDUhVs0gstH92C6hPpoBWxoxkHcwz8gy36nCyB6cYGyq3oN1UnGU4afPyD5\n" +
|
||||||
|
"SmmEjELBd2i2Ll/DYk2x06SnKZMQuWrSCZzWgl/9HsPo5ydVb97OjuEpWtW9xDMA\n" +
|
||||||
|
"KlYPNWEq+b+akOEstNraC3pfVKvypz6ZzaMAS1gWWNYg8dlwBJOUVMSo7iLaUQkK\n" +
|
||||||
|
"yp4uH1DlsyVu1atCUc8thQIMAwAAAAAAAAAAAQ/5AdiZ/sG859Y/rGR7U/8MzGg0\n" +
|
||||||
|
"j3f2vrgDF/0NRRk5aqd1lb4CaZvrztcYqW3cEK7iF9rKwImZZiWIptjJ9Mz6f1Zl\n" +
|
||||||
|
"FbODObSVRZAcZqYGswEEfsQvpQFlwG6Qx48OaQaDPr147raFI3C3kEU9Nb2VBg8+\n" +
|
||||||
|
"MevJaXJft5PXwUTG2Qvfxqr/3hfGAwB4/zHwA8vFd1np3spryfrC9Dq8UXUoRXIS\n" +
|
||||||
|
"xaFPiLEYt8rLef8f11OypEpmknIibu9jjJtuVZo+SjP6jgLHDwM7rqCZFITM2Qra\n" +
|
||||||
|
"2iBCt8YVcIiTK137t+EfsdVN/KHiRbc++e9zUbGMEextbtNbdoFOU4dnKBm6Su8l\n" +
|
||||||
|
"Z5UerNbR8D7+xJKfAEabdi0qI7QFmhTZ/4H/22yrvoD9jMFSBXUTE9ENIX9Hfqom\n" +
|
||||||
|
"UdsHfuE+5PC0JjkZkhchDO1M7XBX++lBCFsq2abfdpmaX+roVX0iTGboxr5Ag1Cf\n" +
|
||||||
|
"T2zWyRX/XKnvmdeGICV5qjy/ThuSWvAclazyFxWLamMztJq5BRpfAzKNQRDqlmKw\n" +
|
||||||
|
"eePtKW2EWUIjFQ5/UAM6Edu/K34ksFxb0w6YGLzQSskGr7gGAipLmpek6vcUSUA1\n" +
|
||||||
|
"oc9XJGdpx93GDRcqDjKDt/ej06VxG33/pW65ntf5QM/+LScGqaLhAHyEOsBzVIXY\n" +
|
||||||
|
"BONcadSgzkTrlbSMGAmFAQwDtLUJy1k24D4BB/0brqR0UN1LtO+Lc/vN6X/Um2CZ\n" +
|
||||||
|
"CM6MRhPnXP63Q9HHkGJ2S8zGWvQLwWL9Y14CFCgm6rACLBSIyPbihhC2OC8afhSy\n" +
|
||||||
|
"apGkdHtdghS2egs2U8qlJ2Y32IAG9CcUtNkRjxp+/RWSrmZeuL4l7DXCyH5lUadx\n" +
|
||||||
|
"5bPZhAHqW9408q2rQd9dBg2o7ciGXTJSKVahjuiB/O0gchOnbqnlYJbKbCkntXUo\n" +
|
||||||
|
"c7h4w1e8MutisSJorh7kbxgxUJSboZzEkiUfnoacPTz6bL+re9tmnpvlee70sIyM\n" +
|
||||||
|
"BiYRCyPw7Ice4R3XyWtsMTjT/wjZ//whMpWdy2drcJSyhh+GQMbekTVsNWod0lQB\n" +
|
||||||
|
"JTPUfti2VU7PMB3LjJA+l/T9iWPPx8lirnLhXOOerWKH9I5Wo4Kqv/47aJhfMO6+\n" +
|
||||||
|
"jmLekAOylq+9DizrslW/EUgQyjIbcWfmyMiV6E2RwbI93tE=\n" +
|
||||||
|
"=GAhR\n" +
|
||||||
|
"-----END PGP MESSAGE-----";
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package de.vanitasvitae.crypto.pgpainless;
|
||||||
|
|
||||||
|
import static junit.framework.TestCase.assertEquals;
|
||||||
|
import static junit.framework.TestCase.assertTrue;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import de.vanitasvitae.crypto.pgpainless.key.UnprotectedKeysProtector;
|
||||||
|
import de.vanitasvitae.crypto.pgpainless.util.BCUtil;
|
||||||
|
import org.bouncycastle.openpgp.PGPException;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||||
|
import org.bouncycastle.util.io.Streams;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class TestKeysTest extends AbstractPGPainlessTest {
|
||||||
|
|
||||||
|
private final PGPSecretKeyRing juliet;
|
||||||
|
private final PGPSecretKeyRing romeo;
|
||||||
|
|
||||||
|
public TestKeysTest() throws IOException, PGPException {
|
||||||
|
this.juliet = TestKeys.getJulietSecretKeyRing();
|
||||||
|
this.romeo = TestKeys.getRomeoSecretKeyRing();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void keyIdTest() {
|
||||||
|
assertEquals(TestKeys.JULIET_KEY_ID, juliet.getSecretKey().getKeyID());
|
||||||
|
assertEquals(TestKeys.ROMEO_KEY_ID, romeo.getSecretKey().getKeyID());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void decryptVerifyTest() throws Exception {
|
||||||
|
String encryptedMessage = TestKeys.TEST_MESSAGE_01;
|
||||||
|
|
||||||
|
PainlessResult.ResultAndInputStream resultAndInputStream = PGPainless.createDecryptor()
|
||||||
|
.onInputStream(new ByteArrayInputStream(encryptedMessage.getBytes()))
|
||||||
|
.decryptWith(new PGPSecretKeyRingCollection(Collections.singleton(juliet)), new UnprotectedKeysProtector())
|
||||||
|
.verifyWith(
|
||||||
|
Collections.singleton(juliet.getPublicKey().getKeyID()),
|
||||||
|
BCUtil.keyRingsToKeyRingCollection(BCUtil.publicKeyRingFromSecretKeyRing(juliet)))
|
||||||
|
.ignoreMissingPublicKeys()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
InputStream decryptor = resultAndInputStream.getInputStream();
|
||||||
|
ByteArrayOutputStream toPlain = new ByteArrayOutputStream();
|
||||||
|
Streams.pipeAll(decryptor, toPlain);
|
||||||
|
decryptor.close();
|
||||||
|
toPlain.close();
|
||||||
|
|
||||||
|
byte[] expected = TestKeys.TEST_MESSAGE_01_PLAIN.getBytes(Charset.forName("UTF-8"));
|
||||||
|
byte[] actual = toPlain.toByteArray();
|
||||||
|
|
||||||
|
assertTrue(Arrays.equals(expected, actual));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue