From 8647fde8969b2c64fbf7560cad979ae1ae778554 Mon Sep 17 00:00:00 2001 From: Paul Schaub Date: Sun, 10 Jun 2018 17:12:44 +0200 Subject: [PATCH] Rework tests --- .../crypto/pgpainless/PainlessResult.java | 26 ++- .../SignatureVerifyingInputStream.java | 5 + .../crypto/pgpainless/util/BCUtil.java | 39 ++++ .../pgpainless/AbstractPGPainlessTest.java | 14 ++ .../crypto/pgpainless/EncryptDecryptTest.java | 176 ++++++++---------- .../crypto/pgpainless/TestKeys.java | 130 ++++++++++++- .../crypto/pgpainless/TestKeysTest.java | 62 ++++++ 7 files changed, 354 insertions(+), 98 deletions(-) create mode 100644 src/main/java/de/vanitasvitae/crypto/pgpainless/util/BCUtil.java create mode 100644 src/test/java/de/vanitasvitae/crypto/pgpainless/AbstractPGPainlessTest.java create mode 100644 src/test/java/de/vanitasvitae/crypto/pgpainless/TestKeysTest.java diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/PainlessResult.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/PainlessResult.java index 8d0a62ed..570fc8b9 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/PainlessResult.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/PainlessResult.java @@ -6,6 +6,8 @@ import java.util.Set; import de.vanitasvitae.crypto.pgpainless.algorithm.CompressionAlgorithm; import de.vanitasvitae.crypto.pgpainless.algorithm.SymmetricKeyAlgorithm; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPPublicKeyRing; public class PainlessResult { @@ -38,6 +40,10 @@ public class PainlessResult { return recipientKeyIds; } + public boolean isEncrypted() { + return !getRecipientKeyIds().isEmpty(); + } + public Long getDecryptionKeyId() { return decryptionKeyId; } @@ -54,14 +60,32 @@ public class PainlessResult { return integrityProtected; } - public Set getSignatureKeyIds() { + public Set getAllSignatureKeyIds() { return signatureKeyIds; } + public boolean isSigned() { + return !signatureKeyIds.isEmpty(); + } + public Set getVerifiedSignatureKeyIds() { 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() { return new Builder(); } diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/SignatureVerifyingInputStream.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/SignatureVerifyingInputStream.java index 2a89b91c..ac01d6a9 100644 --- a/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/SignatureVerifyingInputStream.java +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/decryption_verification/SignatureVerifyingInputStream.java @@ -6,6 +6,8 @@ import java.io.InputStream; import java.security.SignatureException; import java.util.Iterator; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import de.vanitasvitae.crypto.pgpainless.PainlessResult; import org.bouncycastle.openpgp.PGPException; @@ -16,6 +18,8 @@ import org.bouncycastle.openpgp.PGPSignatureList; public class SignatureVerifyingInputStream extends FilterInputStream { + private static final Logger LOGGER = Logger.getLogger(SignatureVerifyingInputStream.class.getName()); + private final PGPObjectFactory objectFactory; private final Map onePassSignatures; private final PainlessResult.Builder resultBuilder; @@ -44,6 +48,7 @@ public class SignatureVerifyingInputStream extends FilterInputStream { private void validateOnePassSignatures() throws IOException { if (onePassSignatures.isEmpty()) { + LOGGER.log(Level.FINE, "No One-Pass-Signatures found -> No validation."); return; } diff --git a/src/main/java/de/vanitasvitae/crypto/pgpainless/util/BCUtil.java b/src/main/java/de/vanitasvitae/crypto/pgpainless/util/BCUtil.java new file mode 100644 index 00000000..9ef57dab --- /dev/null +++ b/src/main/java/de/vanitasvitae/crypto/pgpainless/util/BCUtil.java @@ -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 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()); + } +} \ No newline at end of file diff --git a/src/test/java/de/vanitasvitae/crypto/pgpainless/AbstractPGPainlessTest.java b/src/test/java/de/vanitasvitae/crypto/pgpainless/AbstractPGPainlessTest.java new file mode 100644 index 00000000..42d38766 --- /dev/null +++ b/src/test/java/de/vanitasvitae/crypto/pgpainless/AbstractPGPainlessTest.java @@ -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()); + } +} diff --git a/src/test/java/de/vanitasvitae/crypto/pgpainless/EncryptDecryptTest.java b/src/test/java/de/vanitasvitae/crypto/pgpainless/EncryptDecryptTest.java index d5fd8ddd..27380957 100644 --- a/src/test/java/de/vanitasvitae/crypto/pgpainless/EncryptDecryptTest.java +++ b/src/test/java/de/vanitasvitae/crypto/pgpainless/EncryptDecryptTest.java @@ -1,6 +1,5 @@ package de.vanitasvitae.crypto.pgpainless; -import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertTrue; import java.io.ByteArrayInputStream; @@ -9,133 +8,120 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; 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.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 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.PGPPublicKeyRing; 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.junit.Ignore; import org.junit.Test; -public class EncryptDecryptTest { - 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 class EncryptDecryptTest extends AbstractPGPainlessTest { - 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 - public void keyIdTest() { - assertEquals("b4b509cb5936e03e", Long.toHexString(juliet.getSecretKey().getKeyID())); + public void freshEcTest() throws IOException, PGPException, NoSuchAlgorithmException, NoSuchProviderException, + InvalidAlgorithmParameterException { + PGPSecretKeyRing aliceSec = PGPainless.generateKeyRing().simpleEcKeyRing("alice@wonderland.lit"); + PGPSecretKeyRing hatterSec = PGPainless.generateKeyRing().simpleEcKeyRing("hatter@wonderland.lit"); + + encryptDecryptForSecretKeyRings(aliceSec, hatterSec); } @Test - public void test() throws Exception { - Security.addProvider(new BouncyCastleProvider()); - PGPPublicKeyRing jPub = new PGPPublicKeyRing(PGPUtil.getDecoderStream(new ByteArrayInputStream(TestKeys.JULIET_PUB.getBytes())), new BcKeyFingerprintCalculator()); + public void freshRsaEcTest() + throws PGPException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, + 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) - .toRecipient(jPub.getPublicKey()) + @Test + 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() - .signWith(new PGPSecretKeyRing(PGPUtil.getDecoderStream(new ByteArrayInputStream(TestKeys.JULIET_PRIV.getBytes())), new BcKeyFingerprintCalculator()), new UnprotectedKeysProtector()) - .asciiArmor(); + .signWith(hatterSec, keyDecryptor) + .noArmor(); - String message = "This message is encrypted using OpenPGP"; - ByteArrayInputStream fromPlain = new ByteArrayInputStream(message.getBytes()); - - Streams.pipeAll(fromPlain, encryptor); - fromPlain.close(); + Streams.pipeAll(new ByteArrayInputStream(secretMessage), encryptor); encryptor.close(); + byte[] encryptedSecretMessage = envelope.toByteArray(); - System.out.println(new String(toEncrypted.toByteArray())); - - - ByteArrayInputStream fromEncrypted = new ByteArrayInputStream(toEncrypted.toByteArray()); - ByteArrayOutputStream toPlain = new ByteArrayOutputStream(); + // Juliet trieth to comprehend Romeos words + ByteArrayInputStream envelopeIn = new ByteArrayInputStream(encryptedSecretMessage); PainlessResult.ResultAndInputStream resultAndInputStream = PGPainless.createDecryptor() - .onInputStream(fromEncrypted) - .decryptWith(new PGPSecretKeyRingCollection(Collections.singleton(juliet)), - new UnprotectedKeysProtector()) - .verifyWith(Collections.singleton(jPub.getPublicKey().getKeyID()), Collections.singleton(jPub)) + .onInputStream(envelopeIn) + .decryptWith(BCUtil.keyRingsToKeyRingCollection(aliceSec), keyDecryptor) + .verifyWith(Collections.singleton(TestKeys.ROMEO_KEY_ID), BCUtil.keyRingsToKeyRingCollection(hatterPub)) .ignoreMissingPublicKeys() .build(); InputStream decryptor = resultAndInputStream.getInputStream(); + OutputStream decryptedSecretMessage = new ByteArrayOutputStream(); - Streams.pipeAll(decryptor, toPlain); - - fromEncrypted.close(); + Streams.pipeAll(decryptor, decryptedSecretMessage); decryptor.close(); - assertTrue(Arrays.equals(message.getBytes(), toPlain.toByteArray())); - } + assertTrue(Arrays.equals(secretMessage, ((ByteArrayOutputStream) decryptedSecretMessage).toByteArray())); - @Test - public void decryptVerifyTest() throws Exception { - 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)); + PainlessResult result = resultAndInputStream.getResult(); + assertTrue(result.containsVerifiedSignatureFrom(hatterPub)); } } diff --git a/src/test/java/de/vanitasvitae/crypto/pgpainless/TestKeys.java b/src/test/java/de/vanitasvitae/crypto/pgpainless/TestKeys.java index 106ef0ab..1b0980b4 100644 --- a/src/test/java/de/vanitasvitae/crypto/pgpainless/TestKeys.java +++ b/src/test/java/de/vanitasvitae/crypto/pgpainless/TestKeys.java @@ -16,9 +16,33 @@ */ 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 { + 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 long JULIET_KEY_ID = -5425419407118114754L; /** * Public key of xmpp:juliet@capulet.lit. @@ -46,7 +70,7 @@ public class TestKeys { /** * 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" + "\n" + "lQOYBFrxov4BCAChZwPrBxxIlwzpieR5T2pnaOZLWH0WqSON6rVjvfbJHWdDi3Th\n" + @@ -80,6 +104,7 @@ public class TestKeys { "-----END PGP PRIVATE KEY BLOCK-----"; 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. @@ -107,7 +132,7 @@ public class TestKeys { /** * 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" + "\n" + "lQOYBFrxopkBCADiYg/+mEObXgxuMW6/LFKpEyaJK9pBMgutuxnYZ9PXWZmOhDIT\n" + @@ -139,4 +164,105 @@ public class TestKeys { "qFTwYFYxAf/RA6tuhIQEoCnpCytFMvrRKMb3Bx5vYRDVmE3jeg==\n" + "=LZ1b\n" + "-----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-----"; } diff --git a/src/test/java/de/vanitasvitae/crypto/pgpainless/TestKeysTest.java b/src/test/java/de/vanitasvitae/crypto/pgpainless/TestKeysTest.java new file mode 100644 index 00000000..53800c2e --- /dev/null +++ b/src/test/java/de/vanitasvitae/crypto/pgpainless/TestKeysTest.java @@ -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)); + } +}