diff --git a/external-sop/src/main/kotlin/sop/external/ExternalSOP.kt b/external-sop/src/main/kotlin/sop/external/ExternalSOP.kt index 8ab7737..48a5af9 100644 --- a/external-sop/src/main/kotlin/sop/external/ExternalSOP.kt +++ b/external-sop/src/main/kotlin/sop/external/ExternalSOP.kt @@ -120,6 +120,9 @@ class ExternalSOP( val errorMessage = readString(errIn) when (exitCode) { + UnspecificFailure.EXIT_CODE -> + throw UnspecificFailure( + "External SOP backend reported an unspecific error ($exitCode):\n$errorMessage") NoSignature.EXIT_CODE -> throw NoSignature( "External SOP backend reported error NoSignature ($exitCode):\n$errorMessage") @@ -182,13 +185,16 @@ class ExternalSOP( "External SOP backend reported error NoHardwareKeyFound ($exitCode):\n$errorMessage") HardwareKeyFailure.EXIT_CODE -> throw HardwareKeyFailure( - "External SOP backend reported error HardwareKeyFalure ($exitCode):\n$errorMessage") + "External SOP backend reported error HardwareKeyFailure ($exitCode):\n$errorMessage") PrimaryKeyBad.EXIT_CODE -> throw PrimaryKeyBad( "External SOP backend reported error PrimaryKeyBad ($exitCode):\n$errorMessage") CertUserIdNoMatch.EXIT_CODE -> throw CertUserIdNoMatch( "External SOP backend reported error CertUserIdNoMatch ($exitCode):\n$errorMessage") + KeyCannotCertify.EXIT_CODE -> + throw KeyCannotCertify( + "External SOP backend reported error KeyCannotCertify ($exitCode):\n$errorMessage") // Did you forget to add a case for a new exception type? else -> diff --git a/external-sop/src/main/kotlin/sop/external/operation/CertifyUserIdExternal.kt b/external-sop/src/main/kotlin/sop/external/operation/CertifyUserIdExternal.kt index abf4d50..e3661db 100644 --- a/external-sop/src/main/kotlin/sop/external/operation/CertifyUserIdExternal.kt +++ b/external-sop/src/main/kotlin/sop/external/operation/CertifyUserIdExternal.kt @@ -12,7 +12,7 @@ import sop.operation.CertifyUserId class CertifyUserIdExternal(binary: String, environment: Properties) : CertifyUserId { - private val commandList = mutableListOf(binary, "version") + private val commandList = mutableListOf(binary, "certify-userid") private val envList = ExternalSOP.propertiesToEnv(environment).toMutableList() private var argCount = 0 @@ -44,5 +44,5 @@ class CertifyUserIdExternal(binary: String, environment: Properties) : CertifyUs override fun certs(certs: InputStream): Ready = ExternalSOP.executeTransformingOperation( - Runtime.getRuntime(), commandList.plus(keys), envList, certs) + Runtime.getRuntime(), commandList.plus("--").plus(keys), envList, certs) } diff --git a/external-sop/src/main/kotlin/sop/external/operation/MergeCertsExternal.kt b/external-sop/src/main/kotlin/sop/external/operation/MergeCertsExternal.kt index 0869fab..b739eb3 100644 --- a/external-sop/src/main/kotlin/sop/external/operation/MergeCertsExternal.kt +++ b/external-sop/src/main/kotlin/sop/external/operation/MergeCertsExternal.kt @@ -12,7 +12,7 @@ import sop.operation.MergeCerts class MergeCertsExternal(binary: String, environment: Properties) : MergeCerts { - private val commandList = mutableListOf(binary, "version") + private val commandList = mutableListOf(binary, "merge-certs") private val envList = ExternalSOP.propertiesToEnv(environment).toMutableList() private var argCount = 0 diff --git a/external-sop/src/main/kotlin/sop/external/operation/ValidateUserIdExternal.kt b/external-sop/src/main/kotlin/sop/external/operation/ValidateUserIdExternal.kt index 581d6f5..cf4742b 100644 --- a/external-sop/src/main/kotlin/sop/external/operation/ValidateUserIdExternal.kt +++ b/external-sop/src/main/kotlin/sop/external/operation/ValidateUserIdExternal.kt @@ -12,7 +12,7 @@ import sop.util.UTCUtil class ValidateUserIdExternal(binary: String, environment: Properties) : ValidateUserId { - private val commandList = mutableListOf(binary, "version") + private val commandList = mutableListOf(binary, "validate-userid") private val envList = ExternalSOP.propertiesToEnv(environment).toMutableList() private var argCount = 0 diff --git a/external-sop/src/test/java/sop/testsuite/external/operation/ExternalCertifyValidateUserIdTest.java b/external-sop/src/test/java/sop/testsuite/external/operation/ExternalCertifyValidateUserIdTest.java new file mode 100644 index 0000000..bb319ca --- /dev/null +++ b/external-sop/src/test/java/sop/testsuite/external/operation/ExternalCertifyValidateUserIdTest.java @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2025 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package sop.testsuite.external.operation; + +import org.junit.jupiter.api.condition.EnabledIf; +import sop.testsuite.operation.CertifyValidateUserIdTest; + +@EnabledIf("sop.testsuite.operation.AbstractSOPTest#hasBackends") +public class ExternalCertifyValidateUserIdTest extends CertifyValidateUserIdTest { + +} diff --git a/external-sop/src/test/java/sop/testsuite/external/operation/ExternalChangeKeyPasswordTest.java b/external-sop/src/test/java/sop/testsuite/external/operation/ExternalChangeKeyPasswordTest.java new file mode 100644 index 0000000..42a9693 --- /dev/null +++ b/external-sop/src/test/java/sop/testsuite/external/operation/ExternalChangeKeyPasswordTest.java @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2025 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package sop.testsuite.external.operation; + +import org.junit.jupiter.api.condition.EnabledIf; +import sop.testsuite.operation.ChangeKeyPasswordTest; + +@EnabledIf("sop.testsuite.operation.AbstractSOPTest#hasBackends") +public class ExternalChangeKeyPasswordTest extends ChangeKeyPasswordTest { + +} diff --git a/external-sop/src/test/java/sop/testsuite/external/operation/ExternalMergeCertsTest.java b/external-sop/src/test/java/sop/testsuite/external/operation/ExternalMergeCertsTest.java new file mode 100644 index 0000000..8b22b37 --- /dev/null +++ b/external-sop/src/test/java/sop/testsuite/external/operation/ExternalMergeCertsTest.java @@ -0,0 +1,13 @@ +// SPDX-FileCopyrightText: 2025 Paul Schaub +// +// SPDX-License-Identifier: Apache-2.0 + +package sop.testsuite.external.operation; + +import org.junit.jupiter.api.condition.EnabledIf; +import sop.testsuite.operation.MergeCertsTest; + +@EnabledIf("sop.testsuite.operation.AbstractSOPTest#hasBackends") +public class ExternalMergeCertsTest extends MergeCertsTest { + +} diff --git a/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopCLI.kt b/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopCLI.kt index 98701fc..07caa03 100644 --- a/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopCLI.kt +++ b/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopCLI.kt @@ -64,7 +64,7 @@ class SopCLI { @JvmField var EXECUTABLE_NAME = "sop" @JvmField - @Option(names = ["--stacktrace"], scope = ScopeType.INHERIT) + @Option(names = ["--stacktrace", "--debug"], scope = ScopeType.INHERIT) var stacktrace = false @JvmStatic diff --git a/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopVCLI.kt b/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopVCLI.kt index 9a8b4b4..fa9683f 100644 --- a/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopVCLI.kt +++ b/sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopVCLI.kt @@ -45,7 +45,7 @@ class SopVCLI { @JvmField var EXECUTABLE_NAME = "sopv" @JvmField - @CommandLine.Option(names = ["--stacktrace"], scope = CommandLine.ScopeType.INHERIT) + @CommandLine.Option(names = ["--stacktrace", "--debug"], scope = CommandLine.ScopeType.INHERIT) var stacktrace = false @JvmStatic diff --git a/sop-java-testfixtures/src/main/java/sop/testsuite/operation/CertifyValidateUserIdTest.java b/sop-java-testfixtures/src/main/java/sop/testsuite/operation/CertifyValidateUserIdTest.java index c97fda7..7f9f088 100644 --- a/sop-java-testfixtures/src/main/java/sop/testsuite/operation/CertifyValidateUserIdTest.java +++ b/sop-java-testfixtures/src/main/java/sop/testsuite/operation/CertifyValidateUserIdTest.java @@ -14,7 +14,6 @@ import sop.exception.SOPGPException; import java.io.IOException; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -47,16 +46,17 @@ public class CertifyValidateUserIdTest { // Alice has her own user-id self-certified assertTrue(sop.validateUserId() - .authorities(aliceCert) - .userId("Alice ") - .subjects(aliceCert), + .authorities(aliceCert) + .userId("Alice ") + .subjects(aliceCert), "Alice accepts her own self-certified user-id"); // Alice has not yet certified Bobs user-id - assertFalse(sop.validateUserId() - .authorities(aliceCert) - .userId("Bob ") - .subjects(bobCert), + assertThrows(SOPGPException.CertUserIdNoMatch.class, () -> + sop.validateUserId() + .authorities(aliceCert) + .userId("Bob ") + .subjects(bobCert), "Alice has not yet certified Bobs user-id"); byte[] bobCertifiedByAlice = sop.certifyUserId() @@ -67,10 +67,10 @@ public class CertifyValidateUserIdTest { .getBytes(); assertTrue(sop.validateUserId() - .userId("Bob ") - .authorities(aliceCert) - .subjects(bobCertifiedByAlice), - "Alice accepts Bobs user-id after she certified it"); + .userId("Bob ") + .authorities(aliceCert) + .subjects(bobCertifiedByAlice), + "Alice accepts Bobs user-id after she certified it"); } @ParameterizedTest @@ -132,11 +132,11 @@ public class CertifyValidateUserIdTest { .getBytes(); assertThrows(SOPGPException.CertUserIdNoMatch.class, () -> - sop.certifyUserId() - .userId("Bobby") - .keys(aliceKey) - .certs(bobCert) - .getBytes(), + sop.certifyUserId() + .userId("Bobby") + .keys(aliceKey) + .certs(bobCert) + .getBytes(), "Alice cannot create a pet-name for Bob without the --no-require-self-sig flag"); byte[] bobWithPetName = sop.certifyUserId() @@ -147,15 +147,16 @@ public class CertifyValidateUserIdTest { .getBytes(); assertTrue(sop.validateUserId() - .userId("Bobby") - .authorities(aliceCert) - .subjects(bobWithPetName), + .userId("Bobby") + .authorities(aliceCert) + .subjects(bobWithPetName), "Alice accepts the pet-name she gave to Bob"); - assertFalse(sop.validateUserId() - .userId("Bobby") - .authorities(bobWithPetName) - .subjects(bobWithPetName), + assertThrows(SOPGPException.CertUserIdNoMatch.class, () -> + sop.validateUserId() + .userId("Bobby") + .authorities(bobWithPetName) + .subjects(bobWithPetName), "Bob does not accept the pet-name Alice gave him"); } diff --git a/sop-java-testfixtures/src/main/java/sop/testsuite/operation/GenerateKeyTest.java b/sop-java-testfixtures/src/main/java/sop/testsuite/operation/GenerateKeyTest.java index b63b4b8..0d8b78e 100644 --- a/sop-java-testfixtures/src/main/java/sop/testsuite/operation/GenerateKeyTest.java +++ b/sop-java-testfixtures/src/main/java/sop/testsuite/operation/GenerateKeyTest.java @@ -119,7 +119,9 @@ public class GenerateKeyTest extends AbstractSOPTest { assertThrows(SOPGPException.CertCannotEncrypt.class, () -> sop.encrypt().withCert(signingOnlyCert) - .plaintext(TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8))); + .plaintext(TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8)) + .toByteArrayAndResult() + .getBytes()); } @ParameterizedTest diff --git a/sop-java-testfixtures/src/main/java/sop/testsuite/operation/MergeCertsTest.java b/sop-java-testfixtures/src/main/java/sop/testsuite/operation/MergeCertsTest.java index 7bc99d1..b577017 100644 --- a/sop-java-testfixtures/src/main/java/sop/testsuite/operation/MergeCertsTest.java +++ b/sop-java-testfixtures/src/main/java/sop/testsuite/operation/MergeCertsTest.java @@ -25,18 +25,15 @@ public class MergeCertsTest extends AbstractSOPTest { @MethodSource("provideInstances") public void testMergeWithItself(SOP sop) throws IOException { byte[] key = sop.generateKey() - .noArmor() .userId("Alice ") .generate() .getBytes(); byte[] cert = sop.extractCert() - .noArmor() .key(key) .getBytes(); byte[] merged = sop.mergeCerts() - .noArmor() .updates(cert) .baseCertificates(cert) .getBytes(); @@ -69,20 +66,17 @@ public class MergeCertsTest extends AbstractSOPTest { @MethodSource("provideInstances") public void testMergeWithItselfViaBase(SOP sop) throws IOException { byte[] key = sop.generateKey() - .noArmor() .userId("Alice ") .generate() .getBytes(); byte[] cert = sop.extractCert() - .noArmor() .key(key) .getBytes(); byte[] certs = ArraysKt.plus(cert, cert); byte[] merged = sop.mergeCerts() - .noArmor() .updates(cert) .baseCertificates(certs) .getBytes(); @@ -94,23 +88,19 @@ public class MergeCertsTest extends AbstractSOPTest { @MethodSource("provideInstances") public void testApplyBaseToUpdate(SOP sop) throws IOException { byte[] key = sop.generateKey() - .noArmor() .userId("Alice ") .generate() .getBytes(); byte[] cert = sop.extractCert() - .noArmor() .key(key) .getBytes(); byte[] update = sop.revokeKey() - .noArmor() .keys(key) .getBytes(); byte[] merged = sop.mergeCerts() - .noArmor() .updates(cert) .baseCertificates(update) .getBytes(); @@ -122,23 +112,19 @@ public class MergeCertsTest extends AbstractSOPTest { @MethodSource("provideInstances") public void testApplyUpdateToBase(SOP sop) throws IOException { byte[] key = sop.generateKey() - .noArmor() .userId("Alice ") .generate() .getBytes(); byte[] cert = sop.extractCert() - .noArmor() .key(key) .getBytes(); byte[] update = sop.revokeKey() - .noArmor() .keys(key) .getBytes(); byte[] merged = sop.mergeCerts() - .noArmor() .updates(update) .baseCertificates(cert) .getBytes(); @@ -150,29 +136,24 @@ public class MergeCertsTest extends AbstractSOPTest { @MethodSource("provideInstances") public void testApplyUpdateToMissingBaseDoesNothing(SOP sop) throws IOException { byte[] aliceKey = sop.generateKey() - .noArmor() .userId("Alice ") .generate() .getBytes(); byte[] aliceCert = sop.extractCert() - .noArmor() .key(aliceKey) .getBytes(); byte[] bobKey = sop.generateKey() - .noArmor() .userId("Bob ") .generate() .getBytes(); byte[] bobCert = sop.extractCert() - .noArmor() .key(bobKey) .getBytes(); byte[] merged = sop.mergeCerts() - .noArmor() .updates(bobCert) .baseCertificates(aliceCert) .getBytes();