diff --git a/pgpainless-sop/src/test/java/org/pgpainless/sop/EncryptDecryptTest.java b/pgpainless-sop/src/test/java/org/pgpainless/sop/commands/EncryptDecryptTest.java similarity index 97% rename from pgpainless-sop/src/test/java/org/pgpainless/sop/EncryptDecryptTest.java rename to pgpainless-sop/src/test/java/org/pgpainless/sop/commands/EncryptDecryptTest.java index 66d1ae5b..a521faf2 100644 --- a/pgpainless-sop/src/test/java/org/pgpainless/sop/EncryptDecryptTest.java +++ b/pgpainless-sop/src/test/java/org/pgpainless/sop/commands/EncryptDecryptTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.pgpainless.sop; +package org.pgpainless.sop.commands; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -31,6 +31,8 @@ import java.nio.charset.StandardCharsets; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import org.pgpainless.sop.PGPainlessCLI; +import org.pgpainless.sop.TestUtils; import picocli.CommandLine; public class EncryptDecryptTest { diff --git a/pgpainless-sop/src/test/java/org/pgpainless/sop/ExtractCertTest.java b/pgpainless-sop/src/test/java/org/pgpainless/sop/commands/ExtractCertTest.java similarity index 96% rename from pgpainless-sop/src/test/java/org/pgpainless/sop/ExtractCertTest.java rename to pgpainless-sop/src/test/java/org/pgpainless/sop/commands/ExtractCertTest.java index 41bef399..e9e52e75 100644 --- a/pgpainless-sop/src/test/java/org/pgpainless/sop/ExtractCertTest.java +++ b/pgpainless-sop/src/test/java/org/pgpainless/sop/commands/ExtractCertTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.pgpainless.sop; +package org.pgpainless.sop.commands; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -31,6 +31,7 @@ import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.junit.jupiter.api.Test; import org.pgpainless.PGPainless; import org.pgpainless.key.info.KeyRingInfo; +import org.pgpainless.sop.PGPainlessCLI; import picocli.CommandLine; public class ExtractCertTest { diff --git a/pgpainless-sop/src/test/java/org/pgpainless/sop/GenerateCertTest.java b/pgpainless-sop/src/test/java/org/pgpainless/sop/commands/GenerateCertTest.java similarity index 95% rename from pgpainless-sop/src/test/java/org/pgpainless/sop/GenerateCertTest.java rename to pgpainless-sop/src/test/java/org/pgpainless/sop/commands/GenerateCertTest.java index e51d39a0..91e7d335 100644 --- a/pgpainless-sop/src/test/java/org/pgpainless/sop/GenerateCertTest.java +++ b/pgpainless-sop/src/test/java/org/pgpainless/sop/commands/GenerateCertTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.pgpainless.sop; +package org.pgpainless.sop.commands; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -32,6 +32,8 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.pgpainless.PGPainless; import org.pgpainless.key.info.KeyRingInfo; +import org.pgpainless.sop.PGPainlessCLI; +import org.pgpainless.sop.TestUtils; import picocli.CommandLine; public class GenerateCertTest { diff --git a/pgpainless-sop/src/test/java/org/pgpainless/sop/commands/SignVerifyTest.java b/pgpainless-sop/src/test/java/org/pgpainless/sop/commands/SignVerifyTest.java new file mode 100644 index 00000000..76c28ba7 --- /dev/null +++ b/pgpainless-sop/src/test/java/org/pgpainless/sop/commands/SignVerifyTest.java @@ -0,0 +1,129 @@ +/* + * Copyright 2021 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.pgpainless.sop.commands; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.nio.charset.StandardCharsets; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.util.Date; + +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.util.io.Streams; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.pgpainless.PGPainless; +import org.pgpainless.key.OpenPgpV4Fingerprint; +import org.pgpainless.key.info.KeyRingInfo; +import org.pgpainless.key.util.KeyRingUtils; +import org.pgpainless.sop.PGPainlessCLI; +import org.pgpainless.sop.TestUtils; +import picocli.CommandLine; + +public class SignVerifyTest { + + private static File tempDir; + private static PrintStream originalSout; + + private final String data = "If privacy is outlawed, only outlaws will have privacy.\n"; + + @BeforeAll + public static void prepare() throws IOException { + tempDir = TestUtils.createTempDirectory(); + } + + @Test + public void testSignatureCreationAndVerification() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException { + originalSout = System.out; + InputStream originalIn = System.in; + + // Write alice key to disc + File aliceKeyFile = new File(tempDir, "alice.key"); + assertTrue(aliceKeyFile.createNewFile()); + PGPSecretKeyRing aliceKeys = PGPainless.generateKeyRing() + .modernKeyRing("alice", null); + OutputStream aliceKeyOut = new FileOutputStream(aliceKeyFile); + Streams.pipeAll(new ByteArrayInputStream(aliceKeys.getEncoded()), aliceKeyOut); + aliceKeyOut.close(); + + // Write alice pub key to disc + File aliceCertFile = new File(tempDir, "alice.pub"); + assertTrue(aliceCertFile.createNewFile()); + PGPPublicKeyRing alicePub = KeyRingUtils.publicKeyRingFrom(aliceKeys); + OutputStream aliceCertOut = new FileOutputStream(aliceCertFile); + Streams.pipeAll(new ByteArrayInputStream(alicePub.getEncoded()), aliceCertOut); + aliceCertOut.close(); + + // Write test data to disc + File dataFile = new File(tempDir, "data"); + assertTrue(dataFile.createNewFile()); + FileOutputStream dataOut = new FileOutputStream(dataFile); + Streams.pipeAll(new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)), dataOut); + dataOut.close(); + + // Sign test data + FileInputStream dataIn = new FileInputStream(dataFile); + System.setIn(dataIn); + File sigFile = new File(tempDir, "sig.asc"); + assertTrue(sigFile.createNewFile()); + FileOutputStream sigOut = new FileOutputStream(sigFile); + System.setOut(new PrintStream(sigOut)); + new CommandLine(new PGPainlessCLI()).execute("sign", "--armor", aliceKeyFile.getAbsolutePath()); + sigOut.close(); + + // verify test data signature + ByteArrayOutputStream verifyOut = new ByteArrayOutputStream(); + System.setOut(new PrintStream(verifyOut)); + dataIn = new FileInputStream(dataFile); + System.setIn(dataIn); + new CommandLine(new PGPainlessCLI()).execute("verify", sigFile.getAbsolutePath(), aliceCertFile.getAbsolutePath()); + dataIn.close(); + + // Test verification output + + // [date] [signing-key-fp] [primary-key-fp] signed by [key.pub] + String verification = verifyOut.toString(); + String[] split = verification.split(" "); + OpenPgpV4Fingerprint primaryKeyFingerprint = new OpenPgpV4Fingerprint(aliceKeys); + OpenPgpV4Fingerprint signingKeyFingerprint = new OpenPgpV4Fingerprint(new KeyRingInfo(alicePub, new Date()).getSigningSubkeys().get(0)); + assertEquals(signingKeyFingerprint.toString(), split[1]); + assertEquals(primaryKeyFingerprint.toString(), split[2]); + + System.setIn(originalIn); + } + + @AfterAll + public static void after() { + System.setOut(originalSout); + // CHECKSTYLE:OFF + System.out.println(tempDir.getAbsolutePath()); + // CHECKSTYLE:ON + } +}